def _handle_referral(self, exception): # Following referral e = exception.args[0] info = e.get('info') ldap_url = info[info.find('ldap'):] if isLDAPUrl(ldap_url): conn_str = LDAPUrl(ldap_url).initializeUrl() lo_ref = ldap.initialize(conn_str) if self.ca_certfile: lo_ref.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_certfile) if self.start_tls == 1: try: lo_ref.start_tls_s() except: univention.debug.debug(univention.debug.LDAP, univention.debug.WARN, 'Could not start TLS') elif self.start_tls == 2: lo_ref.start_tls_s() lo_ref.simple_bind_s(self.binddn, self.__encode_pwd(self.bindpw)) return lo_ref else: raise ldap.CONNECT_ERROR, 'Bad referral "%s"' % str(e)
def __init__(self, url, **kwargs): if not ldapurl.isLDAPUrl(url): # # assume a hostname or ip address # url = 'ldap://%s' % url self.url = url self._initialize() self._username = '' self._password = '' # # Process kwargs # for key in ('user', 'username', 'binddn'): if kwargs.has_key(key): self._username = kwargs[key] break for key in ('passwd', 'password', 'bindpw'): if kwargs.has_key(key): self._password = kwargs[key] break self._bind()
def _handle_referral(self, exception): # Following referral e = exception.args[0] info = e.get("info") ldap_url = info[info.find("ldap") :] if isLDAPUrl(ldap_url): conn_str = LDAPUrl(ldap_url).initializeUrl() lo_ref = ldap.initialize(conn_str) if self.ca_certfile: lo_ref.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_certfile) if self.start_tls == 1: try: lo_ref.start_tls_s() except: univention.debug.debug(univention.debug.LDAP, univention.debug.WARN, "Could not start TLS") elif self.start_tls == 2: lo_ref.start_tls_s() lo_ref.simple_bind_s(self.binddn, self.__encode_pwd(self.bindpw)) return lo_ref else: raise ldap.CONNECT_ERROR, 'Bad referral "%s"' % str(e)
def _handle_referral(self, exception): univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, 'Following LDAP referral') exc = exception.args[0] info = exc.get('info') ldap_url = info[info.find('ldap'):] if isLDAPUrl(ldap_url): conn_str = LDAPUrl(ldap_url).initializeUrl() lo_ref = ldap.ldapobject.ReconnectLDAPObject(conn_str, trace_stack_limit=None) if self.ca_certfile: lo_ref.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_certfile) if self.start_tls == 1: try: lo_ref.start_tls_s() except: univention.debug.debug(univention.debug.LDAP, univention.debug.WARN, 'Could not start TLS') elif self.start_tls == 2: lo_ref.start_tls_s() lo_ref.simple_bind_s(self.binddn, self.__encode_pwd(self.bindpw)) return lo_ref else: raise ldap.CONNECT_ERROR('Bad referral "%s"' % (exc,))
def doLogin(self, server=None,username=None,password=None,suffix=None,remember=True,_dc=None): if not username or not password: return "{'failure':1,'info':'Missing username or password'}" if logged_in(): do_redirect('/index') if username == "admin": username = "******" elif not "=" in username: username="******" % (username, suffix) use_SSL=0 if ldapurl.isLDAPUrl(server): u = ldapurl.LDAPUrl(server) if u.urlscheme == "ldaps": use_SSL=1 server = u.hostport if ":" in server: server,port = server.split(":") port = int(port) else: if use_SSL: port = 636 else: port = 389 if use_SSL: return """{failure:1,'info':"Unfortunately SSL is not supported at the moment"}""" try: l = ldap.open(server,port) except ldap.LDAPError, e: err = parse_ldap_error(e) return """{failure:1,'info':"%s"}""" % (err)
def _ldap_bind(self): """ Set LDAP binding """ #ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095) if self.auth_type == 'gssapi' : if not ldap.SASL_AVAIL: raise AnsibleLookupError("Cannot use auth=gssapi when SASL is not configured with the local LDAP install") # if self.username or self.password: # raise AnsibleError("Explicit credentials are not supported when auth_type='gssapi'. Call kinit outside of Ansible") elif self.auth_type == 'simple' and not (self.username and self.password): raise AnsibleError("The username and password values are required when auth_type=simple") else: if self.username and self.password: pass # self.auth_type = 'simple' if ldap.SASL_AVAIL: self.auth_type == 'gssapi' else: raise AnsibleError("Invalid auth_type value '%s': expecting either 'gssapi', or 'simple'" % self.auth_type) if ldapurl.isLDAPUrl(self.domain): ldap_url = ldapurl.LDAPUrl(ldapUrl=self.domain) else: self.port = self.port if self.port else 389 if self.scheme == 'ldap' else 636 ldap_url = ldapurl.LDAPUrl(hostport="%s:%d" % (self.domain, self.port), urlscheme=self.scheme) if self.validate_certs is False : ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW) if not ldap.TLS_AVAIL and conn_url.urlscheme == 'ldaps': raise AnsibleLookupError("Cannot use TLS as the local LDAP installed has not been configured to support it") conn_url = ldap_url.initializeUrl() #self.ldap_session = MyLDAPObject(conn_url, trace_level=3) # higher trace levels self.ldap_session = MyLDAPObject(conn_url) self.ldap_session.page_size = 900 self.ldap_session.set_option(ldap.OPT_PROTOCOL_VERSION, 3) self.ldap_session.set_option(ldap.OPT_REFERRALS, 0) if self.auth_type == 'simple': try: self.ldap_session.bind_s(self.username, self.password, ldap.AUTH_SIMPLE) except ldap.LDAPError as err: raise AnsibleError("Failed to simple bind against LDAP host '%s': %s " % (conn_url, to_native(err))) else: cmd = ['kinit', self.username] error_code = subprocess.run(cmd, input=self.password.encode(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode if error_code > 0: raise AnsibleError("kinit failure") try: self.ldap_session.sasl_gssapi_bind_s() except ldap.AUTH_UNKNOWN as err: # The SASL GSSAPI binding is not installed, e.g. cyrus-sasl-gssapi. Give a better error message than what python-ldap provides raise AnsibleError("Failed to do a sasl bind against LDAP host '%s', the GSSAPI mech is not installed: %s" % (conn_url, to_native(err))) except ldap.LDAPError as err: raise AnsibleError("Failed to do a sasl bind against LDAP host '%s': %s" % (conn_url, to_native(err)))
def test_isLDAPUrl(self): for ldap_url, expected in self.is_ldap_url_tests.items(): result = ldapurl.isLDAPUrl(ldap_url) self.assertEqual( result, expected, 'isLDAPUrl("%s") returns %d instead of %d.' % ( ldap_url, result, expected, ) )
def run(self): start = time.time() self.logger.debug("starting thread to download {0}".format(self.crl)) try: crlraw = None end = 0 # should be ok as a starting value, since it's 2016 # LDAP if( ldapurl.isLDAPUrl( self.crl ) ): url_parts = ldapurl.LDAPUrl( self.crl ) connectionstring = "{0}://{1}".format(url_parts.urlscheme, url_parts.hostport) try: l = ldap.initialize(connectionstring) try: l.bind_s('','') #anonymous bind scope = url_parts.scope if url_parts.scope != None else 0 if url_parts.filterstr == None: res = l.search_s(url_parts.dn, scope, attrlist=url_parts.attrs) else: res = l.search_s(url_parts.dn, scope, url_parts.filterstr, attrlist=url_parts.attrs) for item in res: for key in item[1]: for crlraw in item[1][key]: self.output_queue.put((self.crl, crlraw)) end = time.time() self.logger.debug("downloading {0} finished, took {1} seconds".format(self.crl, (end - start))) self.log_queue.put((self.crl, (end-start))) except ldap.LDAPError, e: if type(e.message) == dict: for (k, v) in e.message.iteritems(): self.logger.warn("%s: %s" % (k, v) ) else: self.logger.warn(e) end = time.time() self.log_queue.put((self.crl, "LDAPError: {1} (after {0} seconds)".format((end-start), e))) finally: try: l.unbind() except Error: pass # HTTP(S) else: crlraw = urllib2.urlopen(self.crl).read() self.output_queue.put((self.crl, crlraw)) end = time.time() self.logger.debug("downloading {0} finished, took {1} seconds".format(self.crl, (end - start))) self.log_queue.put((self.crl, (end-start))) if(end - start > 30): self.logger.warn("{0} was hella slow, took {1} seconds".format(self.crl, (end - start))) except Exception as e: end = time.time() self.logger.warn("Exception when downloading {0}: {1}".format(self.crl, str(e))) self.log_queue.put((self.crl, "EXCEPTION {1} (after {0} seconds)".format((end-start), e))) finally: self.semaphore.release()
def execute(self): args = self.args # we can connect in 2 ways. By hostname/ip (and portnumber) # or by ldap-uri if "url" in args and ldapurl.isLDAPUrl(args["url"]): conn = ldap.initialize(args["url"]) else: ip, port = self.get_address() conn = ldap.initialize("ldap://%s:%s" % (ip, port)) try: username = args.get("username", "") password = args.get("password", "") conn.simple_bind(username, password) try: self._set_version(args, conn) except ValueError: return Event.DOWN, "unsupported protocol version" base = args.get("base", "dc=example,dc=org") if base == "cn=monitor": my_res = conn.search_st(base, ldap.SCOPE_BASE, timeout=self.timeout) versionstr = str(my_res[0][-1]['description'][0]) self.version = versionstr return Event.UP, versionstr scope = args.get("scope", "SUBTREE").upper() if scope == "BASE": scope = ldap.SCOPE_BASE elif scope == "ONELEVEL": scope = ldap.SCOPE_ONELEVEL else: scope = ldap.SCOPE_SUBTREE filtr = args.get("filter", "objectClass=*") try: conn.search_ext_s(base, scope, filterstr=filtr, timeout=self.timeout) # pylint: disable=W0703 except Exception as err: return ( Event.DOWN, "Failed ldapSearch on %s for %s: %s" % (self.get_address(), filtr, str(err)), ) finally: try: conn.unbind() except Exception: pass return Event.UP, "Ok"
def main(): """ Process user's arguments """ # Setup logging logging.basicConfig(format='%(message)s', level=logging.INFO) menu = menu_handler() args = menu[0] # Invoke sub-commands in argparse ldap_ls = menu[1].choices['ls'] ldap_search = menu[1].choices['search'] ldap_modify = menu[1].choices['modify'] ldap_delete = menu[1].choices['delete'] ldap_bulk = menu[1].choices['bulk'] # Validate LDAP server URL if not ldapurl.isLDAPUrl(args.SERVER): logging.critical("\nERROR: %s has an invalid URL format!\n", args.SERVER) exit(1) try: if args.action == "ls": ldap_session = start_ldap_session(args.SERVER, args.BINDDN) ldap_ls.set_defaults( func=ldap_action_ls(ldap_session, args.basedn)) elif args.action == "search": ldap_session = start_ldap_session(args.SERVER, args.BINDDN) ldap_search.set_defaults(func=ldap_action_search(ldap_session, \ args.basedn, args.ldap_filter)) elif args.action == "modify": ldap_session = start_ldap_session(args.SERVER, args.BINDDN) ldap_modify.set_defaults(func=ldap_action_modify(ldap_session, \ args.modify_dn, args.target_attr, args.new_value, \ args.modifymode)) elif args.action == "delete": ldap_session = start_ldap_session(args.SERVER, args.BINDDN) ldap_delete.set_defaults(func=ldap_action_delete(ldap_session, \ args.delete_dn)) elif args.action == "bulk": ldap_session = start_ldap_session(args.SERVER, args.BINDDN) ldap_bulk.set_defaults(func=ldap_action_bulk(ldap_session, \ args)) else: logging.critical( "You need to provide at least one action to perform!") exit(0) except (KeyboardInterrupt, ldap.SERVER_DOWN, ldap.UNWILLING_TO_PERFORM, \ ldap.INVALID_CREDENTIALS, ldap.INVALID_DN_SYNTAX, \ ldap.NO_SUCH_OBJECT) as e: exit(e)
def __input_connection_uri(self): ''' Asks for the connection uri ''' uri = raw_input('Enter LDAP server URI [%s]: ' \ % self.config.connection_uri) if not uri: return self.config.connection_uri if not ldapurl.isLDAPUrl(uri): raise LDAPInvalidURI return uri
def _handle_referral(self, exception): """ Handle a referral specified in the passed-in exception """ payload = exception.args[0] info = payload.get('info') ldap_url = info[info.find('ldap'):] if ldapurl.isLDAPUrl(ldap_url): conn_str = ldapurl.LDAPUrl(ldap_url).initializeUrl() conn = self._connect(conn_str) conn.simple_bind_s(self._encode_incoming(self.bind_dn), self._encode_incoming(self.bind_pwd)) return conn else: raise ldap.CONNECT_ERROR('Bad referral "%s"' % str(exception))
def test_isLDAPUrl(self): for ldap_url, expected in self.is_ldap_url_tests.items(): result = ldapurl.isLDAPUrl(ldap_url) self.assertEqual( result, expected, 'isLDAPUrl("%s") returns %d instead of %d.' % ( ldap_url, result, expected, )) if expected: LDAPUrl(ldapUrl=ldap_url) else: with self.assertRaises(ValueError): LDAPUrl(ldapUrl=ldap_url)
def _handle_referral(self, exception): """ Handle a referral specified in the passed-in exception """ payload = exception.args[0] info = payload.get('info') ldap_url = info[info.find('ldap'):] if ldapurl.isLDAPUrl(ldap_url): conn_str = ldapurl.LDAPUrl(ldap_url).initializeUrl() conn = self._connect(conn_str) conn.simple_bind_s(self._encode_incoming(self.bind_dn), self._encode_incoming(self.bind_pwd)) return conn else: raise ldap.CONNECT_ERROR, 'Bad referral "%s"' % str(exception)
def ldap_setup_url(module, hostname, encryption=None): prefix = 'ldap' port = 389 if encryption == 'SSL': prefix = 'ldaps' port = 636 server = _setup_url(prefix, port, hostname) if ldapurl.isLDAPUrl(server): return server else: fail_msg = "Invalid ldap uri for: {}".format(server) module.fail_json(msg=fail_msg)
def main(): """ LDAP session and logging setup """ try: # Setup logging logging.basicConfig(stream=stdout, format='%(message)s', level=logging.INFO) # Setup arguments for LDAP session menu = menu_handler() BASEDN = menu.BASEDN PAGE_SIZE = menu.sizelimit SEARCH_FILTER = menu.filter ATTRS_LIST = menu.ATTRIBUTES.split(',') ldap_user = menu.userdn writetocsv = bool(menu.writetocsv) # Validate LDAP server URL if not ldapurl.isLDAPUrl(menu.SERVER): logging.critical("\nERROR: %s has an invalid URL format!\n", menu.SERVER) exit(1) if menu.userdn: # Set ldap_auth=True when LDAP authentication is chosen! LDAP_SESSION = start_session(menu.SERVER, ldap_user, ldap_auth=True) else: # Anonymous query is performed!. LDAP_SESSION = start_session(menu.SERVER, ldap_user, ldap_auth=False) ldap_data = ldap_paging(PAGE_SIZE, BASEDN, SEARCH_FILTER, ATTRS_LIST, LDAP_SESSION) retrieved_ldap_attrs = process_ldap_data(ldap_data, ATTRS_LIST, writetocsv) if writetocsv: csv_file = menu.writetocsv write_to_csv(csv_file, retrieved_ldap_attrs) csv_headers = ';'.join(ATTRS_LIST) + '\n' write_csv_headers(csv_file, csv_headers) logging.info("\nResults have been written to CSV file: %s !\n", csv_file) except (KeyboardInterrupt, SERVER_DOWN, UNWILLING_TO_PERFORM, \ INVALID_CREDENTIALS, SIZELIMIT_EXCEEDED) as e: exit(e)
def execute(self): args = self.getArgs() # we can connect in 2 ways. By hostname/ip (and portnumber) # or by ldap-uri if "url" in args and ldapurl.isLDAPUrl(args["url"]): conn = ldap.initialize(args["url"]) else: ip, port = self.getAddress() conn = ldap.initialize("ldap://%s:%s" % (ip, port)) username = args.get("username", "") password = args.get("password", "") conn.simple_bind(username, password) try: self._set_version(args, conn) except ValueError: return Event.DOWN, "unsupported protocol version" base = args.get("base", "dc=example,dc=org") if base == "cn=monitor": my_res = conn.search_st(base, ldap.SCOPE_BASE, timeout=self.getTimeout()) versionstr = str(my_res[0][-1]['description'][0]) self.setVersion(versionstr) return Event.UP, versionstr scope = args.get("scope", "SUBTREE").upper() if scope == "BASE": scope = ldap.SCOPE_BASE elif scope == "ONELEVEL": scope = ldap.SCOPE_ONELEVEL else: scope = ldap.SCOPE_SUBTREE filtr = args.get("filter", "objectClass=*") try: conn.search_ext_s(base, scope, filterstr=filtr, timeout=self.getTimeout()) # pylint: disable=W0703 except Exception as err: return (Event.DOWN, "Failed ldapSearch on %s for %s: %s" % ( self.getAddress(), filtr, str(err))) conn.unbind() return Event.UP, "Ok"
def _handle_referral(self, exception): # type: (ldap.REFERRAL) -> ldap.ldapobject.ReconnectLDAPObject """ Follow LDAP rederral. :param exception ldap.REFERRAL: The LDAP referral exception. :returns: LDAP connection object for the referred LDAP server. :rtype: ldap.ldapobject.ReconnectLDAPObject """ univention.debug.debug(univention.debug.LDAP, univention.debug.INFO, 'Following LDAP referral') exc = exception.args[0] info = exc.get('info') ldap_url = info[info.find('ldap'):] if isLDAPUrl(ldap_url): conn_str = LDAPUrl(ldap_url).initializeUrl() # FIXME?: this upgrades a access(reconnect=False) connection to a reconnect=True connection lo_ref = ldap.ldapobject.ReconnectLDAPObject( conn_str, trace_stack_limit=None) if self.ca_certfile: lo_ref.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_certfile) if self.start_tls == 1: try: lo_ref.start_tls_s() except: univention.debug.debug(univention.debug.LDAP, univention.debug.WARN, 'Could not start TLS') elif self.start_tls == 2: lo_ref.start_tls_s() lo_ref.simple_bind_s(self.binddn, self.__encode_pwd(self.bindpw)) return lo_ref else: raise ldap.CONNECT_ERROR('Bad referral "%s"' % (exc, ))
def handle_referral(self, exception): """ Handle a referral specified in a exception """ payload = exception.args[0] info = payload.get('info') ldap_url = info[info.find('ldap'):] if isLDAPUrl(ldap_url): conn_str = LDAPUrl(ldap_url).initializeUrl() if self.binduid_usage == 1: user_dn = self.bind_dn user_pwd = self.bind_pwd else: user = getSecurityManager().getUser() try: user_dn = user.getUserDN() user_pwd = user._getPassword() except AttributeError: # User object is not a LDAPUser user_dn = user_pwd = '' return self._connect(conn_str, user_dn, user_pwd) else: raise ldap.CONNECT_ERROR, 'Bad referral "%s"' % str(exception)
def run(self, terms, variables=None, **kwargs): if not HAS_LDAP: msg = missing_required_lib("python-ldap", url="https://pypi.org/project/python-ldap/") msg += ". Import Error: %s" % LDAP_IMP_ERR raise AnsibleLookupError(msg) # Load the variables and direct args into the lookup options self.set_options(var_options=variables, direct=kwargs) domain = self.get_option('domain') port = self.get_option('port') scheme = self.get_option('scheme') start_tls = self.get_option('start_tls') validate_certs = self.get_option('validate_certs') cacert_file = self.get_option('ca_cert') search_base = self.get_option('search_base') username = self.get_option('username') password = self.get_option('password') auth = self.get_option('auth') allow_plaintext = self.get_option('allow_plaintext') # Validate and set input values # https://www.openldap.org/lists/openldap-software/200202/msg00456.html validate_certs_map = { 'never': ldap.OPT_X_TLS_NEVER, 'allow': ldap.OPT_X_TLS_ALLOW, 'try': ldap.OPT_X_TLS_TRY, 'demand': ldap.OPT_X_TLS_DEMAND, # Same as OPT_X_TLS_HARD } validate_certs_value = validate_certs_map.get(validate_certs, None) if validate_certs_value is None: valid_keys = list(validate_certs_map.keys()) valid_keys.sort() raise AnsibleLookupError("Invalid validate_certs value '%s': valid values are '%s'" % (validate_certs, "', '".join(valid_keys))) if auth not in ['gssapi', 'simple']: raise AnsibleLookupError("Invalid auth value '%s': expecting either 'gssapi', or 'simple'" % auth) elif auth == 'gssapi': if not ldap.SASL_AVAIL: raise AnsibleLookupError("Cannot use auth=gssapi when SASL is not configured with the local LDAP " "install") if username or password: raise AnsibleLookupError("Explicit credentials are not supported when auth='gssapi'. Call kinit " "outside of Ansible") elif auth == 'simple' and not (username and password): raise AnsibleLookupError("The username and password values are required when auth=simple") if ldapurl.isLDAPUrl(domain): ldap_url = ldapurl.LDAPUrl(ldapUrl=domain) else: port = port if port else 389 if scheme == 'ldap' else 636 ldap_url = ldapurl.LDAPUrl(hostport="%s:%d" % (domain, port), urlscheme=scheme) # We have encryption if using LDAPS, or StartTLS is used, or we auth with SASL/GSSAPI encrypted = ldap_url.urlscheme == 'ldaps' or start_tls or auth == 'gssapi' if not encrypted and not allow_plaintext: raise AnsibleLookupError("Current configuration will result in plaintext traffic exposing credentials. " "Set auth=gssapi, scheme=ldaps, start_tls=True, or allow_plaintext=True to " "continue") if ldap_url.urlscheme == 'ldaps' or start_tls: # We cannot use conn.set_option as OPT_X_TLS_NEWCTX (required to use the new context) is not supported on # older distros like EL7. Setting it on the ldap object works instead if not ldap.TLS_AVAIL: raise AnsibleLookupError("Cannot use TLS as the local LDAP installed has not been configured to support it") ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, validate_certs_value) if cacert_file: cacert_path = os.path.expanduser(os.path.expandvars(cacert_file)) if not os.path.exists(to_bytes(cacert_path)): raise AnsibleLookupError("The cacert_file specified '%s' does not exist" % to_native(cacert_path)) try: # While this is a path, python-ldap expects a str/unicode and not bytes ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, to_text(cacert_path)) except ValueError: # https://keathmilligan.net/python-ldap-and-macos/ raise AnsibleLookupError("Failed to set path to cacert file, this is a known issue with older " "OpenLDAP libraries on the host. Update OpenLDAP and reinstall " "python-ldap to continue") conn_url = ldap_url.initializeUrl() conn = ldap.initialize(conn_url, bytes_mode=False) conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3) conn.set_option(ldap.OPT_REFERRALS, 0) # Allow us to search from the base # Make sure we run StartTLS before doing the bind to protect the credentials if start_tls: try: conn.start_tls_s() except ldap.LDAPError as err: raise AnsibleLookupError("Failed to send StartTLS to LDAP host '%s': %s" % (conn_url, to_native(err))) if auth == 'simple': try: conn.bind_s(to_text(username), to_text(password)) except ldap.LDAPError as err: raise AnsibleLookupError("Failed to simple bind against LDAP host '%s': %s" % (conn_url, to_native(err))) else: try: conn.sasl_gssapi_bind_s() except ldap.AUTH_UNKNOWN as err: # The SASL GSSAPI binding is not installed, e.g. cyrus-sasl-gssapi. Give a better error message than # what python-ldap provides raise AnsibleLookupError("Failed to do a sasl bind against LDAP host '%s', the GSSAPI mech is not " "installed: %s" % (conn_url, to_native(err))) except ldap.LDAPError as err: raise AnsibleLookupError("Failed to do a sasl bind against LDAP host '%s': %s" % (conn_url, to_native(err))) try: if not search_base: root_dse = conn.read_rootdse_s() search_base = root_dse['defaultNamingContext'][0] ret = [] # TODO: change method to search for all servers in 1 request instead of multiple requests for server in terms: ret.append(get_laps_password(conn, server, search_base)) finally: conn.unbind_s() return ret
#! /usr/bin/env python2 import sys import ldap, ldapurl import time url = sys.argv[1] start = time.time() if( ldapurl.isLDAPUrl( url ) ): url_parts = ldapurl.LDAPUrl( url ) connectionstring = "{0}://{1}".format(url_parts.urlscheme, url_parts.hostport) try: l = ldap.initialize(connectionstring) try: l.bind_s('','') #anonymous bind scope = url_parts.scope if url_parts.scope != None else 0 if url_parts.filterstr == None: res = l.search_s(url_parts.dn, scope, attrlist=url_parts.attrs) else: res = l.search_s(url_parts.dn, scope, url_parts.filterstr, attrlist=url_parts.attrs) for item in res: for key in item[1]: for crlraw in item[1][key]: print("got crlraw!") except ldap.LDAPError, e: if type(e.message) == dict: for (k, v) in e.message.iteritems(): print("%s: %sn" % (k, v) ) else:
def run(self): start = time.time() self.logger.debug("starting thread to download {0}".format(self.crl)) try: crlraw = None end = 0 # should be ok as a starting value, since it's 2016 # LDAP if (ldapurl.isLDAPUrl(self.crl)): url_parts = ldapurl.LDAPUrl(self.crl) connectionstring = "{0}://{1}".format(url_parts.urlscheme, url_parts.hostport) try: l = ldap.initialize(connectionstring) try: l.bind_s('', '') #anonymous bind scope = url_parts.scope if url_parts.scope != None else 0 if url_parts.filterstr == None: res = l.search_s(url_parts.dn, scope, attrlist=url_parts.attrs) else: res = l.search_s(url_parts.dn, scope, url_parts.filterstr, attrlist=url_parts.attrs) for item in res: for key in item[1]: for crlraw in item[1][key]: self.output_queue.put((self.crl, crlraw)) end = time.time() self.logger.debug( "downloading {0} finished, took {1} seconds" .format(self.crl, (end - start))) self.log_queue.put( (self.crl, (end - start))) except ldap.LDAPError, e: if type(e.message) == dict: for (k, v) in e.message.iteritems(): self.logger.warn("%s: %s" % (k, v)) else: self.logger.warn(e) end = time.time() self.log_queue.put( (self.crl, "LDAPError: {1} (after {0} seconds)".format( (end - start), e))) finally: try: l.unbind() except Error: pass # HTTP(S) else: crlraw = urllib2.urlopen(self.crl).read() self.output_queue.put((self.crl, crlraw)) end = time.time() self.logger.debug( "downloading {0} finished, took {1} seconds".format( self.crl, (end - start))) self.log_queue.put((self.crl, (end - start))) if (end - start > 30): self.logger.warn("{0} was hella slow, took {1} seconds".format( self.crl, (end - start))) except Exception as e: end = time.time() self.logger.warn("Exception when downloading {0}: {1}".format( self.crl, str(e))) self.log_queue.put( (self.crl, "EXCEPTION {1} (after {0} seconds)".format( (end - start), e))) finally: self.semaphore.release()
def modify_dsrc(inst, log, args): """Modify the instance config """ dsrc_file = f'{expanduser("~")}/.dsrc' if path.exists(dsrc_file): config = configparser.ConfigParser() config.read(dsrc_file) # Verify we have a section to modify instances = config.sections() if inst.serverid not in instances: raise ValueError( "There is no configuration section for this instance to modify!" ) # Process and validate the args if args.uri is not None: if not isLDAPUrl(args.uri): raise ValueError("The uri is not a valid LDAP URL!") if args.uri.startswith("ldapi"): # We must use EXTERNAL saslmech for LDAPI args.saslmech = "EXTERNAL" if args.uri == '': del config[inst.serverid]['uri'] else: config[inst.serverid]['uri'] = args.uri if args.basedn is not None: if not is_dn(args.basedn): raise ValueError("The basedn is not a valid DN!") if args.basedn == '': del config[inst.serverid]['basedn'] else: config[inst.serverid]['basedn'] = args.basedn if args.binddn is not None: if not is_dn(args.binddn): raise ValueError("The binddn is not a valid DN!") if args.binddn == '': del config[inst.serverid]['binddn'] else: config[inst.serverid]['binddn'] = args.binddn if args.saslmech is not None: if args.saslmech not in ['EXTERNAL', 'PLAIN']: raise ValueError("The saslmech must be EXTERNAL or PLAIN!") if args.saslmech == '': del config[inst.serverid]['saslmech'] else: config[inst.serverid]['saslmech'] = args.saslmech if args.tls_cacertdir is not None: if not path.exists(args.tls_cacertdir): raise ValueError('--tls-cacertdir directory does not exist!') if args.tls_cacertdir == '': del config[inst.serverid]['tls_cacertdir'] else: config[inst.serverid]['tls_cacertdir'] = args.tls_cacertdir if args.tls_cert is not None: if not path.exists(args.tls_cert): raise ValueError( '--tls-cert does not point to an existing file!') if args.tls_cert == '': del config[inst.serverid]['tls_cert'] else: config[inst.serverid]['tls_cert'] = args.tls_cert if args.tls_key is not None: if not path.exists(args.tls_key): raise ValueError( '--tls-key does not point to an existing file!') if args.tls_key == '': del config[inst.serverid]['tls_key'] else: config[inst.serverid]['tls_key'] = args.tls_key if args.tls_reqcert is not None: if args.tls_reqcert not in ['never', 'hard', 'allow']: raise ValueError( '--tls-reqcert value is invalid (must be either "never", "allow", or "hard")!' ) if args.tls_reqcert == '': del config[inst.serverid]['tls_reqcert'] else: config[inst.serverid]['tls_reqcert'] = args.tls_reqcert if args.starttls: config[inst.serverid]['starttls'] = 'true' if args.cancel_starttls: config[inst.serverid]['starttls'] = 'false' if args.pwdfile is not None: if not path.exists(args.pwdfile): raise ValueError('--pwdfile does not exist!') if args.pwdfile == '': del config[inst.serverid]['pwdfile'] else: config[inst.serverid]['pwdfile'] = args.pwdfile # Okay now rewrite the file with open(dsrc_file, 'w') as configfile: config.write(configfile) log.info(f'Successfully updated: {dsrc_file}') else: raise ValueError(f'There is no .dsrc file "{dsrc_file}" to update!')
def create_dsrc(inst, log, args): """Create the .dsrc file [instance] uri = ldaps://hostname:port basedn = dc=example,dc=com binddn = uid=user,.... saslmech = [EXTERNAL|PLAIN] tls_cacertdir = /path/to/cacertdir tls_cert = /path/to/user.crt tls_key = /path/to/user.key tls_reqcert = [never, hard, allow] starttls = [true, false] pwdfile = /path/to/file """ dsrc_file = f'{expanduser("~")}/.dsrc' config = configparser.ConfigParser() config.read(dsrc_file) # Verify this section does not already exist instances = config.sections() if inst.serverid in instances: raise ValueError( "There is already a configuration section for this instance!") # Process and validate the args config[inst.serverid] = {} if args.uri is not None: if not isLDAPUrl(args.uri): raise ValueError("The uri is not a valid LDAP URL!") if args.uri.startswith("ldapi"): # We must use EXTERNAL saslmech for LDAPI args.saslmech = "EXTERNAL" config[inst.serverid]['uri'] = args.uri if args.basedn is not None: if not is_dn(args.basedn): raise ValueError("The basedn is not a valid DN!") config[inst.serverid]['basedn'] = args.basedn if args.binddn is not None: if not is_dn(args.binddn): raise ValueError("The binddn is not a valid DN!") config[inst.serverid]['binddn'] = args.binddn if args.saslmech is not None: if args.saslmech not in ['EXTERNAL', 'PLAIN']: raise ValueError("The saslmech must be EXTERNAL or PLAIN!") config[inst.serverid]['saslmech'] = args.saslmech if args.tls_cacertdir is not None: if not path.exists(args.tls_cacertdir): raise ValueError('--tls-cacertdir directory does not exist!') config[inst.serverid]['tls_cacertdir'] = args.tls_cacertdir if args.tls_cert is not None: if not path.exists(args.tls_cert): raise ValueError('--tls-cert does not point to an existing file!') config[inst.serverid]['tls_cert'] = args.tls_cert if args.tls_key is not None: if not path.exists(args.tls_key): raise ValueError('--tls-key does not point to an existing file!') config[inst.serverid]['tls_key'] = args.tls_key if args.tls_reqcert is not None: if args.tls_reqcert not in ['never', 'hard', 'allow']: raise ValueError( '--tls-reqcert value is invalid (must be either "never", "allow", or "hard")!' ) config[inst.serverid]['tls_reqcert'] = args.tls_reqcert if args.starttls: config[inst.serverid]['starttls'] = 'true' if args.pwdfile is not None: if not path.exists(args.pwdfile): raise ValueError('--pwdfile does not exist!') config[inst.serverid]['pwdfile'] = args.pwdfile if len(config[inst.serverid]) == 0: # No args set raise ValueError( "You must set at least one argument for the new dsrc file!") # Print a preview of the config log.info(f'Updating "{dsrc_file}" with:\n') log.info(f' [{inst.serverid}]') for k, v in config[inst.serverid].items(): log.info(f' {k} = {v}') # Perform confirmation? if not args.do_it: while 1: val = input(f'\nUpdate "{dsrc_file}" ? [yes]: ').rstrip().lower() if val == '' or val == 'y' or val == 'yes': break if val == 'n' or val == 'no': return # Now write the file with open(dsrc_file, 'w') as configfile: config.write(configfile) log.info(f'Successfully updated: {dsrc_file}')