def connexion(): global con print("methode de connexion") con = Connection(server, user=dn_connect, password=dn_pass) if not con.bind(): print("error de connexion a {}".format(server))
def get_ad_users(self): """Returns a list of users from specific OUs via LDAPS. Outputs: user_list - A list of active users in AD. Raises: OSError - Occurs when the script is unable to locate or open the configuration file. It can also occur when the value used as input for the wintime_to_timestr function receives an invalid input. LDAPExceptionError - Occurs when the LDAP3 functions generate an error. The base class for all LDAPExcetionErrors is used so that the log.exception call will catch the detailed exception while not missing any potential exceptions. A fail safe, as it were.""" # Setting logging and configuration. config = ConfigParser() try: config.read(self.conf) except OSError: self.log.exception( 'Fatal Error: Unable to open configuration file.') exit(1) ldap_url = config['ldap']['url'] ldap_bind_dn = config['ldap']['bind_dn'] search_ou = config['ldap']['search_ou'].split('|') ldap_bind_secret = get_credentials({ 'api_key': config['ldap']['scss_api'], 'otp': config['ldap']['scss_otp'], 'userid': config['ldap']['scss_user'], 'url': config['ldap']['scss_url'] }) # Connecting to LDAP. Raising an exception with logging if the # connection is unsuccessful. start = time() tls_config = Tls(validate=CERT_NONE, version=PROTOCOL_TLSv1_2) server = Server(ldap_url, use_ssl=True, tls=tls_config) try: conn = Connection(server, user=ldap_bind_dn, password=ldap_bind_secret, auto_bind=True) except LDAPExceptionError: self.log.exception('Error occurred connecting to LDAP server.') self.log.debug('Successfully connected to LDAP server: %s', ldap_url) # Getting user data from LDAP, and converting the data (a list # of strings) to a dictionary so that it can be easily written # to different outputs if so desired. user_list = [] raw_user_data = [] # Searching LDAP for users that are in the OUs (and all sub-OUs) # specified in config['ldap']['search_ou']. ldap_filter = ('(&(objectClass=user)(objectCategory=CN=Person,' + 'CN=Schema,CN=Configuration,DC=24hourfit,DC=com))') for ou in search_ou: user_data = conn.extend.standard.paged_search( ou, ldap_filter, search_scope=SUBTREE, attributes=['sAMAccountName'], paged_size=500, ) for raw_data in user_data: raw_user_data.append(raw_data['raw_attributes']) # Mapping LDAP data to a dictionary. We are decoding the values # so that Python recognizes them as a string instead of byte-like # objects for compatibiltiy with other string (or string realted) # functions/methods. for data in raw_user_data: acct_name = data['sAMAccountName'][0].decode().lower() self.ad_users.append(acct_name) self.log.info('Successfully retrieved active user information from %s', config['ldap']['url']) # Unbinding the LDAP object as a good house cleaning measure. conn.unbind() end = time() _elapsed = end - start elapsed = int(round(_elapsed, 0)) self.log.debug('Retrieved active users in %d seconds', elapsed) user_list = self.ad_users return user_list
def get_bad_svc_acct_pwd(self): """Produces a list of service accounts that have not had a password change in 365 days. Keyword Arguments: None Returns: self.svc_acct_pwd_exp - A list of service accounts that have aged passwords. Raises: OSError - Occurs when the script is unable to locate or open the configuration file. LDAPExceptionError - Occurs when the LDAP3 functions generate an error. The base class for all LDAPExcetionErrors is used so that the log.exception call will catch the detailed exception while not missing any potential exceptions.""" # Retrieving information from the configuration file. config = ConfigParser() try: config.read(self.conf) except OSError: self.log.exception('Unable to open configuration file.') exit(1) ldap_url = config['ldap']['url'] ldap_bind_dn = config['ldap']['bind_dn'] search_ou = config['ldap']['svc_ou'].split('|') # Getting credentials from SCSS. ldap_bind_secret = get_credentials({ 'api_key': config['ldap']['scss_api'], 'otp': config['ldap']['scss_otp'], 'userid': config['ldap']['scss_user'], 'url': config['ldap']['scss_url'] }) # Getting password expiration time (in days). Change this # value in the configuration as approrpiate for your # organization. passwd_exp_days = int(config['ldap']['passwd_exp']) # Connecting to LDAP. tls_config = Tls(validate=CERT_NONE, version=PROTOCOL_TLSv1_2) server = Server(ldap_url, use_ssl=True, tls=tls_config) try: conn = Connection(server, user=ldap_bind_dn, password=ldap_bind_secret, auto_bind=True) except LDAPExceptionError: self.log.exception('Error occurred connecting to LDAP server.') self.log.debug('Successfully connected to LDAP server: %s', ldap_url) raw_user_data = [] # Searching LDAP for service accounts that are in the OUs # (and all sub-OUs) specified in config['ldap']['svc_ou']. ldap_filter = ('(&(objectClass=user)(objectCategory=CN=Person,' + 'CN=Schema,CN=Configuration,DC=24hourfit,DC=com))') for ou in search_ou: user_data = conn.extend.standard.paged_search( ou, ldap_filter, search_scope=SUBTREE, attributes=['sAMAccountName', 'passwordLastChange'], paged_size=500, ) for raw_data in user_data: raw_user_data.append(raw_data['raw_attributes']) current_time = round(time()) for data in raw_data: # Coverting wintime to epoch. wintime = int(data[0]['passwordLastChange']) pwd_change = wintime / 10000000 - 11644473600 # Determining password age. pwd_age = int(current_time - pwd_change) / 60 / 24 / 24 # Determing if a password hasn't been changed since the # value specified in the configuration. if pwd_age >= passwd_exp_days: self.svc_acct_pwd_exp.append( data[0]['sAMAccountName'].decode()) return self.svc_acct_pwd_exp
def authenticatVFUser(self, username, password): try: ldap_server = settings.LDAP_SERVER # adjust this to your base dn for searching base_dn = settings.LDAP_BASE_DN # the following is the user_dn format provided by the ldap server user_dn = "uid=" + username + "," + base_dn try: conn = Connection(ldap_server, user_dn, password, auto_bind=True) search_filter = "(uid=" + username + ")" try: #if authentication successful, get the full user data conn.search(search_base=base_dn, search_filter=search_filter, search_scope=ldap3.SUBTREE, attributes=['*']) infoLDAPUser = json.loads(conn.entries[0].entry_to_json()) conn.unbind() groups = [] ldap_groups = infoLDAPUser['attributes']['memberOf'] for i in range(len(ldap_groups)): if ldap_groups[i].replace('cn=', '').replace( ',o=airtel.es', '') in settings.LDAP_ALLOWED_GROUPS: groups.append(ldap_groups[i].replace( 'cn=', '').replace(',o=airtel.es', '')) if len(groups) == 0: raise ApiException('User with invalid privileges.') output = { 'username': infoLDAPUser['attributes']['uid'][0], 'firstname': infoLDAPUser['attributes']['givenName'][0], 'surname': infoLDAPUser['attributes']['sn'][0], 'groups': groups } if ("mail" in infoLDAPUser['attributes']): output['email'] = infoLDAPUser['attributes']['mail'][0] else: output['email'] = output['username'] + '@unknown.com' return (output) except Exception as e: conn.unbind() raise ApiException('Authentication Error:' + str(e.args[0])) except ldap3.core.exceptions.LDAPBindError as e2: log.error('Exception:' + type(e2).__name__ + " " + str(e2)) raise ApiException( 'Authentication Error:Invalid user or credentials') except ldap3.core.exceptions.LDAPSocketOpenError as e3: log.error('Exception:' + type(e3).__name__ + " " + str(e3)) raise ApiException( 'Authentication Error:Unable to connect to LDAP server') except Exception as ex: log.error('Exception:' + type(ex).__name__ + " " + str(ex)) log.error(traceback.format_exc()) raise ApiException(str(ex))
def init_and_get_ldap_user(self, username): if username is None or username == '': return None, None # add LDAP_BIND_PASSWORD as password field password_field = 'LDAP_BIND_PWD' if hasattr( settings, 'LDAP_BIND_PWD') else 'LDAP_BIND_PASSWORD' # check configuration if not (hasattr(settings, 'LDAP_SERVERS') and hasattr(settings, 'LDAP_BIND_USER') and hasattr(settings, password_field) and hasattr(settings, 'LDAP_SEARCH_BASE') and hasattr(settings, 'LDAP_USER_SEARCH_FILTER') and hasattr(settings, 'LDAP_ATTRIBUTES_MAP')): raise ImproperlyConfigured() # as first release of the module does not have this parameter, default is to set it true to keep the same # comportment after updates. if hasattr(settings, 'LDAP_USE_LDAP_GROUPS') and isinstance( settings.LDAP_USE_LDAP_GROUPS, bool): LDAP3ADBackend.use_groups = settings.LDAP_USE_LDAP_GROUPS else: LDAP3ADBackend.use_groups = True if LDAP3ADBackend.use_groups and not ( hasattr(settings, 'LDAP_GROUPS_SEARCH_FILTER') and hasattr(settings, 'LDAP_GROUP_MEMBER_ATTRIBUTE') and hasattr(settings, 'LDAP_GROUPS_MAP')): raise ImproperlyConfigured() # LDAP_IGNORED_LOCAL_GROUPS is a list of local Django groups that must be kept. if (hasattr(settings, 'LDAP_IGNORED_LOCAL_GROUPS') and not isinstance(settings.LDAP_IGNORED_LOCAL_GROUPS, list)): raise ImproperlyConfigured() if hasattr(settings, 'LDAP_AUTHENTICATION'): authentication = getattr(settings, 'LDAP_AUTHENTICATION') else: authentication = SIMPLE # first: build server pool from settings if LDAP3ADBackend.pool is None: LDAP3ADBackend.pool = ServerPool(None, pool_strategy=FIRST, active=True) for srv in settings.LDAP_SERVERS: # check if LDAP_SERVERS settings has set ldap3 `get_info` parameter if 'get_info' in srv: server = Server(srv['host'], srv['port'], srv['use_ssl'], get_info=srv['get_info']) else: server = Server(srv['host'], srv['port'], srv['use_ssl']) LDAP3ADBackend.pool.add(server) # then, try to connect with user/pass from settings con = Connection(LDAP3ADBackend.pool, auto_bind=True, client_strategy=SYNC, user=settings.LDAP_BIND_USER, password=getattr(settings, password_field) or settings.LDAP_BIND_PASSWORD, authentication=authentication, check_names=True) # search for the desired user user_dn = None user_attribs = None con.search(settings.LDAP_SEARCH_BASE, settings.LDAP_USER_SEARCH_FILTER.replace( '%s', '{0}').format(username), attributes=list(settings.LDAP_ATTRIBUTES_MAP.values())) if con.result['result'] == 0 and len( con.response) > 0 and 'dn' in con.response[0].keys(): user_dn = con.response[0]['dn'] user_attribs = con.response[0]['attributes'] # convert `user_attribs` values to string if the returned value is a list for attrib in user_attribs: if isinstance(user_attribs[attrib], list): user_attribs[attrib] = user_attribs[attrib][0] con.unbind() return user_dn, user_attribs
def _init(): if not HOOK.server: HOOK.server = Server(LDAP_SERVER_IP) HOOK.connection = Connection(HOOK.server, auto_bind=True)
def connect(self): """Setup the connection to the LDAP server and authenticate the user. """ # Parse the server URI uri = getattr(config, 'LDAP_SERVER_URI', None) if uri: uri = urlparse(uri) # Create the TLS configuration object if required tls = None if type(uri) == str: return False, "LDAP configuration error: Set the proper LDAP URI." if uri.scheme == 'ldaps' or config.LDAP_USE_STARTTLS: ca_cert_file = getattr(config, 'LDAP_CA_CERT_FILE', None) cert_file = getattr(config, 'LDAP_CERT_FILE', None) key_file = getattr(config, 'LDAP_KEY_FILE', None) cert_validate = ssl.CERT_NONE if ca_cert_file and cert_file and key_file: cert_validate = ssl.CERT_REQUIRED try: tls = Tls(local_private_key_file=key_file, local_certificate_file=cert_file, validate=cert_validate, version=ssl.PROTOCOL_TLSv1_2, ca_certs_file=ca_cert_file) except LDAPSSLConfigurationError as e: current_app.logger.exception( "LDAP configuration error: {}\n".format(e)) return False, "LDAP configuration error: {}\n".format( e.args[0]) try: # Create the server object server = Server(uri.hostname, port=uri.port, use_ssl=(uri.scheme == 'ldaps'), get_info=ALL, tls=tls, connect_timeout=config.LDAP_CONNECTION_TIMEOUT) except ValueError as e: return False, "LDAP configuration error: {}.".format(e) # Create the connection try: user_dn = "{0}={1},{2}".format(config.LDAP_USERNAME_ATTRIBUTE, self.username, config.LDAP_BASE_DN) self.conn = Connection(server, user=user_dn, password=self.password, auto_bind=True) except LDAPSocketOpenError as e: current_app.logger.exception( "Error connecting to the LDAP server: {}\n".format(e)) return False, "Error connecting to the LDAP server:" \ " {}\n".format(e.args[0]) except LDAPBindError as e: current_app.logger.exception("Error binding to the LDAP server.") return False, "Error binding to the LDAP server." except Exception as e: current_app.logger.exception( "Error connecting to the LDAP server: {}\n".format(e)) return False, "Error connecting to the LDAP server:" \ " {}\n".format(e.args[0]) # Enable TLS if STARTTLS is configured if not uri.scheme == 'ldaps' and config.LDAP_USE_STARTTLS: try: self.conn.start_tls() except LDAPStartTLSError as e: current_app.logger.exception( "Error starting TLS: {}\n".format(e)) return False, "Error starting TLS: {}\n".format(e.args[0]) return True, None
def authenticate(self, request, username=None, password=None, **keyword_arguments): # Check for remote user in extra arguments if no username and password. # In case of basic authentication if not username or not password: if "remote_user" in keyword_arguments: credentials = base_64_decode_basic_auth(keyword_arguments["remote_user"]) if credentials: username, password = credentials[0], credentials[1] else: return None else: return None user = check_user_exists_and_active(self, username) is_authenticated_with_ldap = False errors = [] for server in settings.LDAP_SERVERS: try: port = server.get("port", 636) use_ssl = server.get("use_ssl", True) bind_as_authentication = server.get("bind_as_authentication", True) domain = server.get("domain") t = Tls(validate=CERT_REQUIRED, version=PROTOCOL_TLSv1_2, ca_certs_file=server.get("certificate")) s = Server(server["url"], port=port, use_ssl=use_ssl, tls=t) auto_bind = AUTO_BIND_TLS_BEFORE_BIND if use_ssl else AUTO_BIND_NO_TLS ldap_bind_user = f"{domain}\\{username}" if domain else username if not bind_as_authentication: # binding to LDAP first, then search for user bind_username = server.get("bind_username", None) bind_username = f"{domain}\\{bind_username}" if domain and bind_username else bind_username bind_password = server.get("bind_password", None) authentication = SIMPLE if bind_username and bind_password else ANONYMOUS c = Connection( s, user=bind_username, password=bind_password, auto_bind=auto_bind, authentication=authentication, raise_exceptions=True, ) search_username_field = server.get("search_username_field", "uid") search_attribute = server.get("search_attribute", "cn") search = c.search( server["base_dn"], f"({search_username_field}={username})", attributes=[search_attribute] ) if not search or search_attribute not in c.response[0].get("attributes", []): # no results, unbind and continue to next server c.unbind() errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but the search with dn:{server['base_dn']}, username_field:{search_username_field} and attribute:{search_attribute} did not return any results. The user was denied access" ) continue else: # we got results, get the dn that will be used for binding authentication response = c.response[0] ldap_bind_user = response["dn"] c.unbind() # let's proceed with binding using the user trying to authenticate c = Connection( s, user=ldap_bind_user, password=password, auto_bind=auto_bind, authentication=SIMPLE, raise_exceptions=True, ) c.unbind() # At this point the user successfully authenticated to at least one LDAP server. is_authenticated_with_ldap = True auth_logger.debug(f"User {username} was successfully authenticated with LDAP ({server['url']})") break except LDAPBindError as e: errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but entered an incorrect password. The user was denied access: {str(e)}" ) except LDAPException as e: errors.append( f"User {username} attempted to authenticate with LDAP ({server['url']}), but an error occurred. The user was denied access: {str(e)}" ) if is_authenticated_with_ldap: return user else: for error in errors: auth_logger.warning(error) return None
def clean(self): userLocal = self.cleaned_data.get( 'username') + '@familyorientedmusic.local' userNet = self.cleaned_data.get( 'username') + '@familyorientedmusic.net' s = Server('128.187.61.57', port=389, use_ssl=False, get_info=ALL) c = Connection(s, user=userLocal, password=self.cleaned_data.get('password'), auto_bind='NONE', version=3, authentication='SIMPLE', client_strategy='SYNC', auto_referrals=True, check_names=True, read_only=False, lazy=False, raise_exceptions=False) if not c.bind(): print('error in bind', c.user) else: currentuser = amod.FomoUser.objects.filter( username=self.cleaned_data.get('username')) print('after current user', currentuser) c.search('cn=users,dc=familyorientedmusic,dc=local', '(objectclass=Person)', attributes=['mail', 'givenName', 'sn', 'streetaddress']) if not currentuser: for entry in c.response: print('in the for loop', entry) if 'mail' in entry['attributes']: print('in the mail if statement', entry['attributes']['mail']) if entry['attributes']['mail'] == userNet: adFomoUser = amod.FomoUser() adFomoUser.username = self.cleaned_data.get( 'username') adFomoUser.set_password( self.cleaned_data.get('password')) adFomoUser.first_name = entry['attributes'][ 'givenName'] adFomoUser.last_name = entry['attributes']['sn'] adFomoUser.shipping_address = entry['attributes'][ 'streetaddress'] adFomoUser.email = entry['attributes']['mail'] adFomoUser.is_superuser = True adFomoUser.is_staff = True adFomoUser.is_admin = True adFomoUser.save() user = authenticate( username=self.cleaned_data.get('username'), password=self.cleaned_data.get('password')) if user is None: raise forms.ValidationError( 'Invalid username or password.') return self.cleaned_data else: for entry in c.response: print('in the for loop', entry) if 'mail' in entry['attributes']: print('in the mail if statement', entry['attributes']['mail']) if entry['attributes']['mail'] == userNet: currentuser[0].first_name = entry['attributes'][ 'givenName'] currentuser[0].last_name = entry['attributes'][ 'sn'] currentuser[0].shipping_address = entry[ 'attributes']['streetaddress'] currentuser[0].email = entry['attributes']['mail'] currentuser[0].save() user = authenticate( username=self.cleaned_data.get('username'), password=self.cleaned_data.get('password')) if user is None: raise forms.ValidationError( 'Invalid username or password.') return self.cleaned_data user = authenticate(username=self.cleaned_data.get('username'), password=self.cleaned_data.get('password')) if user is None: raise forms.ValidationError('Invalid username or password.') return self.cleaned_data
def create_single_user(first_name=None, last_name=None, uid=None, code=None, teacher_code=None, write_to_db=False, out_stream=sys.stdout): """ Add a new user, create a Teacher object. """ logger = logging.getLogger(__name__) logger.info("Creating single user") logger.debug( "FN: {0}, LN: {1}, UID: {2}, code: {3}, tc: {4}, wdb: {5}, os: {6}". format(first_name, last_name, uid, code, teacher_code, write_to_db, out_stream)) try: logger.debug("Creating LDAP backend") ldap_backend = LDAPBackend() except: logger.exception() ldap_backend = None logger.debug("LDAP connecting to {0}".format( settings.AUTH_LDAP_SERVER_URI)) attributes = ['userprincipalname', 'givenname', 'sn', 'objectclass'] server = Server(settings.AUTH_LDAP_SERVER_URI, get_info=ALL) conn = Connection(server, settings.AUTH_LDAP_BIND_DN, settings.AUTH_LDAP_BIND_PASSWORD, auto_bind=True) logger.debug("LDAP BIND with username {0}".format( settings.AUTH_LDAP_BIND_DN)) time.sleep(1) s = settings.AUTH_LDAP_USER_SEARCH if uid is None and (first_name is not None and last_name is not None): logger.debug("UID is none, trying name based search") k = (first_name, last_name) filterstr = '(&(givenName={0})(sn={1}))'.format( first_name.encode('cp1250'), last_name.encode('cp1250')) logger.debug("Filterstring: {0}".format(filterstr)) try: conn.search(s.base_dn, filterstr, attributes=attributes) except Exception: logger.debug("Error during LDAP search") try: results = conn.entries except Exception as e: logger.exception("Error fetching results from LDAP") logger.debug("Got results: {0}".format(results)) if len(results) == 0: logger.debug("No results found") return False res1 = results[0] v = res1.userprincipalname.value else: logger.debug("UID is not none, perform UID search") k = None v = uid filterstr = "(userprincipalname={0})".format(v) logger.debug("Filterstring: {0}".format(filterstr)) try: conn.search(s.base_dn, filterstr, attributes=attributes) except Exception: logger.exception("Error during LDAP search") try: results = conn.entries except Exception as e: logger.exception("Error fetching results from LDAP: {0}".format(e)) logger.debug("Got results: {0}".format(results)) if len(results) == 0: logger.debug("No results found") return False res1 = results[0] k = (res1.givenname.value, res1.sn.value) if first_name is None: # first_name = k[0].decode('cp1250') first_name = k[0] logger.debug("Set first name to {0}".format(first_name)) if last_name is None: # last_name = k[1].decode('cp1250').upper() last_name = k[1].upper() logger.debug("Set last name to {0}".format(first_name)) logger.debug("Found {} {}: {}".format(first_name, last_name, v)) if ldap_backend is not None: try: logger.debug("Populating user") u = ldap_backend.populate_user(v) if u is None: raise Exception("user " + v + " not found in ldap!") else: logger.debug("Populated user: {0}".format(u)) u.save() u = User.objects.get(username__iexact=v) u.first_name = first_name u.last_name = last_name logger.debug("Setting first nad last name: {}; {}".format( first_name, last_name)) if write_to_db: logger.debug("Saving user to DB") u.save() try: if teacher_code is not None: logger.debug("Creating corresponding teacher") t = Teacher.objects.get_or_create(code=teacher_code) logger.debug("{}".format(t)) t = t[0] old_user = t.user t.user = u logger.debug("Changing user on teacher to {0}".format(u)) if write_to_db: if old_user is not None: logger.debug( "Deleting old user {}".format(old_user)) old_user.delete() logger.debug("Saving teacher") t.save() else: logger.debug("Teacher not saved: {}".format(t)) except Exception as e: logger.exception("Error creating teacher") return u except: logger.exception("Error during teacher creation") else: logger.error("No LDAP backend found")
def clean(self): if self.is_valid(): # check ldap try: # create server, make connection change server to cheritagefoundation.com later s = Server('www.cheritagefoundation.com', port=12345, get_info=GET_ALL_INFO) c = Connection(s, auto_bind=True, user=self.cleaned_data['username'] + '@cheritagefoundation.local', password=self.cleaned_data['password'], authentication=AUTH_SIMPLE, client_strategy=STRATEGY_SYNC) # search for user in Active Directory search_results = c.search( search_base='CN=Users,DC=cheritagefoundation,DC=local', search_filter='(samAccountName=' + self.cleaned_data['username'] + ')', search_scope=SEARCH_SCOPE_WHOLE_SUBTREE, attributes=[ 'givenName', 'sn', 'l', 'streetAddress', 'postalCode', 'st', 'mobile', 'info', ]) # if user exists if search_results: # get info from active directory user_info = c.response[0]['attributes'] # update chf user user = hmod.User.objects.get_or_create( username=self.cleaned_data['username'], first_name=user_info['givenName'], last_name=user_info['sn'], phone=user_info['mobile'], email=user_info['info'], ) user = hmod.User.objects.get( username=self.cleaned_data['username']) # set user password user.set_password(self.cleaned_data['password']) user.save() except: # user does not exist in Active Directory # try to log user in user = authenticate(username=self.cleaned_data['username'], password=self.cleaned_data['password']) if user is None: # report invalid user raise forms.ValidationError( "Incorrect username and password") return self.cleaned_data return self.cleaned_data
def login(username: str, password: str) -> tuple: try: if SERVER.lower().startswith("ldaps://"): server = Server(SERVER, port=PORT, get_info=NONE, use_ssl=True) else: server = Server( SERVER, port=PORT, get_info=NONE, use_ssl=False ) # define an unsecure LDAP server, requesting info on DSE and schema c = None if BIND_DN is not None and BIND_DN != '': c = Connection(server, auto_bind=True, client_strategy=SYNC, user=BIND_DN, password=BIND_PASSWORD, authentication=AUTH_SIMPLE, check_names=True) else: c = Connection(server, auto_bind=True, client_strategy=SYNC, user=None, password=None, authentication=AUTH_ANONYMOUS, check_names=True) except Exception as e: error = "Error connecting to LDAP server: %s" % e raise LDAPLoginError({"error_message": error}) try: if (SEARCH_SUFFIX is not None and SEARCH_SUFFIX != ''): search_filter = '(%s=%s)' % (SEARCH_PROPERTY, username + SEARCH_SUFFIX) else: search_filter = '(%s=%s)' % (SEARCH_PROPERTY, username) c.search(search_base=SEARCH_BASE, search_filter=search_filter, search_scope=SUBTREE, attributes=[EMAIL_PROPERTY, FULL_NAME_PROPERTY], paged_size=5) if len(c.response) > 0: dn = c.response[0].get('dn') user_email = c.response[0].get('raw_attributes').get( EMAIL_PROPERTY)[0].decode('utf-8') full_name = c.response[0].get('raw_attributes').get( FULL_NAME_PROPERTY)[0].decode('utf-8') user_conn = Connection(server, auto_bind=True, client_strategy=SYNC, user=dn, password=password, authentication=SIMPLE, check_names=True) return (user_email, full_name) raise LDAPLoginError( {"error_message": "Username or password incorrect"}) except Exception as e: error = "LDAP account or password incorrect: %s" % e raise LDAPLoginError({"error_message": error})
def authenticate(self, userPrincipalName, password): """ [概要] 認証 [引数] userPrincipalName: ユーザ名 password: パスワード read_timeout: 取得タイムアウト値(秒) [戻り値] AD_AUTH結果コード(define.AD_AUTH.RESULT_*) """ # TODO:server_poolのほうが使える? server = None serverList = [] for host in self._hosts: server = Server(host, port=self._port, use_ssl=self._use_ssl, get_info='ALL', connect_timeout=self._connect_timeout) # 対象hostの応答がなければ次のhostへ if not server.check_availability() : continue # 応答があればそれを使用する logger.logic_log('LOSI11003', host) serverList.append(server) if len(serverList) == 0: # すべてのhostがNGの場合はエラー logger.logic_log('LOSM11001', ', '.join(self._hosts)) return AD_AUTH.RESULT_OTHER_ERROR try: # step1. domainに対する認証 conn = Connection( serverList, auto_bind=AUTO_BIND_NONE, client_strategy=SYNC, user=userPrincipalName, password=password, authentication=SIMPLE, check_names=True, receive_timeout=self._read_timeout ) if not conn.bind(): logger.logic_log('LOSM11002', conn.last_error, conn.result['message']) result_message = conn.result['message'] error_code = AD_AUTH.RESULT_OTHER_ERROR if AD_AUTH.REGEXP_INVALID_CREDENCIALS_MESSAGE.match(result_message): error_code = AD_AUTH.RESULT_INVALID_CREDENCIALS error_message = 'Authentication information error' if AD_AUTH.REGEXP_ACCOUNT_LOCKED_MESSAGE.match(result_message): error_code = AD_AUTH.RESULT_ACCOUNT_LOCKED error_message = 'Account lock status' logger.logic_log('LOSM11003', error_code, error_message) return error_code # step2. 検索文字列で指定される組織内に存在するか # TODO 管理者の認証のときは除外する? success = conn.search(search_base=self._search_path, search_filter='(userPrincipalName=%s)' % userPrincipalName, search_scope=SUBTREE) if not success or len(conn.entries) != 1: logger.logic_log('LOSM11004', self._search_path) return AD_AUTH.RESULT_INVALID_CREDENCIALS except Exception as e: logger.system_log('LOSM11005', server.host, userPrincipalName) return AD_AUTH.RESULT_OTHER_ERROR logger.system_log('LOSI11004', conn) # 成功時 self._conn = conn return AD_AUTH.RESULT_SUCCESS
# from ldap3 import Server, Connection, ALL, NTLM from ldap3 import Connection, Server, SIMPLE, SYNC, SUBTREE, ALL server = Server('abc.com', get_info=ALL) conn = Connection(server, 'CN=user.name,OU=ProQC,OU=Users,OU=AI,DC=abc,DC=com', '', auto_bind=True) filter = "(userAccountControl=66048)" base_dn = "DC=abc,DC=com" conn.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE, attributes=['mail']) result = conn.response for i in result: # smail=i['raw_attributes']['mail'] if 'raw_attributes' in i.keys(): smail=i['raw_attributes']['mail'] output=' '.join(str(e) for e in smail) if output != "": output=output.replace("b'", "").replace("'", "") print(output) if output == "*****@*****.**": print("exit") conn.unbind()
def __init__(self, app=None, handler=None): """:func:`burpui.misc.auth.ldap.LdapLoader.__init__` establishes a connection to the LDAP server. :param app: Instance of the app we are running in :type app: :class:`burpui.server.BUIServer` """ self.app = app conf = self.app.config['CFG'] defaults = { 'host': 'localhost', 'port': None, 'encryption': None, 'binddn': None, 'bindpw': None, 'filter': None, 'base': None, 'searchattr': 'uid', 'validate': 'none', 'version': None, 'cafile': None } mapping = { 'host': 'host', 'port': 'port', 'encryption': 'encryption', 'filt': 'filter', 'base': 'base', 'attr': 'searchattr', 'binddn': 'binddn', 'bindpw': 'bindpw', 'validate': 'validate', 'version': 'version', 'cafile': 'cafile' } c = ConfigParser.ConfigParser(defaults) with open(conf) as fp: c.readfp(fp) # Maybe the handler argument is None, maybe the 'priority' # option is missing. We don't care. try: handler.priority = c.getint('LDAP', 'priority') except: pass for (opt, key) in viewitems(mapping): try: setattr(self, opt, c.get('LDAP', key)) except ConfigParser.NoOptionError as e: self.builogger.info(str(e)) except ConfigParser.NoSectionError as e: self.builogger.error(str(e)) if self.validate and self.validate.lower() in ['none', 'optional', 'required']: self.validate = getattr(ssl, 'CERT_{}'.format(self.validate.upper())) else: self.validate = None if self.version and self.version in ['SSLv2', 'SSLv3', 'SSLv23', 'TLSv1', 'TLSv1_1']: self.version = getattr(ssl, 'PROTOCOL_{}'.format(self.version)) else: self.version = None self.tls = None self.ssl = False self.auto_bind = AUTO_BIND_NONE if self.encryption == 'ssl': self.ssl = True elif self.encryption == 'tls': self.tls = Tls(local_certificate_file=self.cafile, validate=self.validate, version=self.version) self.auto_bind = AUTO_BIND_TLS_BEFORE_BIND if self.port: try: self.port = int(self.port) except ValueError: self.builogger.error('LDAP port must be a valid integer') self.port = None self.builogger.info('LDAP host: {0}'.format(self.host)) self.builogger.info('LDAP port: {0}'.format(self.port)) self.builogger.info('LDAP encryption: {0}'.format(self.encryption)) self.builogger.info('LDAP filter: {0}'.format(self.filt)) self.builogger.info('LDAP base: {0}'.format(self.base)) self.builogger.info('LDAP search attr: {0}'.format(self.attr)) self.builogger.info('LDAP binddn: {0}'.format(self.binddn)) self.builogger.info('LDAP bindpw: {0}'.format('*****' if self.bindpw else 'None')) self.builogger.info('TLS object: {0}'.format(self.tls)) try: self.server = Server(host=self.host, port=self.port, use_ssl=self.ssl, get_info=ALL, tls=self.tls) self.builogger.debug('LDAP Server = {0}'.format(str(self.server))) if self.binddn: self.ldap = Connection(self.server, user=self.binddn, password=self.bindpw, raise_exceptions=True, client_strategy=RESTARTABLE, auto_bind=self.auto_bind, authentication=SIMPLE) else: self.ldap = Connection(self.server, raise_exceptions=True, client_strategy=RESTARTABLE, auto_bind=self.auto_bind) with self.ldap: self.builogger.debug('LDAP Connection = {0}'.format(str(self.ldap))) self.builogger.info('OK, connected to LDAP') return raise Exception('Not connected') except Exception as e: self.builogger.error('Could not connect to LDAP: {0}'.format(str(e))) self.server = None self.ldap = None
else: setupObj.createLdapPw() ox_ldap_prop = read_properties_file('/etc/gluu/conf/gluu-ldap.properties') bindDN = ox_ldap_prop['bindDN'] bindPassword_e = ox_ldap_prop['bindPassword'] cmd = '/opt/gluu/bin/encode.py -D ' + bindPassword_e bindPassword = os.popen(cmd).read().strip() ldap_host, ldap_port = ox_ldap_prop['servers'].split(',')[0].strip().split( ':') ldap_server = Server(ldap_host, port=int(ldap_port), use_ssl=True) ldap_conn = Connection(ldap_server, user=bindDN, password=bindPassword) ldap_conn.bind() def get_oxAuthConfiguration_ldap(): ldap_conn.search(search_base='o=gluu', search_scope=SUBTREE, search_filter='(objectClass=oxAuthConfiguration)', attributes=["oxAuthConfDynamic"]) dn = ldap_conn.response[0]['dn'] oxAuthConfDynamic = json.loads( ldap_conn.response[0]['attributes']['oxAuthConfDynamic'][0]) return dn, oxAuthConfDynamic
from ldap3 import Server, Connection, ALL, SASL, KERBEROS import datetime server = Server('ldap.llnw.com', get_info=ALL) con = Connection(server) services = { 'servicenow': 'limon2.rest.dev', 'servicenow_stage': 'limon2.rest.uat', 'servicenow_prod': 'limon.te.prod.b', 'confluence': 'limonconfluenceread', 'zabbix_qa': 'zabbix-api-limon-qa', 'zabbix_dba_qa': 'zabbix-api-limon2', 'email': 'limon_noreply', 'zabbix_prod': 'zabbix-api-limon', 'zabbix_dba_prod': 'zabbix-api-limon1' } def find_expiration(): expiration = [] try: con.bind() for service, user in services.items(): if con.search('cn={0},ou=Applications,dc=llnw,dc=com'.format(user), '(objectclass=*)', attributes=['llnwUnixPasswordChangedTime']): expiration.append(con.response[0]['attributes']) print(expiration) except Exception:
try: print(' Выбрано OU:', AD_SEARCH_TREE) except NameError: print(' Выход из программы\n') exit() print('') AD_SERVER = 'dc.domain.local' # DNS имя сервера Active Directory AD_USER = '******' # Пользователь AD, два \\ обязательно AD_PASSWORD = '******' # Пароль #AD_SEARCH_TREE = 'DC=domain,DC=local' # Начальное дерево поиска #AD_SEARCH_TREE = 'OU=Dismissed,OU=Users,OU=Insigma (office),DC=domain,DC=local' # Начальное дерево поиска server = Server(AD_SERVER) # Строка сервера conn = Connection(server, user=AD_USER, password=AD_PASSWORD, authentication=NTLM) # Строка соединения if not conn.bind(): print(' ERROR IN BIND', conn.result) # Статус соединения ошибка else: print(' Соединение с DC... - OK') # Статус соединения ОК print('') # разрыв строк print('') # разрыв строк uAC_66048 = 66048 # Атрибут userAccountControl - Учетка Включена, срок действия пароля не ограничен uAC_66050 = 66050 # Атрибут userAccountControl - Учетка Отключена, срок действия пароля не ограничен uAC_512 = 512 # Атрибут userAccountControl - Учетная запись по умолчанию. Представляет собой типичного пользователя uAC_514 = 514 # Атрибут userAccountControl - Учетка Отключена
def home(request): """Страница автоизации""" next = '/dashboard/' if request.method == 'POST': # Проверка типа запроса username = request.POST['username'] # Имя пользователя password = request.POST['password'] # Пароль if 'next' in request.POST.keys(): next = request.POST['next'] user = authenticate(username=username, password=password) # Аутинтификация if user: # Проверка на правильность введенных данных if user.is_active: # Проверка активности профиля login(request, user) # Установка статуса авторизации в положительный log = slog.Log(key="", type=18, body="IP: {0}".format( slog.Log.get_client_ip(request)), user=request.user.doctorprofile) log.save() else: return HttpResponse( "Ваш аккаунт отключен") # Сообщение об ошибке else: if settings.LDAP and settings.LDAP[ "enable"] and False: # Проверка на наличие и активность настройки LDAP s = Server(settings.LDAP["server"]["host"], port=settings.LDAP["server"]["port"], get_info=ALL) # Создание объекта сервера c = Connection( s, auto_bind=True, user=settings.LDAP["server"]["user"], password=settings.LDAP["server"]["password"], client_strategy=SYNC, authentication=SIMPLE, check_names=True) # Создание соединения с сервером c.search(search_base=settings.LDAP["base"], search_filter='(&(uid=' + username + ')(userPassword='******'))', search_scope=SUBTREE, attributes=ALL_ATTRIBUTES, get_operational_attributes=True ) # Выполнение поиска пользователя в LDAP resp = json.loads(c.response_to_json()) # Нормализация ответа if len(resp["entries"]) == 1: # Если пользователь был найден if not User.objects.filter(username=username).exists( ): # Проверка существования пользователя user = User.objects.create_user( username) # Создание пользователя user.set_password(password) # Установка пароля if resp["entries"][0]["attributes"][ "accountStatus"] == "active": # Проверка статуса активности user.is_active = True # Активация пользователя else: user.is_active = False # Деактивация user.save() # Сохранение пользователя profile = DoctorProfile.objects.create( ) # Создание профиля profile.user = user # Привязка профиля к пользователю profile.isLDAP_user = True # Установка флага, показывающего, что это импортированый из LDAP пользователь profile.fio = resp["entries"][0]["attributes"][ "displayName"] # ФИО profile.save() # Сохранение профиля c.unbind() # Отключение от сервера return home(request) # Запуск запроса еще раз c.unbind() # Отключение от сервера return render(request, 'auth.html', { 'error': True, 'username': username }) # Сообщение об ошибке if request.user.is_authenticated(): # Проверка статуса автоизации return HttpResponseRedirect(next) # Редирект в п/у response = render( request, 'auth.html', { 'error': False, 'username': '' }, ) # Вывод формы авторизации response["Login-Screen"] = 1 return response
# import class and constants from ldap3 import Server, Connection, ALL, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, MODIFY_INCREMENT # define the server s = Server(host='yourhostname.com', port=389, use_ssl=False, get_info='ALL') # define the connection c = Connection(s, user='******', password='******', version=3, authentication='SIMPLE', client_strategy='SYNC', read_only=False, raise_exceptions=True) if not c.bind(): print('error in binding', c.result) else: print('Bind is successful!!') status = c.modify( 'uid=testuser,ou=people,o=yyy org,c=uk,dc=yourhostname,dc=com', { 'givenName': [(MODIFY_REPLACE, ['test-replaced'])], 'homePhone': [(MODIFY_ADD, ['1234567889'])], 'gecos': [(MODIFY_DELETE, ['test user'])], 'uidNumber': [(MODIFY_INCREMENT, ['10011'])] }) if not status:
from ldap3 import Server, Connection, MODIFY_ADD, MODIFY_REPLACE, ALL_ATTRIBUTES from ldap3.utils.dn import safe_rdn server = Server('ipa.demo1.freeipa.org') conn = Connection( server, 'uid=admin, cn=users, cn=accounts, dc=demo1, dc=freeipa, dc=org', 'Secret123', auto_bind=True) print(0, conn.extend.standard.who_am_i()) # print(server.schema) # print(server.info) # print(server.schema.object_classes['inetorgperson']) # print(server.schema.object_classes['organizationalperson']) # print(server.schema.object_classes['person']) # print(server.schema.object_classes['top']) # conn.search('dc=demo1, dc=freeipa, dc=org', '(&(objectclass=person)(uid=admin))', attributes=['sn', 'krbLastPwdChange', 'objectclass']) # entry = conn.entries[0] # print(entry) conn.add('ou=ldap3-tutorial, dc=demo1, dc=freeipa, dc=org', 'organizationalUnit') # conn.delete('cn=b.smith,ou=moved,ou=ldap3-tutorial,dc=demo1,dc=freeipa,dc=org') # from ldap3.protocol.rfc4527 import pre_read_control, post_read_control # print(1, conn.last_error) # conn.add('cn=b.young,ou=ldap3-tutorial,dc=demo1,dc=freeipa,dc=org', 'inetOrgPerson', {'givenName': 'Beatrix', 'sn': 'Young', 'departmentNumber': 'DEV', 'telephoneNumber': 1111}) # print(2, conn.modify('cn=b.young,ou=ldap3-tutorial,dc=demo1,dc=freeipa,dc=org', {'sn': [(MODIFY_ADD, ['Smyth'])]}, controls=[pre_read_control('sn'), post_read_control('sn')]))
def get_connection(bind=None, use_ssl=None, check_names=None, lazy_connection=None, authentication=None, sasl_mechanism=None, sasl_credentials=None, ntlm_credentials=(None, None), get_info=None, usage=None, fast_decoder=None, simple_credentials=(None, None), receive_timeout=None, auto_escape=None, auto_encode=None): if bind is None: bind = True if check_names is None: check_names = test_check_names if lazy_connection is None: lazy_connection = test_lazy_connection if authentication is None: authentication = test_authentication if get_info is None: get_info = test_get_info if usage is None: usage = test_usage if fast_decoder is None: fast_decoder = test_fast_decoder if receive_timeout is None: receive_timeout = test_receive_timeout if auto_escape is None: auto_escape = test_auto_escape if auto_encode is None: auto_encode = test_auto_encode if test_server_type == 'AD' and use_ssl is None: use_ssl = True # Active directory forbids Add operations in cleartext if test_strategy not in [MOCK_SYNC, MOCK_ASYNC]: # define real server if isinstance(test_server, (list, tuple)): server = ServerPool(pool_strategy=test_pooling_strategy, active=test_pooling_active, exhaust=test_pooling_exhaust) for host in test_server: server.add( Server(host=host, use_ssl=use_ssl, port=test_port_ssl if use_ssl else test_port, allowed_referral_hosts=('*', True), get_info=get_info, mode=test_server_mode)) else: server = Server(host=test_server, use_ssl=use_ssl, port=test_port_ssl if use_ssl else test_port, allowed_referral_hosts=('*', True), get_info=get_info, mode=test_server_mode) else: if test_server_type == 'EDIR': schema = SchemaInfo.from_json(edir_8_8_8_schema) info = DsaInfo.from_json(edir_8_8_8_dsa_info, schema) server = Server.from_definition('MockSyncServer', info, schema) elif test_server_type == 'AD': schema = SchemaInfo.from_json(ad_2012_r2_schema) info = DsaInfo.from_json(ad_2012_r2_dsa_info, schema) server = Server.from_definition('MockSyncServer', info, schema) elif test_server_type == 'SLAPD': schema = SchemaInfo.from_json(slapd_2_4_schema) info = DsaInfo.from_json(slapd_2_4_dsa_info, schema) server = Server.from_definition('MockSyncServer', info, schema) if authentication == SASL: connection = Connection(server, auto_bind=bind, version=3, client_strategy=test_strategy, authentication=SASL, sasl_mechanism=sasl_mechanism, sasl_credentials=sasl_credentials, lazy=lazy_connection, pool_name='pool1', check_names=check_names, collect_usage=usage, fast_decoder=fast_decoder, receive_timeout=receive_timeout, auto_escape=auto_escape, auto_encode=auto_encode) elif authentication == NTLM: connection = Connection(server, auto_bind=bind, version=3, client_strategy=test_strategy, user=ntlm_credentials[0], password=ntlm_credentials[1], authentication=NTLM, lazy=lazy_connection, pool_name='pool1', check_names=check_names, collect_usage=usage, fast_decoder=fast_decoder, receive_timeout=receive_timeout, auto_escape=auto_escape, auto_encode=auto_encode) elif authentication == ANONYMOUS: connection = Connection(server, auto_bind=bind, version=3, client_strategy=test_strategy, user=None, password=None, authentication=ANONYMOUS, lazy=lazy_connection, pool_name='pool1', check_names=check_names, collect_usage=usage, fast_decoder=fast_decoder, receive_timeout=receive_timeout, auto_escape=auto_escape, auto_encode=auto_encode) else: connection = Connection(server, auto_bind=bind, version=3, client_strategy=test_strategy, user=simple_credentials[0] or test_user, password=simple_credentials[1] or test_password, authentication=authentication, lazy=lazy_connection, pool_name='pool1', check_names=check_names, collect_usage=usage, fast_decoder=fast_decoder, receive_timeout=receive_timeout, auto_escape=auto_escape, auto_encode=auto_encode) if test_strategy in [MOCK_SYNC, MOCK_ASYNC]: # create authentication identities for testing mock strategies connection.strategy.add_entry(test_user, { 'objectClass': 'inetOrgPerson', 'userPassword': test_password }) connection.strategy.add_entry( test_secondary_user, { 'objectClass': 'inetOrgPerson', 'userPassword': test_secondary_password }) connection.strategy.add_entry(test_sasl_user_dn, { 'objectClass': 'inetOrgPerson', 'userPassword': test_sasl_password }) connection.strategy.add_entry( test_sasl_secondary_user_dn, { 'objectClass': 'inetOrgPerson', 'userPassword': test_sasl_secondary_password }) # connection.strategy.add_entry(test_ntlm_user, {'objectClass': 'inetOrgPerson', 'userPassword': test_ntlm_password}) if bind: connection.bind() if 'TRAVIS,' in location and test_server_type == 'SLAPD' and not connection.closed: # try to create the contexts for fixtures result1 = connection.add(test_base, 'organizationalUnit') result2 = connection.add(test_moved, 'organizationalUnit') if not connection.strategy.sync: connection.get_response(result1) connection.get_response(result2) return connection
def authenticate(self, request, username=None, password=None): logger.info("AUDIT BEGIN LOGIN PROCESS FOR: %s AT %s" % (username, datetime.now())) if username is None or username == '': return None # search capacities differs on LDAP engines. ldap_engine = 'AD' # to keep compatibility with previous version if hasattr(settings, 'LDAP_ENGINE') and settings.LDAP_ENGINE is not None: ldap_engine = settings.LDAP_ENGINE user_dn, user_attribs = self.init_and_get_ldap_user(username) if user_dn is not None and user_attribs is not None: # now, we know the dn of the user, we try a simple bind. This way, # the LDAP checks the password with it's algorithm and the active state of the user in one test con = Connection(LDAP3ADBackend.pool, user=user_dn, password=password) if con.bind(): logger.info("AUDIT SUCCESS LOGIN FOR: %s AT %s" % (username, datetime.now())) user_model = get_user_model() """ We add special attributes only during the authentication process to store user DN & Business Unit Those attributes are saved in the current session by the user_logged_in_handler """ user_model.dn = lambda: None user_model.bu = lambda: None try: # try to retrieve user from database and update it username_field = getattr(settings, 'LDAP_USER_MODEL_USERNAME_FIELD', 'username') lookup_username = user_attribs[ settings.LDAP_ATTRIBUTES_MAP[username_field]] usr = user_model.objects.get(**{ "{0}__iexact".format(username_field): lookup_username }) except user_model.DoesNotExist: # user does not exist in database already, create it usr = user_model() # update existing or new user with LDAP data self.update_user(usr, user_attribs) usr.set_password(password) usr.last_login = datetime.now() usr.save() # if we want to use LDAP group membership: if LDAP3ADBackend.use_groups: # if using AD filter groups in result by using groups in the config if ldap_engine == 'AD': # inspired from # https://github.com/Lucterios2/django_auth_ldap3_ad/commit/ce24d4687f85ed12a0c4c796022ae7dcb3ff38e3 # by jobec all_ldap_groups = [] for group in settings.LDAP_SUPERUSER_GROUPS + settings.LDAP_STAFF_GROUPS + list( settings.LDAP_GROUPS_MAP.values()): all_ldap_groups.append( "(distinguishedName={0})".format(group)) if len(all_ldap_groups) > 0: settings.LDAP_GROUPS_SEARCH_FILTER = "(&{0}(|{1}))".format( settings.LDAP_GROUPS_SEARCH_FILTER, "".join(all_ldap_groups)) # end # if using OpenLDAP, filter groups in search by membership of the user elif ldap_engine == 'OpenLDAP': # add filter on member settings.LDAP_GROUPS_SEARCH_FILTER = "(&%s(member=%s))" % ( settings.LDAP_GROUPS_SEARCH_FILTER, user_dn) # add filter on groups to match all_ldap_groups = [] for group in settings.LDAP_SUPERUSER_GROUPS + settings.LDAP_STAFF_GROUPS + list( settings.LDAP_GROUPS_MAP.values()): if "(%s)" % group.split( ',')[0] not in all_ldap_groups: all_ldap_groups.append("(%s)" % group.split(',')[0]) if len(all_ldap_groups) > 0: settings.LDAP_GROUPS_SEARCH_FILTER = "(&{0}(|{1}))".format( settings.LDAP_GROUPS_SEARCH_FILTER, "".join(all_ldap_groups)) logger.info("AUDIT LOGIN FOR: %s AT %s USING LDAP GROUPS" % (username, datetime.now())) # check for groups membership # first cleanup alter_superuser_membership = False if hasattr(settings, 'LDAP_SUPERUSER_GROUPS') and isinstance(settings.LDAP_SUPERUSER_GROUPS, list) \ and len(settings.LDAP_SUPERUSER_GROUPS) > 0: usr.is_superuser = False alter_superuser_membership = True alter_staff_membership = False if hasattr(settings, 'LDAP_STAFF_GROUPS') and isinstance(settings.LDAP_STAFF_GROUPS, list) \ and len(settings.LDAP_STAFF_GROUPS) > 0: usr.is_staff = False alter_staff_membership = True usr.save() logger.info( "AUDIT LOGIN FOR: %s AT %s CLEANING OLD GROUP MEMBERSHIP" % (username, datetime.now())) if hasattr(settings, 'LDAP_IGNORED_LOCAL_GROUPS'): grps = Group.objects.exclude( name__in=settings.LDAP_IGNORED_LOCAL_GROUPS) else: grps = Group.objects.all() for grp in grps: grp.user_set.remove(usr) grp.save() # then re-fill con.search(settings.LDAP_GROUPS_SEARCH_BASE if hasattr( settings, 'LDAP_GROUPS_SEARCH_BASE') else settings.LDAP_SEARCH_BASE, settings.LDAP_GROUPS_SEARCH_FILTER, attributes=[ 'cn', settings.LDAP_GROUP_MEMBER_ATTRIBUTE ]) if len(con.response) > 0: for resp in con.response: if 'attributes' in resp and settings.LDAP_GROUP_MEMBER_ATTRIBUTE in resp['attributes'] \ and user_dn in resp['attributes'][settings.LDAP_GROUP_MEMBER_ATTRIBUTE]: logger.info( "AUDIT LOGIN FOR: %s AT %s DETECTED IN GROUP %s" % (username, datetime.now(), resp['dn'])) # special super user group if alter_superuser_membership: if resp['dn'] in settings.LDAP_SUPERUSER_GROUPS: usr.is_superuser = True logger.info( "AUDIT LOGIN FOR: %s AT %s GRANTING ADMIN RIGHTS" % (username, datetime.now())) else: logger.info( "AUDIT LOGIN FOR: %s AT %s DENY ADMIN RIGHTS" % (username, datetime.now())) # special staff group if alter_staff_membership: if resp['dn'] in settings.LDAP_STAFF_GROUPS: usr.is_staff = True logger.info( "AUDIT LOGIN FOR: %s AT %s GRANTING STAFF RIGHTS" % (username, datetime.now())) else: logger.info( "AUDIT LOGIN FOR: %s AT %s DENY STAFF RIGHTS" % (username, datetime.now())) # other groups membership for grp in settings.LDAP_GROUPS_MAP.keys(): if resp['dn'] == settings.LDAP_GROUPS_MAP[ grp]: try: logger.info(grp) usr.groups.add( Group.objects.get(name=grp)) logger.info( "AUDIT LOGIN FOR: %s AT %s ADDING GROUP %s MEMBERSHIP" % (username, datetime.now(), grp)) except ObjectDoesNotExist: pass usr.save() con.unbind() # if set, apply min group membership logger.info( "AUDIT LOGIN FOR: %s AT %s BEFORE MIN GROUP MEMBERSHIP" % (username, datetime.now())) if hasattr(settings, 'LDAP_MIN_GROUPS'): for grp in settings.LDAP_MIN_GROUPS: logger.info( "AUDIT LOGIN FOR: %s AT %s MIN GROUP MEMBERSHIP: %s" % (username, datetime.now(), grp)) try: usr.groups.add(Group.objects.get(name=grp)) logger.info( "AUDIT LOGIN FOR: %s AT %s ADDING GROUP %s MIN MEMBERSHIP" % (username, datetime.now(), grp)) except ObjectDoesNotExist: pass # if you want to be able to get full user DN from session, store it if hasattr(settings, 'LDAP_STORE_USER_DN') \ and isinstance(settings.LDAP_USE_LDAP_GROUPS, bool) \ and settings.LDAP_USE_LDAP_GROUPS: usr.dn = user_dn # if you want to know in which business unit the user is, check it if hasattr(settings, 'LDAP_STORE_BUSINESS_UNIT') \ and isinstance(settings.LDAP_STORE_BUSINESS_UNIT, dict): user_bu = ','.join(user_dn.split(',')[1:]) if user_bu in settings.LDAP_STORE_BUSINESS_UNIT: usr.bu = settings.LDAP_STORE_BUSINESS_UNIT[user_bu] return usr return None
for whitelisted_rcpt in re.split(',|\s', whitelisted_rcpts_str): if g_re_email.match(whitelisted_rcpt) == None: logging.error( "ENV[MILTER_WHITELISTED_RCPTS]: invalid email address: " + whitelisted_rcpt) sys.exit(1) else: logging.info("ENV[MILTER_WHITELISTED_RCPTS]: " + whitelisted_rcpt) g_milter_whitelisted_rcpts[whitelisted_rcpt] = {} set_config_parameter("RESTARTABLE_SLEEPTIME", 2) set_config_parameter("RESTARTABLE_TRIES", 2) server = Server(g_ldap_server, get_info=NONE) g_ldap_conn = Connection(server, g_ldap_binddn, g_ldap_bindpw, auto_bind=True, raise_exceptions=True, client_strategy='RESTARTABLE') logging.info("Connected to LDAP-server: " + g_ldap_server) timeout = 600 # Register to have the Milter factory create instances of your class: Milter.factory = LdapAclMilter # Tell the MTA which features we use flags = Milter.ADDHDRS Milter.set_flags(flags) logging.info("Startup " + g_milter_name + "@socket: " + g_milter_socket + " in mode: " + g_milter_mode) Milter.runmilter(g_milter_name, g_milter_socket, timeout, True) logging.info("Shutdown " + g_milter_name) except: logging.error("MAIN-EXCEPTION: " + traceback.format_exc())
def add_ad_user(xingming, phone, qq, mail, start_time, type='sec_ccie'): # 转换汉字到拼音 hanzi = xingming try: xingming = pinyin.get(xingming, format='strip') except Exception: pass # 根据类型找到组 if type == 'sec_ccie' or type == 'sec_ccnp' or type == 'sec_ccnp1111': group_dn = 'CN=npsecremotelab, OU=NPSEC_RemoteLab, OU=Security, OU=QYT, DC=qytang,DC=com' display_name = 'rsec-' + xingming user_cn = 'cn=' + display_name + ',' + ','.join(group_dn.split(',')[1:]) # 判断是否重名, 如果重名就产生新的用户名 while True: try: display_name = get_user_attributes(user_cn).sAMAccountName name_randint = str(randint(1, 100)) display_name = display_name.value + name_randint user_cn = 'cn=' + display_name + ',' + ','.join( group_dn.split(',')[1:]) except Exception: break try: # 连接服务器 c = Connection(server, auto_bind=AUTO_BIND_NO_TLS, read_only=False, check_names=True, user="******" + username, password=password) if type == 'sec_ccie' or type == 'sec_ccnp': end_time = parser.parse(start_time) + timedelta(days=365 * 1.5) elif type == 'sec_ccnp1111': end_time = parser.parse(start_time) + timedelta(days=180) c.add( user_cn, attributes={ 'objectClass': ['top', 'person', 'organizationalPerson', 'user'], # 用户名 'sAMAccountName': display_name, # 用户名 'userPrincipalName': display_name, # 有效期一年半 'accountExpires': end_time, # 姓为中文的汉字 'sn': hanzi, # 显示名为用户名 'displayName': display_name, # 电话 "telephoneNumber": phone, # 邮件 "Mail": mail, # QQ "description": hanzi + qq }) # 添加用户到组 c.extend.microsoft.add_members_to_groups(user_cn, group_dn) # 产生随机密码 rand_pass = random_password() # 创建用户初始密码 c.extend.microsoft.modify_password(user_cn, new_password=rand_pass) # 激活用户 c.modify(user_cn, {'userAccountControl': [(MODIFY_REPLACE, [544])]}) # 发送通知客户邮件 return display_name, rand_pass except Exception: return None
def ldap_login(request): '''LDAP登录方式 ''' if request.method == 'POST': # 前端传值 req_data = json.loads(request.body) ldap = req_data.get("ldap") ldap_pwd = req_data.get("ldapPwd") type_req = req_data.get("type") # 从redis读取AD配置 conn_redis = get_redis_connection("configs_cache") str_data = conn_redis.get('AdServerConfig') json_data = json.loads(str_data) adServerIp = json_data['adServerIp'] baseDn = json_data['baseDn'] conn_ad = access_ad_server() if not conn_ad: res = { 'code': -1, 'message': 'LDAP服务器连接失败!', 'status': 'error', } return JsonResponse(res) else: res = conn_ad.search( search_base=baseDn, search_filter='(sAMAccountName={})'.format(ldap), search_scope=SUBTREE, attributes=['cn', 'givenName', 'mail', 'sAMAccountName'], paged_size=5) # 如果有此用户 if res: entry = conn_ad.response[0] if 'attributes' in entry.keys(): # 校验dn的密码 dn = entry['dn'] try: SERVER = Server( host=adServerIp, port=636, # 636安全端口 use_ssl=True, get_info=ALL, connect_timeout=3) # 连接超时为3秒 conn_ad_login = Connection(server=SERVER, user=dn, password=ldap_pwd, check_names=True, lazy=False, raise_exceptions=False) conn_ad_login.bind() if conn_ad_login.result["result"] == 0: res = { 'code': 0, 'message': 'LDAP用户登录成功!', 'status': 'ok', } return JsonResponse(res) else: res = { 'code': -1, 'message': '密码错误!', 'status': 'error', } return JsonResponse(res) except Exception: message = conn_ad_login.result["message"] res = { 'code': -1, 'message': message, 'status': 'error', } return res else: res = {'code': -1, 'message': '无此LDAP用户!', 'data': ''} return JsonResponse(res) else: res = {'code': -1, 'message': 'LDAP服务器错误!', 'data': ''} return JsonResponse(res)
def get_no_pwd_exp(self): """Retrieves users with no password expiration. Keyword Arguments: None. Returns: self.no_pwd_exp - A list of user accounts that do not have a password expiration. Raises: OSError - Occurs when the script is unable to locate or open the configuration file. LDAPExceptionError - Occurs when the LDAP3 functions generate an error. The base class for all LDAPExcetionErrors is used so that the log.exception call will catch the detailed exception while not missing any potential exceptions.""" # Obtaining configuration information. config = ConfigParser() try: config.read(self.conf) except OSError: self.log.exception( 'Fatal Error: Unable to open configuration file.') exit(1) ldap_url = config['ldap']['url'] ldap_bind_dn = config['ldap']['bind_dn'] search_ou = config['ldap']['search_ou'].split('|') ldap_bind_secret = get_credentials({ 'api_key': config['ldap']['scss_api'], 'otp': config['ldap']['scss_otp'], 'userid': config['ldap']['scss_user'], 'url': config['ldap']['scss_url'] }) # Connecting to LDAP. Raising an exception with logging if the # connection is unsuccessful. start = time() tls_config = Tls(validate=CERT_NONE, version=PROTOCOL_TLSv1_2) server = Server(ldap_url, use_ssl=True, tls=tls_config) try: conn = Connection(server, user=ldap_bind_dn, password=ldap_bind_secret, auto_bind=True) except LDAPExceptionError: self.log.exception('Error occurred connecting to LDAP server.') self.log.debug('Successfully connected to LDAP server: %s', ldap_url) raw_user_data = [] # Searching LDAP for users that are in the OUs (and all sub-OUs) # specified in config['ldap']['search_ou']. ldap_filter = ('(&(objectClass=user)(objectCategory=CN=Person,' + 'CN=Schema,CN=Configuration,DC=24hourfit,DC=com))') for ou in search_ou: user_data = conn.extend.standard.paged_search( ou, ldap_filter, search_scope=SUBTREE, attributes=[ 'sAMAccountName', 'userAccountControl', 'passwordLastChange' ], paged_size=500, ) for raw_data in user_data: raw_user_data.append(raw_data['raw_attributes']) # Checking to see if each user account has their password set # to never expire based on the value of the userAccountControl # attribute in AD. If the user has their password set to never # expire, append a dictionary containing their SAM account # name and last password change date to a list. for data in raw_user_data: acct_name = data['sAMAccountName'][0].decode().lower() uac = data['userAccountControl'][0] last_pwd_change = data['passwordLastChange'][0] if int(uac) >= 66048 and int(uac) <= 66096: self.no_pwd_exp.append({ 'name': acct_name, 'last_pwd_change': last_pwd_change }) self.log.info('%s has their password set to never expire', acct_name) self.log.info('Password expiration policy audit complete.') # Unbinding the LDAP object as a good house cleaning measure. conn.unbind() end = time() _elapsed = end - start elapsed = int(round(_elapsed, 0)) self.log.debug('Peformed password expiration audit in %d seconds', elapsed) return self.no_pwd_exp
def main(): ''' INSTANCE CONFIGURATION ''' SERVER_IP = demisto.params().get('server_ip') USERNAME = demisto.params().get('credentials')['identifier'] PASSWORD = demisto.params().get('credentials')['password'] DEFAULT_BASE_DN = demisto.params().get('base_dn') SECURE_CONNECTION = demisto.params().get('secure_connection') DEFAULT_PAGE_SIZE = int(demisto.params().get('page_size')) NTLM_AUTH = demisto.params().get('ntlm') UNSECURE = demisto.params().get('unsecure', False) PORT = demisto.params().get('port') if PORT: # port was configured, cast to int PORT = int(PORT) try: server = initialize_server(SERVER_IP, PORT, SECURE_CONNECTION, UNSECURE) except Exception as e: return_error(str(e)) return global conn if NTLM_AUTH: # intialize connection to LDAP server with NTLM authentication # user example: domain\user domain_user = SERVER_IP + '\\' + USERNAME if '\\' not in USERNAME else USERNAME conn = Connection(server, user=domain_user, password=PASSWORD, authentication=NTLM) else: # here username should be the user dn conn = Connection(server, user=USERNAME, password=PASSWORD) # bind operation is the “authenticate” operation. try: # open socket and bind to server if not conn.bind(): message = "Failed to bind to server. Please validate the credentials configured correctly.\n{}".format( json.dumps(conn.result)) demisto.info(message) return_error(message) return except Exception as e: exc_msg = str(e) demisto.info("Failed bind to: {}:{}. {}: {}".format(SERVER_IP, PORT, type(e), exc_msg + "\nTrace:\n{}".format(traceback.format_exc()))) message = "Failed to access LDAP server. Please validate the server host and port are configured correctly" if 'ssl wrapping error' in exc_msg: message = "Failed to access LDAP server. SSL error." if not UNSECURE: message += ' Try using: "Trust any certificate" option.' demisto.info(message) return_error(message) return demisto.info('Established connection with AD LDAP server') if not base_dn_verified(DEFAULT_BASE_DN): message = "Failed to verify the base DN configured for the instance.\n" \ "Last connection result: {}\n" \ "Last error from LDAP server: {}".format(json.dumps(conn.result), json.dumps(conn.last_error)) demisto.info(message) return_error(message) return demisto.info('Verfied base DN "{}"'.format(DEFAULT_BASE_DN)) ''' COMMAND EXECUTION ''' try: if demisto.command() == 'test-module': if conn.user == '': # Empty response means you have no authentication status on the server, so you are an anonymous user. raise Exception("Failed to authenticate user") demisto.results('ok') if demisto.command() == 'ad-search': free_search(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-expire-password': expire_user_password(DEFAULT_BASE_DN) if demisto.command() == 'ad-set-new-password': set_user_password(DEFAULT_BASE_DN) if demisto.command() == 'ad-unlock-account': unlock_account(DEFAULT_BASE_DN) if demisto.command() == 'ad-disable-account': disable_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-enable-account': enable_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-remove-from-group': remove_member_from_group(DEFAULT_BASE_DN) if demisto.command() == 'ad-add-to-group': add_member_to_group(DEFAULT_BASE_DN) if demisto.command() == 'ad-create-user': create_user() if demisto.command() == 'ad-delete-user': delete_user() if demisto.command() == 'ad-update-user': update_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-modify-computer-ou': modify_computer_ou(DEFAULT_BASE_DN) if demisto.command() == 'ad-create-contact': create_contact() if demisto.command() == 'ad-update-contact': update_contact() if demisto.command() == 'ad-get-user': search_users(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-get-computer': search_computers(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-get-group-members': search_group_members(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) except Exception as e: message = "{}\nLast connection result: {}\nLast error from LDAP server: {}".format( str(e), json.dumps(conn.result), conn.last_error) demisto.info(message) return_error(message) return finally: # disconnect and close the connection conn.unbind()
def audit_domain_admins(self): """Returns a list of unauthorized domain admins. Keyword Arguments: None Returns: self.bad_domain_admins - A list of user account names and descriptionsthat are not authorized to have domain admin privileges. Raises: OSError - Occurs when the script is unable to locate or open the configuration file. LDAPExceptionError - Occurs when the LDAP3 functions generate an error. The base class for all LDAPExcetionErrors is used so that the log.exception call will catch the detailed exception while not missing any potential exceptions.""" # Retrieving information from the configuration file. config = ConfigParser() try: config.read(self.conf) except OSError: self.log.exception('Unable to open configuration file.') exit(1) ldap_url = config['ldap']['url'] ldap_bind_dn = config['ldap']['bind_dn'] adm_dn = config['ldap']['adm_dn'] # Creating list of approved admins. approved_admins = [] _file = open(config['ldap']['domain_admins'], 'r') for entry in _file: approved_admins.append(entry.strip('\n')) # Getting credentials from SCSS. ldap_bind_secret = get_credentials({ 'api_key': config['ldap']['scss_api'], 'otp': config['ldap']['scss_otp'], 'userid': config['ldap']['scss_user'], 'url': config['ldap']['scss_url'] }) # Creating variables to use later. admin_list = [] admin_groups = [] # Connecting to LDAP. tls_config = Tls(validate=CERT_NONE, version=PROTOCOL_TLSv1_2) server = Server(ldap_url, use_ssl=True, tls=tls_config) try: conn = Connection(server, user=ldap_bind_dn, password=ldap_bind_secret, auto_bind=True) except LDAPExceptionError: self.log.exception('Error occurred connecting to LDAP server.') self.log.debug('Successfully connected to LDAP server: %s', ldap_url) # Getting admins builtin_admins = conn.extend.standard.paged_search( adm_dn, '(objectClass=group)', search_scope=SUBTREE, attributes=['member'], paged_size=50, generator=False) # Determining if the built-in admininstrator group member is a # group or a user. If it is a group, enumerating that groups # members as well. ldap_filter = '(|(objectClass=group)(objectClass=user))' for builtin_admin in builtin_admins[0]['attributes']['member']: search_base = builtin_admin admin_data = conn.extend.standard.paged_search( search_base, ldap_filter, BASE, attributes=[ 'sAMAccountName', 'distinguishedName', 'objectClass', 'description' ], paged_size=100, generator=False) # Checking to see if the group member is a group. if 'group' in admin_data[0]['attributes']['objectClass']: admin_groups.append( admin_data[0]['attributes']['distinguishedName']) # Checking to see if the group member is a user. elif 'user' in admin_data[0]['attributes']['objectClass']: admin_list.append({ 'name': admin_data[0]['attributes']['sAMAccountName'], 'desc': admin_data[0]['attributes']['description'][0], }) # Retrieving nested group information. If the group member is # a user, we append it to admin_list. If the group member is # a group, we append it to admin_groups. This process is # repeated until there are no more groups (we ahve a list of # only users). while len(admin_groups) > 0: entry = admin_groups.pop(0) admin_data = conn.extend.standard.paged_search( entry, ldap_filter, BASE, attributes=[ 'sAMAccountName', 'distinguishedName', 'objectClass', 'description', 'member' ], paged_size=100, generator=False) # Checking to see if the member is a user. If it is not # already in the admin_list, append it to the admin_list. if 'user' in admin_data[0]['attributes']['objectClass']: admin_data = { 'name': admin_data[0]['attributes']['sAMAccountName'], 'desc': admin_data[0]['attributes']['description'][0] } if admin_data not in admin_list: admin_list.append(admin_data) # Checking to see if the group member is a group. elif 'group' in admin_data[0]['attributes']['objectClass']: for member in admin_data[0]['attributes']['member']: admin_groups.append(member) # Unbinding ldap object. conn.unbind() # Determining if admin is approved or not. for admin in admin_list: if admin['name'] not in approved_admins: self.bad_domain_admins.append(admin) return self.bad_domain_admins
account.", "In order to do that, visit https://accounts.tolabaki.gr and add your \ Telegram User ID under the Pager field, in Generic settings." ] API_KEY = os.environ['TELEGRAM_BOT_API_KEY'] ldap_server = "ldap.tolabaki.gr" ldap_user = "******" ldap_password = os.environ['LDAP_PASSWORD'] search_base = "dc=tolabaki,dc=gr" allowed_users = "objectClass=person" telegram_uid_field = "pager" doorlock_bin = "/usr/local/bin/doorlock" server = Server(ldap_server, use_ssl=True) conn = Connection(server, ldap_user, ldap_password) conn.bind() class Logic(telepot.helper.ChatHandler): def __init__(self, *args, **kwargs): super(Logic, self).__init__(*args, **kwargs) # Message handler. # Don't change function name, it is recognized by default from telepot. def on_chat_message(self, msg): telegram_uid = msg['from']['id'] if msg['text'] == "/start": for message in welcome_messages[0:4]: bot.sendMessage(telegram_uid, message) sleep(3)