void uwsgi_ldap_config(char *url) { LDAP *ldp; LDAPMessage *results, *entry; BerElement *ber; struct berval **bervalues; char *attr; char *uwsgi_attr; char *url_slash; int desired_version = LDAP_VERSION3; int ret; LDAPURLDesc *ldap_url; if (!ldap_is_ldap_url(url)) { uwsgi_log("invalid LDAP url.\n"); exit(1); } if (ldap_url_parse(url, &ldap_url) != LDAP_SUCCESS) { uwsgi_log("unable to parse LDAP url.\n"); exit(1); } uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url); url_slash = strchr(url, '/'); url_slash = strchr(url_slash + 1, '/'); url_slash = strchr(url_slash + 1, '/'); if (url_slash) { url_slash[0] = 0; } #ifdef UWSGI_DEBUG uwsgi_debug("LDAP URL: %s\n", url); uwsgi_debug("LDAP BASE DN: %s\n", ldap_url->lud_dn); #endif #if LDAP_API_VERSION >= 3000 if ((ret = ldap_initialize(&ldp, url)) != LDAP_SUCCESS) { uwsgi_log("LDAP: %s\n", ldap_err2string(ret)); exit(1); } #else if ((ldp = ldap_init(ldap_url->lud_host, ldap_url->lud_port)) == NULL) { uwsgi_error("ldap_init()"); exit(1); } #endif if ((ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) { uwsgi_log("LDAP: %s\n", ldap_err2string(ret)); exit(1); } if ((ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) { uwsgi_log("LDAP: %s\n", ldap_err2string(ret)); exit(1); } #ifdef UWSGI_DEBUG uwsgi_debug("LDAP connection initialized %p\n", ldp); #endif free(ldap_url); if (ldap_count_entries(ldp, results) < 1) { uwsgi_log("no LDAP entry found\n"); exit(1); } entry = ldap_first_entry(ldp, results); int found = 0; for (attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) { if (!strncmp(attr, "uWSGI", 5)) { found = 1; uwsgi_attr = malloc(calc_ldap_name(attr) + 1); if (!uwsgi_attr) { uwsgi_error("malloc()"); exit(1); } ldap2uwsgi(attr + 5, uwsgi_attr); #ifdef UWSGI_DEBUG uwsgi_debug("LDAP attribute: %s = --%s\n", attr, uwsgi_attr); #endif bervalues = ldap_get_values_len(ldp, entry, attr); if (bervalues) { // do not free uwsgi_attr/uwsgi_val; char *uwsgi_val = malloc(bervalues[0]->bv_len + 1); if (!uwsgi_val) { uwsgi_error("malloc()"); exit(1); } memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len); uwsgi_val[bervalues[0]->bv_len] = 0; add_exported_option((char *) uwsgi_attr, uwsgi_val, 0); free(bervalues); } else { free(uwsgi_attr); } } free(attr); } if (!found) { uwsgi_log("no uWSGI LDAP entry found\n"); exit(1); } free(ber); free(results); ldap_unbind_ext_s(ldp, NULL, NULL); }
void ldapMessage(struct threadInfo * ti, int fatalError, char *infoMessage, char *ldapString) { if(ldapString != NULL && ldapString[0] != 0) { if((ti->directoryInfo.l != NULL) && (ldap_get_option(ti->directoryInfo.l, LDAP_OPT_RESULT_CODE, (int *) &ti->directoryInfo.i) == LDAP_OPT_SUCCESS)) { snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s: %s%c", infoMessage, ldapString, ldap_err2string(ti->directoryInfo.i), 0); } else { snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s%c", infoMessage, ldapString, 0); } } else { if((ti->directoryInfo.l != NULL) && (ldap_get_option(ti->directoryInfo.l, LDAP_OPT_RESULT_CODE, (int *) &ti->directoryInfo.i) == LDAP_OPT_SUCCESS)) { snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s%c", infoMessage, ldap_err2string(ti->directoryInfo.i), 0); } else { snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s%c", infoMessage, 0); } } warningThread(fatalError, ti->directoryInfo.errorString, ti->directoryInfo.errorSpace, sizeof(ti->directoryInfo.errorSpace), ti->directoryInfo.a, &ti->directoryInfo.i); }
/* * sets last_ldap_result and last_ldap_handle */ int lds_search( char* _lds_name, char* _dn, int _scope, char* _filter, char** _attrs, struct timeval* _search_timeout, int* _ld_result_count, int* _ld_error) { struct ld_session* lds; #ifdef LDAP_PERF struct timeval before_search = { 0, 0 }, after_search = { 0, 0 }; #endif /* * get ld_handle */ if (get_connected_ldap_session(_lds_name, &lds) != 0) { LM_ERR("[%s]: couldn't get ldap session\n", _lds_name); return -1; } /* * free last_ldap_result */ if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } LM_DBG( "[%s]: performing LDAP search: dn [%s]," " scope [%d], filter [%s], client_timeout [%d] usecs\n", _lds_name, _dn, _scope, _filter, (int)(lds->client_search_timeout.tv_sec * 1000000 + lds->client_search_timeout.tv_usec)); #ifdef LDAP_PERF gettimeofday(&before_search, NULL); #endif /* * perform ldap search */ *_ld_error = ldap_search_ext_s( lds->handle, _dn, _scope, _filter, _attrs, 0, NULL, NULL, &lds->client_search_timeout, 0, &last_ldap_result); #ifdef LDAP_PERF gettimeofday(&after_search, NULL); LM_INFO("[%s]: LDAP search took [%d] usecs\n", _lds_name, (int)((after_search.tv_sec * 1000000 + after_search.tv_usec) - (before_search.tv_sec * 1000000 + before_search.tv_usec))); #endif if (*_ld_error != LDAP_SUCCESS) { if (last_ldap_result != NULL) { ldap_msgfree(last_ldap_result); last_ldap_result = NULL; } if (LDAP_API_ERROR(*_ld_error)) { ldap_disconnect(_lds_name); } LM_DBG( "[%s]: ldap_search_ext_st failed: %s\n", _lds_name, ldap_err2string(*_ld_error)); return -1; } last_ldap_handle = lds->handle; *_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result); if (*_ld_result_count < 0) { LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name); return -1; } return 0; }
static void *add_thread(char *id) { LDAPMod mod[4]; LDAPMod *mods[5]; char dn[BUFSIZ], name[40]; char *cnvals[2], *snvals[2], *pwdvals[2], *ocvals[3]; int i, rc, opcount; void *voidrc = (void *)0; printf("Starting add_thread %s.\n", id); opcount = 0; tsd_setup(); for (i = 0; i < 4; i++) { mods[i] = &mod[i]; } mods[4] = NULL; mod[0].mod_op = 0; mod[0].mod_type = "cn"; mod[0].mod_values = cnvals; cnvals[1] = NULL; mod[1].mod_op = 0; mod[1].mod_type = "sn"; mod[1].mod_values = snvals; snvals[1] = NULL; mod[2].mod_op = 0; mod[2].mod_type = "objectclass"; mod[2].mod_values = ocvals; ocvals[0] = "top"; ocvals[1] = "person"; ocvals[2] = NULL; mod[3].mod_op = 0; mod[3].mod_type = "userPassword"; mod[3].mod_values = pwdvals; pwdvals[1] = NULL; mods[4] = NULL; for (;;) { sprintf(name, "%d", get_random_id()); sprintf(dn, "cn=%s, " BASE, name); cnvals[0] = name; snvals[0] = name; pwdvals[0] = name; printf("Thread %s: Adding entry (%s)\n", id, dn); rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL); if (rc != LDAP_SUCCESS) { fprintf(stderr, "ldap_add_ext_s: %s\n", ldap_err2string(rc)); if (rc == LDAP_SERVER_DOWN) { perror("ldap_add_ext_s"); voidrc = (void *)1; goto add_cleanup_and_return; } } ++opcount; if (maxops != 0 && opcount >= maxops) { break; } } add_cleanup_and_return: printf("Thread %s: attempted %d add operations\n", id, opcount); set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */ tsd_cleanup(); free(id); return voidrc; }
main(int argc, char **argv) { pthread_attr_t attr; pthread_t *threadids; void *status; struct ldap_thread_fns tfns; struct ldap_extra_thread_fns extrafns; int rc, c, errflg, i, inited_attr; int doadd, dodelete, domodify, docompare, dosearch, dobind; int option_extthreads, option_restart; int each_thread_count, thread_count; extern int optind; extern char *optarg; doadd = dodelete = domodify = docompare = dobind = dosearch = 0; option_extthreads = option_restart = 0; inited_attr = 0; errflg = 0; each_thread_count = 1; /* how many of each type of thread? */ rc = LDAP_SUCCESS; /* optimistic */ while ((c = getopt(argc, argv, "abcdmrsERi:n:o:S:")) != EOF) { switch (c) { case 'a': /* perform add operations */ ++doadd; break; case 'b': /* perform bind operations */ ++dobind; break; case 'c': /* perform compare operations */ ++docompare; break; case 'd': /* perform delete operations */ ++dodelete; break; case 'm': /* perform modify operations */ ++domodify; break; case 'r': /* use range filters in searches */ ++range_filters; break; case 's': /* perform search operations */ ++dosearch; break; case 'E': /* use extended thread functions */ ++option_extthreads; break; case 'R': /* turn on LDAP_OPT_RESTART */ ++option_restart; break; case 'i': /* highest # used for entry names */ maxid = atoi(optarg); break; case 'n': /* # threads for each operation */ if ((each_thread_count = atoi(optarg)) < 1) { fprintf(stderr, "thread count must be > 0\n"); ++errflg; } break; case 'o': /* operations to perform per thread */ if ((maxops = atoi(optarg)) < 0) { fprintf(stderr, "operation limit must be >= 0\n"); ++errflg; } break; case 'S': /* random number seed */ if (*optarg == 'r') { int seed = (int)time((time_t *)0); srandom(seed); printf("Random seed: %d\n", seed); } else { srandom(atoi(optarg)); } break; default: ++errflg; break; } } /* Check command-line syntax. */ thread_count = each_thread_count * (doadd + dodelete + domodify + dobind + docompare + dosearch); if (thread_count < 1) { fprintf(stderr, "Specify at least one of -a, -b, -c, -d, -m, or -s\n"); ++errflg; } if (errflg || argc - optind != 2) { fprintf(stderr, "usage: %s [-abcdmrsER] [-i id] [-n thr]" " [-o oplim] [-S sd] host port\n", argv[0]); fputs( "\nWhere:\n" "\t\"id\" is the highest entry id (name) to use" " (default is MAXINT)\n" "\t\"thr\" is the number of threads for each operation" " (default is 1)\n" "\t\"oplim\" is the number of ops done by each thread" " (default is infinite)\n" "\t\"sd\" is a random() number seed (default is 1). Use" " the letter r for\n" "\t\tsd to seed random() using time of day.\n" "\t\"host\" is the hostname of an LDAP directory server\n" "\t\"port\" is the TCP port of the LDAP directory server\n", stderr); fputs( "\nAnd the single character options are:\n" "\t-a\tstart thread(s) to perform add operations\n" "\t-b\tstart thread(s) to perform bind operations\n" "\t-c\tstart thread(s) to perform compare operations\n" "\t-d\tstart thread(s) to perform delete operations\n" "\t-m\tstart thread(s) to perform modify operations\n" "\t-s\tstart thread(s) to perform search operations\n" "\t-r\tuse range filters in searches\n" "\t-E\tinstall LDAP_OPT_EXTRA_THREAD_FN_PTRS\n" "\t-R\tturn on LDAP_OPT_RESTART\n", stderr); return (LDAP_PARAM_ERROR); } /* Create a key. */ if (pthread_key_create(&key, free) != 0) { perror("pthread_key_create"); } tsd_setup(); /* Allocate space for thread ids */ if ((threadids = (pthread_t *)calloc(thread_count, sizeof(pthread_t))) == NULL) { rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } /* Initialize the LDAP session. */ if ((ld = ldap_init(argv[optind], atoi(argv[optind + 1]))) == NULL) { perror("ldap_init"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } /* Set the function pointers for dealing with mutexes and error information. */ memset(&tfns, '\0', sizeof(struct ldap_thread_fns)); tfns.ltf_mutex_alloc = (void *(*)(void))my_mutex_alloc; tfns.ltf_mutex_free = (void (*)(void *))my_mutex_free; tfns.ltf_mutex_lock = (int (*)(void *))pthread_mutex_lock; tfns.ltf_mutex_unlock = (int (*)(void *))pthread_mutex_unlock; tfns.ltf_get_errno = get_errno; tfns.ltf_set_errno = set_errno; tfns.ltf_get_lderrno = get_ld_error; tfns.ltf_set_lderrno = set_ld_error; tfns.ltf_lderrno_arg = NULL; /* Set up this session to use those function pointers. */ rc = ldap_set_option(ld, LDAP_OPT_THREAD_FN_PTRS, (void *)&tfns); if (rc < 0) { rc = ldap_get_lderrno(ld, NULL, NULL); fprintf(stderr, "ldap_set_option (LDAP_OPT_THREAD_FN_PTRS): %s\n", ldap_err2string(rc)); goto clean_up_and_return; } if (option_extthreads) { /* Set the function pointers for working with semaphores. */ memset(&extrafns, '\0', sizeof(struct ldap_extra_thread_fns)); extrafns.ltf_mutex_trylock = (int (*)(void *))pthread_mutex_trylock; extrafns.ltf_sema_alloc = (void *(*)(void))my_sema_alloc; extrafns.ltf_sema_free = (void (*)(void *))my_sema_free; extrafns.ltf_sema_wait = (int (*)(void *))my_sema_wait; extrafns.ltf_sema_post = (int (*)(void *))my_sema_post; /* Set up this session to use those function pointers. */ if (ldap_set_option(ld, LDAP_OPT_EXTRA_THREAD_FN_PTRS, (void *)&extrafns) != 0) { rc = ldap_get_lderrno(ld, NULL, NULL); ldap_perror(ld, "ldap_set_option" " (LDAP_OPT_EXTRA_THREAD_FN_PTRS)"); goto clean_up_and_return; } } if (option_restart && ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON) != 0) { rc = ldap_get_lderrno(ld, NULL, NULL); ldap_perror(ld, "ldap_set_option(LDAP_OPT_RESTART)"); goto clean_up_and_return; } /* Attempt to bind to the server. */ rc = ldap_simple_bind_s(ld, NAME, PASSWORD); if (rc != LDAP_SUCCESS) { fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc)); goto clean_up_and_return; } /* Initialize the attribute. */ if (pthread_attr_init(&attr) != 0) { perror("pthread_attr_init"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++inited_attr; /* Specify that the threads are joinable. */ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* Create all the requested threads */ thread_count = 0; if (domodify) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, modify_thread, get_id_str(thread_count)) != 0) { perror("pthread_create modify_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } if (doadd) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, add_thread, get_id_str(thread_count)) != 0) { perror("pthread_create add_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } if (dodelete) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, delete_thread, get_id_str(thread_count)) != 0) { perror("pthread_create delete_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } if (dobind) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, bind_thread, get_id_str(thread_count)) != 0) { perror("pthread_create bind_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } if (docompare) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, compare_thread, get_id_str(thread_count)) != 0) { perror("pthread_create compare_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } if (dosearch) { for (i = 0; i < each_thread_count; ++i) { if (pthread_create(&threadids[thread_count], &attr, search_thread, get_id_str(thread_count)) != 0) { perror("pthread_create search_thread"); rc = LDAP_LOCAL_ERROR; goto clean_up_and_return; } ++thread_count; } } /* Wait until these threads exit. */ for (i = 0; i < thread_count; ++i) { pthread_join(threadids[i], &status); } clean_up_and_return: if (ld != NULL) { set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */ ldap_unbind(ld); } if (threadids != NULL) { free(threadids); } if (inited_attr) { pthread_attr_destroy(&attr); } tsd_cleanup(); return (rc); }
/*% * This function is the real core of the driver. Zone, record * and client strings are passed in (or NULL is passed if the * string is not available). The type of query we want to run * is indicated by the query flag, and the dbdata object is passed * passed in to. dbdata really holds either: * 1) a list of database instances (in multithreaded mode) OR * 2) a single database instance (in single threaded mode) * The function will construct the query and obtain an available * database instance (DBI). It will then run the query and hopefully * obtain a result set. */ static isc_result_t ldap_get_results (const char *zone, const char *record, const char *client, unsigned int query, void *dbdata, void *ptr) { isc_result_t result; dbinstance_t *dbi = NULL; char *querystring = NULL; LDAPURLDesc *ldap_url = NULL; int ldap_result = 0; LDAPMessage *ldap_msg = NULL; int i; int entries; /* get db instance / connection */ #ifdef ISC_PLATFORM_USETHREADS /* find an available DBI from the list */ dbi = ldap_find_avail_conn ((db_list_t *) ((ldap_instance_t *) dbdata)->db); #else /* ISC_PLATFORM_USETHREADS */ /* * only 1 DBI - no need to lock instance lock either * only 1 thread in the whole process, no possible contention. */ dbi = (dbinstance_t *) ((ldap_instance_t *) dbdata)->db; #endif /* ISC_PLATFORM_USETHREADS */ /* if DBI is null, can't do anything else */ if (dbi == NULL) return (ISC_R_FAILURE); /* set fields */ if (zone != NULL) { dbi->zone = isc_mem_strdup (ns_g_mctx, zone); if (dbi->zone == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->zone = NULL; } if (record != NULL) { dbi->record = isc_mem_strdup (ns_g_mctx, record); if (dbi->record == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->record = NULL; } if (client != NULL) { dbi->client = isc_mem_strdup (ns_g_mctx, client); if (dbi->client == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } else { dbi->client = NULL; } /* what type of query are we going to run? */ switch (query) { case ALLNODES: /* * if the query was not passed in from the config file * then we can't run it. return not_implemented, so * it's like the code for that operation was never * built into the driver.... AHHH flexibility!!! */ if (dbi->allnodes_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring (ns_g_mctx, dbi->allnodes_q); } break; case ALLOWXFR: /* same as comments as ALLNODES */ if (dbi->allowxfr_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring (ns_g_mctx, dbi->allowxfr_q); } break; case AUTHORITY: /* same as comments as ALLNODES */ if (dbi->authority_q == NULL) { result = ISC_R_NOTIMPLEMENTED; goto cleanup; } else { querystring = build_querystring (ns_g_mctx, dbi->authority_q); } break; case FINDZONE: /* this is required. It's the whole point of DLZ! */ if (dbi->findzone_q == NULL) { isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (2), "No query specified for findzone. " "Findzone requires a query"); result = ISC_R_FAILURE; goto cleanup; } else { querystring = build_querystring (ns_g_mctx, dbi->findzone_q); } break; case LOOKUP: /* this is required. It's also a major point of DLZ! */ if (dbi->lookup_q == NULL) { isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (2), "No query specified for lookup. " "Lookup requires a query"); result = ISC_R_FAILURE; goto cleanup; } else { querystring = build_querystring (ns_g_mctx, dbi->lookup_q); } break; default: /* * this should never happen. If it does, the code is * screwed up! */ UNEXPECTED_ERROR (__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results"); result = ISC_R_UNEXPECTED; goto cleanup; } /* if the querystring is null, Bummer, outta RAM. UPGRADE TIME!!! */ if (querystring == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } /* * output the full query string during debug so we can see * what lame error the query has. */ isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (1), "\nQuery String: %s\n", querystring); /* break URL down into it's component parts, if error cleanup */ ldap_result = ldap_url_parse (querystring, &ldap_url); if (ldap_result != LDAP_SUCCESS || ldap_url == NULL) { result = ISC_R_FAILURE; goto cleanup; } for (i = 0; i < 3; i++) { /* * dbi->dbconn may be null if trying to reconnect on a * previous query failed. */ if (dbi->dbconn == NULL) { isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect"); result = dlz_ldap_connect ((ldap_instance_t *) dbdata, dbi); if (result != ISC_R_SUCCESS) { result = ISC_R_FAILURE; continue; } } /* perform ldap search syncronously */ ldap_result = ldap_search_s ((LDAP *) dbi->dbconn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, 0, &ldap_msg); /* * check return code. No such object is ok, just * didn't find what we wanted */ switch (ldap_result) { case LDAP_NO_SUCH_OBJECT: isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (1), "No object found matching " "query requirements"); result = ISC_R_NOTFOUND; goto cleanup; break; case LDAP_SUCCESS: /* on success do nothing */ result = ISC_R_SUCCESS; i = 3; break; case LDAP_SERVER_DOWN: isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect"); result = dlz_ldap_connect ((ldap_instance_t *) dbdata, dbi); if (result != ISC_R_SUCCESS) result = ISC_R_FAILURE; break; default: /* * other errors not ok. Log error message and * get out */ isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP error: %s", ldap_err2string (ldap_result)); result = ISC_R_FAILURE; goto cleanup; break; } /* close switch(ldap_result) */ } /* end for (int i = 0 i < 3; i++) */ if (result != ISC_R_SUCCESS) goto cleanup; switch (query) { case ALLNODES: result = ldap_process_results ((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_true); break; case AUTHORITY: case LOOKUP: result = ldap_process_results ((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_false); break; case ALLOWXFR: entries = ldap_count_entries ((LDAP *) dbi->dbconn, ldap_msg); if (entries == 0) result = ISC_R_NOPERM; else if (entries > 0) result = ISC_R_SUCCESS; else result = ISC_R_FAILURE; break; case FINDZONE: entries = ldap_count_entries ((LDAP *) dbi->dbconn, ldap_msg); if (entries == 0) result = ISC_R_NOTFOUND; else if (entries > 0) result = ISC_R_SUCCESS; else result = ISC_R_FAILURE; break; default: /* * this should never happen. If it does, the code is * screwed up! */ UNEXPECTED_ERROR (__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results"); result = ISC_R_UNEXPECTED; } cleanup: /* it's always good to cleanup after yourself */ /* if we retrieved results, free them */ if (ldap_msg != NULL) ldap_msgfree (ldap_msg); if (ldap_url != NULL) ldap_free_urldesc (ldap_url); /* cleanup */ if (dbi->zone != NULL) isc_mem_free (ns_g_mctx, dbi->zone); if (dbi->record != NULL) isc_mem_free (ns_g_mctx, dbi->record); if (dbi->client != NULL) isc_mem_free (ns_g_mctx, dbi->client); #ifdef ISC_PLATFORM_USETHREADS /* release the lock so another thread can use this dbi */ isc_mutex_unlock (&dbi->instance_lock); #endif /* ISC_PLATFORM_USETHREADS */ /* release query string */ if (querystring != NULL) isc_mem_free (ns_g_mctx, querystring); /* return result */ return (result); }
int slapschema( int argc, char **argv ) { ID id; int rc = EXIT_SUCCESS; const char *progname = "slapschema"; Connection conn = { 0 }; OperationBuffer opbuf; Operation *op = NULL; void *thrctx; int requestBSF = 0; int doBSF = 0; slap_tool_init( progname, SLAPCAT, argc, argv ); requestBSF = ( sub_ndn.bv_len || filter ); #ifdef SIGPIPE (void) SIGNAL( SIGPIPE, slapcat_sig ); #endif #ifdef SIGHUP (void) SIGNAL( SIGHUP, slapcat_sig ); #endif (void) SIGNAL( SIGINT, slapcat_sig ); (void) SIGNAL( SIGTERM, slapcat_sig ); if( !be->be_entry_open || !be->be_entry_close || !( be->be_entry_first || be->be_entry_first_x ) || !be->be_entry_next || !be->be_entry_get ) { fprintf( stderr, "%s: database doesn't support necessary operations.\n", progname ); exit( EXIT_FAILURE ); } if( be->be_entry_open( be, 0 ) != 0 ) { fprintf( stderr, "%s: could not open database.\n", progname ); exit( EXIT_FAILURE ); } thrctx = ldap_pvt_thread_pool_context(); connection_fake_init( &conn, &opbuf, thrctx ); op = &opbuf.ob_op; op->o_tmpmemctx = NULL; op->o_bd = be; if ( !requestBSF && be->be_entry_first ) { id = be->be_entry_first( be ); } else { if ( be->be_entry_first_x ) { id = be->be_entry_first_x( be, sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter ); } else { assert( be->be_entry_first != NULL ); doBSF = 1; id = be->be_entry_first( be ); } } for ( ; id != NOID; id = be->be_entry_next( be ) ) { Entry* e; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof(textbuf); const char *text = NULL; if ( gotsig ) break; e = be->be_entry_get( be, id ); if ( e == NULL ) { printf("# no data for entry id=%08lx\n\n", (long) id ); rc = EXIT_FAILURE; if( continuemode ) continue; break; } if ( doBSF ) { if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) ) { be_entry_release_r( op, e ); continue; } if ( filter != NULL ) { int rc = test_filter( NULL, e, filter ); if ( rc != LDAP_COMPARE_TRUE ) { be_entry_release_r( op, e ); continue; } } } if( verbose ) { printf( "# id=%08lx\n", (long) id ); } rc = entry_schema_check( op, e, NULL, 0, 0, NULL, &text, textbuf, textlen ); if ( rc != LDAP_SUCCESS ) { fprintf( ldiffp->fp, "# (%d) %s%s%s\n", rc, ldap_err2string( rc ), text ? ": " : "", text ? text : "" ); fprintf( ldiffp->fp, "dn: %s\n\n", e->e_name.bv_val ); } be_entry_release_r( op, e ); } be->be_entry_close( be ); if ( slap_tool_destroy() ) rc = EXIT_FAILURE; return rc; }
/* Check the userid & password. * Return 0 on success, 1 on failure */ static int checkLDAP(LDAP * persistent_ld, const char *userid, const char *password, const char *ldapServer, int port) { char dn[1024]; int ret = 0; LDAP *bind_ld = NULL; if (!*password) { /* LDAP can't bind with a blank password. Seen as "anonymous" * and always granted access */ if (debug) fprintf(stderr, "Blank password given\n"); return 1; } if (searchfilter) { char filter[16384]; char escaped_login[1024]; LDAPMessage *res = NULL; LDAPMessage *entry; char *searchattr[] = {(char *)LDAP_NO_ATTRS, NULL}; char *userdn; int rc; LDAP *search_ld = persistent_ld; if (!search_ld) search_ld = open_ldap_connection(ldapServer, port); ldap_escape_value(escaped_login, sizeof(escaped_login), userid); if (binddn) { rc = ldap_simple_bind_s(search_ld, binddn, bindpasswd); if (rc != LDAP_SUCCESS) { fprintf(stderr, PROGRAM_NAME ": WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); ret = 1; goto search_done; } } snprintf(filter, sizeof(filter), searchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login); if (debug) fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, basedn); rc = ldap_search_s(search_ld, basedn, searchscope, filter, searchattr, 1, &res); if (rc != LDAP_SUCCESS) { if (noreferrals && rc == LDAP_PARTIAL_RESULTS) { /* Everything is fine. This is expected when referrals * are disabled. */ if (debug) fprintf(stderr, "noreferrals && rc == LDAP_PARTIAL_RESULTS\n"); } else { fprintf(stderr, PROGRAM_NAME ": WARNING, LDAP search error '%s'\n", ldap_err2string(rc)); #if defined(NETSCAPE_SSL) if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) { int sslerr = PORT_GetError(); fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr)); } #endif ret = 1; goto search_done; } } entry = ldap_first_entry(search_ld, res); if (!entry) { if (debug) fprintf(stderr, "Ldap search returned nothing\n"); ret = 1; goto search_done; } userdn = ldap_get_dn(search_ld, entry); if (!userdn) { fprintf(stderr, PROGRAM_NAME ": ERROR, could not get user DN for '%s'\n", userid); ret = 1; goto search_done; } snprintf(dn, sizeof(dn), "%s", userdn); squid_ldap_memfree(userdn); if (ret == 0 && (!binddn || !bind_once || passwdattr)) { /* Reuse the search connection for comparing the user password attribute */ bind_ld = search_ld; search_ld = NULL; } search_done: if (res) { ldap_msgfree(res); res = NULL; } if (search_ld && search_ld != persistent_ld) { ldap_unbind(search_ld); search_ld = NULL; } if (ret != 0) return ret; } else { snprintf(dn, sizeof(dn), "%s=%s,%s", userattr, userid, basedn); } if (debug) fprintf(stderr, "attempting to authenticate user '%s'\n", dn); if (!bind_ld && !bind_once) bind_ld = persistent_ld; if (!bind_ld) bind_ld = open_ldap_connection(ldapServer, port); if (passwdattr) { if (ldap_compare_s(bind_ld, dn, passwdattr, password) != LDAP_COMPARE_TRUE) { ret = 1; } } else if (ldap_simple_bind_s(bind_ld, dn, password) != LDAP_SUCCESS) ret = 1; if (bind_ld != persistent_ld) { ldap_unbind(bind_ld); bind_ld = NULL; } return ret; }
int main(int argc, char **argv) { char buf[8192]; char *user, *group, *extension_dn = NULL; char *ldapServer = NULL; LDAP *ld = NULL; int tryagain = 0, rc; int port = LDAP_PORT; int use_extension_dn = 0; int strip_nt_domain = 0; int strip_kerberos_realm = 0; int err = 0; setbuf(stdout, NULL); while (argc > 1 && argv[1][0] == '-') { char *value = ""; char option = argv[1][1]; switch (option) { case 'P': case 'R': case 'z': case 'Z': case 'd': case 'g': case 'S': break; default: if (strlen(argv[1]) > 2) { value = argv[1] + 2; } else if (argc > 2) { value = argv[2]; argv++; argc--; } else value = ""; break; } argv++; argc--; switch (option) { case 'H': #if !HAS_URI_SUPPORT fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n"); exit(1); #endif /* Fall thru to -h */ case 'h': if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } break; case 'b': basedn = value; break; case 'f': searchfilter = value; break; case 'B': userbasedn = value; break; case 'F': usersearchfilter = value; break; case 'u': userdnattr = value; break; case 's': if (strcmp(value, "base") == 0) searchscope = LDAP_SCOPE_BASE; else if (strcmp(value, "one") == 0) searchscope = LDAP_SCOPE_ONELEVEL; else if (strcmp(value, "sub") == 0) searchscope = LDAP_SCOPE_SUBTREE; else { fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value); exit(1); } break; case 'E': #if defined(NETSCAPE_SSL) sslpath = value; if (port == LDAP_PORT) port = LDAPS_PORT; #else fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n"); exit(1); #endif break; case 'c': connect_timeout = atoi(value); break; case 't': timelimit = atoi(value); break; case 'a': if (strcmp(value, "never") == 0) aliasderef = LDAP_DEREF_NEVER; else if (strcmp(value, "always") == 0) aliasderef = LDAP_DEREF_ALWAYS; else if (strcmp(value, "search") == 0) aliasderef = LDAP_DEREF_SEARCHING; else if (strcmp(value, "find") == 0) aliasderef = LDAP_DEREF_FINDING; else { fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value); exit(1); } break; case 'D': binddn = value; break; case 'w': bindpasswd = value; break; case 'W': readSecret(value); break; case 'P': persistent = !persistent; break; case 'p': port = atoi(value); break; case 'R': noreferrals = !noreferrals; break; #ifdef LDAP_VERSION3 case 'v': switch (atoi(value)) { case 2: version = LDAP_VERSION2; break; case 3: version = LDAP_VERSION3; break; default: fprintf(stderr, "Protocol version should be 2 or 3\n"); exit(1); } break; case 'Z': if (version == LDAP_VERSION2) { fprintf(stderr, "TLS (-Z) is incompatible with version %d\n", version); exit(1); } version = LDAP_VERSION3; use_tls = 1; break; #endif case 'd': debug = 1; break; case 'g': use_extension_dn = 1; break; case 'S': strip_nt_domain = 1; break; case 'K': strip_kerberos_realm = 1; break; default: fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option); exit(1); } } while (argc > 1) { char *value = argv[1]; if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } argc--; argv++; } if (!ldapServer) ldapServer = "localhost"; if (!basedn || !searchfilter) { fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n"); fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n"); fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n"); fprintf(stderr, "\t-f filter (REQUIRED)\tgroup search filter pattern. %%u = user,\n\t\t\t\t%%g = group\n"); fprintf(stderr, "\t-B basedn (REQUIRED)\tbase dn under where to search for users\n"); fprintf(stderr, "\t-F filter (REQUIRED)\tuser search filter pattern. %%s = login\n"); fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n"); fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n"); fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n"); fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n"); #if HAS_URI_SUPPORT fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n"); #endif fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n"); fprintf(stderr, "\t-p port\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT); fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n"); #if defined(NETSCAPE_SSL) fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n"); #endif fprintf(stderr, "\t-c timeout\t\tconnect timeout\n"); fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n"); fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n"); fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n"); #ifdef LDAP_VERSION3 fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n"); fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n"); #endif fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n"); fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n"); fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n"); fprintf(stderr, "\n"); fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n"); exit(1); } /* On Windows ldap_start_tls_s is available starting from Windows XP, * so we need to bind at run-time with the function entry point */ #ifdef _SQUID_MSWIN_ if (use_tls) { HMODULE WLDAP32Handle; WLDAP32Handle = GetModuleHandle("wldap32"); if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) { fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n"); exit(1); } } #endif while (fgets(buf, 256, stdin) != NULL) { int found = 0; if (!strchr(buf, '\n')) { /* too large message received.. skip and deny */ fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf); while (fgets(buf, sizeof(buf), stdin)) { fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf); if (strchr(buf, '\n') != NULL) break; } goto error; } user = strtok(buf, " \n"); if (!user) { fprintf(stderr, "%s: Invalid request\n", argv[0]); goto error; } rfc1738_unescape(user); if (strip_nt_domain) { char *u = strrchr(user, '\\'); if (!u) u = strrchr(user, '/'); if (u && u[1]) user = u + 1; } if (strip_kerberos_realm) { char *u = strchr(user, '@'); if (u != NULL) { *u = '\0'; } } if (use_extension_dn) { extension_dn = strtok(NULL, " \n"); if (!extension_dn) { fprintf(stderr, "%s: Invalid request\n", argv[0]); goto error; } rfc1738_unescape(extension_dn); } while (!found && user && (group = strtok(NULL, " \n")) != NULL) { rfc1738_unescape(group); recover: if (ld == NULL) { #if HAS_URI_SUPPORT if (strstr(ldapServer, "://") != NULL) { rc = ldap_initialize(&ld, ldapServer); if (rc != LDAP_SUCCESS) { fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); break; } } else #endif #if NETSCAPE_SSL if (sslpath) { if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n", sslpath); exit(1); } else { sslinit++; } if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) { fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n", ldapServer, port); exit(1); } } else #endif if ((ld = ldap_init(ldapServer, port)) == NULL) { fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port); break; } if (connect_timeout) squid_ldap_set_connect_timeout(ld, connect_timeout); #ifdef LDAP_VERSION3 if (version == -1) { version = LDAP_VERSION2; } if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) { fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version); ldap_unbind(ld); ld = NULL; break; } if (use_tls) { #ifdef LDAP_OPT_X_TLS if (version != LDAP_VERSION3) { fprintf(stderr, "TLS requires LDAP version 3\n"); exit(1); } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { fprintf(stderr, "Could not Activate TLS connection\n"); ldap_unbind(ld); ld = NULL; break; } #else fprintf(stderr, "TLS not supported with your LDAP library\n"); exit(1); #endif } #endif squid_ldap_set_timelimit(ld, timelimit); squid_ldap_set_referrals(ld, !noreferrals); squid_ldap_set_aliasderef(ld, aliasderef); if (binddn && bindpasswd && *binddn && *bindpasswd) { rc = ldap_simple_bind_s(ld, binddn, bindpasswd); if (rc != LDAP_SUCCESS) { fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); ldap_unbind(ld); ld = NULL; break; } } if (debug) fprintf(stderr, "Connected OK\n"); } if (searchLDAP(ld, group, user, extension_dn) == 0) { found = 1; break; } else { if (tryagain) { tryagain = 0; ldap_unbind(ld); ld = NULL; goto recover; } } } if (found) printf("OK\n"); else { error: printf("ERR\n"); } if (ld != NULL) { if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) { ldap_unbind(ld); ld = NULL; } else { tryagain = 1; } } err = 0; } if (ld) ldap_unbind(ld); return 0; }
/* * Look up a user in the directory to see if this is an account that can be authenticated */ int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size, uid_t *uid, int lookup_based_on_username) { LDAP *ldserver = NULL; int i; LDAPMessage *search_result = NULL; LDAPMessage *entry = NULL; char searchstring[1024]; struct timeval tv; char **values; char *user_dn = NULL; if (fullname) safestrncpy(fullname, username, fullname_size); if (ctdl_ldap_initialize(&ldserver) != LDAP_SUCCESS) { return(errno); } ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version); ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF); striplt(CtdlGetConfigStr("c_ldap_bind_dn")); striplt(CtdlGetConfigStr("c_ldap_bind_pw")); syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn")); i = ldap_simple_bind_s(ldserver, (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL), (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL) ); if (i != LDAP_SUCCESS) { syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i); return(i); } tv.tv_sec = 10; tv.tv_usec = 0; if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { if (lookup_based_on_username != 0) snprintf(searchstring, sizeof(searchstring), "(displayName=%s)",username); else snprintf(searchstring, sizeof(searchstring), "(sAMAccountName=%s)", username); } else { if (lookup_based_on_username != 0) snprintf(searchstring, sizeof(searchstring), "(cn=%s)",username); else snprintf(searchstring, sizeof(searchstring), "(&(objectclass=posixAccount)(uid=%s))", username); } syslog(LOG_DEBUG, "LDAP search: %s", searchstring); (void) ldap_search_ext_s( ldserver, /* ld */ CtdlGetConfigStr("c_ldap_base_dn"), /* base */ LDAP_SCOPE_SUBTREE, /* scope */ searchstring, /* filter */ NULL, /* attrs (all attributes) */ 0, /* attrsonly (attrs + values) */ NULL, /* serverctrls (none) */ NULL, /* clientctrls (none) */ &tv, /* timeout */ 1, /* sizelimit (1 result max) */ &search_result /* res */ ); /* Ignore the return value of ldap_search_ext_s(). Sometimes it returns an error even when * the search succeeds. Instead, we check to see whether search_result is still NULL. */ if (search_result == NULL) { syslog(LOG_DEBUG, "LDAP search: zero results were returned"); ldap_unbind(ldserver); return(2); } /* At this point we've got at least one result from our query. If there are multiple * results, we still only look at the first one. */ entry = ldap_first_entry(ldserver, search_result); if (entry) { user_dn = ldap_get_dn(ldserver, entry); if (user_dn) { syslog(LOG_DEBUG, "dn = %s", user_dn); } if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { values = ldap_get_values(ldserver, search_result, "displayName"); if (values) { if (values[0]) { if (fullname) safestrncpy(fullname, values[0], fullname_size); syslog(LOG_DEBUG, "displayName = %s", values[0]); } ldap_value_free(values); } } else { values = ldap_get_values(ldserver, search_result, "cn"); if (values) { if (values[0]) { if (fullname) safestrncpy(fullname, values[0], fullname_size); syslog(LOG_DEBUG, "cn = %s", values[0]); } ldap_value_free(values); } } /* If we know the username is the CN/displayName, we already set the uid*/ if (lookup_based_on_username==0) { if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) { values = ldap_get_values(ldserver, search_result, "objectGUID"); if (values) { if (values[0]) { if (uid != NULL) { *uid = abs(HashLittle(values[0], strlen(values[0]))); syslog(LOG_DEBUG, "uid hashed from objectGUID = %d", *uid); } } ldap_value_free(values); } } else { values = ldap_get_values(ldserver, search_result, "uidNumber"); if (values) { if (values[0]) { syslog(LOG_DEBUG, "uidNumber = %s", values[0]); if (uid != NULL) { *uid = atoi(values[0]); } } ldap_value_free(values); } } } } /* free the results */ ldap_msgfree(search_result); /* unbind so we can go back in as the authenticating user */ ldap_unbind(ldserver); if (!user_dn) { syslog(LOG_DEBUG, "No such user was found."); return(4); } if (found_dn) safestrncpy(found_dn, user_dn, found_dn_size); ldap_memfree(user_dn); return(0); }
int main(int argc, char **argv) { char buf[1024]; char *user, *passwd; char *ldapServer = NULL; LDAP *ld = NULL; int tryagain; int port = LDAP_PORT; setbuf(stdout, NULL); while (argc > 1 && argv[1][0] == '-') { const char *value = ""; char option = argv[1][1]; switch (option) { case 'P': case 'R': case 'z': case 'Z': case 'd': case 'O': break; default: if (strlen(argv[1]) > 2) { value = argv[1] + 2; } else if (argc > 2) { value = argv[2]; argv++; argc--; } else value = ""; break; } argv++; argc--; switch (option) { case 'H': #if !HAS_URI_SUPPORT fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n"); exit(1); #endif /* Fall thru to -h */ case 'h': if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } break; case 'b': basedn = value; break; case 'f': searchfilter = value; break; case 'u': userattr = value; break; case 'U': passwdattr = value; break; case 's': if (strcmp(value, "base") == 0) searchscope = LDAP_SCOPE_BASE; else if (strcmp(value, "one") == 0) searchscope = LDAP_SCOPE_ONELEVEL; else if (strcmp(value, "sub") == 0) searchscope = LDAP_SCOPE_SUBTREE; else { fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown search scope '%s'\n", value); exit(1); } break; case 'E': #if defined(NETSCAPE_SSL) sslpath = value; if (port == LDAP_PORT) port = LDAPS_PORT; #else fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n"); exit(1); #endif break; case 'c': connect_timeout = atoi(value); break; case 't': timelimit = atoi(value); break; case 'a': if (strcmp(value, "never") == 0) aliasderef = LDAP_DEREF_NEVER; else if (strcmp(value, "always") == 0) aliasderef = LDAP_DEREF_ALWAYS; else if (strcmp(value, "search") == 0) aliasderef = LDAP_DEREF_SEARCHING; else if (strcmp(value, "find") == 0) aliasderef = LDAP_DEREF_FINDING; else { fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown alias dereference method '%s'\n", value); exit(1); } break; case 'D': binddn = value; break; case 'w': bindpasswd = value; break; case 'W': readSecret(value); break; case 'P': persistent = !persistent; break; case 'O': bind_once = !bind_once; break; case 'p': port = atoi(value); break; case 'R': noreferrals = !noreferrals; break; #ifdef LDAP_VERSION3 case 'v': switch (atoi(value)) { case 2: version = LDAP_VERSION2; break; case 3: version = LDAP_VERSION3; break; default: fprintf(stderr, "Protocol version should be 2 or 3\n"); exit(1); } break; case 'Z': if (version == LDAP_VERSION2) { fprintf(stderr, "TLS (-Z) is incompatible with version %d\n", version); exit(1); } version = LDAP_VERSION3; use_tls = 1; break; #endif case 'd': debug++; break; default: fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown command line option '%c'\n", option); exit(1); } } while (argc > 1) { char *value = argv[1]; if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } argc--; argv++; } if (!ldapServer) ldapServer = strdup("localhost"); if (!basedn) { fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn [options] [ldap_server_name[:port]]...\n\n"); fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under which to search\n"); fprintf(stderr, "\t-f filter\t\tsearch filter to locate user DN\n"); fprintf(stderr, "\t-u userattr\t\tusername DN attribute\n"); fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n"); fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n"); fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n"); fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n"); #if HAS_URI_SUPPORT fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n"); #endif fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n"); fprintf(stderr, "\t-p port\t\t\tLDAP server port\n"); fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n"); #if defined(NETSCAPE_SSL) fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n"); #endif fprintf(stderr, "\t-c timeout\t\tconnect timeout\n"); fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n"); fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n"); fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n"); #ifdef LDAP_VERSION3 fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n"); fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires LDAP version 3\n"); #endif fprintf(stderr, "\n"); fprintf(stderr, "\tIf no search filter is specified, then the dn <userattr>=user,basedn\n\twill be used (same as specifying a search filter of '<userattr>=',\n\tbut quicker as as there is no need to search for the user DN)\n\n"); fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n"); exit(1); } /* On Windows ldap_start_tls_s is available starting from Windows XP, * so we need to bind at run-time with the function entry point */ #ifdef _SQUID_MSWIN_ if (use_tls) { HMODULE WLDAP32Handle; WLDAP32Handle = GetModuleHandle("wldap32"); if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) { fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n"); exit(1); } } #endif while (fgets(buf, sizeof(buf), stdin) != NULL) { user = strtok(buf, " \r\n"); passwd = strtok(NULL, "\r\n"); if (!user || !passwd || !passwd[0]) { printf("ERR\n"); continue; } rfc1738_unescape(user); rfc1738_unescape(passwd); if (!validUsername(user)) { printf("ERR No such user\n"); continue; } tryagain = (ld != NULL); recover: if (ld == NULL && persistent) ld = open_ldap_connection(ldapServer, port); if (checkLDAP(ld, user, passwd, ldapServer, port) != 0) { if (tryagain && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS) { tryagain = 0; ldap_unbind(ld); ld = NULL; goto recover; } printf("ERR %s\n", ldap_err2string(squid_ldap_errno(ld))); } else { printf("OK\n"); } if (ld && (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) { ldap_unbind(ld); ld = NULL; } } if (ld) ldap_unbind(ld); return 0; }
/* * Learn LDAP attributes and stuff them into the vCard. * Returns nonzero if we changed anything. */ int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v) { int changed_something = 0; LDAP *ldserver = NULL; int i; struct timeval tv; LDAPMessage *search_result = NULL; LDAPMessage *entry = NULL; char **givenName; char **sn; char **cn; char **initials; char **o; char **street; char **l; char **st; char **postalCode; char **telephoneNumber; char **mobile; char **homePhone; char **facsimileTelephoneNumber; char **mail; char **uid; char **homeDirectory; char **uidNumber; char **loginShell; char **gidNumber; char **c; char **title; char **uuid; char *attrs[] = { "*","+",NULL}; if (!ldap_dn) return(0); if (!v) return(0); if (ctdl_ldap_initialize(&ldserver) != LDAP_SUCCESS) { return(0); } ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version); ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF); striplt(CtdlGetConfigStr("c_ldap_bind_dn")); striplt(CtdlGetConfigStr("c_ldap_bind_pw")); syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn")); i = ldap_simple_bind_s(ldserver, (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL), (!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL) ); if (i != LDAP_SUCCESS) { syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i); return(0); } tv.tv_sec = 10; tv.tv_usec = 0; syslog(LOG_DEBUG, "LDAP search: %s", ldap_dn); (void) ldap_search_ext_s( ldserver, /* ld */ ldap_dn, /* base */ LDAP_SCOPE_SUBTREE, /* scope */ NULL, /* filter */ attrs, /* attrs (all attributes) */ 0, /* attrsonly (attrs + values) */ NULL, /* serverctrls (none) */ NULL, /* clientctrls (none) */ &tv, /* timeout */ 1, /* sizelimit (1 result max) */ &search_result /* res */ ); /* Ignore the return value of ldap_search_ext_s(). Sometimes it returns an error even when * the search succeeds. Instead, we check to see whether search_result is still NULL. */ if (search_result == NULL) { syslog(LOG_DEBUG, "LDAP search: zero results were returned"); ldap_unbind(ldserver); return(0); } /* At this point we've got at least one result from our query. If there are multiple * results, we still only look at the first one. */ entry = ldap_first_entry(ldserver, search_result); if (entry) { syslog(LOG_DEBUG, "LDAP search, got user details for vcard."); givenName=ldap_get_values(ldserver, search_result, "givenName"); sn=ldap_get_values(ldserver, search_result, "sn"); cn=ldap_get_values(ldserver, search_result, "cn"); initials=ldap_get_values(ldserver, search_result, "initials"); title=ldap_get_values(ldserver, search_result, "title"); o=ldap_get_values(ldserver, search_result, "o"); street=ldap_get_values(ldserver, search_result, "street"); l=ldap_get_values(ldserver, search_result, "l"); st=ldap_get_values(ldserver, search_result, "st"); postalCode=ldap_get_values(ldserver, search_result, "postalCode"); telephoneNumber=ldap_get_values(ldserver, search_result, "telephoneNumber"); mobile=ldap_get_values(ldserver, search_result, "mobile"); homePhone=ldap_get_values(ldserver, search_result, "homePhone"); facsimileTelephoneNumber=ldap_get_values(ldserver, search_result, "facsimileTelephoneNumber"); mail=ldap_get_values(ldserver, search_result, "mail"); uid=ldap_get_values(ldserver, search_result, "uid"); homeDirectory=ldap_get_values(ldserver, search_result, "homeDirectory"); uidNumber=ldap_get_values(ldserver, search_result, "uidNumber"); loginShell=ldap_get_values(ldserver, search_result, "loginShell"); gidNumber=ldap_get_values(ldserver, search_result, "gidNumber"); c=ldap_get_values(ldserver, search_result, "c"); uuid=ldap_get_values(ldserver, search_result, "entryUUID"); if (street && l && st && postalCode && c) changed_something |= vcard_set_one_prop_iff_different(v,"adr",";;%s;%s;%s;%s;%s",street[0],l[0],st[0],postalCode[0],c[0]); if (telephoneNumber) changed_something |= vcard_set_one_prop_iff_different(v,"tel;work","%s",telephoneNumber[0]); if (facsimileTelephoneNumber) changed_something |= vcard_set_one_prop_iff_different(v,"tel;fax","%s",facsimileTelephoneNumber[0]); if (mobile) changed_something |= vcard_set_one_prop_iff_different(v,"tel;cell","%s",mobile[0]); if (homePhone) changed_something |= vcard_set_one_prop_iff_different(v,"tel;home","%s",homePhone[0]); if (givenName && sn) { if (initials) { changed_something |= vcard_set_one_prop_iff_different(v,"n","%s;%s;%s",sn[0],givenName[0],initials[0]); } else { changed_something |= vcard_set_one_prop_iff_different(v,"n","%s;%s",sn[0],givenName[0]); } } if (mail) { changed_something |= vcard_set_props_iff_different(v,"email;internet",ldap_count_values(mail),mail); } if (uuid) changed_something |= vcard_set_one_prop_iff_different(v,"X-uuid","%s",uuid[0]); if (o) changed_something |= vcard_set_one_prop_iff_different(v,"org","%s",o[0]); if (cn) changed_something |= vcard_set_one_prop_iff_different(v,"fn","%s",cn[0]); if (title) changed_something |= vcard_set_one_prop_iff_different(v,"title","%s",title[0]); if (givenName) ldap_value_free(givenName); if (initials) ldap_value_free(initials); if (sn) ldap_value_free(sn); if (cn) ldap_value_free(cn); if (o) ldap_value_free(o); if (street) ldap_value_free(street); if (l) ldap_value_free(l); if (st) ldap_value_free(st); if (postalCode) ldap_value_free(postalCode); if (telephoneNumber) ldap_value_free(telephoneNumber); if (mobile) ldap_value_free(mobile); if (homePhone) ldap_value_free(homePhone); if (facsimileTelephoneNumber) ldap_value_free(facsimileTelephoneNumber); if (mail) ldap_value_free(mail); if (uid) ldap_value_free(uid); if (homeDirectory) ldap_value_free(homeDirectory); if (uidNumber) ldap_value_free(uidNumber); if (loginShell) ldap_value_free(loginShell); if (gidNumber) ldap_value_free(gidNumber); if (c) ldap_value_free(c); if (title) ldap_value_free(title); if (uuid) ldap_value_free(uuid); } /* free the results */ ldap_msgfree(search_result); /* unbind so we can go back in as the authenticating user */ ldap_unbind(ldserver); return(changed_something); /* tell the caller whether we made any changes */ }
int main (int argc, char *argv[]) { LDAP *ld; LDAPMessage *result; /* should be int result = STATE_UNKNOWN; */ int status = STATE_UNKNOWN; long microsec; double elapsed_time; /* for ldap tls */ int tls; int version=3; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); if (strstr(argv[0],"check_ldaps")) { xasprintf (&progname, "check_ldaps"); } /* Parse extra opts if any */ argv=np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect) starttls = TRUE; /* initialize alarm signal handling */ signal (SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ alarm (timeout_interval); /* get the start time */ gettimeofday (&tv, NULL); /* initialize ldap */ if (ld_uri != NULL) { #ifdef HAVE_LDAP_INITIALIZE int result = ldap_initialize(&ld, ld_uri); if (result != LDAP_SUCCESS) { printf ("Failed to connect to LDAP server at %s: %s\n", ld_uri, ldap_err2string(result)); return STATE_CRITICAL; } #else printf ("Sorry, this version of %s was compiled without URI support!\n", argv[0]); return STATE_CRITICAL; #endif } #ifdef HAVE_LDAP_INIT else if (!(ld = ldap_init (ld_host, ld_port))) { printf ("Could not connect to the server at port %i\n", ld_port); return STATE_CRITICAL; } #else else if (!(ld = ldap_open (ld_host, ld_port))) { if (verbose) ldap_perror(ld, "ldap_open"); printf (_("Could not connect to the server at port %i\n"), ld_port); return STATE_CRITICAL; } #endif /* HAVE_LDAP_INIT */ #ifdef HAVE_LDAP_SET_OPTION /* set ldap options */ if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) != LDAP_OPT_SUCCESS ) { printf(_("Could not set protocol version %d\n"), ld_protocol); return STATE_CRITICAL; } #endif if (ld_port == LDAPS_PORT || ssl_on_connect) { xasprintf (&SERVICE, "LDAPS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) /* ldaps: set option tls */ tls = LDAP_OPT_X_TLS_HARD; if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldaps_option"); printf (_("Could not init TLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else printf (_("TLS not supported by the libraries!\n")); return STATE_CRITICAL; #endif /* LDAP_OPT_X_TLS */ } else if (starttls) { xasprintf (&SERVICE, "LDAP-TLS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) /* ldap with startTLS: set option version */ if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS ) { if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); } } /* call start_tls */ if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_start_tls"); printf (_("Could not init startTLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else printf (_("startTLS not supported by the library, needs LDAPv3!\n")); return STATE_CRITICAL; #endif /* HAVE_LDAP_START_TLS_S */ } /* bind to the ldap server */ if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_bind"); printf (_("Could not bind to the LDAP server\n")); return STATE_CRITICAL; } /* do a search of all objectclasses in the base dn */ if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_search"); printf (_("Could not search/find objectclasses in %s\n"), ld_base); return STATE_CRITICAL; } /* unbind from the ldap server */ ldap_unbind (ld); /* reset the alarm handler */ alarm (0); /* calcutate the elapsed time and compare to thresholds */ microsec = deltime (tv); elapsed_time = (double)microsec / 1.0e6; if (crit_time!=UNDEFINED && elapsed_time>crit_time) status = STATE_CRITICAL; else if (warn_time!=UNDEFINED && elapsed_time>warn_time) status = STATE_WARNING; else status = STATE_OK; /* print out the result */ printf (_("LDAP %s - %.3f seconds response time|%s\n"), state_text (status), elapsed_time, fperfdata ("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, TRUE, 0, FALSE, 0)); return status; }
int slapauth( int argc, char **argv ) { int rc = EXIT_SUCCESS; const char *progname = "slapauth"; Connection conn = {0}; OperationBuffer opbuf; Operation *op; void *thrctx; slap_tool_init( progname, SLAPAUTH, argc, argv ); argv = &argv[ optind ]; argc -= optind; thrctx = ldap_pvt_thread_pool_context(); connection_fake_init( &conn, &opbuf, thrctx ); op = &opbuf.ob_op; conn.c_sasl_bind_mech = mech; if ( !BER_BVISNULL( &authzID ) ) { struct berval authzdn; rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = 1; BER_BVZERO( &authzID ); goto destroy; } authzID = authzdn; } if ( !BER_BVISNULL( &authcID ) ) { if ( !BER_BVISNULL( &authzID ) || argc == 0 ) { rc = do_check( &conn, op, &authcID ); goto destroy; } for ( ; argc--; argv++ ) { struct berval authzdn; ber_str2bv( argv[ 0 ], 0, 0, &authzID ); rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = -1; BER_BVZERO( &authzID ); if ( !continuemode ) { goto destroy; } } authzID = authzdn; rc = do_check( &conn, op, &authcID ); op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); BER_BVZERO( &authzID ); if ( rc && !continuemode ) { goto destroy; } } goto destroy; } for ( ; argc--; argv++ ) { struct berval id; ber_str2bv( argv[ 0 ], 0, 0, &id ); rc = do_check( &conn, op, &id ); if ( rc && !continuemode ) { goto destroy; } } destroy:; if ( !BER_BVISNULL( &authzID ) ) { op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); } if ( slap_tool_destroy()) rc = EXIT_FAILURE; return rc; }
int main() { LDAP *ld; /* LDAP resource handle */ LDAPMessage *result, *e; /* LDAP result handle */ BerElement *ber; /* array of attributes */ char *attribute; char **vals; int i,rc=0; char *attribs[3]; /* attribute array for search */ attribs[0]=strdup("uid"); /* return uid and cn of entries */ attribs[1]=strdup("cn"); attribs[2]=NULL; /* array must be NULL terminated */ /* setup LDAP connection */ if ((ld=ldap_init(LDAP_HOST, LDAP_PORT)) == NULL) { perror("ldap_init failed"); return EXIT_FAILURE; } printf("connected to LDAP server %s on port %d\n",LDAP_HOST,LDAP_PORT); /* anonymous bind */ rc = ldap_simple_bind_s(ld,BIND_USER,BIND_PW); if (rc != LDAP_SUCCESS) { fprintf(stderr,"LDAP error: %s\n",ldap_err2string(rc)); return EXIT_FAILURE; } else { printf("bind successful\n"); } /* perform ldap search */ rc = ldap_search_s(ld, SEARCHBASE, SCOPE, FILTER, attribs, 0, &result); if (rc != LDAP_SUCCESS) { fprintf(stderr,"LDAP search error: %s\n",ldap_err2string(rc)); return EXIT_FAILURE; } printf("Total results: %d\n", ldap_count_entries(ld, result)); for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld,e)) { printf("DN: %s\n", ldap_get_dn(ld,e)); // ab hier kann abgebrochen werden für unser ftp-server /* Now print the attributes and values of each found entry */ for (attribute = ldap_first_attribute(ld,e,&ber); attribute!=NULL; attribute = ldap_next_attribute(ld,e,ber)) { if ((vals=ldap_get_values(ld,e,attribute)) != NULL) { for (i=0;vals[i]!=NULL;i++) { printf("\t%s: %s\n",attribute,vals[i]); } /* free memory used to store the values of the attribute */ ldap_value_free(vals); } /* free memory used to store the attribute */ ldap_memfree(attribute); } /* free memory used to store the value structure */ if (ber != NULL) ber_free(ber,0); printf("\n"); } /* free memory used for result */ ldap_msgfree(result); free(attribs[0]); free(attribs[1]); printf("LDAP search suceeded\n"); ldap_unbind(ld); return EXIT_SUCCESS; }
krb5_error_code krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, char **db_args) { int l=0, kerberos_principal_object_type=0; krb5_error_code st=0, tempst=0; LDAP *ld=NULL; LDAPMessage *result=NULL, *ent=NULL; char *user=NULL, *subtree=NULL, *principal_dn=NULL; char **values=NULL, *strval[10]={NULL}, errbuf[1024]; char *filtuser=NULL; struct berval **bersecretkey=NULL; LDAPMod **mods=NULL; krb5_boolean create_standalone_prinicipal=FALSE; krb5_boolean krb_identity_exists=FALSE, establish_links=FALSE; char *standalone_principal_dn=NULL; krb5_tl_data *tl_data=NULL; krb5_key_data **keys=NULL; kdb5_dal_handle *dal_handle=NULL; krb5_ldap_context *ldap_context=NULL; krb5_ldap_server_handle *ldap_server_handle=NULL; osa_princ_ent_rec princ_ent; xargs_t xargs = {0}; char *polname = NULL; OPERATION optype; krb5_boolean found_entry = FALSE; /* Clear the global error string */ krb5_clear_error_message(context); SETUP_CONTEXT(); if (ldap_context->lrparams == NULL || ldap_context->container_dn == NULL) return EINVAL; /* get ldap handle */ GET_HANDLE(); if (is_principal_in_realm(ldap_context, entry->princ) != 0) { st = EINVAL; krb5_set_error_message(context, st, _("Principal does not belong to " "the default realm")); goto cleanup; } /* get the principal information to act on */ if (((st=krb5_unparse_name(context, entry->princ, &user)) != 0) || ((st=krb5_ldap_unparse_principal_name(user)) != 0)) goto cleanup; filtuser = ldap_filter_correct(user); if (filtuser == NULL) { st = ENOMEM; goto cleanup; } /* Identity the type of operation, it can be * add principal or modify principal. * hack if the entry->mask has KRB_PRINCIPAL flag set * then it is a add operation */ if (entry->mask & KADM5_PRINCIPAL) optype = ADD_PRINCIPAL; else optype = MODIFY_PRINCIPAL; if (((st=krb5_get_princ_type(context, entry, &kerberos_principal_object_type)) != 0) || ((st=krb5_get_userdn(context, entry, &principal_dn)) != 0)) goto cleanup; if ((st=process_db_args(context, db_args, &xargs, optype)) != 0) goto cleanup; if (entry->mask & KADM5_LOAD) { unsigned int tree = 0, ntrees = 0; int numlentries = 0; char **subtreelist = NULL, *filter = NULL; /* A load operation is special, will do a mix-in (add krbprinc * attrs to a non-krb object entry) if an object exists with a * matching krbprincipalname attribute so try to find existing * object and set principal_dn. This assumes that the * krbprincipalname attribute is unique (only one object entry has * a particular krbprincipalname attribute). */ if (asprintf(&filter, FILTER"%s))", filtuser) < 0) { filter = NULL; st = ENOMEM; goto cleanup; } /* get the current subtree list */ if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0) goto cleanup; found_entry = FALSE; /* search for entry with matching krbprincipalname attribute */ for (tree = 0; found_entry == FALSE && tree < ntrees; ++tree) { result = NULL; if (principal_dn == NULL) { LDAP_SEARCH_1(subtreelist[tree], ldap_context->lrparams->search_scope, filter, principal_attributes, IGNORE_STATUS); } else { /* just look for entry with principal_dn */ LDAP_SEARCH_1(principal_dn, LDAP_SCOPE_BASE, filter, principal_attributes, IGNORE_STATUS); } if (st == LDAP_SUCCESS) { numlentries = ldap_count_entries(ld, result); if (numlentries > 1) { ldap_msgfree(result); free(filter); st = EINVAL; krb5_set_error_message(context, st, _("operation can not continue, " "more than one entry with " "principal name \"%s\" found"), user); goto cleanup; } else if (numlentries == 1) { found_entry = TRUE; if (principal_dn == NULL) { ent = ldap_first_entry(ld, result); if (ent != NULL) { /* setting principal_dn will cause that entry to be modified further down */ if ((principal_dn = ldap_get_dn(ld, ent)) == NULL) { ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st); st = set_ldap_error (context, st, 0); ldap_msgfree(result); free(filter); goto cleanup; } } } } if (result) ldap_msgfree(result); } else if (st != LDAP_NO_SUCH_OBJECT) { /* could not perform search, return with failure */ st = set_ldap_error (context, st, 0); free(filter); goto cleanup; } /* * If it isn't found then assume a standalone princ entry is to * be created. */ } /* end for (tree = 0; principal_dn == ... */ free(filter); if (found_entry == FALSE && principal_dn != NULL) { /* * if principal_dn is null then there is code further down to * deal with setting standalone_principal_dn. Also note that * this will set create_standalone_prinicipal true for * non-mix-in entries which is okay if loading from a dump. */ create_standalone_prinicipal = TRUE; standalone_principal_dn = strdup(principal_dn); CHECK_NULL(standalone_principal_dn); } } /* end if (entry->mask & KADM5_LOAD */ /* time to generate the DN information with the help of * containerdn, principalcontainerreference or * realmcontainerdn information */ if (principal_dn == NULL && xargs.dn == NULL) { /* creation of standalone principal */ /* get the subtree information */ if (entry->princ->length == 2 && entry->princ->data[0].length == strlen("krbtgt") && strncmp(entry->princ->data[0].data, "krbtgt", entry->princ->data[0].length) == 0) { /* if the principal is a inter-realm principal, always created in the realm container */ subtree = strdup(ldap_context->lrparams->realmdn); } else if (xargs.containerdn) { if ((st=checkattributevalue(ld, xargs.containerdn, NULL, NULL, NULL)) != 0) { if (st == KRB5_KDB_NOENTRY || st == KRB5_KDB_CONSTRAINT_VIOLATION) { int ost = st; st = EINVAL; snprintf(errbuf, sizeof(errbuf), _("'%s' not found: "), xargs.containerdn); prepend_err_str(context, errbuf, st, ost); } goto cleanup; } subtree = strdup(xargs.containerdn); } else if (ldap_context->lrparams->containerref && strlen(ldap_context->lrparams->containerref) != 0) { /* * Here the subtree should be changed with * principalcontainerreference attribute value */ subtree = strdup(ldap_context->lrparams->containerref); } else { subtree = strdup(ldap_context->lrparams->realmdn); } CHECK_NULL(subtree); if (asprintf(&standalone_principal_dn, "krbprincipalname=%s,%s", filtuser, subtree) < 0) standalone_principal_dn = NULL; CHECK_NULL(standalone_principal_dn); /* * free subtree when you are done using the subtree * set the boolean create_standalone_prinicipal to TRUE */ create_standalone_prinicipal = TRUE; free(subtree); subtree = NULL; } /* * If the DN information is presented by the user, time to * validate the input to ensure that the DN falls under * any of the subtrees */ if (xargs.dn_from_kbd == TRUE) { /* make sure the DN falls in the subtree */ unsigned int tre=0, ntrees=0; int dnlen=0, subtreelen=0; char **subtreelist=NULL; char *dn=NULL; krb5_boolean outofsubtree=TRUE; if (xargs.dn != NULL) { dn = xargs.dn; } else if (xargs.linkdn != NULL) { dn = xargs.linkdn; } else if (standalone_principal_dn != NULL) { /* * Even though the standalone_principal_dn is constructed * within this function, there is the containerdn input * from the user that can become part of the it. */ dn = standalone_principal_dn; } /* get the current subtree list */ if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0) goto cleanup; for (tre=0; tre<ntrees; ++tre) { if (subtreelist[tre] == NULL || strlen(subtreelist[tre]) == 0) { outofsubtree = FALSE; break; } else { dnlen = strlen (dn); subtreelen = strlen(subtreelist[tre]); if ((dnlen >= subtreelen) && (strcasecmp((dn + dnlen - subtreelen), subtreelist[tre]) == 0)) { outofsubtree = FALSE; break; } } } for (tre=0; tre < ntrees; ++tre) { free(subtreelist[tre]); } if (outofsubtree == TRUE) { st = EINVAL; krb5_set_error_message(context, st, _("DN is out of the realm subtree")); goto cleanup; } /* * dn value will be set either by dn, linkdn or the standalone_principal_dn * In the first 2 cases, the dn should be existing and in the last case we * are supposed to create the ldap object. so the below should not be * executed for the last case. */ if (standalone_principal_dn == NULL) { /* * If the ldap object is missing, this results in an error. */ /* * Search for krbprincipalname attribute here. * This is to find if a kerberos identity is already present * on the ldap object, in which case adding a kerberos identity * on the ldap object should result in an error. */ char *attributes[]={"krbticketpolicyreference", "krbprincipalname", NULL}; LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attributes, IGNORE_STATUS); if (st == LDAP_SUCCESS) { ent = ldap_first_entry(ld, result); if (ent != NULL) { if ((values=ldap_get_values(ld, ent, "krbticketpolicyreference")) != NULL) { ldap_value_free(values); } if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) { krb_identity_exists = TRUE; ldap_value_free(values); } } ldap_msgfree(result); } else { st = set_ldap_error(context, st, OP_SEARCH); goto cleanup; } } } /* * If xargs.dn is set then the request is to add a * kerberos principal on a ldap object, but if * there is one already on the ldap object this * should result in an error. */ if (xargs.dn != NULL && krb_identity_exists == TRUE) { st = EINVAL; snprintf(errbuf, sizeof(errbuf), _("ldap object is already kerberized")); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } if (xargs.linkdn != NULL) { /* * link information can be changed using modprinc. * However, link information can be changed only on the * standalone kerberos principal objects. A standalone * kerberos principal object is of type krbprincipal * structural objectclass. * * NOTE: kerberos principals on an ldap object can't be * linked to other ldap objects. */ if (optype == MODIFY_PRINCIPAL && kerberos_principal_object_type != KDB_STANDALONE_PRINCIPAL_OBJECT) { st = EINVAL; snprintf(errbuf, sizeof(errbuf), _("link information can not be set/updated as the " "kerberos principal belongs to an ldap object")); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } /* * Check the link information. If there is already a link * existing then this operation is not allowed. */ { char **linkdns=NULL; int j=0; if ((st=krb5_get_linkdn(context, entry, &linkdns)) != 0) { snprintf(errbuf, sizeof(errbuf), _("Failed getting object references")); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } if (linkdns != NULL) { st = EINVAL; snprintf(errbuf, sizeof(errbuf), _("kerberos principal is already linked to a ldap " "object")); krb5_set_error_message(context, st, "%s", errbuf); for (j=0; linkdns[j] != NULL; ++j) free (linkdns[j]); free (linkdns); goto cleanup; } } establish_links = TRUE; } if (entry->mask & KADM5_LAST_SUCCESS) { memset(strval, 0, sizeof(strval)); if ((strval[0]=getstringtime(entry->last_success)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastSuccessfulAuth", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } if (entry->mask & KADM5_LAST_FAILED) { memset(strval, 0, sizeof(strval)); if ((strval[0]=getstringtime(entry->last_failed)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastFailedAuth", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free(strval[0]); } if (entry->mask & KADM5_FAIL_AUTH_COUNT) { krb5_kvno fail_auth_count; fail_auth_count = entry->fail_auth_count; if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT) fail_auth_count++; st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_REPLACE, fail_auth_count); if (st != 0) goto cleanup; } else if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT) { int attr_mask = 0; krb5_boolean has_fail_count; /* Check if the krbLoginFailedCount attribute exists. (Through * krb5 1.8.1, it wasn't set in new entries.) */ st = krb5_get_attributes_mask(context, entry, &attr_mask); if (st != 0) goto cleanup; has_fail_count = ((attr_mask & KDB_FAIL_AUTH_COUNT_ATTR) != 0); /* * If the client library and server supports RFC 4525, * then use it to increment by one the value of the * krbLoginFailedCount attribute. Otherwise, assert the * (provided) old value by deleting it before adding. */ #ifdef LDAP_MOD_INCREMENT if (ldap_server_handle->server_info->modify_increment && has_fail_count) { st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_INCREMENT, 1); if (st != 0) goto cleanup; } else { #endif /* LDAP_MOD_INCREMENT */ if (has_fail_count) { st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_DELETE, entry->fail_auth_count); if (st != 0) goto cleanup; } st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_ADD, entry->fail_auth_count + 1); if (st != 0) goto cleanup; #ifdef LDAP_MOD_INCREMENT } #endif } else if (optype == ADD_PRINCIPAL) { /* Initialize krbLoginFailedCount in new entries to help avoid a * race during the first failed login. */ st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_ADD, 0); } if (entry->mask & KADM5_MAX_LIFE) { if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_REPLACE, entry->max_life)) != 0) goto cleanup; } if (entry->mask & KADM5_MAX_RLIFE) { if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_REPLACE, entry->max_renewable_life)) != 0) goto cleanup; } if (entry->mask & KADM5_ATTRIBUTES) { if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_REPLACE, entry->attributes)) != 0) goto cleanup; } if (entry->mask & KADM5_PRINCIPAL) { memset(strval, 0, sizeof(strval)); strval[0] = user; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalname", LDAP_MOD_REPLACE, strval)) != 0) goto cleanup; } if (entry->mask & KADM5_PRINC_EXPIRE_TIME) { memset(strval, 0, sizeof(strval)); if ((strval[0]=getstringtime(entry->expiration)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalexpiration", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } if (entry->mask & KADM5_PW_EXPIRATION) { memset(strval, 0, sizeof(strval)); if ((strval[0]=getstringtime(entry->pw_expiration)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpasswordexpiration", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } if (entry->mask & KADM5_POLICY) { memset(&princ_ent, 0, sizeof(princ_ent)); for (tl_data=entry->tl_data; tl_data; tl_data=tl_data->tl_data_next) { if (tl_data->tl_data_type == KRB5_TL_KADM_DATA) { /* FIX ME: I guess the princ_ent should be freed after this call */ if ((st = krb5_lookup_tl_kadm_data(tl_data, &princ_ent)) != 0) { goto cleanup; } } } if (princ_ent.aux_attributes & KADM5_POLICY) { memset(strval, 0, sizeof(strval)); if ((st = krb5_ldap_name_to_policydn (context, princ_ent.policy, &polname)) != 0) goto cleanup; strval[0] = polname; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, strval)) != 0) goto cleanup; } else { st = EINVAL; krb5_set_error_message(context, st, "Password policy value null"); goto cleanup; } } else if (entry->mask & KADM5_LOAD && found_entry == TRUE) { /* * a load is special in that existing entries must have attrs that * removed. */ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, NULL)) != 0) goto cleanup; } if (entry->mask & KADM5_POLICY_CLR) { if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_DELETE, NULL)) != 0) goto cleanup; } if (entry->mask & KADM5_KEY_DATA || entry->mask & KADM5_KVNO) { krb5_kvno mkvno; if ((st=krb5_dbe_lookup_mkvno(context, entry, &mkvno)) != 0) goto cleanup; bersecretkey = krb5_encode_krbsecretkey (entry->key_data, entry->n_key_data, mkvno); if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0) goto cleanup; if (!(entry->mask & KADM5_PRINCIPAL)) { memset(strval, 0, sizeof(strval)); if ((strval[0]=getstringtime(entry->pw_expiration)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpasswordexpiration", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } /* Update last password change whenever a new key is set */ { krb5_timestamp last_pw_changed; if ((st=krb5_dbe_lookup_last_pwd_change(context, entry, &last_pw_changed)) != 0) goto cleanup; memset(strval, 0, sizeof(strval)); if ((strval[0] = getstringtime(last_pw_changed)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastPwdChange", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } } /* Modify Key data ends here */ /* Set tl_data */ if (entry->tl_data != NULL) { int count = 0; struct berval **ber_tl_data = NULL; krb5_tl_data *ptr; krb5_timestamp unlock_time; for (ptr = entry->tl_data; ptr != NULL; ptr = ptr->tl_data_next) { if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE #ifdef SECURID || ptr->tl_data_type == KRB5_TL_DB_ARGS #endif || ptr->tl_data_type == KRB5_TL_KADM_DATA || ptr->tl_data_type == KDB_TL_USER_INFO || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) continue; count++; } if (count != 0) { int j; ber_tl_data = (struct berval **) calloc (count + 1, sizeof (struct berval*)); if (ber_tl_data == NULL) { st = ENOMEM; goto cleanup; } for (j = 0, ptr = entry->tl_data; ptr != NULL; ptr = ptr->tl_data_next) { /* Ignore tl_data that are stored in separate directory * attributes */ if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE #ifdef SECURID || ptr->tl_data_type == KRB5_TL_DB_ARGS #endif || ptr->tl_data_type == KRB5_TL_KADM_DATA || ptr->tl_data_type == KDB_TL_USER_INFO || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) continue; if ((st = tl_data2berval (ptr, &ber_tl_data[j])) != 0) break; j++; } if (st == 0) { ber_tl_data[count] = NULL; st=krb5_add_ber_mem_ldap_mod(&mods, "krbExtraData", LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, ber_tl_data); } for (j = 0; ber_tl_data[j] != NULL; j++) { free(ber_tl_data[j]->bv_val); free(ber_tl_data[j]); } free(ber_tl_data); if (st != 0) goto cleanup; } if ((st=krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time)) != 0) goto cleanup; if (unlock_time != 0) { /* Update last admin unlock */ memset(strval, 0, sizeof(strval)); if ((strval[0] = getstringtime(unlock_time)) == NULL) goto cleanup; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastAdminUnlock", LDAP_MOD_REPLACE, strval)) != 0) { free (strval[0]); goto cleanup; } free (strval[0]); } } /* Directory specific attribute */ if (xargs.tktpolicydn != NULL) { int tmask=0; if (strlen(xargs.tktpolicydn) != 0) { st = checkattributevalue(ld, xargs.tktpolicydn, "objectclass", policyclass, &tmask); CHECK_CLASS_VALIDITY(st, tmask, _("ticket policy object value: ")); strval[0] = xargs.tktpolicydn; strval[1] = NULL; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_REPLACE, strval)) != 0) goto cleanup; } else { /* if xargs.tktpolicydn is a empty string, then delete * already existing krbticketpolicyreference attr */ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_DELETE, NULL)) != 0) goto cleanup; } } if (establish_links == TRUE) { memset(strval, 0, sizeof(strval)); strval[0] = xargs.linkdn; if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbObjectReferences", LDAP_MOD_REPLACE, strval)) != 0) goto cleanup; } /* * in case mods is NULL then return * not sure but can happen in a modprinc * so no need to return an error * addprinc will at least have the principal name * and the keys passed in */ if (mods == NULL) goto cleanup; if (create_standalone_prinicipal == TRUE) { memset(strval, 0, sizeof(strval)); strval[0] = "krbprincipal"; strval[1] = "krbprincipalaux"; strval[2] = "krbTicketPolicyAux"; if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0) goto cleanup; st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL); if (st == LDAP_ALREADY_EXISTS && entry->mask & KADM5_LOAD) { /* a load operation must replace an existing entry */ st = ldap_delete_ext_s(ld, standalone_principal_dn, NULL, NULL); if (st != LDAP_SUCCESS) { snprintf(errbuf, sizeof(errbuf), _("Principal delete failed (trying to replace " "entry): %s"), ldap_err2string(st)); st = translate_ldap_error (st, OP_ADD); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } else { st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL); } } if (st != LDAP_SUCCESS) { snprintf(errbuf, sizeof(errbuf), _("Principal add failed: %s"), ldap_err2string(st)); st = translate_ldap_error (st, OP_ADD); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } } else { /* * Here existing ldap object is modified and can be related * to any attribute, so always ensure that the ldap * object is extended with all the kerberos related * objectclasses so that there are no constraint * violations. */ { char *attrvalues[] = {"krbprincipalaux", "krbTicketPolicyAux", NULL}; int p, q, r=0, amask=0; if ((st=checkattributevalue(ld, (xargs.dn) ? xargs.dn : principal_dn, "objectclass", attrvalues, &amask)) != 0) goto cleanup; memset(strval, 0, sizeof(strval)); for (p=1, q=0; p<=2; p<<=1, ++q) { if ((p & amask) == 0) strval[r++] = attrvalues[q]; } if (r != 0) { if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0) goto cleanup; } } if (xargs.dn != NULL) st=ldap_modify_ext_s(ld, xargs.dn, mods, NULL, NULL); else st = ldap_modify_ext_s(ld, principal_dn, mods, NULL, NULL); if (st != LDAP_SUCCESS) { snprintf(errbuf, sizeof(errbuf), _("User modification failed: %s"), ldap_err2string(st)); st = translate_ldap_error (st, OP_MOD); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT) entry->fail_auth_count++; } cleanup: if (user) free(user); if (filtuser) free(filtuser); free_xargs(xargs); if (standalone_principal_dn) free(standalone_principal_dn); if (principal_dn) free (principal_dn); if (polname != NULL) free(polname); if (subtree) free (subtree); if (bersecretkey) { for (l=0; bersecretkey[l]; ++l) { if (bersecretkey[l]->bv_val) free (bersecretkey[l]->bv_val); free (bersecretkey[l]); } free (bersecretkey); } if (keys) free (keys); ldap_mods_free(mods, 1); krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle); return(st); }
/** @brief Return LDAP error for a ldap error. * @param res LDAP error id. * @returns Error string.*/ extern const char *ldap_errmsg(int res) { return ldap_err2string(res); }
static int ldap_verify_user_password (CcnetUserManager *manager, const char *uid, const char *password) { LDAP *ld = NULL; int res; GString *filter; char *filter_str = NULL; char *attrs[2]; LDAPMessage *msg = NULL, *entry; char *dn = NULL; int ret = 0; /* First search for the DN with the given uid. */ ld = ldap_init_and_bind (manager->ldap_host, #ifdef WIN32 manager->use_ssl, #endif manager->user_dn, manager->password); if (!ld) return -1; filter = g_string_new (NULL); g_string_printf (filter, "(%s=%s)", manager->login_attr, uid); filter_str = g_string_free (filter, FALSE); attrs[0] = manager->login_attr; attrs[1] = NULL; res = ldap_search_s (ld, manager->base, LDAP_SCOPE_SUBTREE, filter_str, attrs, 0, &msg); if (res != LDAP_SUCCESS) { ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res)); ret = -1; goto out; } entry = ldap_first_entry (ld, msg); if (!entry) { ccnet_warning ("user with uid %s not found in LDAP.\n", uid); ret = -1; goto out; } dn = ldap_get_dn (ld, entry); /* Then bind the DN with password. */ ldap_unbind_s (ld); ld = ldap_init_and_bind (manager->ldap_host, #ifdef WIN32 manager->use_ssl, #endif dn, password); if (!ld) { ccnet_warning ("Password check for %s failed.\n", uid); ret = -1; } out: ldap_msgfree (msg); ldap_memfree (dn); g_free (filter_str); if (ld) ldap_unbind_s (ld); return ret; }
static int domodrdn( LDAP *ld, char *dn, char *rdn, char *newSuperior, int remove ) /* flag: remove old RDN */ { int rc, code, id; char *matcheddn=NULL, *text=NULL, **refs=NULL; LDAPControl **ctrls = NULL; LDAPMessage *res; if ( verbose ) { printf( _("Renaming \"%s\"\n"), dn ); printf( _("\tnew rdn=\"%s\" (%s old rdn)\n"), rdn, remove ? _("delete") : _("keep") ); if( newSuperior != NULL ) { printf(_("\tnew parent=\"%s\"\n"), newSuperior); } } if( dont ) return LDAP_SUCCESS; rc = ldap_rename( ld, dn, rdn, newSuperior, remove, NULL, NULL, &id ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "%s: ldap_rename: %s (%d)\n", prog, ldap_err2string( rc ), rc ); return rc; } for ( ; ; ) { struct timeval tv = { 0, 0 }; if ( tool_check_abandon( ld, id ) ) { return LDAP_CANCELLED; } tv.tv_sec = 0; tv.tv_usec = 100000; rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res ); if ( rc < 0 ) { tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL ); return rc; } if ( rc != 0 ) { break; } } rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 ); if( rc != LDAP_SUCCESS ) { fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n", prog, ldap_err2string( rc ), rc ); return rc; } if( verbose || code != LDAP_SUCCESS || (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) ) { printf( _("Rename Result: %s (%d)\n"), ldap_err2string( code ), code ); if( text && *text ) { printf( _("Additional info: %s\n"), text ); } if( matcheddn && *matcheddn ) { printf( _("Matched DN: %s\n"), matcheddn ); } if( refs ) { int i; for( i=0; refs[i]; i++ ) { printf(_("Referral: %s\n"), refs[i] ); } } } if (ctrls) { tool_print_ctrls( ld, ctrls ); ldap_controls_free( ctrls ); } ber_memfree( text ); ber_memfree( matcheddn ); ber_memvfree( (void **) refs ); return code; }
/* * @uid: user's uid, list all users if * is passed in. */ static GList *ldap_list_users (CcnetUserManager *manager, const char *uid, int start, int limit) { LDAP *ld = NULL; GList *ret = NULL; int res; GString *filter; char *filter_str; char *attrs[2]; LDAPMessage *msg = NULL, *entry; ld = ldap_init_and_bind (manager->ldap_host, #ifdef WIN32 manager->use_ssl, #endif manager->user_dn, manager->password); if (!ld) return NULL; filter = g_string_new (NULL); g_string_printf (filter, "(%s=%s)", manager->login_attr, uid); filter_str = g_string_free (filter, FALSE); attrs[0] = manager->login_attr; attrs[1] = NULL; res = ldap_search_s (ld, manager->base, LDAP_SCOPE_SUBTREE, filter_str, attrs, 0, &msg); if (res != LDAP_SUCCESS) { ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res)); ret = NULL; goto out; } int i = 0; if (start == -1) start = 0; for (entry = ldap_first_entry (ld, msg); entry != NULL; entry = ldap_next_entry (ld, entry), ++i) { char *attr; char **vals; BerElement *ber; CcnetEmailUser *user; if (i < start) continue; if (limit >= 0 && i >= start + limit) break; attr = ldap_first_attribute (ld, entry, &ber); vals = ldap_get_values (ld, entry, attr); user = g_object_new (CCNET_TYPE_EMAIL_USER, "id", 0, "email", vals[0], "is_staff", FALSE, "is_active", TRUE, "ctime", (gint64)0, NULL); ret = g_list_prepend (ret, user); ldap_memfree (attr); ldap_value_free (vals); ber_free (ber, 0); } out: ldap_msgfree (msg); g_free (filter_str); if (ld) ldap_unbind_s (ld); return ret; }
static void *modify_thread(char *id) { LDAPMessage *res; LDAPMessage *e; int i, modentry, num_entries, msgid, parse_rc, finished; int rc, opcount; LDAPMod mod; LDAPMod *mods[2]; char *vals[2]; char *dn; ldapmsgwrapper *list, *lmwp, *lastlmwp; struct timeval zerotime; void *voidrc = (void *)0; zerotime.tv_sec = zerotime.tv_usec = 0L; printf("Starting modify_thread %s.\n", id); opcount = 0; tsd_setup(); rc = ldap_search_ext(ld, BASE, SCOPE, "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid); if (rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: Modify thread: " "ldap_search_ext: %s\n", id, ldap_err2string(rc)); exit(1); } list = lastlmwp = NULL; finished = 0; num_entries = 0; while (!finished) { rc = ldap_result(ld, msgid, LDAP_MSG_ONE, &zerotime, &res); switch (rc) { case -1: rc = ldap_get_lderrno(ld, NULL, NULL); fprintf(stderr, "ldap_result: %s\n", ldap_err2string(rc)); exit(1); break; case 0: break; /* Keep track of the number of entries found. */ case LDAP_RES_SEARCH_ENTRY: num_entries++; if ((lmwp = (ldapmsgwrapper *)malloc(sizeof(ldapmsgwrapper))) == NULL) { fprintf(stderr, "Thread %s: Modify thread: Cannot malloc\n", id); exit(1); } lmwp->lmw_messagep = res; lmwp->lmw_next = NULL; if (lastlmwp == NULL) { list = lastlmwp = lmwp; } else { lastlmwp->lmw_next = lmwp; } lastlmwp = lmwp; break; case LDAP_RES_SEARCH_REFERENCE: break; case LDAP_RES_SEARCH_RESULT: finished = 1; parse_rc = ldap_parse_result(ld, res, &rc, NULL, NULL, NULL, NULL, 1); if (parse_rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: can't parse result code.\n", id); exit(1); } else { if (rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: ldap_search: %s\n", id, ldap_err2string(rc)); } else { printf("Thread %s: Got %d results.\n", id, num_entries); } } break; default: break; } } mods[0] = &mod; mods[1] = NULL; vals[0] = "bar"; vals[1] = NULL; for (;;) { modentry = random() % num_entries; for (i = 0, lmwp = list; lmwp != NULL && i < modentry; i++, lmwp = lmwp->lmw_next) { /* NULL */ } if (lmwp == NULL) { fprintf(stderr, "Thread %s: Modify thread could not find entry %d of %d\n", id, modentry, num_entries); continue; } e = lmwp->lmw_messagep; printf("Thread %s: Modify thread picked entry %d of %d\n", id, i, num_entries); dn = ldap_get_dn(ld, e); mod.mod_op = LDAP_MOD_REPLACE; mod.mod_type = "description"; mod.mod_values = vals; printf("Thread %s: Modifying (%s)\n", id, dn); rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL); if (rc != LDAP_SUCCESS) { fprintf(stderr, "ldap_modify_ext_s: %s\n", ldap_err2string(rc)); if (rc == LDAP_SERVER_DOWN) { perror("ldap_modify_ext_s"); voidrc = (void *)1; goto modify_cleanup_and_return; } } free(dn); ++opcount; if (maxops != 0 && opcount >= maxops) { break; } } modify_cleanup_and_return: printf("Thread %s: attempted %d modify operations\n", id, opcount); set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */ tsd_cleanup(); free(id); return voidrc; }
/* * This function will look in ldap id the token correspond to the * requested user. It will returns 0 for failure and 1 for success. * * For the moment ldaps is not supported. ldap serve can be on a * remote host. * * You need the following parameters in you pam config: * ldapserver= OR ldap_uri= * ldapdn= * user_attr= * yubi_attr= * */ static int authorize_user_token_ldap (struct cfg *cfg, const char *user, const char *token_id) { DBG(("called")); int retval = 0; int protocol; #ifdef HAVE_LIBLDAP int yubi_attr_prefix_len = 0; LDAP *ld = NULL; LDAPMessage *result = NULL, *e; BerElement *ber; char *a; char *attrs[2] = {NULL, NULL}; struct berval **vals; int i, rc; char *find = NULL; if (cfg->user_attr == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but user_attr not set!")); return 0; } if (cfg->yubi_attr == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but yubi_attr not set!")); return 0; } if (cfg->ldapdn == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but ldapdn not set!")); return 0; } /* Get a handle to an LDAP connection. */ if (cfg->ldap_uri) { rc = ldap_initialize (&ld, cfg->ldap_uri); if (rc != LDAP_SUCCESS) { DBG (("ldap_init: %s", ldap_err2string (rc))); retval = 0; goto done; } } else { if ((ld = ldap_init (cfg->ldapserver, PORT_NUMBER)) == NULL) { DBG (("ldap_init")); retval = 0; goto done; } } /* LDAPv2 is historical -- RFC3494. */ protocol = LDAP_VERSION3; ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); /* Bind anonymously to the LDAP server. */ rc = ldap_simple_bind_s (ld, NULL, NULL); if (rc != LDAP_SUCCESS) { DBG (("ldap_simple_bind_s: %s", ldap_err2string (rc))); retval = 0; goto done; } /* Allocation of memory for search strings depending on input size */ i = (strlen(cfg->user_attr) + strlen(cfg->ldapdn) + strlen(user) + 3) * sizeof(char); if ((find = malloc(i)) == NULL) { DBG (("Failed allocating %i bytes", i)); retval = 0; goto done; } sprintf (find, "%s=%s,%s", cfg->user_attr, user, cfg->ldapdn); attrs[0] = (char *) cfg->yubi_attr; DBG(("LDAP : look up object '%s', ask for attribute '%s'", find, cfg->yubi_attr)); /* Search for the entry. */ if ((rc = ldap_search_ext_s (ld, find, LDAP_SCOPE_BASE, NULL, attrs, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result)) != LDAP_SUCCESS) { DBG (("ldap_search_ext_s: %s", ldap_err2string (rc))); retval = 0; goto done; } e = ldap_first_entry (ld, result); if (e == NULL) { DBG (("No result from LDAP search")); } else { /* Iterate through each returned attribute. */ for (a = ldap_first_attribute (ld, e, &ber); a != NULL; a = ldap_next_attribute (ld, e, ber)) { if ((vals = ldap_get_values_len (ld, e, a)) != NULL) { DBG(("LDAP : Found %i values - checking if any of them match '%s%s'", ldap_count_values_len(vals), cfg->yubi_attr_prefix ? cfg->yubi_attr_prefix : "", token_id)); yubi_attr_prefix_len = cfg->yubi_attr_prefix ? strlen(cfg->yubi_attr_prefix) : 0; /* Compare each value for the attribute against the token id. */ for (i = 0; vals[i] != NULL; i++) { /* Only values containing this prefix are considered. */ if ((!cfg->yubi_attr_prefix || !strncmp (cfg->yubi_attr_prefix, vals[i]->bv_val, yubi_attr_prefix_len))) { if(!strncmp (token_id, vals[i]->bv_val + yubi_attr_prefix_len, strlen (token_id))) { DBG (("Token Found :: %s", vals[i]->bv_val)); retval = 1; } } } ldap_value_free_len (vals); } ldap_memfree (a); } if (ber != NULL) ber_free (ber, 0); } done: if (result != NULL) ldap_msgfree (result); if (ld != NULL) ldap_unbind (ld); /* free memory allocated for search strings */ if (find != NULL) free(find); #else DBG (("Trying to use LDAP, but this function is not compiled in pam_yubico!!")); DBG (("Install libldap-dev and then recompile pam_yubico.")); #endif return retval; }
static void *delete_thread(char *id) { LDAPMessage *res; char dn[BUFSIZ], name[40]; int num_entries, msgid, rc, parse_rc, finished, opcount; struct timeval zerotime; void *voidrc = (void *)0; zerotime.tv_sec = zerotime.tv_usec = 0L; printf("Starting delete_thread %s.\n", id); opcount = 0; tsd_setup(); rc = ldap_search_ext(ld, BASE, SCOPE, "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid); if (rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: Delete thread: " "ldap_search_ext: %s\n", id, ldap_err2string(rc)); exit(1); } finished = 0; num_entries = 0; while (!finished) { rc = ldap_result(ld, msgid, LDAP_MSG_ONE, &zerotime, &res); switch (rc) { case -1: rc = ldap_get_lderrno(ld, NULL, NULL); fprintf(stderr, "ldap_result: %s\n", ldap_err2string(rc)); exit(1); break; case 0: break; /* Keep track of the number of entries found. */ case LDAP_RES_SEARCH_ENTRY: num_entries++; break; case LDAP_RES_SEARCH_REFERENCE: break; case LDAP_RES_SEARCH_RESULT: finished = 1; parse_rc = ldap_parse_result(ld, res, &rc, NULL, NULL, NULL, NULL, 1); if (parse_rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: can't parse result code.\n", id); exit(1); } else { if (rc != LDAP_SUCCESS) { fprintf(stderr, "Thread %s error: ldap_search: %s\n", id, ldap_err2string(rc)); } else { printf("Thread %s: Got %d results.\n", id, num_entries); } } break; default: break; } } for (;;) { sprintf(name, "%d", get_random_id()); sprintf(dn, "cn=%s, " BASE, name); printf("Thread %s: Deleting entry (%s)\n", id, dn); if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) != LDAP_SUCCESS) { ldap_perror(ld, "ldap_delete_ext_s"); if (rc == LDAP_SERVER_DOWN) { perror("ldap_delete_ext_s"); voidrc = (void *)1; goto delete_cleanup_and_return; } } ++opcount; if (maxops != 0 && opcount >= maxops) { break; } } delete_cleanup_and_return: printf("Thread %s: attempted %d delete operations\n", id, opcount); set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */ tsd_cleanup(); free(id); return voidrc; }
void LDAPSession::remove ( string dn ) { int errc= ldap_delete_s ( ld,dn.c_str() ); if ( errc != LDAP_SUCCESS ) throw LDAPExeption ( "ldap_delete_s",ldap_err2string ( errc ) ); }
void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int querytimeout) { #ifdef XYMON_LDAP ldap_data_t *req; testitem_t *t; struct timespec starttime; struct timespec endtime; /* Pick a sensible default for the timeout setting */ if (querytimeout == 0) querytimeout = 30; for (t = ldaptest->items; (t); t = t->next) { LDAPURLDesc *ludp; LDAP *ld; int rc, finished; int msgID = -1; struct timeval ldaptimeout; struct timeval openldaptimeout; LDAPMessage *result; LDAPMessage *e; strbuffer_t *response; char buf[MAX_LINE_LEN]; req = (ldap_data_t *) t->privdata; if (req->skiptest) continue; ludp = (LDAPURLDesc *) req->ldapdesc; getntimer(&starttime); /* Initiate session with the LDAP server */ dbgprintf("Initiating LDAP session for host %s port %d\n", ludp->lud_host, ludp->lud_port); if( (ld = ldap_init(ludp->lud_host, ludp->lud_port)) == NULL ) { dbgprintf("ldap_init failed\n"); req->ldapstatus = XYMON_LDAP_INITFAIL; continue; } /* * There is apparently no standard way of defining a network * timeout for the initial connection setup. */ #if (LDAP_VENDOR == OpenLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT) /* * OpenLDAP has an undocumented ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv) */ openldaptimeout.tv_sec = querytimeout; openldaptimeout.tv_usec = 0; ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &openldaptimeout); #else /* * So using an alarm() to interrupt any pending operations * seems to be the least insane way of doing this. * * Note that we must do this right after ldap_init(), as * any operation on the session handle (ld) may trigger the * network connection to be established. */ connect_timeout = 0; signal(SIGALRM, ldap_alarmhandler); alarm(querytimeout); #endif /* * This is completely undocumented in the OpenLDAP docs. * But apparently it is documented in * http://www.ietf.org/proceedings/99jul/I-D/draft-ietf-ldapext-ldap-c-api-03.txt * * Both of these routines appear in the <ldap.h> file * from OpenLDAP 2.1.22. Their use to enable TLS has * been deciphered from the ldapsearch() utility * sourcecode. * * According to Manon Goo <*****@*****.**>, recent (Jan. 2005) * OpenLDAP implementations refuse to talk LDAPv2. */ #ifdef LDAP_OPT_PROTOCOL_VERSION { int protocol = LDAP_VERSION3; dbgprintf("Attempting to select LDAPv3\n"); if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) { dbgprintf("Failed to select LDAPv3, trying LDAPv2\n"); protocol = LDAP_VERSION2; if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) { req->output = strdup(ldap_err2string(rc)); req->ldapstatus = XYMON_LDAP_TLSFAIL; } continue; } } #endif #ifdef XYMON_LDAP_USESTARTTLS if (req->usetls) { dbgprintf("Trying to enable TLS for session\n"); if ((rc = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) { dbgprintf("ldap_start_tls failed\n"); req->output = strdup(ldap_err2string(rc)); req->ldapstatus = XYMON_LDAP_TLSFAIL; continue; } } #endif if (!connect_timeout) { msgID = ldap_simple_bind(ld, (t->host->ldapuser ? t->host->ldapuser : ""), (t->host->ldappasswd ? t->host->ldappasswd : "")); } /* Cancel any pending alarms */ alarm(0); signal(SIGALRM, SIG_DFL); /* Did we connect? */ if (connect_timeout || (msgID == -1)) { req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = "Cannot connect to server"; continue; } /* Wait for bind to complete */ rc = 0; finished = 0; ldaptimeout.tv_sec = querytimeout; ldaptimeout.tv_usec = 0L; while( ! finished ) { int rc2; rc = ldap_result(ld, msgID, LDAP_MSG_ONE, &ldaptimeout, &result); dbgprintf("ldap_result returned %d for ldap_simple_bind()\n", rc); if(rc == -1) { finished = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; if (result == NULL) { errprintf("LDAP library problem - NULL result returned\n"); req->output = strdup("LDAP BIND failed\n"); } else { rc2 = ldap_result2error(ld, result, 1); req->output = strdup(ldap_err2string(rc2)); } ldap_unbind(ld); } else if (rc == 0) { finished = 1; req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup("Connection timeout"); ldap_unbind(ld); } else if( rc > 0 ) { finished = 1; if (result == NULL) { errprintf("LDAP library problem - got a NULL resultcode for status %d\n", rc); req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup("LDAP library problem: ldap_result2error returned a NULL result for status %d\n"); ldap_unbind(ld); } else { rc2 = ldap_result2error(ld, result, 1); if(rc2 != LDAP_SUCCESS) { req->ldapstatus = XYMON_LDAP_BINDFAIL; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); } } } } /* ... while() */ /* We're done connecting. If something went wrong, go to next query. */ if (req->ldapstatus != 0) continue; /* Now do the search. With a timeout */ ldaptimeout.tv_sec = querytimeout; ldaptimeout.tv_usec = 0L; rc = ldap_search_st(ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldaptimeout, &result); if(rc == LDAP_TIMEOUT) { req->ldapstatus = XYMON_LDAP_TIMEOUT; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); continue; } if( rc != LDAP_SUCCESS ) { req->ldapstatus = XYMON_LDAP_SEARCHFAILED; req->output = strdup(ldap_err2string(rc)); ldap_unbind(ld); continue; } getntimer(&endtime); response = newstrbuffer(0); sprintf(buf, "Searching LDAP for %s yields %d results:\n\n", t->testspec, ldap_count_entries(ld, result)); addtobuffer(response, buf); for(e = ldap_first_entry(ld, result); (e != NULL); e = ldap_next_entry(ld, e) ) { char *dn; BerElement *ber; char *attribute; char **vals; dn = ldap_get_dn(ld, e); sprintf(buf, "DN: %s\n", dn); addtobuffer(response, buf); /* Addtributes and values */ for (attribute = ldap_first_attribute(ld, e, &ber); (attribute != NULL); attribute = ldap_next_attribute(ld, e, ber) ) { if ((vals = ldap_get_values(ld, e, attribute)) != NULL) { int i; for(i = 0; (vals[i] != NULL); i++) { sprintf(buf, "\t%s: %s\n", attribute, vals[i]); addtobuffer(response, buf); } } /* Free memory used to store values */ ldap_value_free(vals); } /* Free memory used to store attribute */ ldap_memfree(attribute); ldap_memfree(dn); if (ber != NULL) ber_free(ber, 0); addtobuffer(response, "\n"); } req->ldapstatus = XYMON_LDAP_OK; req->output = grabstrbuffer(response); tvdiff(&starttime, &endtime, &req->duration); ldap_msgfree(result); ldap_unbind(ld); ldap_free_urldesc(ludp); } #endif }
void LDAPSession::stringSearch ( string dn,const list<string> &attributes, string searchParam, list<LDAPStringEntry>& result ) { char** attr; attr= ( char** ) malloc ( sizeof ( char* ) *attributes.size() +1 ); int i=0; list<string>::const_iterator it=attributes.begin(); list<string>::const_iterator end=attributes.end(); for ( ;it!=end;++it ) { attr[i]= ( char* ) malloc ( sizeof ( char ) * ( *it ).length() +1 ); strcpy ( attr[i], ( *it ).c_str() ); ++i; } attr[i]=0l; LDAPMessage* res; int errc=ldap_search_s ( ld,dn.c_str(),LDAP_SCOPE_SUBTREE, searchParam.c_str(),attr,0,&res ); if ( errc != LDAP_SUCCESS ) { i=0; it=attributes.begin(); for ( ;it!=end;++it ) { free ( attr[i] ); ++i; } free ( attr ); throw LDAPExeption ( "ldap_search_s",ldap_err2string ( errc ) ); } LDAPMessage *entry=ldap_first_entry ( ld,res ); while ( entry ) { LDAPStringEntry stringEntry; it=attributes.begin(); for ( ;it!=end;++it ) { LDAPStringValue val; val.attr= ( *it ); char **atr=ldap_get_values ( ld,entry, ( *it ).c_str() ); int count=ldap_count_values ( atr ); for ( i=0;i<count;i++ ) { val.value.push_back ( atr[i] ); } ldap_value_free ( atr ); stringEntry.push_back ( val ); } entry=ldap_next_entry ( ld,entry ); result.push_back ( stringEntry ); } free ( res ); i=0; it=attributes.begin(); for ( ;it!=end;++it ) { free ( attr[i] ); ++i; } free ( attr ); }
int ldap_params_search( int* _ld_result_count, char* _lds_name, char* _dn, int _scope, char** _attrs, char* _filter, ...) { int rc; static char filter_str[LDAP_MAX_FILTER_LEN]; char *filter_ptr = NULL; va_list filter_vars; /* * check _scope */ switch (_scope) { case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_BASE: case LDAP_SCOPE_SUBTREE: break; default: LM_ERR("[%s]: invalid scope argument [%d]\n", _lds_name, _scope); return -1; } if (_filter) { /* * vsnprintf */ va_start(filter_vars, _filter); rc = vsnprintf(filter_str, (size_t)LDAP_MAX_FILTER_LEN, _filter, filter_vars); va_end(filter_vars); if (rc >= LDAP_MAX_FILTER_LEN) { LM_ERR( "[%s]: filter string too long (len [%d], max len [%d])\n", _lds_name, rc, LDAP_MAX_FILTER_LEN); return -1; } else if (rc < 0) { LM_ERR("vsnprintf failed\n"); return -1; } filter_ptr = filter_str; } /* * ldap search */ if (lds_search(_lds_name, _dn, _scope, filter_ptr, _attrs, NULL, _ld_result_count, &rc) != 0) { /* try again if LDAP API ERROR */ if (LDAP_API_ERROR(rc) && (lds_search(_lds_name, _dn, _scope, filter_str, _attrs, NULL, _ld_result_count, &rc) != 0)) { LM_ERR( "[%s]: LDAP search (dn [%s], scope [%d]," " filter [%s]) failed: %s\n", _lds_name, _dn, _scope, filter_str, ldap_err2string(rc)); return -1; } } LM_DBG( "[%s]: [%d] LDAP entries found\n", _lds_name, *_ld_result_count); return 0; }
static int process( void *arg ) { char *rbuf, *saved_rbuf, *start, *p, *q; FILE *rfp = NULL; int rc, use_ldif, deref; LDAPControl *ldctrl; #ifdef SOLARIS_LDAP_CMD LDAP *ld; #endif /* SOLARIS_LDAP_CMD */ ld = ldaptool_ldap_init( 0 ); if ( !ldaptool_not ) { deref = LDAP_DEREF_NEVER; /* this seems prudent */ ldap_set_option( ld, LDAP_OPT_DEREF, &deref ); } ldaptool_bind( ld ); if (( ldctrl = ldaptool_create_manage_dsait_control()) != NULL ) { ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); } if ((ldctrl = ldaptool_create_proxyauth_control(ld)) !=NULL) { ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); } rc = 0; /* turn on bulk import?*/ if (bulkimport_suffix) { struct berval bv, *retdata; char *retoid; bv.bv_val = bulkimport_suffix; bv.bv_len = strlen(bulkimport_suffix); if ((rc = ldap_extended_operation_s(ld, BULKIMPORT_START_OID, &bv, NULL, NULL, &retoid, &retdata)) != 0) { fprintf(stderr, gettext("Error: unable to service " "extended operation request\n\t'%s' for " "bulk import\n\t(error:%d:'%s')\n"), BULKIMPORT_START_OID, rc, ldap_err2string(rc)); return (rc); } if (retoid) ldap_memfree(retoid); if (retdata) ber_bvfree(retdata); } while (( rc == 0 || contoper ) && ( rbuf = read_one_record( ldaptool_fp )) != NULL ) { /* * we assume record is ldif/slapd.replog if the first line * has a colon that appears to the left of any equal signs, OR * if the first line consists entirely of digits (an entry id) */ use_ldif = ( p = strchr( rbuf, ':' )) != NULL && ( q = strchr( rbuf, '\n' )) != NULL && p < q && (( q = strchr( rbuf, '=' )) == NULL || p < q ); start = rbuf; saved_rbuf = strdup( rbuf ); if ( !use_ldif && ( q = strchr( rbuf, '\n' )) != NULL ) { for ( p = rbuf; p < q; ++p ) { if ( !isdigit( *p )) { break; } } if ( p >= q ) { use_ldif = 1; start = q + 1; } } #ifdef SOLARIS_LDAP_CMD if ( use_ldif ) { rc = process_ldif_rec( ld, start ); } else { rc = process_ldapmod_rec( ld, start ); } #else if ( use_ldif ) { rc = process_ldif_rec( start ); } else { rc = process_ldapmod_rec( start ); } #endif /* SOLARIS_LDAP_CMD */ if ( rc != LDAP_SUCCESS && rejfile != NULL ) { /* Write this record to the reject file */ int newfile = 0; struct stat stbuf; if ( stat( rejfile, &stbuf ) < 0 ) { if ( errno == ENOENT ) { newfile = 1; } } if (( rfp = ldaptool_open_file( rejfile, "a" )) == NULL ) { fprintf( stderr, gettext("Cannot open error file \"%s\" - " "erroneous entries will not be saved\n"), rejfile ); rejfile = NULL; } else { if ( newfile == 0 ) { fputs( "\n", rfp ); } fprintf( rfp, gettext("# Error: %s\n"), ldap_err2string( rc )); fputs( saved_rbuf, rfp ); fclose( rfp ); rfp = NULL; } } free( rbuf ); free( saved_rbuf ); } ldaptool_reset_control_array( ldaptool_request_ctrls ); /* turn off bulk import?*/ if (bulkimport_suffix) { struct berval bv, *retdata; char *retoid; bv.bv_val = ""; bv.bv_len = 0; if ((rc = ldap_extended_operation_s(ld, BULKIMPORT_STOP_OID, &bv, NULL, NULL, &retoid, &retdata)) != 0) { fprintf(stderr, gettext("Error: unable to service " "extended operation request\n\t '%s' for " "bulk import\n\t(rc:%d:'%s')\n"), BULKIMPORT_STOP_OID, rc, ldap_err2string(rc)); return (rc); } if (retoid) ldap_memfree(retoid); if (retdata) ber_bvfree(retdata); } #ifdef SOLARIS_LDAP_CMD mutex_lock(&read_mutex); #endif ldaptool_cleanup( ld ); #ifdef SOLARIS_LDAP_CMD mutex_unlock(&read_mutex); #endif return( rc ); }
/* * Remove an array of values from a value set. * The removed values are passed back in an array. * * Flags * SLAPI_VALUE_FLAG_PRESERVECSNSET - csnset in the value set is duplicated and * preserved in the matched element of the * array of values. * SLAPI_VALUE_FLAG_IGNOREERROR - ignore an error: Couldn't find the value to * be deleted. * SLAPI_VALUE_FLAG_USENEWVALUE - replace the value between the value set and * the matched element of the array of values * (used by entry_add_present_values_wsi). * * Returns * LDAP_SUCCESS - OK. * LDAP_NO_SUCH_ATTRIBUTE - A value to be deleted was not in the value set. * LDAP_OPERATIONS_ERROR - Something very bad happened. */ int valueset_remove_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **valuestodelete, int flags, Slapi_Value ***va_out) { int rc= LDAP_SUCCESS; if(!valuearray_isempty(vs->va)) { int numberofvaluestodelete= valuearray_count(valuestodelete); struct valuearrayfast vaf_out; if ( va_out ) { valuearrayfast_init(&vaf_out,*va_out); } /* * If there are more then one values, build an AVL tree to check * the duplicated values. */ if ( numberofvaluestodelete > 1 ) { /* * Several values to delete: first build an AVL tree that * holds all of the existing values and use that to find * the values we want to delete. */ Avlnode *vtree = NULL; int numberofexistingvalues= slapi_valueset_count(vs); rc= valuetree_add_valuearray( a, vs->va, &vtree, NULL ); if ( rc!=LDAP_SUCCESS ) { /* * failed while constructing AVL tree of existing * values... something bad happened. */ rc= LDAP_OPERATIONS_ERROR; } else { int i; /* * find and mark all the values that are to be deleted */ for ( i = 0; rc == LDAP_SUCCESS && valuestodelete[i] != NULL; ++i ) { int index= 0; rc = valuetree_find( a, valuestodelete[i], vtree, &index ); if(rc==LDAP_SUCCESS) { if(vs->va[index]!=NULL) { /* Move the value to be removed to the out array */ if ( va_out ) { if (vs->va[index]->v_csnset && (flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET| SLAPI_VALUE_FLAG_USENEWVALUE))) { valuestodelete[i]->v_csnset = csnset_dup (vs->va[index]->v_csnset); } if (flags & SLAPI_VALUE_FLAG_USENEWVALUE) { valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]); valuestodelete[i] = vs->va[index]; vs->va[index] = NULL; } else { valuearrayfast_add_value_passin(&vaf_out,vs->va[index]); vs->va[index] = NULL; } } else { if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET) { valuestodelete[i]->v_csnset = vs->va[index]->v_csnset; vs->va[index]->v_csnset = NULL; } slapi_value_free ( & vs->va[index] ); } } else { /* We already deleted this value... */ if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0) { /* ...that's an error. */ rc= LDAP_NO_SUCH_ATTRIBUTE; } } } else { /* Couldn't find the value to be deleted */ if(rc==LDAP_NO_SUCH_ATTRIBUTE && (flags & SLAPI_VALUE_FLAG_IGNOREERROR )) { rc= LDAP_SUCCESS; } } } valuetree_free( &vtree ); if ( rc != LDAP_SUCCESS ) { LDAPDebug( LDAP_DEBUG_ANY,"could not find value %d for attr %s (%s)\n", i-1, a->a_type, ldap_err2string( rc )); } else { /* Shunt up all the remaining values to cover the deleted ones. */ valuearray_compress(vs->va,numberofexistingvalues); } } } else { /* We delete one or no value, so we use brute force. */ int i; for ( i = 0; rc==LDAP_SUCCESS && valuestodelete[i] != NULL; ++i ) { Slapi_Value *found= valueset_remove_value(a, vs, valuestodelete[i]); if(found!=NULL) { if ( va_out ) { if (found->v_csnset && (flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET| SLAPI_VALUE_FLAG_USENEWVALUE))) { valuestodelete[i]->v_csnset = csnset_dup (found->v_csnset); } if (flags & SLAPI_VALUE_FLAG_USENEWVALUE) { valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]); valuestodelete[i] = found; } else { valuearrayfast_add_value_passin(&vaf_out,found); } } else { if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET) { valuestodelete[i]->v_csnset = found->v_csnset; found->v_csnset = NULL; } slapi_value_free ( & found ); } } else { if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0) { LDAPDebug( LDAP_DEBUG_ARGS,"could not find value %d for attr %s\n", i-1, a->a_type, 0 ); rc= LDAP_NO_SUCH_ATTRIBUTE; } } } } if ( va_out ) { *va_out= vaf_out.va; if(rc!=LDAP_SUCCESS) { valuearray_free(va_out); } } } return rc; }
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { #ifdef USE_LDAP int ret; #if 0 if (s->auth_ldap_basedn->used == 0) { log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); return HANDLER_ERROR; } #endif if (s->auth_ldap_hostname->used) { /* free old context */ if (NULL != s->ldap) ldap_unbind_s(s->ldap); if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); return HANDLER_ERROR; } ret = LDAP_VERSION3; if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } if (s->auth_ldap_starttls) { /* if no CA file is given, it is ok, as we will use encryption * if the server requires a CAfile it will tell us */ if (!buffer_is_empty(s->auth_ldap_cafile)) { if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, s->auth_ldap_cafile->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "Loading CA certificate failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } /* 1. */ if (s->auth_ldap_binddn->used) { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } else { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } } return HANDLER_GO_ON; #else UNUSED(s); log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available"); return HANDLER_ERROR; #endif }