def bind(self): while True: with self.cv: notify = self.cv.wait(60) if self.enabled: if self.parameters['krb_principal']: try: obtain_or_renew_ticket( self.principal, keytab=True, renew_life=TICKET_RENEW_LIFE ) 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 self.directory.state == DirectoryState.BOUND and not notify: continue try: self.directory.put_state(DirectoryState.JOINING) if self.parameters['krb_principal']: self.conn = ldap3.Connection( self.server, client_strategy='ASYNC', authentication=ldap3.SASL, sasl_mechanism='GSSAPI' ) else: self.conn = ldap3.Connection( self.server, client_strategy='ASYNC', user=self.parameters['bind_dn'], password=self.parameters['password'] ) if self.start_tls: logger.debug('Performing STARTTLS...') self.conn.open() self.conn.start_tls() if not self.conn.bind(): raise RuntimeError('Bind failed: wrong credentials') self.directory.put_state(DirectoryState.BOUND) continue except BaseException as err: self.directory.put_status(errno.ENXIO, '{0} <{1}>'.format(str(err), type(err).__name__)) self.directory.put_state(DirectoryState.FAILURE) continue else: if self.directory.state != DirectoryState.DISABLED: self.directory.put_state(DirectoryState.EXITING) self.conn.unbind() self.directory.put_state(DirectoryState.DISABLED) continue
def bind(self): while True: with self.cv: notify = self.cv.wait(60) if self.enabled: try: obtain_or_renew_ticket(self.principal, self.parameters['password'], renew_life=TICKET_RENEW_LIFE) 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 self.directory.state == DirectoryState.BOUND and not notify: continue try: self.directory.put_state(DirectoryState.JOINING) self.servers = [ ldap3.Server(i) for i in self.ldap_addresses ] self.conn = ldap3.Connection(self.servers, client_strategy='ASYNC', authentication=ldap3.SASL, sasl_mechanism='GSSAPI') self.conn.bind() self.directory.put_state(DirectoryState.BOUND) continue except BaseException as err: self.directory.put_status( errno.ENXIO, '{0} <{1}>'.format(str(err), type(err).__name__)) self.directory.put_state(DirectoryState.FAILURE) continue else: if self.directory.state != DirectoryState.DISABLED: if self.conn: self.conn.unbind() self.directory.put_state(DirectoryState.DISABLED) continue
def join(self): logger.info('Trying to join to {0}...'.format(self.realm)) try: self.configure_smb(True) obtain_or_renew_ticket(self.principal, self.parameters['password']) subprocess.call( ['/usr/local/bin/net', 'ads', 'join', self.realm, '-k']) subprocess.call(['/usr/sbin/service', 'samba_server', 'restart']) self.dc = self.wbc.ping_dc(self.realm) self.domain_info = self.wbc.get_domain_info(self.realm) self.domain_name = self.wbc.interface.netbios_domain except BaseException as err: self.directory.put_status(errno.ENXIO, str(err)) self.directory.put_state(DirectoryState.FAILURE) return False logger.info('Sucessfully joined to the domain {0}'.format(self.realm)) self.directory.put_state(DirectoryState.BOUND) return True
def bind(self): def create_args(params): validate = ssl.CERT_REQUIRED if params.get( 'verify_certificate', False) 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} while True: with self.cv: notify = self.cv.wait(60) if self.enabled: try: obtain_or_renew_ticket(self.principal, self.parameters['password'], renew_life=TICKET_RENEW_LIFE) 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 self.directory.state == DirectoryState.BOUND and not notify: continue try: self.directory.put_state(DirectoryState.JOINING) self.servers = [ ldap3.Server(i, **create_args(self.parameters)) for i in self.ldap_addresses ] self.conn = ldap3.Connection(self.servers, client_strategy='ASYNC', authentication=ldap3.SASL, sasl_mechanism='GSSAPI') if self.parameters['encryption'] == 'TLS': logger.debug('Performing STARTTLS...') self.conn.open() self.conn.start_tls() self.conn.bind() self.directory.put_state(DirectoryState.BOUND) continue 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) continue else: if self.directory.state != DirectoryState.DISABLED: if self.conn: self.conn.unbind() self.directory.put_state(DirectoryState.DISABLED) continue
def bind(self): logger.debug('Bind thread: starting') while True: with self.cv: notify = self.cv.wait(60) if notify: pass 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 self.directory.put_state(DirectoryState.BOUND) if not self.ldap: 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) try: self.ldap.bind() logger.debug('LDAP bound') except BaseException as err: logging.exception('err') self.directory.put_status(errno.ENXIO, str(err)) self.directory.put_state(DirectoryState.FAILURE) continue # Prefetch "Domain Users" GUID du = self.search_one(self.base_dn, '(sAMAccountName=Domain Users)') self.domain_users_guid = uuid.UUID( bytes=du['attributes']['objectGUID'][0]) logger.debug('Domain Users GUID is {0}'.format( self.domain_users_guid)) else: if self.directory.state != DirectoryState.DISABLED: self.leave() self.directory.put_state(DirectoryState.DISABLED)
def __renew_ticket(self): obtain_or_renew_ticket(self.principal, self.parameters['password'])
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: # 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'] self.domain_admins_sid = f'{self.domain_sid}-512' logger.info('Domain SID: {0}'.format( self.domain_sid)) # Figure out group DN and prefetch "Domain Users" GUID dsid = 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)