Example #1
0
 def _create_user(self, username, password, name, surname):
     # FIXME ms windows stores strings as UTF-8 while mmc base module waits for ascii
     # them so we decode
     #         username = username.decode('utf-8)')
     #         name = name.decode('utf-8)').encode('ascii', errors='replace')
     #         surname = surname.decode('utf-8)').encode('ascii', errors='replace')
     logger.debug('calling ldapUserGroupControl().addUser(%s, %s, %s, %s)',
                  username, password, name, surname)
     ldapUserGroupControl().addUser(username, password, name, surname)
Example #2
0
 def _create_user(self, username, password, name, surname):
     # FIXME ms windows stores strings as UTF-8 while mmc base module waits for ascii
     # them so we decode
     #         username = username.decode('utf-8)')
     #         name = name.decode('utf-8)').encode('ascii', errors='replace')
     #         surname = surname.decode('utf-8)').encode('ascii', errors='replace')
     logger.debug('calling ldapUserGroupControl().addUser(%s, %s, %s, %s)',
                  username, password, name, surname)
     ldapUserGroupControl().addUser(username, password, name, surname)
Example #3
0
    def getACLOnShare(self, name):
        """
        Return a list with all the groups that have rwx access to the share.

        @param name: name of the share (last component of the path)
        @type name: str

        @rtype: tuple
        @return: tuple of groups, users that have rwx access to the share.
        """
        path = self.getContent(name, "path")
        ret = ([], [])
        ldapobj = ldapUserGroupControl()
        acl1 = posix1e.ACL(file=path)
        for e in acl1:
            if e.permset.write:
                if e.tag_type == posix1e.ACL_GROUP:
                    res = ldapobj.getDetailedGroupById(str(e.qualifier))
                    if res:
                        ret[0].append(res['cn'][0])
                    else:
                        ret[0].append(grp.getgrgid(e.qualifier).gr_name)
                if e.tag_type == posix1e.ACL_USER:
                    res = ldapobj.getDetailedUserById(str(e.qualifier))
                    if res:
                        ret[1].append(res['uid'][0])
                    else:
                        ret[1].append(pwd.getpwuid(e.qualifier).pw_name)

        return ret
Example #4
0
    def getACLOnShare(self, name):
        """
        Return a list with all the groups that have rwx access to the share.

        @param name: name of the share (last component of the path)
        @type name: str

        @rtype: tuple
        @return: tuple of groups, users that have rwx access to the share.
        """
        path = self.getContent(name, "path")
        ret = ([], [])
        ldapobj = ldapUserGroupControl()
        acl1 = posix1e.ACL(file=path)
        for e in acl1:
            if e.permset.write:
                if e.tag_type == posix1e.ACL_GROUP:
                    res = ldapobj.getDetailedGroupById(str(e.qualifier))
                    if res:
                        ret[0].append(res['cn'][0])
                    else:
                        ret[0].append(grp.getgrgid(e.qualifier).gr_name)
                if e.tag_type == posix1e.ACL_USER:
                    res = ldapobj.getDetailedUserById(str(e.qualifier))
                    if res:
                        ret[1].append(res['uid'][0])
                    else:
                        ret[1].append(pwd.getpwuid(e.qualifier).pw_name)

        return ret
Example #5
0
 def _cbProvisioning(self, auth, authtoken):
     """
     Provision the MMC user account with ACLs
     """
     if not auth:
         self.logger.warning("User authentication with GLPI web interface failed, but going on with provisioning")
     profiles = Glpi().getUserProfiles(authtoken.getLogin())
     self.logger.debug("User %s GLPI profiles: %s" % (authtoken.getLogin(), str(profiles)))
     selected = None
     for profile in self.config.profilesOrder:
         if profile in profiles:
             selected = profile
             break
     if not selected:
         self.logger.info("User GLPI profile can't be applied")
     else:
         self.logger.debug("Selected GLPI profile is %s" % selected)
         try:
             acls = self.config.profilesAcl[selected.lower()]
         except KeyError:
             acls = None
         if not acls:
             self.logger.info("No ACL to apply for the GLPI profile %s" % selected)
         else:
             l = ldapUserGroupControl()
             self.logger.info("Setting MMC ACL corresponding to GLPI profile %s: %s" % (selected, acls))
             uid = authtoken.getLogin()
             entry = l.getDetailedUser(uid)
             if not "lmcUserObject" in entry["objectClass"]:
                 entry["objectClass"].append("lmcUserObject")
                 l.changeUserAttributes(uid, "objectClass", entry["objectClass"])
             l.changeUserAttributes(authtoken.getLogin(), "lmcAcl", acls)
     return authtoken
Example #6
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("grouptestA")
     self.l.addGroup("grouptestB")
     os.system("cp contrib/samba/smb.conf /etc/samba/smb.conf")
     self.s = smbConf(conffile = "tests-mds/sambatest.ini", conffilebase = "tests-mds/basetest.ini")
     os.system("rm -fr %s" % self.s.defaultSharesPath)
Example #7
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("grouptestA")
     self.l.addGroup("grouptestB")
     os.system("cp contrib/samba/smb.conf /etc/samba/smb.conf")
     self.s = smbConf(conffile="tests-mds/sambatest.ini", conffilebase="tests-mds/basetest.ini")
     os.system("rm -fr %s" % self.s.defaultSharesPath)
Example #8
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = MailConfig("mail")
    if config.disabled:
        logger.warning("Plugin mail: disabled by configuration.")
        return False

    mailSchema = {
        "mailAccount": [
            "mail", "mailalias", "maildrop", "mailenable", "mailbox",
            "mailuserquota", "mailhost", "mailproxy", "mailhidden"
        ],
        "mailGroup": ["mail"],
        "mailDomain":
        ["virtualdomain", "virtualdomaindescription", "mailuserquota"],
    }

    # Additional LDAP classes/attributes to check for ZARAFA support
    if config.zarafa:
        mailSchema['zarafa-user'] = [
            'zarafaAdmin', 'zarafaSharedStoreOnly', 'zarafaAccount',
            'zarafaSendAsPrivilege', 'zarafaHidden'
        ]
        mailSchema['zarafa-group'] = []

    # Additional LDAP classes for virtual aliases
    if config.vAliasesSupport:
        mailSchema['mailAlias'] = ['mailaliasmember']

    for objectClass in mailSchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error(
                "LDAP mail schema is not up to date: %s objectClass is not included in LDAP directory"
                % objectClass)
            return False
        for attribute in mailSchema[objectClass]:
            if attribute not in schema:
                logger.error(
                    "LDAP mail schema is not up to date: %s attribute is not included in LDAP directory"
                    % attribute)
                return False

    if config.vAliasesSupport:
        # Create required OU
        head, path = config.vAliasesDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)

    if config.vDomainSupport:
        # Create required OU
        head, path = config.vDomainDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)

    return True
Example #9
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("allusers")
     os.system("cp contrib/samba/smb.conf /etc/samba/smb.conf")
     os.system("/etc/init.d/samba stop")
     os.system("/usr/bin/smbpasswd -w secret")
     os.system("/etc/init.d/samba start")
     self.s = sambaLdapControl(conffile = "tests-mds/sambatest.ini", conffilebase = "tests-mds/basetest.ini")
Example #10
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("allusers")
     os.system("cp contrib/samba/smb.conf /etc/samba/smb.conf")
     os.system("/etc/init.d/samba stop")
     os.system("/usr/bin/smbpasswd -w secret")
     os.system("/etc/init.d/samba start")
     self.s = sambaLdapControl(conffile="tests-mds/sambatest.ini", conffilebase="tests-mds/basetest.ini")
Example #11
0
 def doProvisioning(self, authtoken):
     from mmc.plugins.base import ldapUserGroupControl
     self.logger.debug(str(authtoken.getInfos()))
     l = ldapUserGroupControl()
     userentry = authtoken.getInfos()[1]
     uid = userentry[self.config.ldap_uid][0]
     if l.existUser(uid):
         self.logger.debug("User %s already exists, so this user won't be added" % uid)
     else:
         givenName = userentry[self.config.ldap_givenName][0].decode("utf-8")
         sn = userentry[self.config.ldap_sn][0].decode("utf-8")
         l.addUser(uid, authtoken.getPassword(), givenName, sn)
     if self.config.profileAttr and self.config.profilesAcl:
         # Set or update the user right
         try:
             profile = userentry[self.config.profileAttr][0].lower()
         except KeyError:
             self.logger.info("No profile information for user %s in attribute %s" % (uid, self.config.profileAttr))
             profile = ""
         profile = profile.strip()
         try:
             acls = self.config.profilesAcl[profile]
         except KeyError:
             self.logger.info("No ACL defined in configuration file for profile '%s'" % profile)
             self.logger.info("Setting ACL to empty")
             acls = None
         if profile and acls:
             self.logger.info("Setting MMC ACL corresponding to user profile %s: %s" % (profile, str(acls)))
         entry = l.getDetailedUser(uid)
         if not "lmcUserObject" in entry["objectClass"]:
             entry["objectClass"].append("lmcUserObject")
             l.changeUserAttributes(uid, "objectClass", entry["objectClass"])
         l.changeUserAttributes(uid, "lmcAcl", acls)
         if self.config.profileGroupMapping:
             # Set user group membership according to mapping
             for prof in self.config.profilesAcl:
                 groupname = self.config.profileGroupPrefix + prof
                 if prof != profile:
                     # Delete the user from a group not belonging to her/his
                     # profile
                     try:
                         l.delUserFromGroup(groupname, uid)
                         self.logger.debug('Deleting user %s from group %s' % (uid, groupname))
                     except ldap.NO_SUCH_OBJECT:
                         # The group does not exist
                         pass
                 else:
                     # Add the user to this group
                     try:
                         l.addGroup(groupname)
                     except ldap.ALREADY_EXISTS:
                         # This group already exists
                         pass
                     self.logger.debug('Adding user %s to group %s' % (uid, groupname))
                     l.addUserToGroup(groupname, uid)
Example #12
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = MailConfig("mail")
    if config.disabled:
        logger.warning("Plugin mail: disabled by configuration.")
        return False

    mailSchema = {
        "mailAccount" : ["mail", "mailalias", "maildrop", "mailenable", "mailbox", "mailuserquota", "mailhost", "mailproxy"],
        "mailGroup" : ["mail"],
        "mailDomain" : ["virtualdomain", "virtualdomaindescription", "mailuserquota"],
        }

    # Additional LDAP classes/attributes to check for ZARAFA support
    if config.zarafa:
        mailSchema['zarafa-user'] = ['zarafaAdmin', 'zarafaSharedStoreOnly',
                                     'zarafaAccount', 'zarafaSendAsPrivilege',
                                     'zarafaHidden']
        mailSchema['zarafa-group'] = []

    # Additional LDAP classes for virtual aliases
    if config.vAliasesSupport:
        mailSchema['mailAlias'] = ['mailaliasmember']

    for objectClass in mailSchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("LDAP mail schema is not up to date: %s objectClass is not included in LDAP directory" % objectClass)
            return False
        for attribute in mailSchema[objectClass]:
            if not attribute in schema:
                logger.error("LDAP mail schema is not up to date: %s attribute is not included in LDAP directory" % attribute)
                return False

    if config.vAliasesSupport:
        # Create required OU
        head, path = config.vAliasesDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)

    if config.vDomainSupport:
        # Create required OU
        head, path = config.vDomainDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)

    return True
Example #13
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = UserSshKeyConfig("sshlpk")
    if config.disabled:
        logger.warning("Plugin sshlpk: disabled by configuration.")
        return False

    sshkeySchema = ['posixAccount', 'ldapPublicKey']

    for objectClass in sshkeySchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("OpenSSH LDAP public key schema is not available: %s objectClass is not included in LDAP directory" % objectClass)
            return False

    return True
Example #14
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = UserSshKeyConfig("sshlpk")
    if config.disabled:
        logger.warning("Plugin sshlpk: disabled by configuration.")
        return False

    sshkeySchema = ['posixAccount', 'ldapPublicKey']

    for objectClass in sshkeySchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("OpenSSH LDAP public key schema is not available: %s objectClass is not included in LDAP directory" % objectClass);
            return False

    return True
Example #15
0
    def getACLOnShare(self, name):
        """
        Return a list with all the groups that have rwx access to the share.

        @param name: name of the share (last component of the path)
        @type name: str

        @rtype: dict
        @return: dict of permissions: [list of users/groups]
        """
        ldapobj = ldapUserGroupControl(self.conffilebase)
        path = self.getContent(name, "path")
        public = self.getContent(name, "public")
        perms = {'rx': [], 'rwx': []}
        if path is False:
            return perms
        if public == "yes":
            return {'rwx': ['@all']}
        acls = posix1e.ACL(file=path)
        for e in acls:
            permset = zip(['r', 'w', 'x'], [e.permset.read, e.permset.write, e.permset.execute])
            perm = ''.join([r for r, b in permset if b is True])
            entity = ""

            if e.tag_type == posix1e.ACL_GROUP:
                res = ldapobj.getDetailedGroupById(str(e.qualifier))
                if res:
                    entity = '@' + res['cn'][0]
                else:
                    entity = '@' + grp.getgrgid(e.qualifier).gr_name

            if e.tag_type == posix1e.ACL_USER:
                res = ldapobj.getDetailedUserById(str(e.qualifier))
                if res:
                    entity = res['uid'][0]
                else:
                    entity = pwd.getpwuid(e.qualifier).pw_name

            if perm not in perms and entity:
                perms[perm] = [entity]
            elif entity:
                perms[perm].append(entity)

        return perms
Example #16
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = RadiusConfig("radius")
    if config.disabled:
        logger.warning("Plugin radius: disabled by configuration.")
        return False

    radiusSchema = ['posixAccount', 'radiusprofile']

    for objectClass in radiusSchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("Radius schema is not available: %s objectClass is \
                          not included in LDAP directory" % objectClass)
            return False

    return True
Example #17
0
def cleanLdap():
    # Wipe out /home
    os.system("rm -fr /home/*")
    # Wipe out LDAP
    os.system("/etc/init.d/slapd stop")
    os.system("killall -9 slapd")
    os.system("rm -f /var/lib/ldap/*")
    os.system("rm -fr /var/backups/*.ldapdb")
    os.system("cp contrib/ldap/*.schema /etc/ldap/schema")
    os.system("echo slapd slapd/password1 string secret | debconf-set-selections")
    os.system("echo slapd slapd/password2 string secret | debconf-set-selections")
    os.system("dpkg-reconfigure -pcritical slapd")
    os.system("cp contrib/ldap/slapd.conf /etc/ldap")
    os.system("/etc/init.d/slapd restart")
    time.sleep(5)
    # Create Base OU
    l = ldapUserGroupControl("tests-mds/basetest.ini")
    l.addOu("Groups", "dc=mandriva,dc=com")
    l.addOu("Users",  "dc=mandriva,dc=com")
Example #18
0
def activate():
    ldapObj = ldapUserGroupControl()
    logger = logging.getLogger()

    config = RadiusConfig("radius")
    if config.disabled:
        logger.warning("Plugin radius: disabled by configuration.")
        return False

    radiusSchema = ['posixAccount', 'radiusprofile']

    for objectClass in radiusSchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("Radius schema is not available: %s objectClass is \
                          not included in LDAP directory" % objectClass)
            return False

    return True
Example #19
0
 def _cbProvisioning(self, auth, authtoken):
     """
     Provision the MMC user account with ACLs
     """
     if not auth:
         self.logger.warning(
             "User authentication with GLPI web interface failed, but going on with provisioning"
         )
     profiles = Glpi().getUserProfiles(authtoken.getLogin())
     self.logger.debug("User '%s' GLPI's profiles: %s" %
                       (authtoken.getLogin(), str(profiles)))
     self.logger.debug("Profiles order (from ini configuration): %s" %
                       (self.config.profilesOrder))
     selected = None
     for profile in self.config.profilesOrder:
         if profile in profiles:
             selected = profile
             break
     if not selected:
         self.logger.info("User GLPI's profile can't be applied")
     else:
         self.logger.debug("Selected GLPI profile is %s" % selected)
         try:
             acls = self.config.profilesAcl[selected.lower()]
         except KeyError:
             acls = None
         if not acls:
             self.logger.info("No ACL to apply for the GLPI profile %s" %
                              selected)
         else:
             l = ldapUserGroupControl()
             self.logger.info(
                 "Setting MMC ACL corresponding to GLPI profile %s: %s" %
                 (selected, acls))
             uid = authtoken.getLogin()
             entry = l.getDetailedUser(uid)
             if not "lmcUserObject" in entry["objectClass"]:
                 entry["objectClass"].append("lmcUserObject")
                 l.changeUserAttributes(uid, "objectClass",
                                        entry["objectClass"])
             l.changeUserAttributes(authtoken.getLogin(), "lmcAcl", acls)
     return authtoken
Example #20
0
def activate():
    ldapObj = ldapUserGroupControl()

    config = PPolicyConfig("ppolicy")
    if config.disabled:
        logger.warning("Plugin ppolicy: disabled by configuration.")
        return False

    ppolicySchema = ['pwdPolicy', 'device']

    for objectClass in ppolicySchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("LDAP Password Policy schema is not included in LDAP directory: %s objectClass is not available" % objectClass)
            return False

    # Register default password policy into the LDAP if it does not exist
    PPolicy().addPPolicy()

    return True
Example #21
0
def activate():
    ldapObj = ldapUserGroupControl()

    config = PPolicyConfig("ppolicy")
    if config.disabled:
        logger.warning("Plugin ppolicy: disabled by configuration.")
        return False

    ppolicySchema = ['pwdPolicy', 'device']

    for objectClass in ppolicySchema:
        schema = ldapObj.getSchema(objectClass)
        if not len(schema):
            logger.error("LDAP Password Policy schema is not included in LDAP directory: %s objectClass is not available" % objectClass)
            return False

    # Register default password policy into the LDAP if it does not exist
    PPolicy().addPPolicy()

    return True
Example #22
0
def cleanLdap():
    # Wipe out /home
    os.system("rm -fr /home/*")
    # Wipe out LDAP
    os.system("/etc/init.d/slapd stop")
    os.system("killall -9 slapd")
    os.system("rm -f /var/lib/ldap/*")
    os.system("rm -fr /var/backups/*.ldapdb")
    os.system("cp contrib/ldap/*.schema /etc/ldap/schema")
    os.system("echo slapd slapd/password1 string secret | debconf-set-selections")
    os.system("echo slapd slapd/password2 string secret | debconf-set-selections")
    os.system("dpkg-reconfigure -pcritical slapd")
    os.system("cp contrib/ldap/slapd.conf.samba /etc/ldap/slapd.conf")
    os.system("/etc/init.d/slapd restart")
    time.sleep(5)
    # Create Base OU
    l = ldapUserGroupControl("tests-mds/basetest.ini")
    l.addOu("Groups", "dc=mandriva,dc=com")
    l.addOu("Users",  "dc=mandriva,dc=com")
    l.addOu("Computers",  "dc=mandriva,dc=com")
Example #23
0
def activate():
    config = UserQuotaConfig("userquota")

    if config.disabled:
        logger.warning("Plugin userquota: disabled by configuration.")
        return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the quota LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("systemQuotas")
        if len(schema) <= 0:
            logger.error("Quota schema is not included in LDAP directory")
            return False
    except:
        logger.exception("Invalid schema")
        return False

    # Check local file systems
    if config.runquotascript == "/bin/sh":
        for device in getDevicemap():
            dev, blocksize, name = device.split(':')
            if not os.path.exists(dev):
                logger.error("%s does not exists")
                return False
            code, out, err = mmctools.shlaunch(
                "quotaon -aup | grep '%s) is on'" % dev)
            if code != 0 or not len(out) == 1:
                logger.error("User quotas are not enabled on %s" % dev)
                return False

    return True
Example #24
0
def activate():
    config = UserQuotaConfig("userquota")

    if config.disabled:
        logger.warning("Plugin userquota: disabled by configuration.")
        return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the quota LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("systemQuotas")
        if len(schema) <= 0:
            logger.error("Quota schema is not included in LDAP directory");
            return False
    except:
        logger.exception("Invalid schema")
        return False

    # Check local file systems
    if config.runquotascript == "/bin/sh":
        for device in getDevicemap():
            dev, blocksize, name = device.split(':')
            if not os.path.exists(dev):
                logger.error("%s does not exists");
                return False
            code, out, err = mmctools.shlaunch("quotaon -aup | grep '%s) is on'" % dev)
            if code != 0 or not len(out) == 1:
                logger.error("User quotas are not enabled on %s" % dev);
                return False

    return True
Example #25
0
 def _create_group(self, name, description=None):
     logger.debug('calling ldapUserGroupControl().addGroup(%s)', name)
     ldapUserGroupControl().addGroup(name)
Example #26
0
 # Add and set default mask to rwx
 # This is needed by the ACL system, else the ACLs won't be valid
 e = acl1.append()
 e.permset.add(posix1e.ACL_READ)
 e.permset.add(posix1e.ACL_WRITE)
 e.permset.add(posix1e.ACL_EXECUTE)
 e.tag_type = posix1e.ACL_MASK
 # For each specified group, we add rwx access
 for group in usergroups:
     e = acl1.append()
     e.permset.add(posix1e.ACL_READ)
     e.permset.add(posix1e.ACL_WRITE)
     e.permset.add(posix1e.ACL_EXECUTE)
     e.tag_type = posix1e.ACL_GROUP
     # Search the gid number corresponding to the given group
     ldapobj = ldapUserGroupControl(self.conffilebase)
     try:
         gidNumber = ldapobj.getDetailedGroup(group)['gidNumber'][0]
     except ldap.NO_SUCH_OBJECT:
         gidNumber = grp.getgrnam(group).gr_gid
     e.qualifier = int(gidNumber)
     # FIXME
     # howto use posix1e for this ?
     shlaunch("setfacl -d -m g:%s:rwx %s" % (str(gidNumber), path))
 for user in users:
     e = acl1.append()
     e.permset.add(posix1e.ACL_READ)
     e.permset.add(posix1e.ACL_WRITE)
     e.permset.add(posix1e.ACL_EXECUTE)
     e.tag_type = posix1e.ACL_USER
     # Search the gid number corresponding to the given group
Example #27
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.assertEqual(self.l.addGroup("allusers"), 10001)
Example #28
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
Example #29
0
def activate():
    config = NetworkConfig("network")
    logger = logging.getLogger()

    if config.disabled:
        logger.warning("Plugin network: disabled by configuration.")
        return False

    if not config.dhcpEnable and not config.dnsEnable:
        logger.warning("Plugin network: disabled by configuration.")
        return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    if config.dhcpEnable:
        # Test if the DHCP/LDAP schema is available in the directory
        try:
            schema = ldapObj.getSchema("dhcpServer")
            if len(schema) <= 0:
                logger.error("DHCP schema is not included in LDAP directory")
                return False
            # Test if DHCP/LDAP schema contains the dhcpComments attribute
            if "dhcpComments" not in schema:
                logger.error(
                    "DHCP/LDAP schema does not support the dhcpComments attribute. Please use the latest version of DCHP/LDAP schema."
                )
                return False
        except:
            logger.exception("invalid schema")
            return False
    else:
        logger.info("DHCP submodule is disabled")

    if config.dnsEnable:
        # Test if the DNS/LDAP schema is available in the directory
        serverType = config.dnsType
        if serverType == "pdns":
            try:
                schema = ldapObj.getSchema("dNSDomain2")
                if len(schema) <= 0:
                    logger.error(
                        "DNS zone schema (dnsdomain2.schema) is not included in LDAP directory"
                    )
                    return False
            except:
                logger.exception("invalid DNS schema")
                return False
        elif serverType == "bind":
            try:
                schema = ldapObj.getSchema("dNSZone")
                if len(schema) <= 0:
                    logger.error(
                        "DNS zone schema (dnszone.schema) is not included in LDAP directory"
                    )
                    return False
            except:
                logger.exception("invalid DNS schema")
                return False
        else:
            logger.error("%s : Unknown DNS server." % serverType)
            return False
    else:
        logger.info("DNS submodule is disabled")

    if config.dhcpEnable:
        # Create DHCP ou
        head, path = config.dhcpDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)
        # Create DHCP config base structure
        d = Dhcp()
        try:
            d.addServiceConfig("DHCP config")
            logger.info("Created DHCP config object")
        except ldap.ALREADY_EXISTS:
            pass
        hostname = d.configDhcp.dhcpHostname
        try:
            d.addServer(hostname)
            d.setServiceConfigStatement("not", "authoritative")
            logging.info("The DHCP server '%s' was added." % hostname)
        except ldap.ALREADY_EXISTS:
            pass
        d.setServiceServerStatus(hostname, "primary")
        logging.info(
            "The server '%s' has been set as the primary DHCP server" %
            hostname)

    # Create DNS config base structure
    if config.dnsEnable:
        # Create DNS ou
        head, path = config.dnsDN.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)
        if serverType == "bind":
            try:
                gidNumber = grp.getgrnam(config.bindGroup)
            except KeyError:
                logger.error('The group "%s" does not exist.' %
                             config.bindGroup)
                return False
            gidNumber = gidNumber[2]

            try:
                os.mkdir(config.bindLdapDir)
                os.chmod(config.bindLdapDir, 02750)
                os.chown(config.bindLdapDir, -1, gidNumber)
            except OSError, e:
                # errno = 17 is "File exists"
                if e.errno != 17: raise

            if not os.path.exists(config.bindLdap):
                f = open(config.bindLdap, "w")
                f.close()
                os.chmod(config.bindLdap, 0640)
                os.chown(config.bindLdap, -1, gidNumber)
Example #30
0
 def doProvisioning(self, authtoken):
     from mmc.plugins.base import ldapUserGroupControl
     self.logger.debug(str(authtoken.getInfos()))
     l = ldapUserGroupControl()
     userentry = authtoken.getInfos()[1]
     uid = userentry[self.config.ldap_uid][0]
     if l.existUser(uid):
         self.logger.debug(
             "User %s already exists, so this user won't be added" % uid)
     else:
         givenName = userentry[self.config.ldap_givenName][0].decode(
             "utf-8")
         sn = userentry[self.config.ldap_sn][0].decode("utf-8")
         l.addUser(uid, authtoken.getPassword(), givenName, sn)
     if self.config.profileAttr and self.config.profilesAcl:
         # Set or update the user right
         try:
             profile = userentry[self.config.profileAttr][0].lower()
         except KeyError:
             self.logger.info(
                 "No profile information for user %s in attribute %s" %
                 (uid, self.config.profileAttr))
             profile = ""
         profile = profile.strip()
         try:
             acls = self.config.profilesAcl[profile]
         except KeyError:
             self.logger.info(
                 "No ACL defined in configuration file for profile '%s'" %
                 profile)
             self.logger.info("Setting ACL to empty")
             acls = None
         if profile and acls:
             self.logger.info(
                 "Setting MMC ACL corresponding to user profile %s: %s" %
                 (profile, str(acls)))
         entry = l.getDetailedUser(uid)
         if not "lmcUserObject" in entry["objectClass"]:
             entry["objectClass"].append("lmcUserObject")
             l.changeUserAttributes(uid, "objectClass",
                                    entry["objectClass"])
         l.changeUserAttributes(uid, "lmcAcl", acls)
         if self.config.profileGroupMapping:
             # Set user group membership according to mapping
             for prof in self.config.profilesAcl:
                 groupname = self.config.profileGroupPrefix + prof
                 if prof != profile:
                     # Delete the user from a group not belonging to her/his
                     # profile
                     try:
                         l.delUserFromGroup(groupname, uid)
                         self.logger.debug(
                             'Deleting user %s from group %s' %
                             (uid, groupname))
                     except ldap.NO_SUCH_OBJECT:
                         # The group does not exist
                         pass
                 else:
                     # Add the user to this group
                     try:
                         l.addGroup(groupname)
                     except ldap.ALREADY_EXISTS:
                         # This group already exists
                         pass
                     self.logger.debug('Adding user %s to group %s' %
                                       (uid, groupname))
                     l.addUserToGroup(groupname, uid)
Example #31
0
def activate():
    config = NetworkConfig("network")
    logger = logging.getLogger()

    if config.disabled:
        logger.warning("Plugin network: disabled by configuration.")
        return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the DHCP/LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("dhcpServer")
        if len(schema) <= 0:
            logger.error("DHCP schema is not included in LDAP directory");
            return False
        # Test if DHCP/LDAP schema contains the dhcpComments attribute
        if "dhcpComments" not in schema:
            logger.error("DHCP/LDAP schema does not support the dhcpComments attribute. Please use the latest version of DCHP/LDAP schema.")
            return False
    except:
        logger.exception("invalid schema")
        return False

    # Test if the DNS/LDAP schema is available in the directory
    serverType = config.dnsType
    if serverType == "pdns":
        try:
            schema = ldapObj.getSchema("dNSDomain2")
            if len(schema) <= 0:
                logger.error("DNS zone schema (dnsdomain2.schema) is not included in LDAP directory");
                return False
        except:
            logger.exception("invalid DNS schema")
            return False
    elif serverType == "bind":
        try:
            schema = ldapObj.getSchema("dNSZone")
            if len(schema) <= 0:
                logger.error("DNS zone schema (dnszone.schema) is not included in LDAP directory");
                return False
        except:
            logger.exception("invalid DNS schema")
            return False
    else:
        logger.error("%s : Unknown DNS server."%serverType);
        return False

    # Create required OUs
    config = NetworkConfig("network")
    for dn in [config.dhcpDN, config.dnsDN]:
        head, path = dn.split(",", 1)
        ouName = head.split("=")[1]
        ldapObj.addOu(ouName, path)

    # Create DHCP config base structure
    d = Dhcp()
    try:
        d.addServiceConfig("DHCP config")
        logger.info("Created DHCP config object")
    except ldap.ALREADY_EXISTS:
        pass
    hostname = d.configDhcp.dhcpHostname
    try:
        d.addServer(hostname)
        d.setServiceConfigStatement("not", "authoritative")
        logging.info("The DHCP server '%s' was added." % hostname)
    except ldap.ALREADY_EXISTS:
        pass
    d.setServiceServerStatus(hostname, "primary")
    logging.info("The server '%s' has been set as the primary DHCP server" % hostname)

    # Create DNS config base structure
    if serverType == "bind":
        try:
            gidNumber = grp.getgrnam(config.bindGroup)
        except KeyError:
            logger.error('The group "%s" does not exist.' % config.bindGroup)
            return False
        gidNumber = gidNumber[2]

        try:
            os.mkdir(config.bindLdapDir)
            os.chmod(config.bindLdapDir, 02750)
            os.chown(config.bindLdapDir, -1, gidNumber)
        except OSError, e:
            # errno = 17 is "File exists"
            if e.errno != 17: raise

        if not os.path.exists(config.bindLdap):
            f = open(config.bindLdap, "w")
            f.close()
            os.chmod(config.bindLdap, 0640)
            os.chown(config.bindLdap, -1, gidNumber)
Example #32
0
 def _create_user(self, username, password, name, surname):
     ldapUserGroupControl().addUser(username, password, name, surname)
Example #33
0
class SambaConf:

    """
    Handle smb.conf file for Samba 4
    """

    supportedGlobalOptions = ['realm', 'workgroup',
                              'netbios name', 'server role',
                              'logon path', 'logon drive',
                              'logon home', 'logon script',
                              'ldap passwd sync', 'wins support',
                              'dns forwarder']

    KRB5_CONF_PATH = '/etc/krb5.conf'

    def __init__(self):
        config = Samba4Config("samba4")
        self.smb_conf_path = config.conf_file
        self.default_shares_path = config.defaultSharesPath
        self.authorizedSharePaths = config.authorizedSharePaths
        self.prefix = config.samba_prefix
        self.db_dir = config.db_dir
        try:
            self.config = ConfigObj(self.smb_conf_path, interpolation=False,
                                    list_values=False, write_empty_values=True,
                                    encoding='utf8')
        except ParseError as e:
            logger.error("Failed to parse %s : %s ", self.smb_conf_path, e)

    def private_dir(self):
        return os.path.join(self.db_dir, 'private')

    def validate(self, conf_file):
        """
        Validate SAMBA configuration file with testparm.
        Try also to parse the configuration with ConfigObj.

        @return: Whether smb.conf has been validated or not
        @rtype: boolean
        """
        cmd = shLaunch("%s/bin/testparm -s %s" % (self.prefix,
                                                  shellquote(conf_file)))
        if cmd.exitCode:
            ret = False
        elif ("Unknown" in cmd.err or "ERROR:" in cmd.err or
              "Ignoring badly formed line" in cmd.err):
            ret = False
        else:
            ret = True

        try:
            ConfigObj(conf_file, interpolation=False, list_values=False)
        except ParseError:
            ret = False

        return ret

    def isValueTrue(self, string):
        """
        @param string: a string
        @type string: str
        @return: Return 1 if string is yes/true/1 (case insensitive),
        return 0 if string is no/false/0 (case insensitive), else return -1
        @rtype: int
        """
        string = str(string).lower()
        if string in ["yes", "true", "1", "on"]:
            return 1
        elif string in ["no", "false", "0"]:
            return 0
        else:
            return -1

    def getContent(self, section, option):
        try:
            return self.config[section][option]
        except KeyError:
            return False

    def setContent(self, section, option, value):
        try:
            self.config[section][option] = value
        except KeyError:
            self.config[section] = {}
            self.setContent(section, option, value)

    def getGlobalInfo(self):
        """
        return main information about global section
        """
        resArray = {}
        for option in self.supportedGlobalOptions:
            resArray[option] = self.getContent('global', option)
        resArray['hashomes'] = 'homes' in self.config
        return resArray

    def workgroupFromRealm(self, realm):
        return realm.split('.')[0][:15].upper()

    def writeSambaConfig(self, mode, netbios_name, realm, description,
                         logon_path='', dns_forwarder=None, hashomes=True):
        """
        Write SAMBA configuration file (smb.conf) to disk.

        @return values used to write the smb.conf template
        @rtype: dict
        """
        openchange = False  # FIXME
        openchange_conf = self.prefix + 'etc/openchange.conf'
        workgroup = self.workgroupFromRealm(realm)
        netbios_name = netbios_name.lower()
        realm = realm.upper()
        domain = realm.lower()

        params = {'workgroup': workgroup,
                  'realm': realm,
                  'netbios_name': netbios_name,
                  'description': description,
                  'mode': mode,
                  'sysvol_path': os.path.join(self.db_dir, 'sysvol'),
                  'openchange': openchange,
                  'openchange_conf': openchange_conf,
                  'domain': domain,
                  'interfaces': get_internal_interfaces(),
                  'logon_path': logon_path,
                  'dns_forwarder': dns_forwarder,
                  'hashomes': hashomes}

        smb_conf_template = env.get_template("smb.conf")
        with open(self.smb_conf_path, 'w') as f:
            f.write(smb_conf_template.render(params))

        if openchange:
            openchange_conf_template = env.get_template("openchange.conf")
            with open(openchange_conf, 'w') as f:
                f.write(openchange_conf_template.render())
        return params

    def writeKrb5Config(self, realm):
        params = {'realm': realm.upper()}
        krb5_conf_template = env.get_template('krb5.conf')
        with open(self.KRB5_CONF_PATH, 'w') as f:
            f.write(krb5_conf_template.render(params))

    def getDetailedShares(self):
        """Return detailed list of shares"""
        return [self.getDetailedShare(section)
                for section in self._getSharesSectionList()]

    def getDetailedShare(self, section):
        guest = (self.isValueTrue(self.getContent(section, 'public')) == 1 or
                 self.isValueTrue(self.getContent(section, 'guest ok')) == 1)
        enabled = (not self.getContent(section, 'browseable') or
                   self.isValueTrue(self.getContent(section, 'browseable')) == 1)
        share_detail = {
            'shareName': section,
            'sharePath': self.getContent(section, 'path'),
            'shareEnable': enabled,
            'shareDescription': self.getContent(section, 'comment') or '',
            'shareGuest': guest
        }
        # return share_detail
        return [share_detail['shareName'], share_detail['sharePath'], share_detail['shareEnable'],
                share_detail['shareDescription'], share_detail['shareGuest']]

    def _getSharesSectionList(self):
        return [k for k, _ in self.config.items()
                if k not in ("global", "printers", "print$")]

    def save(self):
        """
        Write SAMBA configuration file (smb.conf) to disk
        """
        _, tmpfname = tempfile.mkstemp("mmc")
        self.config.filename = tmpfname
        self.config.write()
        if not self.validate(tmpfname):
            raise Exception("smb.conf file is not valid (%s)" % tmpfname)
        shutil.copy(tmpfname, self.smb_conf_path)
        os.remove(tmpfname)
        return True

    def delShare(self, name, remove):
        """
        Delete a share from SAMBA configuration, and maybe delete the share
        directory from disk.
        The save method must be called to update smb.conf.

        @param name: Name of the share
        @param remove: If true, we physically remove the directory
        """
        r = AF().log(PLUGIN_NAME, AA.SAMBA4_DEL_SHARE, [(name, AT.SHARE)],
                     remove)
        path = self.getContent(name, 'path')
        if not path:
            raise Exception('Share "%s" does not exist' % name)
        del self.config[name]

        if remove:
            if os.path.exists(path):
                shutil.rmtree(path)
            else:
                logger.error('The "%s" share path does not exist.' % path)
        r.commit()

    def shareInfo(self, name):
        """
        Get information about a share
        """
        ret = {}
        ret['desc'] = self.getContent(name, 'comment')
        if not ret['desc']:
            ret['desc'] = ""
        ret['sharePath'] = self.getContent(name, 'path')
        if self.isValueTrue(self.getContent(name, 'public')) == 1:
            ret['permAll'] = 1
        elif self.isValueTrue(self.getContent(name, 'guest ok')) == 1:
            ret['permAll'] = 1
        else:
            ret['permAll'] = 0

        # If we cannot find it
        if not self.getContent(name, 'vfs objects'):
            ret['antivirus'] = 0
        else:
            ret['antivirus'] = 1

        if not self.getContent(name, 'browseable'):
            ret["browseable"] = 1
        elif self.isValueTrue(self.getContent(name, 'browseable')):
            ret["browseable"] = 1
        else:
            ret["browseable"] = 0

        # Get the directory group owner
        if os.path.exists(str(ret['sharePath'])):
            stat_info = os.stat(ret['sharePath'])
            gid = stat_info.st_gid
            try:
                ret['group'] = grp.getgrgid(gid)[0]
            except:
                logger.error("Can't find the primary group of %s. "
                             "Check your libnss settings." % ret['sharePath'])
                return False

        return ret

    def addShare(self, name, path, comment, browseable, permAll, usergroups,
                 users, mod=False):
        """
        Add a share in smb.conf and create it physically
        """
        if mod:
            action = AA.SAMBA4_MOD_SHARE
            oldPath = self.config[name]['path']
        else:
            action = AA.SAMBA4_ADD_SHARE
        r = AF().log(PLUGIN_NAME, action, [(name, AT.SHARE)], path)

        if name in self.config and not mod:
            raise Exception('This share already exist')
        if not name in self.config and mod:
            raise Exception('This share does not exist')

        # If no path is given, create a default one
        if not path:
            path = os.path.join(self.default_shares_path, name)
        path = os.path.realpath(path)

        # Check that the path is authorized
        # FIXME: handle correctly archives in base plugin
        if not self.isAuthorizedSharePath(path) and "/home/archives" not in path:
            raise Exception("%s is not an authorized share path." % path)

        # Create or move samba share directory, if it does not exist
        try:
            if mod:
                os.renames(oldPath, path)
            else:
                os.makedirs(path)
        except OSError, (errno, strerror):
            # Raise exception if error is not "File exists"
            if errno != 17:
                raise OSError(errno, strerror + ' ' + path)
            else:
                pass

        # Directory is owned by root
        os.chown(path, 0, 0)

        if mod:
            # Delete the old share
            del self.config[name]

        # create table and fix permission
        tmpInsert = {'comment': comment}

        if permAll:
            tmpInsert['public'] = 'yes'
            shlaunch("setfacl -b %s" % shellquote(path))
            os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
        else:
            tmpInsert['public'] = 'no'
            os.chmod(path, stat.S_IRWXU | stat.S_IRWXG)
            # flush ACLs
            shlaunch("setfacl -b %s" % path)
            acl1 = posix1e.ACL(file=path)
            # Add and set default mask to rwx
            # This is needed by the ACL system, else the ACLs won't be valid
            e = acl1.append()
            e.permset.add(posix1e.ACL_READ)
            e.permset.add(posix1e.ACL_WRITE)
            e.permset.add(posix1e.ACL_EXECUTE)
            e.tag_type = posix1e.ACL_MASK
            # For each specified group, we add rwx access
            for group in usergroups:
                e = acl1.append()
                e.permset.add(posix1e.ACL_READ)
                e.permset.add(posix1e.ACL_WRITE)
                e.permset.add(posix1e.ACL_EXECUTE)
                e.tag_type = posix1e.ACL_GROUP
                # Search the gid number corresponding to the given group
                ldapobj = ldapUserGroupControl()
                try:
                    gidNumber = ldapobj.getDetailedGroup(group)['gidNumber'][0]
                except ldap.NO_SUCH_OBJECT:
                    gidNumber = grp.getgrnam(group).gr_gid
                e.qualifier = int(gidNumber)
                # FIXME howto use posix1e for this ?
                shlaunch("setfacl -d -m g:%s:rwx %s" % (str(gidNumber), path))
            for user in users:
                e = acl1.append()
                e.permset.add(posix1e.ACL_READ)
                e.permset.add(posix1e.ACL_WRITE)
                e.permset.add(posix1e.ACL_EXECUTE)
                e.tag_type = posix1e.ACL_USER
                # Search the gid number corresponding to the given group
                ldapobj = ldapUserGroupControl()
                try:
                    uidNumber = ldapobj.getDetailedUser(user)['uidNumber'][0]
                except KeyError:
                    uidNumber = pwd.getpwnam(user).pw_uid
                e.qualifier = int(uidNumber)
                # FIXME howto use posix1e for this ?
                shlaunch("setfacl -d -m u:%s:rwx %s" % (str(uidNumber), path))
            # Test if our ACLs are valid
            if acl1.valid():
                acl1.applyto(path)
            else:
                logger.error("Cannot save ACL on folder " + path)

        tmpInsert['writeable'] = 'yes'
        if not browseable:
            tmpInsert['browseable'] = 'No'
        tmpInsert['path'] = path

        self.config[name] = tmpInsert

        info = self.shareInfo(name)
        # FIXME are this signals used?
        if mod and share_modified:
            share_modified.send(sender=self, share_name=name, share_info=info)
        elif not mod and share_created:
            share_created.send(sender=self, share_name=name, share_info=info)
        r.commit()
Example #34
0
 def _create_user(self, username, password, name, surname):
     ldapUserGroupControl().addUser(username, password, name, surname)
Example #35
0
 def _create_group(self, name, description=None):
     ldapUserGroupControl().addGroup(name)
Example #36
0
 def _create_group(self, name, description=None):
     logger.debug('calling ldapUserGroupControl().addGroup(%s)', name)
     ldapUserGroupControl().addGroup(name)
Example #37
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("allusers")
     self.u = UserQuotaControl(conffile="tests-mds/userquotatest.ini",
                               conffilebase="tests-mds/basetest.ini")
Example #38
0
def activate():
    """
     this function define if the module "base" can be activated.
     @return: return True if this module can be activate
     @rtype: boolean
    """
    config = SambaConfig("samba")

    if config.disabled:
        logger.info("samba plugin disabled by configuration.")
        return False

    if config.defaultSharesPath:
        if config.defaultSharesPath.endswith("/"):
            logger.error("Trailing / is not allowed in defaultSharesPath")
            return False
        if not os.path.exists(config.defaultSharesPath):
            logger.error("The default shares path '%s' does not exist" % config.defaultSharesPath)
            return False

    for cpath in config.authorizedSharePaths:
        if cpath.endswith("/"):
            logger.error("Trailing / is not allowed in authorizedSharePaths")
            return False
        if not os.path.exists(cpath):
            logger.error("The authorized share path '%s' does not exist" % cpath)
            return False

    # Verify if samba conf file exist
    conf = config.samba_conf_file
    if not os.path.exists(conf):
        logger.error(conf + " does not exist")
        return False

    # validate smb.conf
    smbconf = SambaConf()
    if not smbconf.validate(conf):
        logger.error("SAMBA configuration file is not valid")
        return False

    # For each share, test if it sharePath exists
    for share in getDetailedShares():
        shareName = share[0]
        infos = shareInfo(shareName)
        if infos:
            sharePath = infos["sharePath"]
            if sharePath and not "%" in sharePath and not os.path.exists(sharePath):
                # only show error
                logger.error("The samba share path '%s' does not exist." % sharePath)
        else:
            return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the Samba LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("sambaSamAccount")
        if len(schema) <= 0:
            logger.error("Samba schema is not included in LDAP directory")
            return False
    except:
        logger.exception("invalid schema")
        return False

    # Verify if init script exist
    init = config.samba_init_script
    if not os.path.exists(init):
        logger.error(init + " does not exist")
        return False

    # If SAMBA is defined as a PDC, make extra checks
    if smbconf.isPdc():
        samba = SambaLDAP()
        # Create SAMBA computers account OU if it doesn't exist
        head, path = samba.baseComputersDN.split(",", 1)
        ouName = head.split("=")[1]
        samba.addOu(ouName, path)
        # Check that a sambaDomainName entry is in LDAP directory
        domainInfos = samba.getDomain()
        # Set domain policy
        samba.setDomainPolicy()
        if not domainInfos:
            logger.error(
                "Can't find sambaDomainName entry in LDAP for domain %s. Please check your SAMBA LDAP configuration."
                % smbconf.getContent("global", "workgroup")
            )
            return False
        smbconfbasesuffix = smbconf.getContent("global", "ldap suffix")
        if not smbconfbasesuffix:
            logger.error("SAMBA 'ldap suffix' option is not setted.")
            return False
        if ldap.explode_dn(samba.baseDN) != ldap.explode_dn(smbconfbasesuffix):
            logger.error("SAMBA 'ldap suffix' option is not equal to MMC 'baseDN' option.")
            return False
        # Check that SAMBA and MMC given OU are in sync
        for option in [
            ("ldap user suffix", "baseUsersDN", samba.baseUsersDN),
            ("ldap group suffix", "baseGroupsDN", samba.baseGroupsDN),
            ("ldap machine suffix", "baseComputersDN", samba.baseComputersDN),
        ]:
            smbconfsuffix = smbconf.getContent("global", option[0])
            if not smbconfsuffix:
                logger.error("SAMBA '" + option[0] + "' option is not setted")
                return False
            # Do a case insensitive comparison of the corresponding MMC / SAMBA options
            if ldap.explode_rdn(smbconfsuffix)[0].lower() != ldap.explode_rdn(option[2])[0].lower():
                logger.error("SAMBA option '" + option[0] + "' is not equal to MMC '" + option[1] + "' option.")
                return False
        # Check that "ldap delete dn" SAMBA option is set to "No"
        smbconfdeletedn = smbconf.isValueTrue(smbconf.getContent("global", "ldap delete dn"))
        if smbconfdeletedn == 1:
            logger.error("SAMBA option 'ldap delete dn' must be disabled.")
            return False
        # Check that Domain Computers group exists
        # We need it to put a machine account in the right group when joigning it to the domain
        if not samba.getDomainComputersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Computers' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Admins group exists
        if not samba.getDomainAdminsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Admins' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Guests group exists
        if not samba.getDomainGuestsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Guests' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Users group exists
        if not samba.getDomainUsersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Users' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that add machine script option is set, and that the given script exist
        addMachineScript = smbconf.getContent("global", "add machine script")
        if not addMachineScript:
            logger.error("SAMBA 'add machine script' option is not set.")
            return False
        else:
            script = addMachineScript.split(" ")[0]
            if not os.path.exists(script):
                logger.error("SAMBA 'add machine script' option is set to a non existing file: " + script)
                return False
        #  Issue a warning if NSCD is running
        if (
            os.path.exists("/var/run/nscd.pid")
            or os.path.exists("/var/run/.nscd_socket")
            or os.path.exists("/var/run/nscd")
        ):
            logger.warning("Looks like NSCD is installed on your system. You should not run NSCD on a SAMBA server.")
        # Check that os level is set to 255
        oslevel = smbconf.getContent("global", "os level")
        if int(oslevel) < 255:
            logger.debug("Set SAMBA os level to 255.")
            smbconf.setContent("global", "os level", "255")
            smbconf.save()
            reloadSamba()
    try:
        from mmc.plugins.dashboard.manager import DashboardManager
        from mmc.plugins.samba.panel import SambaPanel

        DM = DashboardManager()
        DM.register_panel(SambaPanel("samba"))
    except ImportError:
        pass

    return True
Example #39
0
 def _create_group(self, name, description=None):
     ldapUserGroupControl().addGroup(name)
Example #40
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
Example #41
0
def activate():
    """
     this function define if the module "base" can be activated.
     @return: return True if this module can be activate
     @rtype: boolean
    """
    config = SambaConfig("samba")

    if config.disabled:
        logger.info("samba plugin disabled by configuration.")
        return False

    if config.defaultSharesPath:
        if config.defaultSharesPath.endswith("/"):
            logger.error("Trailing / is not allowed in defaultSharesPath")
            return False
        if not os.path.exists(config.defaultSharesPath):
            logger.error("The default shares path '%s' does not exist" %
                         config.defaultSharesPath)
            return False

    for cpath in config.authorizedSharePaths:
        if cpath.endswith("/"):
            logger.error("Trailing / is not allowed in authorizedSharePaths")
            return False
        if not os.path.exists(cpath):
            logger.error("The authorized share path '%s' does not exist" %
                         cpath)
            return False

    # Verify if samba conf file exist
    conf = config.samba_conf_file
    if not os.path.exists(conf):
        logger.error(conf + " does not exist")
        return False

    # validate smb.conf
    smbconf = SambaConf()
    if not smbconf.validate(conf):
        logger.error("SAMBA configuration file is not valid")
        return False

    # For each share, test if it sharePath exists
    for share in getDetailedShares():
        shareName = share[0]
        infos = shareInfo(shareName)
        if infos:
            sharePath = infos['sharePath']
            if sharePath and not '%' in sharePath and not os.path.exists(
                    sharePath):
                # only show error
                logger.error("The samba share path '%s' does not exist." %
                             sharePath)
        else:
            return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the Samba LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("sambaSamAccount")
        if len(schema) <= 0:
            logger.error("Samba schema is not included in LDAP directory")
            return False
    except:
        logger.exception("invalid schema")
        return False

    # Verify if init script exist
    init = config.samba_init_script
    if not os.path.exists(init):
        logger.error(init + " does not exist")
        return False

    # If SAMBA is defined as a PDC, make extra checks
    if smbconf.isPdc():
        samba = SambaLDAP()
        # Create SAMBA computers account OU if it doesn't exist
        head, path = samba.baseComputersDN.split(",", 1)
        ouName = head.split("=")[1]
        samba.addOu(ouName, path)
        # Check that a sambaDomainName entry is in LDAP directory
        domainInfos = samba.getDomain()
        # Set domain policy
        samba.setDomainPolicy()
        if not domainInfos:
            logger.error(
                "Can't find sambaDomainName entry in LDAP for domain %s. Please check your SAMBA LDAP configuration."
                % smbconf.getContent("global", "workgroup"))
            return False
        smbconfbasesuffix = smbconf.getContent("global", "ldap suffix")
        if not smbconfbasesuffix:
            logger.error("SAMBA 'ldap suffix' option is not setted.")
            return False
        if ldap.explode_dn(samba.baseDN) != ldap.explode_dn(smbconfbasesuffix):
            logger.error(
                "SAMBA 'ldap suffix' option is not equal to MMC 'baseDN' option."
            )
            return False
        # Check that SAMBA and MMC given OU are in sync
        for option in [
            ("ldap user suffix", "baseUsersDN", samba.baseUsersDN),
            ("ldap group suffix", "baseGroupsDN", samba.baseGroupsDN),
            ("ldap machine suffix", "baseComputersDN", samba.baseComputersDN)
        ]:
            smbconfsuffix = smbconf.getContent("global", option[0])
            if not smbconfsuffix:
                logger.error("SAMBA '" + option[0] + "' option is not setted")
                return False
            # Do a case insensitive comparison of the corresponding MMC / SAMBA options
            if ldap.explode_rdn(smbconfsuffix)[0].lower() != ldap.explode_rdn(
                    option[2])[0].lower():
                logger.error("SAMBA option '" + option[0] +
                             "' is not equal to MMC '" + option[1] +
                             "' option.")
                return False
        # Check that "ldap delete dn" SAMBA option is set to "No"
        smbconfdeletedn = smbconf.isValueTrue(
            smbconf.getContent("global", "ldap delete dn"))
        if smbconfdeletedn == 1:
            logger.error("SAMBA option 'ldap delete dn' must be disabled.")
            return False
        # Check that Domain Computers group exists
        # We need it to put a machine account in the right group when joigning it to the domain
        if not samba.getDomainComputersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Computers' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Admins group exists
        if not samba.getDomainAdminsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Admins' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Guests group exists
        if not samba.getDomainGuestsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Guests' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Users group exists
        if not samba.getDomainUsersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Users' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that add machine script option is set, and that the given script exist
        addMachineScript = smbconf.getContent("global", "add machine script")
        if not addMachineScript:
            logger.error("SAMBA 'add machine script' option is not set.")
            return False
        else:
            script = addMachineScript.split(" ")[0]
            if not os.path.exists(script):
                logger.error(
                    "SAMBA 'add machine script' option is set to a non existing file: "
                    + script)
                return False
        # Issue a warning if NSCD is running
        if os.path.exists("/var/run/nscd.pid") or os.path.exists(
                "/var/run/.nscd_socket") or os.path.exists("/var/run/nscd"):
            logger.warning(
                "Looks like NSCD is installed on your system. You should not run NSCD on a SAMBA server."
            )
        # Check that os level is set to 255
        oslevel = smbconf.getContent("global", "os level")
        if int(oslevel) < 255:
            logger.debug("Set SAMBA os level to 255.")
            smbconf.setContent("global", "os level", "255")
            smbconf.save()
            reloadSamba()
    try:
        from mmc.plugins.dashboard.manager import DashboardManager
        from mmc.plugins.samba.panel import SambaPanel
        DM = DashboardManager()
        DM.register_panel(SambaPanel("samba"))
    except ImportError:
        pass

    return True
Example #42
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.assertEqual(self.l.addGroup("allusers"), 10001)
Example #43
0
    def doProvisioning(self, authtoken):
        from mmc.plugins.base import ldapUserGroupControl
        self.logger.debug(str(authtoken.getInfos()))
        l = ldapUserGroupControl()
        userentry = authtoken.getInfos()[1]
        uid = userentry[self.config.ldap_uid][0]
        if l.existUser(uid):
            self.logger.debug("User %s already exists, so this user won't be added" % uid)
        else:
            givenName = userentry[self.config.ldap_givenName][0].decode("utf-8")
            sn = userentry[self.config.ldap_sn][0].decode("utf-8")
            l.addUser(uid, authtoken.getPassword(), givenName, sn)
        if self.config.profileAttr and self.config.profilesAcl:
            # Set or update the user right
            try:
                profile = userentry[self.config.profileAttr][0].lower()
            except KeyError:
                self.logger.info("No profile information for user %s in attribute %s" % (uid, self.config.profileAttr))
                profile = ""
            profile = profile.strip()
            
            try:
                entities = self.config.profilesEntity[profile].split()
                self.logger.info("*******ENTITE '%s' " % (entities))
            except KeyError:
                if self.config.profilesEntity.has_key("default"):
                    entities = self.config.profilesEntity["default"].split()
                    self.logger.info("Set the default profile to user.")
                    profile = 'default'
                else:
                    self.logger.info("No entity defined in configuration file for profile '%s'" % profile)
                    self.logger.info("Setting user's entity to empty")
                    entities = []
            if profile and entities:
                tmp = []
                for entity in entities:
                    if entity.startswith('%') and entity.endswith('%'):
                        attr = entity.strip('%')
                        if attr in userentry:
                            tmp.extend(userentry[attr])
                        else:
                            self.logger.info("The user '%s' doesn't have an attribute '%s'" % (uid, attr))

                    elif entity.startswith('plugin:'):
                        plugin = entity.replace('plugin:', '')
                        searchpath = os.path.join(os.path.dirname(__file__), 'provisioning_plugins')
                        try:
                            f, p, d = imp.find_module(plugin, [searchpath])
                            mod = imp.load_module(plugin, f, p, d)
                            klass = mod.PluginEntities
                            found = klass().get(authtoken)
                            if found:
                                self.logger.info("Plugin '%s' found these entities: %s" % (plugin, found))
                            else:
                                self.logger.info("Plugin '%s' found no matching entity" % plugin)
                            tmp.extend(found)
                        except ImportError:
                            self.logger.error("The plugin '%s' can't be imported" % plugin)
                        except Exception, e:
                            self.logger.error("Error while using the plugin '%s'" % plugin)
                            self.logger.exception(e)



                    else:
                        tmp.append(entity)
                entities = tmp[:]
                self.logger.info("****Setting user '%s' entities corresponding to user profile '%s': %s" % (uid, profile, str(entities)))
                from pulse2.database.inventory import Inventory
                Inventory().setUserEntities(uid, entities)
            
            
            try:
                acls = self.config.profilesAcl[profile]
            except KeyError:
                self.logger.info("No ACL defined in configuration file for profile '%s'" % profile)
                self.logger.info("Setting ACL to empty")
                acls = None
            if profile and acls:
                self.logger.info("Setting MMC ACL corresponding to user profile %s: %s" % (profile, str(acls)))
            entry = l.getDetailedUser(uid)
            if not "lmcUserObject" in entry["objectClass"]:
                entry["objectClass"].append("lmcUserObject")
                l.changeUserAttributes(uid, "objectClass", entry["objectClass"])
            l.changeUserAttributes(uid, "lmcAcl", acls)
            if self.config.profileGroupMapping:
                # Set user group membership according to mapping
                for prof in self.config.profilesAcl:
                    groupname = self.config.profileGroupPrefix + prof
                    if prof != profile:
                        # Delete the user from a group not belonging to her/his
                        # profile
                        try:
                            l.delUserFromGroup(groupname, uid)
                            self.logger.debug('Deleting user %s from group %s' % (uid, groupname))
                        except ldap.NO_SUCH_OBJECT:
                            # The group does not exist
                            pass
                    else:
                        # Add the user to this group
                        try:
                            l.addGroup(groupname)
                        except ldap.ALREADY_EXISTS:
                            # This group already exists
                            pass
                        self.logger.debug('Adding user %s to group %s' % (uid, groupname))
                        l.addUserToGroup(groupname, uid)
Example #44
0
 def setUp(self):
     cleanLdap()
     self.l = ldapUserGroupControl("tests-mds/basetest.ini")
     self.l.addGroup("allusers")
     self.u = UserQuotaControl(conffile = "tests-mds/userquotatest.ini", conffilebase = "tests-mds/basetest.ini")
Example #45
0
            tmpInsert['writeable'] = 'yes'
            os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
        else:
            tmpInsert['public'] = 'no'
            tmpInsert['writeable'] = 'no'
            os.chmod(path, stat.S_IRWXU | stat.S_IRWXG)
            acls = posix1e.ACL(file=path)
            # Add and set default mask to rwx
            # This is needed by the ACL system, else the ACLs won't be valid
            e = acls.append()
            e.permset.add(posix1e.ACL_READ)
            e.permset.add(posix1e.ACL_WRITE)
            e.permset.add(posix1e.ACL_EXECUTE)
            e.tag_type = posix1e.ACL_MASK
            # For each specified group, we add rwx access
            ldapobj = ldapUserGroupControl(self.conffilebase)

            def add_acl_permset(acl, entity, rights):
                e = acls.append()
                if 'r' in rights:
                    e.permset.add(posix1e.ACL_READ)
                if 'w' in rights:
                    e.permset.add(posix1e.ACL_WRITE)
                if 'x' in rights:
                    e.permset.add(posix1e.ACL_EXECUTE)
                if entity.startswith('@'):
                    e.tag_type = posix1e.ACL_GROUP
                    try:
                        gidNumber = ldapobj.getDetailedGroup(entity[1:])['gidNumber'][0]
                    except ldap.NO_SUCH_OBJECT:
                        gidNumber = grp.getgrnam(entity[1:]).gr_gid