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 }
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 }
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 }
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 }
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)
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)