#! /usr/local/bin/python

import sys
import os
import ldap
import subprocess
from optparse import OptionParser

sys.path.append(os.path.realpath(os.path.join(__file__, '..', '..', 'conf')))
from ldapConf import *
from ldapUtil import *


##################################################################################
# global constants
##################################################################################
version="%prog: 2012-09-26"
modifiedBy="Garry Thuna"


##################################################################################
# parse command line options
##################################################################################
usage = "usage: %prog [options] [uid1 [[uid2] [[...]]]" 
description = "Ensures that the user's home directory exists; "  +\
              "that it has correct user, group and permissions; "  +\
              "and sets up a subdirectory of links for any workspace "  +\
              "to which the user has access."
parser = OptionParser(usage=usage, version=version, description=description)
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                        help="show changes made to file system [default: %default]")
parser.add_option("-f", "--force-perms", action="store_true", dest="force", default=False,
                        help="force the recursive application of permissions (only needed " +\
                             "if the user's home was migrated/copied from somewhere else)")
(options, args) = parser.parse_args()


##################################################################################
# bind to the ldap server 
#     do the preliminary procssing of users and groups
#     do the preliminary procssing of workspaces
##################################################################################
con = ldap.initialize(BIND_URI_SERVER)
if BIND_TLS:
    con.start_tls_s()
con.simple_bind_s(BIND_DN_SERVER, BIND_PW_SERVER)

groups,                \
    users,             \
     gid2group,        \
     uid2user,         \
     belongsTo,        \
    workspaces,        \
     gtwsName2ws,      \
     gtwsName2path,    \
     gid2gtwsName,     \
     uid2gtwsName,     \
    servers,           \
     gtsName2server  = preProcessLdapObjects(con)

con.unbind_s()


##################################################################################
# set up the homes
##################################################################################
smbConf = ''  #string in which to accumulate the samba share definitions
for u in users:
    dn, attrs = u
    uid = attrs['uid'][0]

    # is the user's home is on this server
    if 'sambaHomePath' not in attrs:
        print >> sys.stderr, '  *** Error no "sambaHomePath" set for user: ' + uid
        continue
    if attrs['sambaHomePath'][0].lower().find(SERVER_SHORT_NAME.lower()) < 0:
        continue

    # accumulate the share definition in a string
    userDir = os.path.join(SAMBA_HOME, uid)
    smbConf = smbConf + SAMBA_HOME_TEMPLATE.format(
            shareName    = uid,
            shareComment = 'home directory of ' + attrs['cn'][0],
            sharePath    = userDir
        )
    #all users get recycle bins
    smbConf = smbConf + SAMBA_RECYCLE_TEMPLATE.format(
            recycleDir = os.path.join(SAMBA_USER_HOME, SAMBA_RECYCLE_DIR)
        ) 

    # were specific users specified on the command line
    if len(args) > 0 and uid.lower() not in [a.lower() for a in args]:
        continue

    if options.verbose: 
        print 'processing user:',
        print uid \
            + '  (' + attrs['uidNumber'][0] + ')  ' \
            + 'dn: ' + dn

    # create user's directory
    userDir = os.path.join(SAMBA_HOME, uid)
    homeDir = os.path.join(SAMBA_HOME, uid, SAMBA_USER_HOME)
    if options.verbose: 
        print '    ensuring user directory exists:       ' + homeDir
    p = subprocess.Popen([ "mkdir", "-p", homeDir ]); p.wait()
    if p.returncode:
        print >> sys.stderr, '  *** Error (re)creating directory: ' + homeDir

    # correct permissions
    if options.verbose: 
        print '    setting ownership and permissions on: ' + SAMBA_HOME
    setOwnerGroupPerms(SAMBA_HOME,  ROOT_UID, MEMBERFULL_GID, 00510)

    if options.verbose:
        print '    setting ownership and permissions on: ' + userDir
    setOwnerGroupPerms(userDir,     uid,      MEMBERLESS_GID, 02550)

    if options.verbose:
        print '    setting ownership and permissions on: ' + homeDir
    if options.force:
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 02770, applyTo='d')
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 00660, applyTo='f')
    else:
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 02770)

    # determine the unique set of workspaces that the user can access
    accessibleWsNames= list()
    for gid in belongsTo[ uid ]:                        #groups that user belongs to
        if gid in gid2gtwsName:                         #there are workspaces to which this gnum has access
            for gtwsName in gid2gtwsName[gid]:          #workspaces accessible by gnum
                if gtwsName not in accessibleWsNames:   #if we haven't already added workspace to list
                    accessibleWsNames.append(gtwsName)  # then do so
    if uid in uid2gtwsName:                             #there are workspaces to which this uid has access
        for gtwsName in uid2gtwsName[uid]:              #workspaces accessible by uid
            if gtwsName not in accessibleWsNames:       #if we haven't already added workspace to list
                accessibleWsNames.append(gtwsName)      # then do so

    # modify the accessbileWsNames so that we also have the server and path
    # and then sort by the server + path
    accessibles = [ (x,) + gtwsName2path[x] for x in accessibleWsNames ]
    accessibles.sort(key=lambda x: x[1]+x[2])

    # setup the linkFiles to accessible workspaces
    linkFiles = list()
    for gtwsName, gtsName, path in accessibles:
        serverAttrs = gtsName2server[gtsName][1]
        serverDir = os.path.join(userDir, serverAttrs['gtDisplayName'][0])
        if not os.path.exists(serverDir):
            os.mkdir(serverDir)
        if options.verbose: 
            print '    setting ownership and permissions on: ' + serverDir
        setOwnerGroupPerms(serverDir, uid, MEMBERLESS_GID, 00500)

        # write out the linkFile/URL
        wsDn, wsAttr = gtwsName2ws[gtwsName] 
        linkFile = os.path.join(serverDir, wsAttr['gtwsName'][0] + '.url')
        if options.verbose: 
            print '    writing link file: ' + linkFile
        with open(linkFile, 'w') as f:
            f.write("[InternetShortcut]" + "\r\n")
            f.write("URL=file://" + serverAttrs['gtFQDN'][0] + "/" + wsAttr['gtwsName'][0] + "\r\n")
        setOwnerGroupPerms(linkFile, uid, MEMBERLESS_GID, 00400)
        linkFiles.append(linkFile)

    # remove links no longer available
    if options.verbose: 
        print '    removing dead/revoked links'
    for dirpath, dirnames, filenames in os.walk(userDir):
        if dirpath == userDir:
            if SAMBA_USER_HOME in dirnames:
                dirnames.remove(SAMBA_USER_HOME)
            continue
        for f in filenames:
            if f.endswith('.url'):
                linkName = os.path.join(dirpath, f)  #reconstruct full linkfile path
                if linkName not in linkFiles:
                    if options.verbose: 
                        print '        removing link ' + linkName
                    os.unlink(os.path.join(dirpath, f))

    # cleanup: if subdir is empty then remove it 
    if options.verbose: 
        print '    cleanup links'
    for dirpath, dirnames, filenames in os.walk(userDir):
        if dirpath == userDir:
            if SAMBA_USER_HOME in dirnames:
                dirnames.remove(SAMBA_USER_HOME)
            continue
        if len(dirnames) + len(filenames) == 0:
            if options.verbose: 
                print '        deleting empty server folder:  ' + dirpath
            os.rmdir(dirpath)

#    # setup the static linkFiles
#    staticDir = os.path.join(userDir, 'links')
#    if not os.path.exists(staticDir):
#        os.mkdir(staticDir)
#    if options.verbose: 
#        print '    setting ownership and permissions on: ' + staticDir
#    setOwnerGroupPerms(staticDir, attrs['uidNumber'][0], attrs['gidNumber'][0], 00500)
#
#    # write out the static linkFile/URL
#    linkFile = os.path.join(staticDir, 'changePassword.url')
#    if options.verbose: 
#        print '    writing link file: ' + linkFile
#    with open(linkFile, 'w') as f:
#        f.write("[InternetShortcut]" + "\r\n")
#        f.write("URL=https://dirsrv1peg.yyc.avmaxgroup.com/changePassword.html" + "\r\n")
#    setOwnerGroupPerms(linkFile, attrs['uidNumber'][0], attrs['gidNumber'][0], 00400)

# write out the smb conf for homes
with open(os.path.join(SAMBA_ROOT, SAMBA_HOME_CONF), 'w') as f:
    f.write(smbConf)
setOwnerGroupPerms(os.path.join(SAMBA_ROOT, SAMBA_HOME_CONF), '0', '0', 00664)


d9a254f9a516b9f59c23721adeba07658968ca73
#! /usr/local/bin/python

import sys
import os
import ldap
import subprocess
from optparse import OptionParser

sys.path.append(os.path.realpath(os.path.join(__file__, '..', '..', 'conf')))
from ldapConf import *
from ldapUtil import *


##################################################################################
# global constants
##################################################################################
version="%prog: 2012-09-26"
modifiedBy="Garry Thuna"


##################################################################################
# parse command line options
##################################################################################
usage = "usage: %prog [options] [uid1 [[uid2] [[...]]]" 
description = "Ensures that the user's home directory exists; "  +\
              "that it has correct user, group and permissions; "  +\
              "and sets up a subdirectory of links for any workspace "  +\
              "to which the user has access."
parser = OptionParser(usage=usage, version=version, description=description)
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                        help="show changes made to file system [default: %default]")
parser.add_option("-f", "--force-perms", action="store_true", dest="force", default=False,
                        help="force the recursive application of permissions (only needed " +\
                             "if the user's home was migrated/copied from somewhere else)")
(options, args) = parser.parse_args()


##################################################################################
# bind to the ldap server 
#     do the preliminary procssing of users and groups
#     do the preliminary procssing of workspaces
##################################################################################
con = ldap.initialize(BIND_URI_SERVER)
if BIND_TLS:
    con.start_tls_s()
con.simple_bind_s(BIND_DN_SERVER, BIND_PW_SERVER)

groups,                \
    users,             \
     gid2group,        \
     uid2user,         \
     belongsTo,        \
    workspaces,        \
     gtwsName2ws,      \
     gtwsName2path,    \
     gid2gtwsName,     \
     uid2gtwsName,     \
    servers,           \
     gtsName2server  = preProcessLdapObjects(con)

con.unbind_s()


##################################################################################
# set up the homes
##################################################################################
smbConf = ''  #string in which to accumulate the samba share definitions
for u in users:
    dn, attrs = u
    uid = attrs['uid'][0]

    # is the user's home is on this server
    if 'sambaHomePath' not in attrs:
        print >> sys.stderr, '  *** Error no "sambaHomePath" set for user: ' + uid
        continue
    if attrs['sambaHomePath'][0].lower().find(SERVER_SHORT_NAME.lower()) < 0:
        continue

    # accumulate the share definition in a string
    userDir = os.path.join(SAMBA_HOME, uid)
    smbConf = smbConf + SAMBA_HOME_TEMPLATE.format(
            shareName    = uid,
            shareComment = 'home directory of ' + attrs['cn'][0],
            sharePath    = userDir
        )
    #all users get recycle bins
    smbConf = smbConf + SAMBA_RECYCLE_TEMPLATE.format(
            recycleDir = os.path.join(SAMBA_USER_HOME, SAMBA_RECYCLE_DIR)
        ) 

    # were specific users specified on the command line
    if len(args) > 0 and uid.lower() not in [a.lower() for a in args]:
        continue

    if options.verbose: 
        print 'processing user:',
        print uid \
            + '  (' + attrs['uidNumber'][0] + ')  ' \
            + 'dn: ' + dn

    # create user's directory
    userDir = os.path.join(SAMBA_HOME, uid)
    homeDir = os.path.join(SAMBA_HOME, uid, SAMBA_USER_HOME)
    if options.verbose: 
        print '    ensuring user directory exists:       ' + homeDir
    p = subprocess.Popen([ "mkdir", "-p", homeDir ]); p.wait()
    if p.returncode:
        print >> sys.stderr, '  *** Error (re)creating directory: ' + homeDir

    # correct permissions
    if options.verbose: 
        print '    setting ownership and permissions on: ' + SAMBA_HOME
    setOwnerGroupPerms(SAMBA_HOME,  ROOT_UID, MEMBERFULL_GID, 00510)

    if options.verbose:
        print '    setting ownership and permissions on: ' + userDir
    setOwnerGroupPerms(userDir,     uid,      MEMBERLESS_GID, 02550)

    if options.verbose:
        print '    setting ownership and permissions on: ' + homeDir
    if options.force:
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 02770, applyTo='d')
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 00660, applyTo='f')
    else:
        setOwnerGroupPerms(homeDir, uid,      MEMBERLESS_GID, 02770)

    # determine the unique set of workspaces that the user can access
    accessibleWsNames= list()
    for gid in belongsTo[ uid ]:                        #groups that user belongs to
        if gid in gid2gtwsName:                         #there are workspaces to which this gnum has access
            for gtwsName in gid2gtwsName[gid]:          #workspaces accessible by gnum
                if gtwsName not in accessibleWsNames:   #if we haven't already added workspace to list
                    accessibleWsNames.append(gtwsName)  # then do so
    if uid in uid2gtwsName:                             #there are workspaces to which this uid has access
        for gtwsName in uid2gtwsName[uid]:              #workspaces accessible by uid
            if gtwsName not in accessibleWsNames:       #if we haven't already added workspace to list
                accessibleWsNames.append(gtwsName)      # then do so

    # modify the accessbileWsNames so that we also have the server and path
    # and then sort by the server + path
    accessibles = [ (x,) + gtwsName2path[x] for x in accessibleWsNames ]
    accessibles.sort(key=lambda x: x[1]+x[2])

    # setup the linkFiles to accessible workspaces
    linkFiles = list()
    for gtwsName, gtsName, path in accessibles:
        serverAttrs = gtsName2server[gtsName][1]
        serverDir = os.path.join(userDir, serverAttrs['gtDisplayName'][0])
        if not os.path.exists(serverDir):
            os.mkdir(serverDir)
        if options.verbose: 
            print '    setting ownership and permissions on: ' + serverDir
        setOwnerGroupPerms(serverDir, uid, MEMBERLESS_GID, 00500)

        # write out the linkFile/URL
        wsDn, wsAttr = gtwsName2ws[gtwsName] 
        linkFile = os.path.join(serverDir, wsAttr['gtwsName'][0] + '.url')
        if options.verbose: 
            print '    writing link file: ' + linkFile
        with open(linkFile, 'w') as f:
            f.write("[InternetShortcut]" + "\r\n")
            f.write("URL=file://" + serverAttrs['gtFQDN'][0] + "/" + wsAttr['gtwsName'][0] + "\r\n")
        setOwnerGroupPerms(linkFile, uid, MEMBERLESS_GID, 00400)
        linkFiles.append(linkFile)

    # remove links no longer available
    if options.verbose: 
        print '    removing dead/revoked links'
    for dirpath, dirnames, filenames in os.walk(userDir):
        if dirpath == userDir:
            if SAMBA_USER_HOME in dirnames:
                dirnames.remove(SAMBA_USER_HOME)
            continue
        for f in filenames:
            if f.endswith('.url'):
                linkName = os.path.join(dirpath, f)  #reconstruct full linkfile path
                if linkName not in linkFiles:
                    if options.verbose: 
                        print '        removing link ' + linkName
                    os.unlink(os.path.join(dirpath, f))

    # cleanup: if subdir is empty then remove it 
    if options.verbose: 
        print '    cleanup links'
    for dirpath, dirnames, filenames in os.walk(userDir):
        if dirpath == userDir:
            if SAMBA_USER_HOME in dirnames:
                dirnames.remove(SAMBA_USER_HOME)
            continue
        if len(dirnames) + len(filenames) == 0:
            if options.verbose: 
                print '        deleting empty server folder:  ' + dirpath
            os.rmdir(dirpath)

#    # setup the static linkFiles
#    staticDir = os.path.join(userDir, 'links')
#    if not os.path.exists(staticDir):
#        os.mkdir(staticDir)
#    if options.verbose: 
#        print '    setting ownership and permissions on: ' + staticDir
#    setOwnerGroupPerms(staticDir, attrs['uidNumber'][0], attrs['gidNumber'][0], 00500)
#
#    # write out the static linkFile/URL
#    linkFile = os.path.join(staticDir, 'changePassword.url')
#    if options.verbose: 
#        print '    writing link file: ' + linkFile
#    with open(linkFile, 'w') as f:
#        f.write("[InternetShortcut]" + "\r\n")
#        f.write("URL=https://dirsrv1peg.yyc.avmaxgroup.com/changePassword.html" + "\r\n")
#    setOwnerGroupPerms(linkFile, attrs['uidNumber'][0], attrs['gidNumber'][0], 00400)

# write out the smb conf for homes
with open(os.path.join(SAMBA_ROOT, SAMBA_HOME_CONF), 'w') as f:
    f.write(smbConf)
setOwnerGroupPerms(os.path.join(SAMBA_ROOT, SAMBA_HOME_CONF), '0', '0', 00664)

