def configure(self, enable, directory): def create_server_args(params): validate = ssl.CERT_REQUIRED if params['verify_certificate'] else ssl.CERT_NONE if params['encryption'] == 'OFF': return {} if params['encryption'] == 'SSL': tls = ldap3.Tls(validate=validate) return { 'port': 636, 'use_ssl': True, 'tls': tls } if params['encryption'] == 'TLS': tls = ldap3.Tls(validate=validate) return { 'tls': tls } with self.cv: self.directory = directory self.parameters = directory.parameters self.enabled = enable self.server = ldap3.Server(self.parameters['server'], **create_server_args(self.parameters)) self.base_dn = self.parameters['base_dn'] self.user_dn = join_dn(self.parameters['user_suffix'], self.base_dn) self.group_dn = join_dn(self.parameters['group_suffix'], self.base_dn) self.start_tls = self.parameters['encryption'] == 'TLS' self.cv.notify_all() return dn_to_domain(directory.parameters['base_dn'])
def configure(self, enable, uid_min, uid_max, gid_min, gid_max, parameters): self.parameters = parameters self.server = ldap3.Server(self.parameters['server']) self.base_dn = self.parameters['base_dn'] self.user_dn = join_dn(self.parameters['user_suffix'], self.base_dn) self.group_dn = join_dn(self.parameters['group_suffix'], self.base_dn) self.conn = ldap3.Connection( self.server, client_strategy='ASYNC', user=self.parameters['bind_dn'], password=self.parameters['password'] ) self.conn.bind() return dn_to_domain(parameters['base_dn'])
def authenticate(self, user, password): logger.debug('authenticate(user={0}, password=<...>)'.format(user)) try: return self.conn.rebind( join_dn('uid={0}'.format(user), self.user_dn), password) except: return False
def authenticate(self, user, password): logger.debug('authenticate(user={0}, password=<...>)'.format(user)) try: self.conn.rebind(join_dn(user, self.user_dn), password) return True except: return False
def authenticate(self, user_name, password): with self.bind_lock: try: self.conn.rebind(user=join_dn('uid={0}'.format(user_name), self.user_dn), password=password) except ldap3.LDAPBindError: self.conn.bind() return False self.conn.bind() return True
def authenticate(self, user_name, password): with self.bind_lock: try: self.conn.rebind( user=join_dn('uid={0}'.format(user_name), self.user_dn), password=password ) except ldap3.LDAPBindError: self.conn.bind() return False self.conn.bind() return True
def getgrnam(self, name): logger.debug('getgrnam(name={0})'.format(name)) group = self.search_one(join_dn('cn={0}'.format(name), self.group_dn), '(objectclass=posixGroup)') return self.convert_group(group)
def getpwnam(self, name): logger.debug('getpwnam(name={0})'.format(name)) user = self.search_one(join_dn('uid={0}'.format(name), self.user_dn), '(objectclass=posixAccount)') return self.convert_user(user)
def base_dn(self): return join_dn('CN=Users', domain_to_dn(self.realm))
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 sasl_credentials = None if self.parameters.get('dc_address'): logger.debug('Using manually configured DC address') sasl_credentials = (self.ldap_addresses[0][:-1],) ldap_addresses = get_a_records(self.ldap_addresses[0], self.parameters['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=sasl_credentials ) 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') # Figure out group DN and prefetch "Domain Users" GUID for dn in ('CN=Users', 'CN=Groups'): du = self.search_one(join_dn(dn, self.base_dn), '(sAMAccountName=Domain Users)') if not du: continue self.domain_users_guid = uuid.UUID(bytes=du['attributes']['objectGUID'][0]) self.user_dn = join_dn('CN=Users', self.base_dn) self.group_dn = join_dn(dn, self.base_dn) logger.debug('Group DN is {0}'.format(self.group_dn)) logger.debug('Domain Users GUID is {0}'.format(self.domain_users_guid)) break else: raise RuntimeError('Failed to fetch Domain Users') except BaseException as err: 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)