/** Iterate over pairs in mapping section creating equivalent client pairs from LDAP values * * If we hit a CONF_SECTION we recurse and process its CONF_PAIRS too. * * @param[in] inst rlm_ldap configuration. * @param[out] client config section. * @param[in] map section. * @param[in] conn LDAP connection. * @param[in] entry returned from search. * @return 0 on success else -1 on error. */ static int rlm_ldap_client_map_section(ldap_instance_t const *inst, CONF_SECTION *client, CONF_SECTION const *map, ldap_handle_t *conn, LDAPMessage *entry) { CONF_ITEM const *ci; for (ci = cf_item_find_next(map, NULL); ci != NULL; ci = cf_item_find_next(map, ci)) { CONF_PAIR const *cp; char **value; char const *attr; /* * Recursively process map subsection */ if (cf_item_is_section(ci)) { CONF_SECTION *cs, *cc; cs = cf_itemtosection(ci); cc = cf_section_alloc(client, cf_section_name1(cs), cf_section_name2(cs)); if (!cc) return -1; cf_section_add(client, cc); if (rlm_ldap_client_map_section(inst, cc, cs, conn, entry) < 0) return -1; continue; } cp = cf_itemtopair(ci); attr = cf_pair_attr(cp); value = ldap_get_values(conn->handle, entry, cf_pair_value(cp)); if (!value) continue; cp = cf_pair_alloc(client, attr, value[0], T_OP_SET, T_SINGLE_QUOTED_STRING); if (!cp) { LDAP_ERR("Failed allocing pair \"%s\" = \"%s\"", attr, value[0]); return -1; } cf_item_add(client, cf_pairtoitem(cp)); } return 0; }
/* * Function: copy_value * Copy value from a LDAP attribute to $copy * INPUT: * $ld: the connection with the LDAP server * $entry: the entry who contains attributes * $attribut: this attribut * $copy: where data can go * OUTPUT: * void */ static void copy_value(LDAP *ld, LDAPMessage *entry, const char *attribut, char **copy, const char *username) { char ** values; values=ldap_get_values(ld,entry, (char *)attribut); if (values==NULL) { #ifdef HAVE_LDAP_RESULT2ERROR int ld_errno = ldap_result2error(ld,entry,0); if (ld_errno && ld_errno != LDAP_DECODING_ERROR) /* We didn't ask for this attribute */ ldap_perror(ld,"ldap_get_values"); #else if (ld->ld_errno != LDAP_DECODING_ERROR) /* We didn't ask for this attribute */ ldap_perror(ld,"ldap_get_values"); #endif *copy=NULL; return; } /* We accept only attribute with one value */ else if (ldap_count_values(values)>1) { *copy=strdup(values[0]); syslog(LOG_DAEMON, "authldaplib: duplicate attribute %s for %s\n", attribut, username); *copy=NULL; } /* We accept only attribute with one value */ else if (ldap_count_values(values)!=1) { *copy=NULL; } else { *copy=strdup(values[0]); } #if DEBUG_LDAP syslog(LOG_DAEMON|LOG_CRIT,"copy_value %s: %s\n",attribut,values[0]); #endif ldap_value_free(values); }
static int fldap_write(const char* path, const char* data, size_t size, off_t offset, struct fuse_file_info* fi) { static char* attrs[] = {"description", NULL}; LDAPMessage* msg = NULL; LDAPMessage* entry = NULL; BerElement* ber = NULL; char* buf = NULL; char strsize[32]; char* dn; char** vals; char* attr; dn = path_to_dn(path, "cn="); ldap_search_s(ld, dn, LDAP_SCOPE_BASE, "(ObjectClass=*)", attrs, 0, &msg); entry = ldap_first_entry(ld, msg); if (!entry) { ldap_msgfree(msg); free(dn); return -ENOENT; } for (entry = ldap_first_entry(ld, msg); entry != NULL; entry = ldap_next_entry(ld, entry)) { for (attr = ldap_first_attribute(ld, entry, &ber); attr != NULL; attr = ldap_next_attribute(ld, entry, ber)) { if (!strcmp(attr, "description") && ((vals = ldap_get_values(ld, entry, attr)) != NULL)) { buf = calloc(strlen(vals[0]) + size + 1, sizeof(char)); strncpy(buf, vals[0], offset); strncat(buf, data, size); ldap_value_free(vals); } ldap_memfree(attr); } ber_free(ber, 0); } ldap_msgfree(msg); if (!buf) { buf = calloc(size + 1, sizeof(char)); strncpy(buf, data, size); } snprintf(strsize, 32, "%"PRIi32, (int)strlen(buf)); modify_attr(path, LDAP_MOD_REPLACE, "description", buf); modify_attr(path, LDAP_MOD_REPLACE, "stsize", strsize); free(dn); free(buf); return size; }
static krb5_error_code LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, krb5_principal * principal) { krb5_error_code ret; int rc; char **values; LDAPMessage *res = NULL, *e; ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) goto out; rc = ldap_search_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE, "(objectClass=krb5Principal)", krb5principal_attrs, 0, &res); if (check_ldap(context, db, rc)) { krb5_set_error_string(context, "ldap_search_s: %s", ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; goto out; } e = ldap_first_entry(HDB2LDAP(db), res); if (e == NULL) { ret = HDB_ERR_NOENTRY; goto out; } values = ldap_get_values(HDB2LDAP(db), e, "krb5PrincipalName"); if (values == NULL) { ret = HDB_ERR_NOENTRY; goto out; } ret = krb5_parse_name(context, values[0], principal); ldap_value_free(values); out: if (res) ldap_msgfree(res); return ret; }
void AD::GetDN() { LPWSTR filters[2]; LDAPMessage *search; LDAPMessage *entry; PWCHAR attribute; PWCHAR *value; BerElement *berElement; filters[0] = L"rootDomainNamingContext"; filters[1] = NULL; ldap = ldap_init((PWCHAR)host.c_str(), LDAP_PORT); // Null binding; to do that we simply do not call ldap_bind. if(ldap_connect(ldap, NULL) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_connect()"); wprintf(L"Ret = %x\n", LdapGetLastError()); } if(ldap_search_s(ldap, L"", LDAP_SCOPE_BASE, L"(&(objectClass=*))", filters, 0, &search) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_search_s()"); wprintf(L"Ret= %x\n", LdapGetLastError()); } entry = ldap_first_entry(ldap, search); attribute = ldap_first_attribute(ldap, entry, &berElement); if(lstrcmpi(L"rootDomainNamingContext", attribute) == 0) { value = ldap_get_values(ldap, entry, attribute); wprintf(L"value = %s\n", value[0]); dn = value[0]; } else { dn.clear(); } ldap_value_free(value); ldap_memfree(attribute); ldap_msgfree(search); ber_free(berElement, 0); }
static krb5_error_code get_time(LDAP *ld, LDAPMessage *ent, char *attribute, krb5_timestamp *time_out, krb5_boolean *attr_present) { char **values = NULL; krb5_error_code ret = 0; *time_out = 0; *attr_present = FALSE; values = ldap_get_values(ld, ent, attribute); if (values == NULL) return 0; if (values[0] != NULL) { *attr_present = TRUE; ret = getepochtime(values[0], time_out); } ldap_value_free(values); return ret; }
/* Checks the depot status. */ int check_depot_status (LDAP *ldap, char *depotname) { LDAPMessage *entry, *result; char *filter; char **status; int length; length = strlen(depotname) + strlen("depotname=") + 1; filter = (char *) malloc (length); memset(filter, 0, length); sprintf(filter, "depotname=%s", depotname); ldap_search_s (ldap, "ou=depots,o=lbone", LDAP_SCOPE_SUBTREE, filter, NULL, 0, &result); entry = ldap_first_entry (ldap, result); status = ldap_get_values (ldap, entry, "status"); if (strcmp(status[0], DEPOT_IDLE) == 0) return IDLE; if (strcmp(status[0], DEPOT_LOCKED) == 0) return LOCKED; return UNAVAIL; }
ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads) { const char *attrs[] = {"supportedSASLMechanisms", NULL}; char **values; ADS_STATUS status; int i, j; LDAPMessage *res; /* get a list of supported SASL mechanisms */ status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms"); if (ads->auth.flags & ADS_AUTH_SASL_SEAL) { ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; } else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) { ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; } else { ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; } /* try our supported mechanisms in order */ for (i=0;sasl_mechanisms[i].name;i++) { /* see if the server supports it */ for (j=0;values && values[j];j++) { if (strcmp(values[j], sasl_mechanisms[i].name) == 0) { DEBUG(4,("Found SASL mechanism %s\n", values[j])); status = sasl_mechanisms[i].fn(ads); ldap_value_free(values); ldap_msgfree(res); return status; } } } ldap_value_free(values); ldap_msgfree(res); return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED); }
char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, const char *attribute, TALLOC_CTX *mem_ctx) { char **values; char *result; if (attribute == NULL) { return NULL; } values = ldap_get_values(ldap_struct, entry, attribute); if (values == NULL) { DEBUG(10, ("attribute %s does not exist\n", attribute)); return NULL; } if (ldap_count_values(values) != 1) { DEBUG(10, ("attribute %s has %d values, expected only one\n", attribute, ldap_count_values(values))); ldap_value_free(values); return NULL; } if (pull_utf8_talloc(mem_ctx, &result, values[0]) == (size_t)-1) { DEBUG(10, ("pull_utf8_talloc failed\n")); ldap_value_free(values); return NULL; } ldap_value_free(values); #ifdef DEBUG_PASSWORDS DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, result)); #endif return result; }
char *ldap_search(char *searchstring, char returnattribute[]){ char **value = 0; char *attribute = (char *) malloc(32 * sizeof(char)); LDAPMessage *entry; LDAPMessage *res; BerElement *berptr; ldap_init(); if(ldap_search_ext_s(ld,LDAP_BASE,LDAP_SCOPE_ONELEVEL,searchstring,NULL,0,NULL,NULL,NULL,LDAP_NO_LIMIT,&res) != LDAP_SUCCESS) { printf("LDAP search faild: %s\n", searchstring); return "failed"; } entry = ldap_first_entry(ld,res); if(entry == NULL) { printf("Could not find first entry\n"); return "failed"; } for(attribute = ldap_first_attribute(ld,entry,&berptr);strcmp(returnattribute,attribute);attribute = ldap_next_attribute(ld,entry,berptr)) { if(!attribute){ printf("Could not find first attribute for: %s\n",entry); return "failed"; } } value = ldap_get_values(ld,entry,attribute); if(value == NULL) { printf("Value returnd NULL\n"); return "failed"; } printf("%s\r\n",value[0]); free(attribute); return value[0]; }
static idmap_stat extract_attribute(idmap_nm_handle_t *p, LDAPMessage *entry, char *name, char **value) { char **values = NULL; idmap_stat rc = IDMAP_SUCCESS; /* No value means it is not requested */ if (value == NULL) return (IDMAP_SUCCESS); values = ldap_get_values(p->ad, entry, name); if (values == NULL || values[0] == NULL) *value = NULL; else { *value = strdup(values[0]); if (*value == NULL) rc = IDMAP_ERR_MEMORY; } errout: ldap_value_free(values); return (rc); }
static krb5_error_code LDAP_get_string_value(HDB * db, LDAPMessage * entry, const char *attribute, char **ptr) { char **vals; int ret; vals = ldap_get_values(HDB2LDAP(db), entry, (char *) attribute); if (vals == NULL) { *ptr = NULL; return HDB_ERR_NOENTRY; } *ptr = strdup(vals[0]); if (*ptr == NULL) ret = ENOMEM; else ret = 0; ldap_value_free(vals); return ret; }
/* Return the first string value of attribute in ent. */ krb5_error_code krb5_ldap_get_string(LDAP *ld, LDAPMessage *ent, char *attribute, char **str_out, krb5_boolean *attr_present) { char **values; krb5_error_code ret = 0; *str_out = NULL; if (attr_present != NULL) *attr_present = FALSE; values = ldap_get_values(ld, ent, attribute); if (values == NULL) return 0; if (values[0] != NULL) { if (attr_present != NULL) *attr_present = TRUE; *str_out = strdup(values[0]); if (*str_out == NULL) ret = ENOMEM; } ldap_value_free(values); return ret; }
/* Get any auth indicator values from LDAP and update the "require_auth" * string. */ static krb5_error_code get_ldap_auth_ind(krb5_context context, LDAP *ld, LDAPMessage *ldap_ent, krb5_db_entry *entry, unsigned int *mask) { krb5_error_code ret; int i; char **auth_inds = NULL; struct k5buf buf = EMPTY_K5BUF; auth_inds = ldap_get_values(ld, ldap_ent, "krbPrincipalAuthInd"); if (auth_inds == NULL) return 0; k5_buf_init_dynamic(&buf); /* Make a space seperated list of indicators. */ for (i = 0; auth_inds[i] != NULL; i++) { k5_buf_add(&buf, auth_inds[i]); if (auth_inds[i + 1] != NULL) k5_buf_add(&buf, " "); } ret = k5_buf_status(&buf); if (ret) goto cleanup; ret = krb5_dbe_set_string(context, entry, KRB5_KDB_SK_REQUIRE_AUTH, buf.data); if (!ret) *mask |= KDB_AUTH_IND_ATTR; cleanup: k5_buf_free(&buf); ldap_value_free(auth_inds); return ret; }
/** Check if user is authorized for remote access * */ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request) { rlm_rcode_t rcode = RLM_MODULE_OK; ldap_rcode_t status; int ldap_errno; int i; ldap_instance_t *inst = instance; char **vals; VALUE_PAIR *vp; ldap_handle_t *conn; LDAPMessage *result, *entry; char const *dn = NULL; rlm_ldap_map_xlat_t expanded; /* faster than mallocing every time */ if (!request->username) { RDEBUG2("Attribute \"User-Name\" is required for authorization"); return RLM_MODULE_NOOP; } /* * Check for valid input, zero length names not permitted */ if (request->username->length == 0) { RDEBUG2("Zero length username not permitted"); return RLM_MODULE_INVALID; } if (rlm_ldap_map_xlat(request, inst->user_map, &expanded) < 0) { return RLM_MODULE_FAIL; } conn = rlm_ldap_get_socket(inst, request); if (!conn) return RLM_MODULE_FAIL; /* * Add any additional attributes we need for checking access, memberships, and profiles */ if (inst->userobj_access_attr) { expanded.attrs[expanded.count++] = inst->userobj_access_attr; } if (inst->userobj_membership_attr && (inst->cacheable_group_dn || inst->cacheable_group_name)) { expanded.attrs[expanded.count++] = inst->userobj_membership_attr; } if (inst->profile_attr) { expanded.attrs[expanded.count++] = inst->profile_attr; } if (inst->valuepair_attr) { expanded.attrs[expanded.count++] = inst->valuepair_attr; } expanded.attrs[expanded.count] = NULL; dn = rlm_ldap_find_user(inst, request, &conn, expanded.attrs, true, &result, &rcode); if (!dn) { goto finish; } entry = ldap_first_entry(conn->handle, result); if (!entry) { ldap_get_option(conn->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); goto finish; } /* * Check for access. */ if (inst->userobj_access_attr) { rcode = rlm_ldap_check_access(inst, request, conn, entry); if (rcode != RLM_MODULE_OK) { goto finish; } } /* * Check if we need to cache group memberships */ if (inst->cacheable_group_dn || inst->cacheable_group_name) { if (inst->userobj_membership_attr) { rcode = rlm_ldap_cacheable_userobj(inst, request, &conn, entry, inst->userobj_membership_attr); if (rcode != RLM_MODULE_OK) { goto finish; } } rcode = rlm_ldap_cacheable_groupobj(inst, request, &conn); if (rcode != RLM_MODULE_OK) { goto finish; } } #ifdef WITH_EDIR /* * We already have a Cleartext-Password. Skip edir. */ if (pairfind(request->config_items, PW_CLEARTEXT_PASSWORD, 0, TAG_ANY)) { goto skip_edir; } /* * Retrieve Universal Password if we use eDirectory */ if (inst->edir) { int res = 0; char password[256]; size_t pass_size = sizeof(password); /* * Retrive universal password */ res = nmasldap_get_password(conn->handle, dn, password, &pass_size); if (res != 0) { REDEBUG("Failed to retrieve eDirectory password: (%i) %s", res, edir_errstr(res)); rcode = RLM_MODULE_FAIL; goto finish; } /* * Add Cleartext-Password attribute to the request */ vp = radius_paircreate(request, &request->config_items, PW_CLEARTEXT_PASSWORD, 0); pairstrcpy(vp, password); vp->length = pass_size; RDEBUG2("Added eDirectory password in check items as %s = %s", vp->da->name, vp->vp_strvalue); if (inst->edir_autz) { RDEBUG2("Binding as user for eDirectory authorization checks"); /* * Bind as the user */ conn->rebound = true; status = rlm_ldap_bind(inst, request, &conn, dn, vp->vp_strvalue, true); switch (status) { case LDAP_PROC_SUCCESS: rcode = RLM_MODULE_OK; RDEBUG("Bind as user \"%s\" was successful", dn); break; case LDAP_PROC_NOT_PERMITTED: rcode = RLM_MODULE_USERLOCK; goto finish; case LDAP_PROC_REJECT: rcode = RLM_MODULE_REJECT; goto finish; case LDAP_PROC_BAD_DN: rcode = RLM_MODULE_INVALID; goto finish; case LDAP_PROC_NO_RESULT: rcode = RLM_MODULE_NOTFOUND; goto finish; default: rcode = RLM_MODULE_FAIL; goto finish; }; } } skip_edir: #endif /* * Apply ONE user profile, or a default user profile. */ if (inst->default_profile) { char profile[1024]; if (radius_xlat(profile, sizeof(profile), request, inst->default_profile, NULL, NULL) < 0) { REDEBUG("Failed creating default profile string"); rcode = RLM_MODULE_INVALID; goto finish; } rlm_ldap_map_profile(inst, request, &conn, profile, &expanded); } /* * Apply a SET of user profiles. */ if (inst->profile_attr) { vals = ldap_get_values(conn->handle, entry, inst->profile_attr); if (vals != NULL) { for (i = 0; vals[i] != NULL; i++) { rlm_ldap_map_profile(inst, request, &conn, vals[i], &expanded); } ldap_value_free(vals); } } if (inst->user_map || inst->valuepair_attr) { RDEBUG("Processing user attributes"); rlm_ldap_map_do(inst, request, conn->handle, &expanded, entry); rlm_ldap_check_reply(inst, request); } finish: rlm_ldap_map_xlat_free(&expanded); if (result) { ldap_msgfree(result); } rlm_ldap_release_socket(inst, conn); return rcode; }
/* * Fill out a krb5_db_entry princ entry struct given a LDAP message containing * the results of a principal search of the directory. */ krb5_error_code populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context, LDAP *ld, LDAPMessage *ent, krb5_const_principal princ, krb5_db_entry *entry) { krb5_error_code ret; unsigned int mask = 0; int val, i, pcount, objtype; krb5_boolean attr_present; krb5_kvno mkvno = 0; krb5_timestamp lastpwdchange, unlock_time; char *policydn = NULL, *pwdpolicydn = NULL, *polname = NULL, *user = NULL; char *tktpolname = NULL, *dn = NULL, **link_references = NULL; char **pnvalues = NULL, **ocvalues = NULL, **a2d2 = NULL; struct berval **ber_key_data = NULL, **ber_tl_data = NULL; krb5_tl_data userinfo_tl_data = { NULL }, **endp, *tl; osa_princ_ent_rec princ_ent; memset(&princ_ent, 0, sizeof(princ_ent)); ret = krb5_copy_principal(context, princ, &entry->princ); if (ret) goto cleanup; /* get the associated directory user information */ pnvalues = ldap_get_values(ld, ent, "krbprincipalname"); if (pnvalues != NULL) { ret = krb5_unparse_name(context, princ, &user); if (ret) goto cleanup; pcount = 0; for (i = 0; pnvalues[i] != NULL; i++) { if (strcasecmp(pnvalues[i], user) == 0) { pcount = ldap_count_values(pnvalues); break; } } dn = ldap_get_dn(ld, ent); if (dn == NULL) { ldap_get_option(ld, LDAP_OPT_RESULT_CODE, &ret); ret = set_ldap_error(context, ret, 0); goto cleanup; } ocvalues = ldap_get_values(ld, ent, "objectclass"); if (ocvalues != NULL) { for (i = 0; ocvalues[i] != NULL; i++) { if (strcasecmp(ocvalues[i], "krbprincipal") == 0) { objtype = KDB_STANDALONE_PRINCIPAL_OBJECT; ret = store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE, &objtype); if (ret) goto cleanup; break; } } } /* Add principalcount, DN and principaltype user information to * tl_data */ ret = store_tl_data(&userinfo_tl_data, KDB_TL_PRINCCOUNT, &pcount); if (ret) goto cleanup; ret = store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, dn); if (ret) goto cleanup; } ret = get_time(ld, ent, "krbLastSuccessfulAuth", &entry->last_success, &attr_present); if (ret) goto cleanup; if (attr_present) mask |= KDB_LAST_SUCCESS_ATTR; ret = get_time(ld, ent, "krbLastFailedAuth", &entry->last_failed, &attr_present); if (ret) goto cleanup; if (attr_present) mask |= KDB_LAST_FAILED_ATTR; if (krb5_ldap_get_value(ld, ent, "krbLoginFailedCount", &val) == 0) { entry->fail_auth_count = val; mask |= KDB_FAIL_AUTH_COUNT_ATTR; } if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", &val) == 0) { entry->max_life = val; mask |= KDB_MAX_LIFE_ATTR; } if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", &val) == 0) { entry->max_renewable_life = val; mask |= KDB_MAX_RLIFE_ATTR; } if (krb5_ldap_get_value(ld, ent, "krbticketflags", &val) == 0) { entry->attributes = val; mask |= KDB_TKT_FLAGS_ATTR; } ret = get_time(ld, ent, "krbprincipalexpiration", &entry->expiration, &attr_present); if (ret) goto cleanup; if (attr_present) mask |= KDB_PRINC_EXPIRE_TIME_ATTR; ret = get_time(ld, ent, "krbpasswordexpiration", &entry->pw_expiration, &attr_present); if (ret) goto cleanup; if (attr_present) mask |= KDB_PWD_EXPIRE_TIME_ATTR; ret = krb5_ldap_get_string(ld, ent, "krbticketpolicyreference", &policydn, &attr_present); if (ret) goto cleanup; if (attr_present) { mask |= KDB_POL_REF_ATTR; /* Ensure that the policy is inside the realm container. */ ret = krb5_ldap_policydn_to_name(context, policydn, &tktpolname); if (ret) goto cleanup; } ret = krb5_ldap_get_string(ld, ent, "krbpwdpolicyreference", &pwdpolicydn, &attr_present); if (ret) goto cleanup; if (attr_present) { mask |= KDB_PWD_POL_REF_ATTR; /* Ensure that the policy is inside the realm container. */ ret = krb5_ldap_policydn_to_name(context, pwdpolicydn, &polname); if (ret) goto cleanup; princ_ent.policy = polname; princ_ent.aux_attributes |= KADM5_POLICY; } ber_key_data = ldap_get_values_len(ld, ent, "krbpwdhistory"); if (ber_key_data != NULL) { mask |= KDB_PWD_HISTORY_ATTR; ret = krb5_decode_histkey(context, ber_key_data, &princ_ent); if (ret) goto cleanup; ldap_value_free_len(ber_key_data); } if (princ_ent.aux_attributes) { ret = krb5_update_tl_kadm_data(context, entry, &princ_ent); if (ret) goto cleanup; } ber_key_data = ldap_get_values_len(ld, ent, "krbprincipalkey"); if (ber_key_data != NULL) { mask |= KDB_SECRET_KEY_ATTR; ret = krb5_decode_krbsecretkey(context, entry, ber_key_data, &mkvno); if (ret) goto cleanup; if (mkvno != 0) { ret = krb5_dbe_update_mkvno(context, entry, mkvno); if (ret) goto cleanup; } } ret = get_time(ld, ent, "krbLastPwdChange", &lastpwdchange, &attr_present); if (ret) goto cleanup; if (attr_present) { ret = krb5_dbe_update_last_pwd_change(context, entry, lastpwdchange); if (ret) goto cleanup; mask |= KDB_LAST_PWD_CHANGE_ATTR; } ret = get_time(ld, ent, "krbLastAdminUnlock", &unlock_time, &attr_present); if (ret) goto cleanup; if (attr_present) { ret = krb5_dbe_update_last_admin_unlock(context, entry, unlock_time); if (ret) goto cleanup; mask |= KDB_LAST_ADMIN_UNLOCK_ATTR; } a2d2 = ldap_get_values(ld, ent, "krbAllowedToDelegateTo"); if (a2d2 != NULL) { for (endp = &entry->tl_data; *endp; endp = &(*endp)->tl_data_next); for (i = 0; a2d2[i] != NULL; i++) { tl = k5alloc(sizeof(*tl), &ret); if (tl == NULL) goto cleanup; tl->tl_data_type = KRB5_TL_CONSTRAINED_DELEGATION_ACL; tl->tl_data_length = strlen(a2d2[i]); tl->tl_data_contents = (unsigned char *)strdup(a2d2[i]); if (tl->tl_data_contents == NULL) { ret = ENOMEM; free(tl); goto cleanup; } tl->tl_data_next = NULL; *endp = tl; endp = &tl->tl_data_next; } } link_references = ldap_get_values(ld, ent, "krbobjectreferences"); if (link_references != NULL) { for (i = 0; link_references[i] != NULL; i++) { ret = store_tl_data(&userinfo_tl_data, KDB_TL_LINKDN, link_references[i]); if (ret) goto cleanup; } } ber_tl_data = ldap_get_values_len(ld, ent, "krbExtraData"); if (ber_tl_data != NULL) { for (i = 0; ber_tl_data[i] != NULL; i++) { ret = berval2tl_data(ber_tl_data[i], &tl); if (ret) goto cleanup; ret = krb5_dbe_update_tl_data(context, entry, tl); free(tl->tl_data_contents); free(tl); if (ret) goto cleanup; } mask |= KDB_EXTRA_DATA_ATTR; } /* Auth indicators from krbPrincipalAuthInd will replace those from * krbExtraData. */ ret = get_ldap_auth_ind(context, ld, ent, entry, &mask); if (ret) goto cleanup; /* Update the mask of attributes present on the directory object to the * tl_data. */ ret = store_tl_data(&userinfo_tl_data, KDB_TL_MASK, &mask); if (ret) goto cleanup; ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data); if (ret) goto cleanup; ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); if (ret) goto cleanup; /* For compatibility with DB2 principals. */ entry->len = KRB5_KDB_V1_BASE_LENGTH; cleanup: ldap_memfree(dn); ldap_value_free_len(ber_key_data); ldap_value_free_len(ber_tl_data); ldap_value_free(pnvalues); ldap_value_free(ocvalues); ldap_value_free(link_references); ldap_value_free(a2d2); free(userinfo_tl_data.tl_data_contents); free(pwdpolicydn); free(polname); free(tktpolname); free(policydn); krb5_free_unparsed_name(context, user); free_princ_ent_contents(&princ_ent); return ret; }
int ldap_sort_entries( LDAP *ld, LDAPMessage **chain, LDAP_CONST char *attr, /* NULL => sort by DN */ int (*cmp) (LDAP_CONST char *, LDAP_CONST char *) ) { int i, count = 0; struct entrything *et; LDAPMessage *e, *ehead = NULL, *etail = NULL; LDAPMessage *ohead = NULL, *otail = NULL; LDAPMessage **ep; assert( ld != NULL ); /* Separate entries from non-entries */ for ( e = *chain; e; e=e->lm_chain ) { if ( e->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) { count++; if ( !ehead ) ehead = e; if ( etail ) etail->lm_chain = e; etail = e; } else { if ( !ohead ) ohead = e; if ( otail ) otail->lm_chain = e; otail = e; } } if ( count < 2 ) { /* zero or one entries -- already sorted! */ if ( ehead ) { etail->lm_chain = ohead; *chain = ehead; } else { *chain = ohead; } return 0; } if ( (et = (struct entrything *) LDAP_MALLOC( count * sizeof(struct entrything) )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( -1 ); } e = ehead; for ( i = 0; i < count; i++ ) { et[i].et_cmp_fn = cmp; et[i].et_msg = e; if ( attr == NULL ) { char *dn; dn = ldap_get_dn( ld, e ); et[i].et_vals = ldap_explode_dn( dn, 1 ); LDAP_FREE( dn ); } else { et[i].et_vals = ldap_get_values( ld, e, attr ); } e = e->lm_chain; } qsort( et, count, sizeof(struct entrything), et_cmp ); ep = chain; for ( i = 0; i < count; i++ ) { *ep = et[i].et_msg; ep = &(*ep)->lm_chain; LDAP_VFREE( et[i].et_vals ); } *ep = ohead; (*chain)->lm_chain_tail = otail ? otail : etail; LDAP_FREE( (char *) et ); return( 0 ); }
char * abook_ldap_search(abook_ldap_state *ldap_state) { int rc, count; LDAP *ld; int msgid; LDAPMessage *result, *entry; char *dn; static char alias[1024]; char **values; struct ldap_config* ldapconfig; if (ldap_state->prevresult == NULL) { /* prevresult is set to NULL when the prior call to ldap_result * indicated that the search ended successfully. */ return NULL; } else { ld = ldap_state->ld; msgid = ldap_state->msgid; result = ldap_state->prevresult; ldapconfig = ldap_state->ldapconfig; /* Find the full name associated with this matching entry so we * can return a pointer to it. */ entry = ldap_first_entry(ld, result); if (entry == NULL) { syslog(LOG_ERR, "abook_ldap_search: ldap_first_entry failed"); return NULL; } values = ldap_get_values(ld, entry, ldapconfig->fullnameattr); if (values == NULL || values[0] == NULL) { syslog(LOG_ERR, "abook_ldap_search: ldap_get_values (%s) failed", ldapconfig->fullnameattr); return NULL; } strlcpy(alias, values[0], sizeof(alias)); ldap_value_free(values); values = ldap_get_values(ld, entry, ldapconfig->uniqueattr); if (values == NULL || values[0] == NULL) { syslog(LOG_ERR, "abook_ldap_search: ldap_get_values (%s) failed", ldapconfig->uniqueattr); syslog(LOG_ERR, "abook_ldap_search: previous value (%s) was %s", ldapconfig->fullnameattr, alias); return NULL; } /* always uniqify the fullname, even if we don't have to */ strlcat(alias, "[", sizeof(alias)); strlcat(alias, ldapconfig->uniqueattr, sizeof(alias)); strlcat(alias, ":", sizeof(alias)); strlcat(alias, values[0], sizeof(alias)); strlcat(alias, "]", sizeof(alias)); ldap_value_free(values); #if 0 count = count_identical_fullnames(ldap_state, alias); if (count > 1) { /* Find the uid for this entry */ values = ldap_get_values(ld, entry, ldapconfig->uniqueattr); if (values == NULL || values[0] == NULL) { syslog(LOG_ERR, "abook_ldap_search: ldap_get_values failed for attr '%s'", ldapconfig->uniqueattr); return NULL; } strlcat(alias, "[", sizeof(alias)); strlcat(alias, ldapconfig->uniqueattr, sizeof(alias)); strlcat(alias, ":", sizeof(alias)); strlcat(alias, values[0], sizeof(alias)); strlcat(alias, "]", sizeof(alias)); ldap_value_free(values); } #endif ldap_msgfree(result); /* Now fetch the next result to get ready for the next iteration * of this function. */ rc = ldap_result(ld, msgid, 0, NULL, &result); switch (rc) { case LDAP_RES_SEARCH_ENTRY: ldap_state->prevresult = result; break; case LDAP_RES_SEARCH_RESULT: rc = ldap_result2error(ld, result, 1 /* free result */); /* This result had no entries, but indicated success or failure. * Return the alias corresponding to the previous entry, * but set "prevresult" to NULL to indicate to the next * iteration that searching is completed. */ if (rc != LDAP_SUCCESS) { syslog(LOG_ERR,"abook_ldap_search: search completed with" " error: %s", ldap_err2string(rc)); } ldap_state->prevresult = NULL; break; default: syslog(LOG_ERR, "abook_ldap_search: ldap_result failed: 3: %s", ldap_err2string(rc)); (void) ldap_msgfree(result); /* ignore message type return value */ ldap_state->prevresult = NULL; } return alias; } }
void AD::AddUsers(LDAPMessage *search) { DWORD i; DWORD j; LDAPMessage *entry = NULL; PWCHAR attribute; PWCHAR *values; BerElement *berElement; for(i = 0; i < ldap_count_entries(ldap, search); i++) { User *u = new User(); if(!i) { entry = ldap_first_entry(ldap, search); } else { entry = ldap_next_entry(ldap, entry); } attribute = ldap_first_attribute(ldap, entry, &berElement); while(attribute != NULL) { //wprintf(L"%s: ", attribute); values = ldap_get_values(ldap, entry, attribute); u->sidString = L"N/A"; u->lastLogin = 0; u->lastLogout = 0; if(lstrcmpi(attribute, L"samaccountname") == 0) { u->accountName.append(values[0]); } if(lstrcmpi(attribute, L"cn") == 0) { u->fullName.append(values[0]); } if(lstrcmpi(attribute, L"homedirectory") == 0) { u->homePath.append(values[0]); } if(lstrcmpi(attribute, L"memberof") == 0) { for(j = 0; j < ldap_count_values(values); j++) { std::wstring groupString = values[j]; // The 3 offset from left makes sense (to cull out the CN=) // but I'm not quite sure whey I need to find()-3. Here's // hoping that doesn't break when tested out in the world. std::wstring subString = groupString.substr(3, groupString.find(L",")-3); std::wstring *testString = new std::wstring(subString); if(subString.length() > 0) { u->groups.push_back(new std::wstring(subString)); } } } ldap_value_free(values); ldap_memfree(attribute); attribute = ldap_next_attribute(ldap, entry, berElement); } ber_free(berElement, 0); // Moment of truth; we only want accounts with account names. if(u->accountName.length() > 0) { GetUserManager()->users.push_back(u); u->PrettyPrint(); } else { delete(u); } } }
/* * Map key -> value resolution * NOTE: these are old-fashion maps; new maps will be parsed on separate * config lines, and referred by name. */ int rewrite_xmap_apply( struct rewrite_info *info, struct rewrite_op *op, struct rewrite_map *map, struct berval *key, struct berval *val ) { int rc = REWRITE_SUCCESS; assert( info != NULL ); assert( op != NULL ); assert( map != NULL ); assert( key != NULL ); assert( val != NULL ); val->bv_val = NULL; val->bv_len = 0; switch ( map->lm_type ) { #ifdef HAVE_GETPWNAM case REWRITE_MAP_XPWDMAP: { struct passwd *pwd; #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_lock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ pwd = getpwnam( key->bv_val ); if ( pwd == NULL ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = LDAP_NO_SUCH_OBJECT; break; } #ifdef HAVE_STRUCT_PASSWD_PW_GECOS if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) { int l = strlen( pwd->pw_gecos ); val->bv_val = strdup( pwd->pw_gecos ); val->bv_len = l; } else #endif /* HAVE_STRUCT_PASSWD_PW_GECOS */ { val->bv_val = strdup( key->bv_val ); val->bv_len = key->bv_len; } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ if ( val->bv_val == NULL ) { rc = REWRITE_ERR; } break; } #endif /* HAVE_GETPWNAM*/ case REWRITE_MAP_XFILEMAP: { char buf[1024]; if ( map->lm_args == NULL ) { rc = REWRITE_ERR; break; } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_lock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rewind( ( FILE * )map->lm_args ); while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) { char *p; int blen; blen = strlen( buf ); if ( buf[ blen - 1 ] == '\n' ) { buf[ blen - 1 ] = '\0'; } p = strtok( buf, " " ); if ( p == NULL ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = REWRITE_ERR; goto rc_return; } if ( strcasecmp( p, key->bv_val ) == 0 && ( p = strtok( NULL, "" ) ) ) { val->bv_val = strdup( p ); if ( val->bv_val == NULL ) { return REWRITE_ERR; } val->bv_len = strlen( p ); #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ goto rc_return; } } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = REWRITE_ERR; break; } case REWRITE_MAP_XLDAPMAP: { LDAP *ld; char filter[1024]; LDAPMessage *res = NULL, *entry; LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args; int attrsonly = 0; char **values; assert( lud != NULL ); /* * No mutex because there is no write on the map data */ ld = ldap_init( lud->lud_host, lud->lud_port ); if ( ld == NULL ) { rc = REWRITE_ERR; goto rc_return; } snprintf( filter, sizeof( filter ), lud->lud_filter, key->bv_val ); if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) { attrsonly = 1; } rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, filter, lud->lud_attrs, attrsonly, &res ); if ( rc != LDAP_SUCCESS ) { ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } if ( ldap_count_entries( ld, res ) != 1 ) { ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } entry = ldap_first_entry( ld, res ); if ( entry == NULL ) { ldap_msgfree( res ); ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } if ( attrsonly == 1 ) { val->bv_val = ldap_get_dn( ld, entry ); } else { values = ldap_get_values( ld, entry, lud->lud_attrs[0] ); if ( values != NULL ) { val->bv_val = strdup( values[ 0 ] ); ldap_value_free( values ); } } ldap_msgfree( res ); ldap_unbind( ld ); if ( val->bv_val == NULL ) { rc = REWRITE_ERR; goto rc_return; } val->bv_len = strlen( val->bv_val ); rc = REWRITE_SUCCESS; } break; } rc_return:; return rc; }
/** Load clients from LDAP on server start * * @param[in] inst rlm_ldap configuration. * @return -1 on error else 0. */ int rlm_ldap_load_clients(ldap_instance_t const *inst) { int ret = 0; ldap_rcode_t status; ldap_handle_t *conn = NULL; /* This needs to be updated if additional attributes need to be retrieved */ char const *attrs[7]; char const **attrs_p; LDAPMessage *result = NULL; LDAPMessage *entry; RADCLIENT *c; LDAP_DBG("Loading dynamic clients"); /* * Basic sanity checks. */ if (!inst->clientobj_identifier) { LDAP_ERR("Told to load clients but 'client.identifier_attribute' not specified"); return -1; } if (!inst->clientobj_secret) { LDAP_ERR("Told to load clients but 'client.secret_attribute' not specified"); return -1; } if (!inst->clientobj_base_dn) { LDAP_ERR("Told to load clients but 'client.base_dn' not specified"); return -1; } if (!inst->clientobj_filter) { LDAP_ERR("Told to load clients but 'client.filter' not specified"); return -1; } /* * Construct the attribute array */ attrs[0] = inst->clientobj_identifier; attrs[1] = inst->clientobj_secret; attrs_p = attrs + 2; if (inst->clientobj_shortname) { /* 2 */ *attrs_p++ = inst->clientobj_shortname; } if (inst->clientobj_type) { /* 3 */ *attrs_p++ = inst->clientobj_type; } if (inst->clientobj_server) { /* 4 */ *attrs_p++ = inst->clientobj_server; } if (inst->clientobj_require_ma) { /* 5 */ *attrs_p++ = inst->clientobj_require_ma; } *attrs_p = NULL; /* 6 - array needs to be NULL terminated */ conn = rlm_ldap_get_socket(inst, NULL); if (!conn) return -1; /* * Perform all searches as the admin user. */ if (conn->rebound) { status = rlm_ldap_bind(inst, NULL, &conn, inst->admin_dn, inst->password, true); if (status != LDAP_PROC_SUCCESS) { return -1; } rad_assert(conn); conn->rebound = false; } status = rlm_ldap_search(inst, NULL, &conn, inst->clientobj_base_dn, inst->clientobj_scope, inst->clientobj_filter, attrs, &result); switch (status) { case LDAP_PROC_SUCCESS: break; case LDAP_PROC_NO_RESULT: LDAP_INFO("No clients were found in the directory"); return 0; default: return -1; } rad_assert(conn); entry = ldap_first_entry(conn->handle, result); if (!entry) { int ldap_errno; ldap_get_option(conn->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); LDAP_ERR("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); ret = -1; goto finish; } do { char *dn; char **identifier = NULL; char **shortname = NULL; char **secret = NULL; char **type = NULL; char **server = NULL; char **require_ma = NULL; dn = ldap_get_dn(conn->handle, entry); /* * Check for the required attributes first */ identifier = ldap_get_values(conn->handle, entry, inst->clientobj_identifier); if (!identifier) { LDAP_WARN("Client \"%s\" missing required attribute 'identifier', skipping...", dn); goto next; } secret = ldap_get_values(conn->handle, entry, inst->clientobj_secret); if (!secret) { LDAP_WARN("Client \"%s\" missing required attribute 'secret', skipping...", dn); goto next; } if (inst->clientobj_shortname) { shortname = ldap_get_values(conn->handle, entry, inst->clientobj_shortname); if (!shortname) { LDAP_DBG("Client \"%s\" missing optional attribute 'shortname'", dn); } } if (inst->clientobj_type) { type = ldap_get_values(conn->handle, entry, inst->clientobj_type); if (!type) { LDAP_DBG("Client \"%s\" missing optional attribute 'type'", dn); } } if (inst->clientobj_server) { server = ldap_get_values(conn->handle, entry, inst->clientobj_server); if (!server) { LDAP_DBG("Client \"%s\" missing optional attribute 'server'", dn); } } if (inst->clientobj_require_ma) { require_ma = ldap_get_values(conn->handle, entry, inst->clientobj_require_ma); if (!require_ma) { LDAP_DBG("Client \"%s\" missing optional attribute 'require_ma'", dn); } } /* FIXME: We should really pass a proper ctx */ c = client_from_query(NULL, identifier[0], secret[0], shortname ? shortname[0] : NULL, type ? type[0] : NULL, server ? server[0] : NULL, require_ma ? strncmp(require_ma[0], "true", 4) == 0 : false); if (!c) { goto next; } if (!client_add(NULL, c)) { WARN("Failed to add client, possible duplicate?"); client_free(c); goto next; } LDAP_DBG("Client \"%s\" added", dn); next: ldap_memfree(dn); if (identifier) ldap_value_free(identifier); if (shortname) ldap_value_free(shortname); if (secret) ldap_value_free(secret); if (type) ldap_value_free(type); if (server) ldap_value_free(server); } while((entry = ldap_next_entry(conn->handle, entry))); finish: if (result) { ldap_msgfree(result); } return ret; }
static switch_status_t xml_ldap_directory_result(void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off) { struct ldap_c *ldap = ldap_connection; switch_xml_t asdf = *xml; switch_xml_t param, variable, params = NULL, variables = NULL; int i = 0; int loff = *off; for (ldap->entry = ldap_first_entry(ldap->ld, ldap->msg); ldap->entry != NULL; ldap->entry = ldap_next_entry(ldap->ld, ldap->entry)) { ldap->key = ldap_first_attribute(ldap->ld, ldap->entry, &ldap->berkey); do { ldap->val = ldap_first_attribute(ldap->ld, ldap->entry, &ldap->berval); do { if (strstr(ldap->val, "value")) { if (strstr(ldap->val, ldap->key) && strcmp(ldap->val, ldap->key)) { if (!strcmp(ldap->key, "param")) { params = switch_xml_add_child_d(asdf, "params", loff++); } else if (!strcmp(ldap->key, "variable")) { variables = switch_xml_add_child_d(asdf, "variables", loff++); } ldap->keyvals = ldap_get_values(ldap->ld, ldap->entry, ldap->key); ldap->valvals = ldap_get_values(ldap->ld, ldap->entry, ldap->val); if (ldap->keyvals && ldap->valvals) { if (ldap_count_values(ldap->valvals) == ldap_count_values(ldap->keyvals)) { for (i = 0; ldap->keyvals[i] != NULL && ldap->valvals[i] != NULL; i++) { if (!strcmp(ldap->key, "param")) { param = switch_xml_add_child_d(params, "param", loff++); switch_xml_set_attr_d(param, "name", ldap->keyvals[i]); switch_xml_set_attr_d(param, "value", ldap->valvals[i]); } else if (!strcmp(ldap->key, "variable")) { variable = switch_xml_add_child_d(variables, "variable", loff++); switch_xml_set_attr_d(variable, "name", ldap->keyvals[i]); switch_xml_set_attr_d(variable, "value", ldap->valvals[i]); } } if (ldap->keyvals) { ldap_value_free(ldap->keyvals); } if (ldap->valvals) { ldap_value_free(ldap->valvals); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Seems the values %d and %d are not the same??\n", ldap_count_values(ldap->valvals), ldap_count_values(ldap->keyvals)); } } } } if (ldap->val) { ldap_memfree(ldap->val); } ldap->val = ldap_next_attribute(ldap->ld, ldap->entry, ldap->berval); } while (ldap->val != NULL); if (ldap->key) { ldap_memfree(ldap->key); } if (ldap->berval) { ber_free(ldap->berval, 0); } ldap->key = ldap_next_attribute(ldap->ld, ldap->entry, ldap->berkey); } while (ldap->key != NULL); if (ldap->berkey) { ber_free(ldap->berkey, 0); } } return SWITCH_STATUS_SUCCESS; }
// wrapper for ldap_get_values() // NS_IMETHODIMP nsLDAPMessage::GetValues(const char *aAttr, PRUint32 *aCount, PRUnichar ***aValues) { char **values; #if defined(DEBUG) // We only want this being logged for debug builds so as not to affect performance too much. PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("nsLDAPMessage::GetValues(): called with aAttr = '%s'", aAttr)); #endif values = ldap_get_values(mConnectionHandle, mMsgHandle, aAttr); // bail out if there was a problem // if (!values) { PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0); if ( lderrno == LDAP_DECODING_ERROR ) { // this may not be an error; it could just be that the // caller has asked for an attribute that doesn't exist. // PR_LOG(gLDAPLogModule, PR_LOG_WARNING, ("nsLDAPMessage::GetValues(): ldap_get_values returned " "LDAP_DECODING_ERROR")); return NS_ERROR_LDAP_DECODING_ERROR; } else if ( lderrno == LDAP_PARAM_ERROR ) { NS_ERROR("nsLDAPMessage::GetValues(): internal error: 1"); return NS_ERROR_UNEXPECTED; } else { NS_ERROR("nsLDAPMessage::GetValues(): internal error: 2"); return NS_ERROR_UNEXPECTED; } } // count the values // PRUint32 numVals = ldap_count_values(values); // create an array of the appropriate size // *aValues = static_cast<PRUnichar **>(nsMemory::Alloc(numVals * sizeof(PRUnichar *))); if (!*aValues) { ldap_value_free(values); return NS_ERROR_OUT_OF_MEMORY; } // clone the array (except for the trailing NULL entry) using the // shared allocator for XPCOM correctness // PRUint32 i; for ( i = 0 ; i < numVals ; i++ ) { nsDependentCString sValue(values[i]); if (IsUTF8(sValue)) (*aValues)[i] = ToNewUnicode(NS_ConvertUTF8toUTF16(sValue)); else (*aValues)[i] = ToNewUnicode(NS_ConvertASCIItoUTF16(sValue)); if ( ! (*aValues)[i] ) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, aValues); ldap_value_free(values); return NS_ERROR_OUT_OF_MEMORY; } } // now free our value array since we already cloned the values array // to the 'aValues' results array. ldap_value_free(values); *aCount = numVals; return NS_OK; }
abook_fielddata * abook_ldap_fetch(char *alias, int *count) { int i, rc, ldapcount, mappedfieldcount; char *ptr; char prefix[1024]; char filter[1024]; abook_fielddata *fdata, *fptr; char *searchattr; char *searchkey; LDAP *ld; LDAPMessage *results, *entry; char **values; if (config_ldap() < 0) { syslog(LOG_ERR, "abook_ldap_fetch: failed to configure LDAP"); return NULL; } /* * Decide how to search for the user. */ snprintf(prefix, sizeof(prefix), "[%s:", config.uniqueattr); ptr = strstr(alias, prefix); if (ptr != NULL) { *ptr = '\0'; ptr += 1 /*[*/ + strlen(config.uniqueattr) + 1 /*:*/; searchkey = ptr; ptr += strlen(ptr) - 1 /*]*/; *ptr = '\0'; searchattr = config.uniqueattr; } else { searchkey = alias; searchattr = config.fullnameattr; } snprintf(filter, sizeof(filter), "(&%s(%s=%s))", config.defaultfilter, searchattr, searchkey); ld = ldap_init(config.ldaphost, config.ldapport); if (ld == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP init failed: %s", strerror(errno)); return NULL; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: simple bind failed: %s", ldap_err2string(rc)); return NULL; } rc = ldap_search_s(ld, config.searchbase, config.scope, filter, NULL/*get all attrs*/, 0/*attrs-only*/, &results); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP search failed: %s", ldap_err2string(rc)); ldap_unbind(ld); return NULL; } ldapcount = ldap_count_entries(ld, results); if (ldapcount == 0) { /* no matches on primary search, try secondary search if configured */ if (secondaryconfig.ldaphost) { /* close the connection to the primary server */ ldap_unbind(ld); snprintf(prefix, sizeof(prefix), "[%s:", secondaryconfig.uniqueattr); ptr = strstr(alias, prefix); if (ptr != NULL) { *ptr = '\0'; ptr += 1 /*[*/ + strlen(secondaryconfig.uniqueattr) + 1 /*:*/; searchkey = ptr; ptr += strlen(ptr) - 1 /*]*/; *ptr = '\0'; searchattr = secondaryconfig.uniqueattr; } else { searchkey = alias; searchattr = secondaryconfig.fullnameattr; } snprintf(filter, sizeof(filter), "(&%s(%s=%s))", secondaryconfig.defaultfilter, searchattr, searchkey); ld=ldap_init(secondaryconfig.ldaphost, secondaryconfig.ldapport); if (ld == NULL){ syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary init failed: %s", strerror(errno)); return NULL; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: simple secondary bind failed: %s", ldap_err2string(rc)); return NULL; } rc = ldap_search_s(ld, secondaryconfig.searchbase, secondaryconfig.scope, filter, NULL/*get all attrs*/, 0/*attrs-only*/, &results); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary search failed: %s", ldap_err2string(rc)); ldap_unbind(ld); return NULL; } ldapcount = ldap_count_entries(ld, results); if (ldapcount != 1) { syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of secondary search" " hits: %d", ldapcount); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } entry = ldap_first_entry(ld, results); if (entry == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } /* This memory is freed by abook_fetchdone() which is called by * show_address() after it's finished sending the field/data pairs * back to the IMSP client */ mappedfieldcount = 0; for (i = 0; secondaryconfig.map[i].field != NULL; i++) { if (secondaryconfig.map[i].attr != NULL) mappedfieldcount++; } fdata = (abook_fielddata *) malloc(sizeof (abook_fielddata) * mappedfieldcount); if (fdata == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: Out of memory"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } *count = 0; fptr = fdata; for (i = 0; secondaryconfig.map[i].field != NULL; i++) { if ((secondaryconfig.map[i].attr != NULL) && (strcmp(secondaryconfig.map[i].attr, secondaryconfig.fullnameattr) != 0)) { values = ldap_get_values(ld, entry, secondaryconfig.map[i].attr); if (values != NULL && values[0] != NULL) { fptr->field = strdup(secondaryconfig.map[i].field); if (secondaryconfig.map[i].append != NULL) { int fptrdatalen = strlen(values[0])+strlen(secondaryconfig.map[i].append)+1; fptr->data=malloc(fptrdatalen); if(!fptr->data) fatal("out of memory", EC_TEMPFAIL); strlcpy(fptr->data, values[0], fptrdatalen); strlcat(fptr->data, secondaryconfig.map[i].append, fptrdatalen); } else { fptr->data = strdup(values[0]); if(!fptr->data) fatal("out of memory", EC_TEMPFAIL); } (*count)++; fptr++; } if (values != NULL) ldap_value_free(values); } } (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return (fdata); } } if (ldapcount != 1) { syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of search" " hits: %d", ldapcount); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } entry = ldap_first_entry(ld, results); if (entry == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } /* This memory is freed by abook_fetchdone() which is called by * show_address() after it's finished sending the field/data pairs * back to the IMSP client */ mappedfieldcount = 0; for (i = 0; config.map[i].field != NULL; i++) { if (config.map[i].attr != NULL) mappedfieldcount++; } fdata = (abook_fielddata *) malloc(sizeof (abook_fielddata) * mappedfieldcount); if (fdata == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: Out of memory"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } *count = 0; fptr = fdata; for (i = 0; config.map[i].field != NULL; i++) { if ((config.map[i].attr != NULL) && (strcmp(config.map[i].attr, config.fullnameattr) != 0)) { values = ldap_get_values(ld, entry, config.map[i].attr); if (values != NULL && values[0] != NULL) { fptr->field = strdup(config.map[i].field); if (config.map[i].append != NULL) { printf("appending %s to field: %s value: %s\n", config.map[i].append, config.map[i].field,values[0]); fptr->data=malloc(strlen(values[0])+strlen(config.map[i].append)+1); fptr->data=strcat(fptr->data, values[0]); fptr->data=strcat(fptr->data, config.map[i].append); } else { fptr->data = strdup(values[0]); } (*count)++; fptr++; } if (values != NULL) ldap_value_free(values); } } (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return (fdata); }
static void rpc_ns__ldap_import_server_element(LDAP *ld, unsigned_char_p_t serverDN, rpc_if_handle_t if_spec, rpc_ns_handle_t *ctx, unsigned32 *status ) { unsigned_char_p_t filter = NULL; unsigned_char_p_t uuid = NULL; rpc_if_id_t if_id; LDAPMessage *msg = NULL, *e; rpc_ns_handle_rep_t *rep; unsigned_char_p_t *bindings; size_t len; rpc_if_inq_id(if_spec, &if_id, status); if (*status != rpc_s_ok) { goto out; } /* Get the interface ID */ uuid_to_string(&if_id.uuid, &uuid, status); if (*status != rpc_s_ok) { goto out; } len = strlen(uuid); len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", uuid, if_id.vers_major, if_id.vers_minor); if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &msg) != LDAP_SUCCESS) { *status = rpc_s_not_found; goto out; } e = ldap_first_entry(ld, msg); if (e == NULL) { *status = rpc_s_not_found; goto out; } bindings = (unsigned_char_p_t *)ldap_get_values(ld, e, "rpcNsBindings"); if (bindings == NULL) { *status = rpc_s_not_found; goto out; } RPC_MEM_ALLOC(rep, rpc_ns_handle_rep_p_t, sizeof(*rep), RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); rep->count = ldap_count_values((char **)bindings); rep->bindings = bindings; rep->cursor = 0; *ctx = (rpc_ns_handle_t)rep; *status = rpc_s_ok; out: if (filter != NULL) { RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); } if (msg != NULL) { ldap_msgfree(msg); } }
/** Expand an LDAP URL into a query, and return a string result from that query. * */ static ssize_t ldap_xlat(void *instance, REQUEST *request, char const *fmt, char *out, size_t freespace) { ldap_rcode_t status; size_t len = 0; ldap_instance_t *inst = instance; LDAPURLDesc *ldap_url; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; char **vals; ldap_handle_t *conn; int ldap_errno; char const *url; char const **attrs; url = fmt; if (!ldap_is_ldap_url(url)) { REDEBUG("String passed does not look like an LDAP URL"); return -1; } if (ldap_url_parse(url, &ldap_url)){ REDEBUG("Parsing LDAP URL failed"); return -1; } /* * Nothing, empty string, "*" string, or got 2 things, die. */ if (!ldap_url->lud_attrs || !ldap_url->lud_attrs[0] || !*ldap_url->lud_attrs[0] || (strcmp(ldap_url->lud_attrs[0], "*") == 0) || ldap_url->lud_attrs[1]) { REDEBUG("Bad attributes list in LDAP URL. URL must specify exactly one attribute to retrieve"); goto free_urldesc; } if (ldap_url->lud_host && ((strncmp(inst->server, ldap_url->lud_host, strlen(inst->server)) != 0) || (ldap_url->lud_port != inst->port))) { RDEBUG("Requested server/port is \"%s:%i\"", ldap_url->lud_host, inst->port); goto free_urldesc; } conn = rlm_ldap_get_socket(inst, request); if (!conn) goto free_urldesc; memcpy(&attrs, &ldap_url->lud_attrs, sizeof(attrs)); status = rlm_ldap_search(inst, request, &conn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, attrs, &result); switch (status) { case LDAP_PROC_SUCCESS: break; case LDAP_PROC_NO_RESULT: RDEBUG("Search returned not found"); default: goto free_socket; } rad_assert(conn); rad_assert(result); entry = ldap_first_entry(conn->handle, result); if (!entry) { ldap_get_option(conn->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); len = -1; goto free_result; } vals = ldap_get_values(conn->handle, entry, ldap_url->lud_attrs[0]); if (!vals) { RDEBUG("No \"%s\" attributes found in specified object", ldap_url->lud_attrs[0]); goto free_result; } len = strlen(vals[0]); if (len >= freespace){ goto free_vals; } strlcpy(out, vals[0], freespace); free_vals: ldap_value_free(vals); free_result: ldap_msgfree(result); free_socket: rlm_ldap_release_socket(inst, conn); free_urldesc: ldap_free_urldesc(ldap_url); return len; }
/** Convert attribute map into valuepairs * * Use the attribute map built earlier to convert LDAP values into valuepairs and insert them into whichever * list they need to go into. * * This is *NOT* atomic, but there's no condition for which we should error out... */ void rlm_ldap_map_do(UNUSED const ldap_instance_t *inst, REQUEST *request, LDAP *handle, rlm_ldap_map_xlat_t const *expanded, LDAPMessage *entry) { value_pair_map_t const *map; unsigned int total = 0; rlm_ldap_result_t result; char const *name; for (map = expanded->maps; map != NULL; map = map->next) { name = expanded->attrs[total++]; result.values = ldap_get_values(handle, entry, name); if (!result.values) { RDEBUG3("Attribute \"%s\" not found in LDAP object", name); goto next; } /* * Find out how many values there are for the * attribute and extract all of them. */ result.count = ldap_count_values(result.values); /* * If something bad happened, just skip, this is probably * a case of the dst being incorrect for the current * request context */ if (radius_map2request(request, map, name, rlm_ldap_map_getvalue, &result) == -1) { return; /* Fail */ } next: ldap_value_free(result.values); } /* * Retrieve any valuepair attributes from the result, these are generic values specifying * a radius list, operator and value. */ if (inst->valuepair_attr) { char **values; int count, i; values = ldap_get_values(handle, entry, inst->valuepair_attr); count = ldap_count_values(values); for (i = 0; i < count; i++) { value_pair_map_t *attr; RDEBUG3("Parsing attribute string '%s'", values[i]); if (radius_strpair2map(&attr, request, values[i], REQUEST_CURRENT, PAIR_LIST_REPLY, REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) { RWDEBUG("Failed parsing '%s' value \"%s\" as valuepair, skipping...", inst->valuepair_attr, values[i]); continue; } if (radius_map2request(request, attr, NULL, radius_map2vp, NULL) < 0) { RWDEBUG("Failed adding \"%s\" to request, skipping...", values[i]); } talloc_free(attr); } ldap_value_free(values); } }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; char *attrfail, *matched = NULL, *errmsg = NULL; char **vals, **referrals; int rc, parse_rc, version; unsigned long sortrc; LDAPControl *sortctrl = NULL; LDAPControl *requestctrls[ 2 ]; LDAPControl **resultctrls = NULL; LDAPsortkey **sortkeylist; /* Arrange for all connections to use LDAPv3 */ version = LDAP_VERSION3; if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { fprintf( stderr, "ldap_set_option protocol version to %d failed\n", version ); return( 1 ); } /* Get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT ) ) == NULL ) { perror( "ldap_init" ); return( 1 ); } /* Authenticate as Directory Manager */ if ( ldap_simple_bind_s( ld, MGR_DN, MGR_PW ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); ldap_unbind( ld ); return( 1 ); } /* * Create a sort key list that specifies the sort order of the results. * Sort the results by last name first, then by first name. */ ldap_create_sort_keylist( &sortkeylist, "description -givenname" ); /* Create the sort control. */ rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_create_sort_control: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } requestctrls[ 0 ] = sortctrl; requestctrls[ 1 ] = NULL; /* Search for all entries in Sunnyvale */ rc = ldap_search_ext_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE, "(objectclass=person)", NULL, 0, requestctrls, NULL, NULL, 0, &result ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg, &referrals, &resultctrls, 0 ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); if ( errmsg != NULL && *errmsg != '\0' ) { fprintf( stderr, "%s\n", errmsg ); } ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_sort_control( ld, resultctrls, &sortrc, &attrfail ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_sort_control: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( sortrc != LDAP_SUCCESS ) { fprintf( stderr, "Sort error: %s\n", ldap_err2string( sortrc )); if ( attrfail != NULL && *attrfail != '\0' ) { fprintf( stderr, "Bad attribute: %s\n", attrfail); } ldap_unbind( ld ); return( 1 ); } /* for each entry print out name + all attrs and values */ for ( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) { if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) { if ( vals[0] != NULL ) { printf( "%s", vals[0] ); } ldap_value_free( vals ); } if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) { if ( vals[0] != NULL ) { printf( "\t%s", vals[0] ); } ldap_value_free( vals ); } putchar( '\n' ); } ldap_msgfree( result ); ldap_free_sort_keylist( sortkeylist ); ldap_control_free( sortctrl ); ldap_controls_free( resultctrls ); ldap_unbind( ld ); return( 0 ); }
/* * Creates an LDAP search URL given a comma-separated list of attributes. * Returns a list of key=values separated by '\n' */ char * pref_get_ldap_attributes(char* host, char* base, char* filter, char* attrs, char** return_error) { char *value = NULL; LDAP* ld; int err, i; char *url; LDAPMessage *result; LDAPMessage *e; char *a; BerElement *ber; char **vals; ld = ldap_init(host, LDAP_PORT); if (!ld) return value; url = (char*) malloc(sizeof(char) * (strlen(host) + strlen(base) + strlen(filter) + strlen(attrs) + 20)); if (!url) return value; XP_SPRINTF(url, "ldap://%s/%s?%s?sub?%s", host, base, attrs, filter); err = ldap_url_search_s( ld, url, 0, &result ); XP_FREE(url); if (err != LDAP_SUCCESS) { *return_error = ldap_err2string(err); return value; } e = ldap_first_entry( ld, result ); if (e) { a = ldap_first_attribute( ld, e, &ber ); if (a) { int total_buf_size = 200; int remaining_buf_size = total_buf_size; value = (char*) malloc(sizeof(char*) * total_buf_size); if (!value) return NULL; value[0] = '\0'; for ( ; a != NULL; a = ldap_next_attribute( ld, e, ber )) { vals = ldap_get_values( ld, e, a ); if (vals && vals[0]) { remaining_buf_size -= (strlen(a) + strlen(vals[0]) + 2); if (remaining_buf_size < 1) { remaining_buf_size += 2 * total_buf_size; total_buf_size += 2 * total_buf_size; value = (char*) realloc(value, sizeof(char*) * total_buf_size); if (!value) return NULL; } strcat(value, "\n"); strcat(value, a); strcat(value, "="); strcat(value, vals[0]); ldap_value_free( vals ); } } ldap_memfree(a); } if (ber) ber_free(ber, 0); } ldap_msgfree(result); ldap_unbind(ld); return value; }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; BerElement *ber; char *host, *a, *dn; char **vals; int i; int rc; int finished; int msgid; int num_entries = 0; struct timeval zerotime; if ( argc > 1 ) { host = argv[1]; } else { host = MY_HOST; } zerotime.tv_sec = zerotime.tv_usec = 0L; if ( prldap_install_routines( NULL, 1 /* shared */ ) != LDAP_SUCCESS ) { ldap_perror( NULL, "prldap_install_routines" ); return( 1 ); } /* get a handle to an LDAP connection */ if ( (ld = ldap_init( host, MY_PORT )) == NULL ) { perror( host ); return( 1 ); } /* authenticate to the directory as nobody */ if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); return( 1 ); } /* search for all entries with surname of Jensen */ if (( msgid = ldap_search( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER, NULL, 0 )) < 0 ) { ldap_perror( ld, "ldap_search" ); return( 1 ); } /* Loop, polling for results until finished */ finished = 0; while ( !finished ) { /* * Poll for results. We call ldap_result with the "all" argument * set to LDAP_MSG_ONE. This causes ldap_result() to return exactly one * entry if at least one entry is available. This allows us to * display the entries as they are received. */ result = NULL; rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &result ); switch ( rc ) { case -1: /* some error occurred */ ldap_perror( ld, "ldap_result" ); return( 1 ); case 0: /* Timeout was exceeded. No entries are ready for retrieval. */ if ( result != NULL ) { ldap_msgfree( result ); } break; default: /* * Either an entry is ready for retrieval, or all entries have * been retrieved. */ if (( e = ldap_first_entry( ld, result )) == NULL ) { /* All done */ finished = 1; if ( result != NULL ) { ldap_msgfree( result ); } continue; } /* for each entry print out name + all attrs and values */ num_entries++; if (( dn = ldap_get_dn( ld, e )) != NULL ) { printf( "dn: %s\n", dn ); ldap_memfree( dn ); } for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; a = ldap_next_attribute( ld, e, ber ) ) { if (( vals = ldap_get_values( ld, e, a )) != NULL ) { for ( i = 0; vals[ i ] != NULL; i++ ) { printf( "%s: %s\n", a, vals[ i ] ); } ldap_value_free( vals ); } ldap_memfree( a ); } if ( ber != NULL ) { ber_free( ber, 0 ); } printf( "\n" ); ldap_msgfree( result ); } /* Do other work here while you are waiting... */ do_other_work(); } /* All done. Print a summary. */ printf( "%d entries retrieved. I counted to %ld " "while I was waiting.\n", num_entries, global_counter ); ldap_unbind( ld ); return( 0 ); }