Ejemplo n.º 1
0
    def convert_user(self, entry):
        if not entry:
            return

        entry = dict(entry['attributes'])
        if 'user' not in get(entry, 'objectClass'):
            # not a user
            return

        username = get(entry, 'sAMAccountName.0')
        usersid = sid.sid(get(entry, 'objectSid.0'), sid.SID_BINARY)
        groups = []
        wbu = self.wbc.get_user(name='{0}\\{1}'.format(self.realm, username))

        if not wbu:
            logging.warning(
                'User {0} found in LDAP, but not in winbindd.'.format(
                    username))
            return

        if get(entry, 'memberOf'):
            builder = LdapQueryBuilder()
            qstr = builder.build_query([('distinguishedName', 'in',
                                         get(entry, 'memberOf'))])

            for r in self.search(self.base_dn, qstr):
                r = dict(r['attributes'])
                guid = uuid.UUID(bytes=get(r, 'objectGUID.0'))
                groups.append(str(guid))

        return {
            'id': str(uuid.UUID(bytes=get(entry, 'objectGUID.0'))),
            'sid': str(usersid),
            'uid': wbu.passwd.pw_uid,
            'builtin': False,
            'username': username,
            'aliases': [wbu.passwd.pw_name],
            'full_name': get(entry, 'name.0'),
            'email': None,
            'locked': False,
            'sudo': False,
            'password_disabled': False,
            'group': str(self.domain_users_guid),
            'groups': groups,
            'shell': wbu.passwd.pw_shell,
            'home': wbu.passwd.pw_dir
        }
Ejemplo n.º 2
0
    def convert_user(self, entry):
        if not entry:
            return

        entry = dict(entry['attributes'])
        if 'user' not in get(entry, 'objectClass'):
            # not a user
            return

        username = get(entry, 'sAMAccountName.0')
        usersid = sid.sid(get(entry, 'objectSid.0'), sid.SID_BINARY)
        groups = []
        wbu = self.wbc.get_user(name='{0}\\{1}'.format(self.realm, username))

        if not wbu:
            logging.warning('User {0} found in LDAP, but not in winbindd.'.format(username))
            return

        if get(entry, 'memberOf'):
            builder = LdapQueryBuilder()
            qstr = builder.build_query([
                ('distinguishedName', 'in', get(entry, 'memberOf'))
            ])

            for r in self.search(self.group_dn, qstr):
                r = dict(r['attributes'])
                guid = uuid.UUID(bytes=get(r, 'objectGUID.0'))
                groups.append(str(guid))

        return {
            'id': str(uuid.UUID(bytes=get(entry, 'objectGUID.0'))),
            'sid': str(usersid),
            'uid': wbu.passwd.pw_uid,
            'builtin': False,
            'username': username,
            'aliases': [wbu.passwd.pw_name],
            'full_name': get(entry, 'name.0'),
            'email': None,
            'locked': False,
            'sudo': False,
            'password_disabled': False,
            'group': str(self.domain_users_guid),
            'groups': groups,
            'shell': wbu.passwd.pw_shell,
            'home': wbu.passwd.pw_dir
        }
Ejemplo n.º 3
0
    def convert_group(self, entry):
        if not entry:
            return

        entry = dict(entry['attributes'])
        if 'group' not in get(entry, 'objectClass'):
            # not a group
            return

        groupname = get(entry, 'sAMAccountName.0')
        groupsid = sid.sid(get(entry, 'objectSid.0'), sid.SID_BINARY)
        parents = []
        wbg = self.wbc.get_group(name='{0}\\{1}'.format(self.realm, groupname))

        if not wbg:
            logging.warning(
                'Group {0} found in LDAP, but not in winbindd.'.format(
                    groupname))
            return

        if get(entry, 'memberOf'):
            builder = LdapQueryBuilder()
            qstr = builder.build_query([('distinguishedName', 'in',
                                         get(entry, 'memberOf'))])

            for r in self.search(self.base_dn, qstr):
                r = dict(r['attributes'])
                guid = uuid.UUID(bytes=get(r, 'objectGUID.0'))
                parents.append(str(guid))

        return {
            'id': str(uuid.UUID(bytes=get(entry, 'objectGUID.0'))),
            'sid': str(groupsid),
            'gid': wbg.group.gr_gid,
            'builtin': False,
            'name': groupname,
            'aliases': [wbg.group.gr_name],
            'parents': parents,
            'sudo': False
        }
Ejemplo n.º 4
0
    def convert_group(self, entry):
        if not entry:
            return

        entry = dict(entry['attributes'])
        if 'group' not in get(entry, 'objectClass'):
            # not a group
            return

        groupname = get(entry, 'sAMAccountName.0')
        groupsid = sid.sid(get(entry, 'objectSid.0'), sid.SID_BINARY)
        parents = []
        wbg = self.wbc.get_group(name='{0}\\{1}'.format(self.realm, groupname))

        if not wbg:
            logging.warning('Group {0} found in LDAP, but not in winbindd.'.format(groupname))
            return

        if get(entry, 'memberOf'):
            builder = LdapQueryBuilder()
            qstr = builder.build_query([
                ('distinguishedName', 'in', get(entry, 'memberOf'))
            ])

            for r in self.search(self.group_dn, qstr):
                r = dict(r['attributes'])
                guid = uuid.UUID(bytes=get(r, 'objectGUID.0'))
                parents.append(str(guid))

        return {
            'id': str(uuid.UUID(bytes=get(entry, 'objectGUID.0'))),
            'sid': str(groupsid),
            'gid': wbg.group.gr_gid,
            'builtin': False,
            'name': groupname,
            'aliases': [wbg.group.gr_name],
            'parents': parents,
            'sudo': False
        }
Ejemplo n.º 5
0
    def bind(self):
        logger.debug('Bind thread: starting')
        while True:
            with self.cv:
                notify = self.cv.wait(60)

                if notify:
                    if self.is_joined() and self.enabled:
                        self.directory.put_state(DirectoryState.EXITING)
                        self.leave()

                if self.enabled:
                    try:
                        obtain_or_renew_ticket(self.principal,
                                               self.parameters['password'])
                    except krb5.KrbException as err:
                        self.directory.put_status(
                            errno.ENXIO,
                            '{0} <{1}>'.format(str(err),
                                               type(err).__name__))
                        self.directory.put_state(DirectoryState.FAILURE)
                        continue

                    if not self.is_joined(True):
                        # Try to rejoin
                        logger.debug('Keepalive thread: rejoining')
                        self.directory.put_state(DirectoryState.JOINING)
                        if not self.join():
                            continue
                    else:
                        self.domain_info = self.wbc.get_domain_info(self.realm)
                        self.domain_name = self.wbc.interface.netbios_domain

                    if self.directory.state != DirectoryState.BOUND:
                        try:
                            logger.debug('Initializing LDAP connection')
                            logger.debug('LDAP server addresses: {0}'.format(
                                ', '.join(self.ldap_addresses)))
                            ldap_addresses = self.ldap_addresses

                            if self.parameters.get('dc_address'):
                                logger.debug(
                                    'Using manually configured DC address')
                                ldap_addresses = [
                                    self.parameters.get('dc_address')
                                ]

                            self.ldap_servers = [
                                ldap3.Server(i) for i in ldap_addresses
                            ]
                            self.ldap = ldap3.Connection(
                                self.ldap_servers,
                                client_strategy='ASYNC',
                                authentication=ldap3.SASL,
                                sasl_mechanism='GSSAPI',
                                sasl_credentials=None)

                            if not self.ldap.bind():
                                # try TLS now
                                logger.warning(
                                    'Regular bind failed, trying STARTTLS...')
                                self.ldap.start_tls()
                                if not self.ldap.bind():
                                    raise RuntimeError("Failed to bind")

                            logger.debug('LDAP bound')

                            # Get the domain object
                            domain = self.search_dn(self.base_dn)
                            if not domain:
                                raise RuntimeError(
                                    'Failed to fetch domain LDAP object, incorrect realm?'
                                )

                            self.domain_sid = domain['attributes']['objectSid']
                            logger.info('Domain SID: {0}'.format(
                                self.domain_sid))

                            # Figure out group DN and prefetch "Domain Users" GUID
                            dsid = sid.sid('{0}-{1}'.format(
                                self.domain_sid, 513))
                            du = self.search_one(
                                self.base_dn,
                                '(objectSid={0})'.format(dsid.ldap()))
                            if not du:
                                raise RuntimeError(
                                    'Failed to fetch Domain Users')

                            self.domain_users_guid = uuid.UUID(
                                du['attributes']['objectGUID'])
                            logger.debug('Domain Users GUID is {0}'.format(
                                self.domain_users_guid))
                        except BaseException as err:
                            logger.debug('Failure details', exc_info=True)
                            self.directory.put_status(
                                errno.ENXIO,
                                '{0} <{1}>'.format(str(err),
                                                   type(err).__name__))
                            self.directory.put_state(DirectoryState.FAILURE)
                        else:
                            self.directory.put_state(DirectoryState.BOUND)
                else:
                    if self.directory.state != DirectoryState.DISABLED:
                        self.leave()
                        self.directory.put_state(DirectoryState.DISABLED)
Ejemplo n.º 6
0
    def bind(self):
        logger.debug('Bind thread: starting')
        while True:
            with self.cv:
                notify = self.cv.wait(60)

                if notify:
                    if self.is_joined() and self.enabled:
                        self.directory.put_state(DirectoryState.EXITING)
                        self.leave()

                if self.enabled:
                    try:
                        obtain_or_renew_ticket(self.principal, self.parameters['password'])
                    except krb5.KrbException as err:
                        self.directory.put_status(errno.ENXIO, '{0} <{1}>'.format(str(err), type(err).__name__))
                        self.directory.put_state(DirectoryState.FAILURE)
                        continue

                    if not self.is_joined(True):
                        # Try to rejoin
                        logger.debug('Keepalive thread: rejoining')
                        self.directory.put_state(DirectoryState.JOINING)
                        if not self.join():
                            continue
                    else:
                        self.domain_info = self.wbc.get_domain_info(self.realm)
                        self.domain_name = self.wbc.interface.netbios_domain

                    if self.directory.state != DirectoryState.BOUND:
                        try:
                            logger.debug('Initializing LDAP connection')
                            logger.debug('LDAP server addresses: {0}'.format(', '.join(self.ldap_addresses)))
                            ldap_addresses = self.ldap_addresses

                            if self.parameters.get('dc_address'):
                                logger.debug('Using manually configured DC address')
                                ldap_addresses = [self.parameters.get('dc_address')]

                            self.ldap_servers = [ldap3.Server(i) for i in ldap_addresses]
                            self.ldap = ldap3.Connection(
                                self.ldap_servers,
                                client_strategy='ASYNC',
                                authentication=ldap3.SASL,
                                sasl_mechanism='GSSAPI',
                                sasl_credentials=None
                            )

                            if not self.ldap.bind():
                                # try TLS now
                                logger.warning('Regular bind failed, trying STARTTLS...')
                                self.ldap.start_tls()
                                if not self.ldap.bind():
                                    raise RuntimeError("Failed to bind")

                            logger.debug('LDAP bound')

                            # Get the domain object
                            domain = self.search_dn(self.base_dn)
                            if not domain:
                                raise RuntimeError('Failed to fetch domain LDAP object, incorrect realm?')

                            self.domain_sid = domain['attributes']['objectSid']
                            logger.info('Domain SID: {0}'.format(self.domain_sid))

                            # Figure out group DN and prefetch "Domain Users" GUID
                            dsid = sid.sid('{0}-{1}'.format(self.domain_sid, 513))
                            du = self.search_one(self.base_dn, '(objectSid={0})'.format(dsid.ldap()))
                            if not du:
                                raise RuntimeError('Failed to fetch Domain Users')

                            self.domain_users_guid = uuid.UUID(du['attributes']['objectGUID'])
                            logger.debug('Domain Users GUID is {0}'.format(self.domain_users_guid))
                        except BaseException as err:
                            logger.debug('Failure details', exc_info=True)
                            self.directory.put_status(errno.ENXIO, '{0} <{1}>'.format(str(err), type(err).__name__))
                            self.directory.put_state(DirectoryState.FAILURE)
                        else:
                            self.directory.put_state(DirectoryState.BOUND)
                else:
                    if self.directory.state != DirectoryState.DISABLED:
                        self.leave()
                        self.directory.put_state(DirectoryState.DISABLED)