static ns_ldap_return_code __ns_ldap_unmapObjectClasses (ns_ldap_cookie_t * cookie, char **mappedClasses, char ***pOrigClasses) { char **origClasses = NULL; int count, i; count = ldap_count_values (mappedClasses); origClasses = (char **) calloc (count + 1, sizeof (char *)); if (origClasses == NULL) { return NS_LDAP_MEMORY; } for (i = 0; i < count; i++) { origClasses[i] = strdup (_nss_ldap_unmap_oc (cookie->sel, mappedClasses[i])); if (origClasses[i] == NULL) { ldap_value_free (origClasses); return NS_LDAP_MEMORY; } } origClasses[i] = NULL; *pOrigClasses = origClasses; return NS_LDAP_SUCCESS; }
void AD::AddGroups(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++) { Group *g = new Group(); 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) { values = ldap_get_values(ldap, entry, attribute); if(lstrcmpi(attribute, L"samaccountname") == 0) { g->name = values[0]; } if(lstrcmpi(attribute, L"member") == 0) { for(j = 0; j < ldap_count_values(values); j++) { std::wstring *ret = new std::wstring(); CNToAccountName(values[j], ret); g->users.push_back(ret); } } ldap_value_free(values); ldap_memfree(attribute); attribute = ldap_next_attribute(ldap, entry, berElement); } ber_free(berElement, 0); if(g->name.length() > 0) { GetGroupManager()->groups.push_back(g); g->PrettyPrint(); } else { delete(g); } } }
/* * 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); }
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; }
/** Query the LDAP directory to check if a user object is a member of a group * * @param[in] inst rlm_ldap configuration. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @param[in] dn of user object. * @param[in] check vp containing the group value (name or dn). * @return One of the RLM_MODULE_* values. */ rlm_rcode_t rlm_ldap_check_userobj_dynamic(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, VALUE_PAIR *check) { rlm_rcode_t rcode = RLM_MODULE_NOTFOUND, ret; ldap_rcode_t status; int name_is_dn = false, value_is_dn = false; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; char **vals = NULL; char const *name = check->vp_strvalue; char const *attrs[] = { inst->userobj_membership_attr, NULL }; int i, count, ldap_errno; RDEBUG2("Checking user object membership (%s) attributes", inst->userobj_membership_attr); status = rlm_ldap_search(inst, request, pconn, dn, LDAP_SCOPE_BASE, NULL, attrs, &result); switch (status) { case LDAP_PROC_SUCCESS: break; case LDAP_PROC_NO_RESULT: RDEBUG("Can't check membership attributes, user object not found"); rcode = RLM_MODULE_NOTFOUND; /* FALL-THROUGH */ default: goto finish; } entry = ldap_first_entry((*pconn)->handle, result); if (!entry) { ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); rcode = RLM_MODULE_FAIL; goto finish; } vals = ldap_get_values((*pconn)->handle, entry, inst->userobj_membership_attr); if (!vals) { RDEBUG("No group membership attribute(s) found in user object"); goto finish; } /* * Loop over the list of groups the user is a member of, * looking for a match. */ name_is_dn = rlm_ldap_is_dn(name); count = ldap_count_values(vals); for (i = 0; i < count; i++) { value_is_dn = rlm_ldap_is_dn(vals[i]); RDEBUG2("Processing group membership value \"%s\"", vals[i]); /* * Both literal group names, do case sensitive comparison */ if (!name_is_dn && !value_is_dn) { if (strcmp(vals[i], name) == 0){ RDEBUG("User found. Comparison between membership: name, check: name]"); rcode = RLM_MODULE_OK; goto finish; } continue; } /* * Both DNs, do case insensitive comparison */ if (name_is_dn && value_is_dn) { if (strcasecmp(vals[i], name) == 0){ RDEBUG("User found. Comparison between membership: dn, check: dn"); rcode = RLM_MODULE_OK; goto finish; } continue; } /* * If the value is not a DN, and the name we were given is a dn * convert the value to a DN and do a comparison. */ if (!value_is_dn && name_is_dn) { char *resolved; int eq; ret = rlm_ldap_group_dn2name(inst, request, pconn, name, &resolved); if (ret != RLM_MODULE_OK) { rcode = ret; goto finish; } eq = strcmp(vals[i], resolved); talloc_free(resolved); if (eq == 0){ RDEBUG("User found. Comparison between membership: name, check: name " "(resolved from DN)"); rcode = RLM_MODULE_OK; goto finish; } continue; } /* * We have a value which is a DN, and a check item which specifies the name of a group, * convert the value to a name so we can do a comparison. */ if (value_is_dn && !name_is_dn) { char *resolved; int eq; ret = rlm_ldap_group_dn2name(inst, request, pconn, vals[i], &resolved); if (ret != RLM_MODULE_OK) { rcode = ret; goto finish; } eq = strcmp(resolved, name); talloc_free(resolved); if (eq == 0){ RDEBUG("User found. Comparison between membership: name (resolved from DN), " "check: name"); rcode = RLM_MODULE_OK; goto finish; } continue; } rad_assert(0); } finish: if (vals) { ldap_value_free(vals); } if (result) { ldap_msgfree(result); } return rcode; }
static int mod_vhost_ldap_translate_name(request_rec *r) { mod_vhost_ldap_request_t *reqc = NULL; mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_ng_module); #if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER <= 2) core_server_config *core = (core_server_config *)ap_get_module_config(r->server->module_config, &core_module); #endif LDAP *ld = NULL; char *realfile = NULL; char *myfilter = NULL; alias_t *alias = NULL, *cursor = NULL; int i = 0, ret = 0; apr_table_t *e; LDAPMessage *ldapmsg = NULL, *vhostentry = NULL; if (conf->enabled != MVL_ENABLED || !conf->url || !r->hostname){ ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c] Module disabled"); return DECLINED; } //Search in cache reqc = (mod_vhost_ldap_request_t *)get_from_requestscache(r); if(!reqc){ ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c] Cannot resolve data from cache"); reqc = apr_pcalloc(vhost_ldap_pool, sizeof(mod_vhost_ldap_request_t)); } if (reqc->expires < apr_time_now()){ //Search ldap //TODO: Create a function while((ret = ldapconnect(&ld, conf)) != 0 && i<2){ i++; ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c] ldapconnect: %s", ldap_err2string(ret)); } if(i == 2){ conf->enabled = MVL_DISABLED; return HTTP_GATEWAY_TIME_OUT; } myfilter = apr_psprintf(r->pool,"(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, r->hostname, r->hostname); ret = ldap_search_s (ld, conf->basedn, conf->scope, myfilter, (char **)attributes, 0, &ldapmsg); if(ret != LDAP_SUCCESS){//SIGPIPE? return DECLINED; } if(ldap_count_entries(ld, ldapmsg)!=1){ if(!conf->fallback_name || !conf->fallback_docroot){ reqc->name = apr_pstrdup(vhost_ldap_pool, r->hostname); reqc->decline = 1; reqc->admin = apr_pstrdup(vhost_ldap_pool, r->server->server_admin); add_to_requestscache(reqc, r); if(ldapmsg) ldap_msgfree(ldapmsg); ldapdestroy(&ld); return DECLINED; }else{ reqc->name = conf->fallback_name; reqc->docroot = conf->fallback_docroot; } }else{ reqc->aliases = (apr_array_header_t *)apr_array_make(vhost_ldap_pool, 2, sizeof(alias_t)); reqc->redirects = (apr_array_header_t *)apr_array_make(vhost_ldap_pool, 2, sizeof(alias_t)); reqc->env = apr_table_make(vhost_ldap_pool, 2); vhostentry = ldap_first_entry(ld, ldapmsg); reqc->dn = ldap_get_dn(ld, vhostentry); i=0; while(attributes[i]){ int k = 0, j; char **eValues = ldap_get_values(ld, vhostentry, attributes[i]), *str[3]; if (eValues){ k = ldap_count_values (eValues); if (strcasecmp(attributes[i], "apacheServerName") == 0){ reqc->name = apr_pstrdup(vhost_ldap_pool, eValues[0]); }else if(strcasecmp(attributes[i], "apacheServerAdmin") == 0){ reqc->admin = apr_pstrdup(vhost_ldap_pool, eValues[0]); }else if(strcasecmp(attributes[i], "apacheDocumentRoot") == 0){ reqc->docroot = apr_pstrdup(vhost_ldap_pool, eValues[0]); /* Make it absolute, relative to ServerRoot */ if(conf->rootdir && (strncmp(reqc->docroot, "/", 1) != 0)) reqc->docroot = apr_pstrcat(vhost_ldap_pool, conf->rootdir, reqc->docroot, NULL); reqc->docroot = ap_server_root_relative(vhost_ldap_pool, reqc->docroot); }else if(strcasecmp(attributes[i], "apacheAlias") == 0){ while(k){ k--; for(j = 0; j < 2; j++) str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]); if(str[--j] == '\0') ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: Wrong apacheAlias parameter: %s", eValues[k]); else{ alias = apr_array_push(reqc->aliases); alias->src = apr_pstrdup(vhost_ldap_pool, str[0]); alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]); } } }else if(strcasecmp(attributes[i], "apacheScriptAlias") == 0){ while(k){ k--; for(j = 0; j < 2; j++) str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]); if(str[--j] == '\0') ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: Wrong apacheScriptAlias parameter: %s", eValues[k]); else{ alias = apr_array_push(reqc->aliases); alias->src = apr_pstrdup(vhost_ldap_pool, str[0]); alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]); } } }else if(strcasecmp (attributes[i], "apacheRedirect") == 0){ while(k){ k--; for(j = 0; j < 3; j++) str[j] = ap_getword_conf(r->pool, (const char **)&eValues[k]); if(str[1] == '\0') ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: Missing apacheRedirect parameter: %s", eValues[k]); else{ alias = apr_array_push(reqc->redirects); alias->src = apr_pstrdup(vhost_ldap_pool, str[0]); if(str[2] != '\0'){ if(strcasecmp(str[1], "gone") == 0) alias->flags |= REDIR_GONE; else if (strcasecmp(str[1], "permanent") == 0) alias->flags |= REDIR_PERMANENT; else if (strcasecmp(str[1], "temp") == 0) alias->flags |= REDIR_TEMP; else if (strcasecmp(str[1], "seeother") == 0) alias->flags |= REDIR_SEEOTHER; else{ alias->flags |= REDIR_PERMANENT; ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: Wrong apacheRedirect type: %s", str[2]); } alias->dst = apr_pstrdup(vhost_ldap_pool, str[2]); }else alias->dst = apr_pstrdup(vhost_ldap_pool, str[1]); } } }else if(strcasecmp(attributes[i], "apacheSuexecUid") == 0){ reqc->uid = apr_pstrdup(vhost_ldap_pool, eValues[0]); }else if(strcasecmp(attributes[i], "apacheSuexecGid") == 0){ reqc->gid = apr_pstrdup(vhost_ldap_pool, eValues[0]); }else if(strcasecmp (attributes[i], "apacheErrorLog") == 0){ if(conf->rootdir && (strncmp(eValues[0], "/", 1) != 0)) r->server->error_fname = apr_pstrcat(vhost_ldap_pool, conf->rootdir, eValues[0], NULL); else r->server->error_fname = apr_pstrdup(vhost_ldap_pool, eValues[0]);; apr_file_open(&r->server->error_log, r->server->error_fname, APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE, APR_OS_DEFAULT, r->pool); } #ifdef HAVEPHP else if(strcasecmp(attributes[i], "phpIncludePath") == 0){ if(conf->php_includepath) reqc->php_includepath = apr_pstrcat(vhost_ldap_pool, conf->php_includepath, ":", eValues[0], NULL); else reqc->php_includepath = apr_pstrdup(vhost_ldap_pool, eValues[0]); }else if(strcasecmp(attributes[i], "phpOpenBasedir") == 0){ if(conf->rootdir && (strncmp(eValues[0], "/", 1) != 0)) reqc->php_openbasedir = apr_pstrcat(vhost_ldap_pool, conf->rootdir, eValues[0], NULL); else reqc->php_openbasedir = apr_pstrdup(vhost_ldap_pool, eValues[0]); } else if(strcasecmp(attributes[i], "php_admin_value") == 0){ } #endif else if(strcasecmp(attributes[i], "SetEnv") == 0){ for(j = 0; j < 2; j++) str[j] = ap_getword_conf(r->pool, (const char **)&eValues[0]); if(str[--j] == '\0') ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: Wrong apacheScriptAlias parameter: %s", eValues[0]); else{ apr_table_set(reqc->env, str[0], str[1]); } }else if(strcasecmp(attributes[i], "PassEnv") == 0){ } } i++; } } if(ldapmsg) ldap_msgfree(ldapmsg); ldapdestroy(&ld); add_to_requestscache(reqc, r); } if(reqc->decline) return DECLINED; ap_set_module_config(r->request_config, &vhost_ldap_ng_module, reqc); e = r->subprocess_env; if(apr_table_elts(reqc->env)->nelts) r->subprocess_env = apr_table_overlay(r->pool, e, reqc->env); #ifdef HAVEPHP char *openbasedir, *include; if(!reqc->php_includepath) include = apr_pstrcat(r->pool, conf->php_includepath, ":", reqc->docroot, NULL); else include = apr_pstrcat(r->pool, reqc->php_includepath, ":", conf->php_includepath, ":", reqc->docroot, NULL); zend_alter_ini_entry("include_path", strlen("include_path") + 1, (void *)include, strlen(include), PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME); if(reqc->php_openbasedir){ openbasedir = apr_pstrcat(r->pool, reqc->php_openbasedir, ":", include, NULL); zend_alter_ini_entry("open_basedir", strlen("open_basedir") + 1, (void *)openbasedir, strlen(openbasedir), PHP_INI_SYSTEM, PHP_INI_STAGE_RUNTIME); } #endif if ((reqc->name == NULL)||(reqc->docroot == NULL)) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c] translate: " "translate failed; ServerName %s or DocumentRoot %s not defined", reqc->name, reqc->docroot); return HTTP_INTERNAL_SERVER_ERROR; } cursor = NULL; //From mod_alias: checking for redirects if(reqc->redirects){ cursor = (alias_t *)reqc->redirects->elts; if (r->uri[0] != '/' && r->uri[0] != '\0') return DECLINED; for(i = 0; i < reqc->redirects->nelts; i++){ alias = (alias_t *) &cursor[i]; if(alias_matches(r->uri, alias->src)){ apr_table_setn(r->headers_out, "Location", alias->dst); /* OLD STUFF if(alias->redir_status){ if (strcasecmp(alias->redir_status, "gone") == 0) return HTTP_GONE; else if (strcasecmp(alias->redir_status, "permanent") == 0) return HTTP_MOVED_PERMANENTLY; else if (strcasecmp(alias->redir_status, "temp") == 0) return HTTP_MOVED_TEMPORARILY; else if (strcasecmp(alias->redir_status, "seeother") == 0) return HTTP_SEE_OTHER; } */ if(alias->flags & REDIR_GONE) return HTTP_GONE; else if(alias->flags & REDIR_TEMP) return HTTP_MOVED_TEMPORARILY; else if(alias->flags & REDIR_SEEOTHER) return HTTP_SEE_OTHER; else return HTTP_MOVED_PERMANENTLY; } } } /* Checking for aliases */ if(reqc->aliases){ cursor = (alias_t *)reqc->aliases->elts; for(i = 0; reqc->aliases && i < reqc->aliases->nelts; i++){ alias = (alias_t *) &cursor[i]; if (alias_matches(r->uri, alias->src)) { /* Set exact filename for CGI script */ realfile = apr_pstrcat(r->pool, alias->dst, r->uri + strlen(alias->src), NULL); /* Add apacheRootDir config param IF realfile is a realative path*/ if(conf->rootdir && (strncmp(realfile, "/", 1) != 0)) realfile = apr_pstrcat(r->pool, conf->rootdir, "/", realfile, NULL); /* Let apache normalize the path */ if((realfile = ap_server_root_relative(r->pool, realfile))) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c]: ap_document_root is: %s", ap_document_root(r)); r->filename = realfile; if(alias->flags & ISCGI){ //r->handler = "cgi-script"; r->handler = "Script"; apr_table_setn(r->notes, "alias-forced-type", r->handler); } return OK; } return OK; } else if (r->uri[0] == '/') { /* we don't set r->filename here, and let other modules do it * this allows other modules (mod_rewrite.c) to work as usual */ /* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */ } else { /* We don't handle non-file requests here */ return DECLINED; } } } if ((r->server = apr_pmemdup(r->pool, r->server, sizeof(*r->server))) == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap_ng.c] translate: " "translate failed; Unable to copy r->server structure"); return HTTP_INTERNAL_SERVER_ERROR; } r->server->server_hostname = apr_pstrdup(r->pool,reqc->name); if (reqc->admin) r->server->server_admin = apr_pstrdup(r->pool, reqc->admin); #if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER <= 2) core->ap_document_root = apr_pstrdup(r->pool, reqc->docroot); if (!ap_is_directory(r->pool, reqc->docroot)) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_vhost_ldap_ng.c] set_document_root: Warning: DocumentRoot [%s] does not exist", core->ap_document_root); #else ap_set_document_root(r, reqc->docroot); #endif //ap_set_module_config(r->server->module_config, &core_module, core); /* Hack to allow post-processing by other modules (mod_rewrite, mod_alias) */ return DECLINED; }
static idmap_stat winname2dn(idmap_nm_handle_t *p, char *winname, int *is_wuser, char **dn, char **unixuser, char **unixgroup) { idmap_stat rc = IDMAP_SUCCESS; char *base; char *filter; int flen; char *attribs[4]; int i; LDAPMessage *results = NULL; LDAPMessage *entry; int ldap_rc; /* Query: */ base = dns2dn(p->windomain, ""); if (base == NULL) { return (IDMAP_ERR_MEMORY); } i = 0; attribs[i++] = "objectClass"; if (unixuser != NULL) attribs[i++] = p->ad_unixuser_attr; if (unixgroup != NULL) attribs[i++] = p->ad_unixgroup_attr; attribs[i] = NULL; flen = snprintf(NULL, 0, FILTER, winname) + 1; if ((filter = (char *)malloc(flen)) == NULL) { free(base); return (IDMAP_ERR_MEMORY); } (void) snprintf(filter, flen, FILTER, winname); ldap_rc = ldap_search_s(p->ad, base, LDAP_SCOPE_SUBTREE, filter, attribs, 0, &results); free(base); free(filter); if (ldap_rc != LDAP_SUCCESS) { namemap_log( gettext("Ldap query to server %s port %d failed. (%s)"), p->ad_host, p->ad_port, ldap_err2string(ldap_rc)); (void) ldap_msgfree(results); return (IDMAP_ERR_OTHER); } for (entry = ldap_first_entry(p->ad, results), *dn = NULL; entry != NULL; entry = ldap_next_entry(p->ad, entry)) { char **values = NULL; int i = 0; values = ldap_get_values(p->ad, entry, "objectClass"); if (values == NULL) { (void) ldap_msgfree(results); return (IDMAP_ERR_MEMORY); } for (i = 0; i < ldap_count_values(values); i++) { /* * is_wuser can be IDMAP_UNKNOWN, in that case we accept * both User/Group */ if (*is_wuser != IDMAP_NO && strcasecmp(values[i], "User") == 0 || *is_wuser != IDMAP_YES && strcasecmp(values[i], "Group") == 0) { *dn = ldap_get_dn(p->ad, entry); if (*dn == NULL) { ldap_value_free(values); (void) ldap_msgfree(results); return (IDMAP_ERR_MEMORY); } *is_wuser = strcasecmp(values[i], "User") == 0 ? IDMAP_YES : IDMAP_NO; break; } } ldap_value_free(values); if (*dn != NULL) break; } if (*dn == NULL) { namemap_log( *is_wuser == IDMAP_YES ? gettext("User %s@%s not found") : *is_wuser == IDMAP_NO ? gettext("Group %s@%s not found") : gettext("%s@%s not found"), winname, p->windomain); return (IDMAP_ERR_NOTFOUND); } if (unixuser != NULL) rc = extract_attribute(p, entry, p->ad_unixuser_attr, unixuser); if (rc == IDMAP_SUCCESS && unixgroup != NULL) rc = extract_attribute(p, entry, p->ad_unixgroup_attr, unixgroup); (void) ldap_msgfree(results); return (rc); }
ns_ldap_return_code __ns_ldap_parseAttr (ns_ldap_cookie_t * cookie, LDAPMessage * entry, const char *attribute, ns_ldap_attr_t ** pAttr) { ns_ldap_attr_t *attr; const char *unmappedAttribute; ns_ldap_return_code ret; char **values; int freeValues = 1; ret = __ns_ldap_allocAttr (&attr); if (ret != NS_LDAP_SUCCESS) { return ret; } if ((cookie->flags & NS_LDAP_NOMAP) == 0) { unmappedAttribute = _nss_ldap_unmap_at (cookie->sel, attribute); if (unmappedAttribute == NULL) { __ns_ldap_freeAttr (&attr); return NS_LDAP_INVALID_PARAM; } } else { unmappedAttribute = attribute; } attr->attrname = strdup (unmappedAttribute); if (attr->attrname == NULL) { __ns_ldap_freeAttr (&attr); return NS_LDAP_MEMORY; } attr->attrvalue = NULL; values = _nss_ldap_get_values (entry, attribute); if ((cookie->flags & NS_LDAP_NOMAP) == 0) { if (strcasecmp (attribute, "objectClass") == 0) { /* Map object class values */ ret = __ns_ldap_unmapObjectClasses (cookie, values, &attr->attrvalue); if (ret != NS_LDAP_SUCCESS) { __ns_ldap_freeAttr (&attr); return ret; } } } if (attr->attrvalue == NULL) { attr->attrvalue = values; freeValues = 0; } attr->value_count = (attr->attrvalue != NULL) ? ldap_count_values (attr->attrvalue) : 0; if (freeValues) { ldap_value_free (values); } *pAttr = attr; return NS_LDAP_SUCCESS; }
/** 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); } }
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; }
static isc_result_t ldap_process_results(ldap_instance_t *db, LDAP *dbc, LDAPMessage *msg, char **attrs, void *ptr, isc_boolean_t allnodes) { isc_result_t result = ISC_R_SUCCESS; int i = 0; int j; int len; char *attribute = NULL; LDAPMessage *entry; char *endp = NULL; char *host = NULL; char *type = NULL; char *data = NULL; char **vals = NULL; int ttl; /* get the first entry to process */ entry = ldap_first_entry(dbc, msg); if (entry == NULL) { db->log(ISC_LOG_INFO, "LDAP no entries to process."); return (ISC_R_FAILURE); } /* loop through all entries returned */ while (entry != NULL) { /* reset for this loop */ ttl = 0; len = 0; i = 0; attribute = attrs[i]; /* determine how much space we need for data string */ for (j = 0; attrs[j] != NULL; j++) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attrs[j]); /* skip empty attributes. */ if (vals == NULL || ldap_count_values(vals) < 1) continue; /* * we only use the first value. this driver * does not support multi-valued attributes. */ len = len + strlen(vals[0]) + 1; /* free vals for next loop */ ldap_value_free(vals); } /* allocate memory for data string */ data = malloc(len + 1); if (data == NULL) { db->log(ISC_LOG_ERROR, "LDAP driver unable to allocate memory " "while processing results"); result = ISC_R_FAILURE; goto cleanup; } /* * Make sure data is null termed at the beginning so * we can check if any data was stored to it later. */ data[0] = '\0'; /* reset j to re-use below */ j = 0; /* loop through the attributes in the order specified. */ while (attribute != NULL) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attribute); /* skip empty attributes. */ if (vals == NULL || vals[0] == NULL) { /* increment attibute pointer */ attribute = attrs[++i]; /* start loop over */ continue; } /* * j initially = 0. Increment j each time we * set a field that way next loop will set * next field. */ switch (j) { case 0: j++; /* * convert text to int, make sure it * worked right */ ttl = strtol(vals[0], &endp, 10); if (*endp != '\0' || ttl < 0) { db->log(ISC_LOG_ERROR, "LDAP driver ttl must " "be a postive number"); goto cleanup; } break; case 1: j++; type = strdup(vals[0]); break; case 2: j++; if (allnodes) host = strdup(vals[0]); else strcpy(data, vals[0]); break; case 3: j++; if (allnodes) strcpy(data, vals[0]); else { strcat(data, " "); strcat(data, vals[0]); } break; default: strcat(data, " "); strcat(data, vals[0]); break; } /* free values */ ldap_value_free(vals); vals = NULL; /* increment attibute pointer */ attribute = attrs[++i]; } if (type == NULL) { db->log(ISC_LOG_ERROR, "LDAP driver unable to retrieve DNS type"); result = ISC_R_FAILURE; goto cleanup; } if (strlen(data) < 1) { db->log(ISC_LOG_ERROR, "LDAP driver unable to retrieve DNS data"); result = ISC_R_FAILURE; goto cleanup; } if (allnodes && host != NULL) { dns_sdlzallnodes_t *an = (dns_sdlzallnodes_t *) ptr; if (strcasecmp(host, "~") == 0) result = db->putnamedrr(an, "*", type, ttl, data); else result = db->putnamedrr(an, host, type, ttl, data); if (result != ISC_R_SUCCESS) db->log(ISC_LOG_ERROR, "ldap_dynamic: putnamedrr failed " "for \"%s %s %u %s\" (%d)", host, type, ttl, data, result); } else { dns_sdlzlookup_t *lookup = (dns_sdlzlookup_t *) ptr; result = db->putrr(lookup, type, ttl, data); if (result != ISC_R_SUCCESS) db->log(ISC_LOG_ERROR, "ldap_dynamic: putrr failed " "for \"%s %u %s\" (%s)", type, ttl, data, result); } if (result != ISC_R_SUCCESS) { db->log(ISC_LOG_ERROR, "LDAP driver failed " "while sending data to BIND."); goto cleanup; } /* free memory for type, data and host for next loop */ free(type); type = NULL; free(data); data = NULL; if (host != NULL) { free(host); host = NULL; } /* get the next entry to process */ entry = ldap_next_entry(dbc, entry); } cleanup: /* de-allocate memory */ if (vals != NULL) ldap_value_free(vals); if (host != NULL) free(host); if (type != NULL) free(type); if (data != NULL) free(data); return (result); }
/*% checks that the LDAP URL parameters make sense */ static isc_result_t ldap_checkURL(ldap_instance_t *db, char *URL, int attrCnt, const char *msg) { isc_result_t result = ISC_R_SUCCESS; int ldap_result; LDAPURLDesc *ldap_url = NULL; if (!ldap_is_ldap_url(URL)) { db->log(ISC_LOG_ERROR, "%s query is not a valid LDAP URL", msg); result = ISC_R_FAILURE; goto cleanup; } ldap_result = ldap_url_parse(URL, &ldap_url); if (ldap_result != LDAP_SUCCESS || ldap_url == NULL) { db->log(ISC_LOG_ERROR, "parsing %s query failed", msg); result = ISC_R_FAILURE; goto cleanup; } if (ldap_count_values(ldap_url->lud_attrs) < attrCnt) { db->log(ISC_LOG_ERROR, "%s query must specify at least " "%d attributes to return", msg, attrCnt); result = ISC_R_FAILURE; goto cleanup; } if (ldap_url->lud_host != NULL) { db->log(ISC_LOG_ERROR, "%s query must not specify a host", msg); result = ISC_R_FAILURE; goto cleanup; } if (ldap_url->lud_port != 389) { db->log(ISC_LOG_ERROR, "%s query must not specify a port", msg); result = ISC_R_FAILURE; goto cleanup; } if (ldap_url->lud_dn == NULL || strlen (ldap_url->lud_dn) < 1) { db->log(ISC_LOG_ERROR, "%s query must specify a search base", msg); result = ISC_R_FAILURE; goto cleanup; } if (ldap_url->lud_exts != NULL || ldap_url->lud_crit_exts != 0) { db->log(ISC_LOG_ERROR, "%s uses extensions. " "The driver does not support LDAP extensions.", msg); result = ISC_R_FAILURE; goto cleanup; } cleanup: if (ldap_url != NULL) ldap_free_urldesc(ldap_url); return (result); }
krb5_error_code krb5_ldap_read_realm_params(krb5_context context, char *lrealm, krb5_ldap_realm_params **rlparamp, int *mask) { char **values=NULL; krb5_error_code st=0, tempst=0; LDAP *ld=NULL; LDAPMessage *result=NULL,*ent=NULL; krb5_ldap_realm_params *rlparams=NULL; kdb5_dal_handle *dal_handle=NULL; krb5_ldap_context *ldap_context=NULL; krb5_ldap_server_handle *ldap_server_handle=NULL; int x=0; SETUP_CONTEXT (); /* validate the input parameter */ if (lrealm == NULL || ldap_context->container_dn == NULL) { st = EINVAL; goto cleanup; } /* get ldap handle */ GET_HANDLE (); /* Initialize realm container structure */ rlparams =(krb5_ldap_realm_params *) malloc(sizeof(krb5_ldap_realm_params)); CHECK_NULL(rlparams); memset(rlparams, 0, sizeof(krb5_ldap_realm_params)); /* allocate tl_data structure to store MASK information */ rlparams->tl_data = malloc (sizeof(krb5_tl_data)); if (rlparams->tl_data == NULL) { st = ENOMEM; goto cleanup; } memset(rlparams->tl_data, 0, sizeof(krb5_tl_data)); rlparams->tl_data->tl_data_type = KDB_TL_USER_INFO; /* set the mask parameter to 0 */ *mask = 0; /* set default values */ rlparams->search_scope = LDAP_SCOPE_SUBTREE; if (asprintf(&rlparams->realmdn, "cn=%s,%s", lrealm, ldap_context->container_dn) < 0) { rlparams->realmdn = NULL; st = ENOMEM; goto cleanup; } /* populate the realm name in the structure */ rlparams->realm_name = strdup(lrealm); CHECK_NULL(rlparams->realm_name); LDAP_SEARCH(rlparams->realmdn, LDAP_SCOPE_BASE, "(objectclass=krbRealmContainer)", realm_attributes); if ((st = ldap_count_entries(ld, result)) <= 0) { /* This could happen when the DN used to bind and read the realm object * does not have sufficient rights to read its attributes */ st = KRB5_KDB_ACCESS_ERROR; /* return some other error ? */ goto cleanup; } ent = ldap_first_entry (ld, result); if (ent == NULL) { ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, (void *) &st); #if 0 st = translate_ldap_error(st, OP_SEARCH); #endif goto cleanup; } /* Read the attributes */ { if ((values=ldap_get_values(ld, ent, "krbSubTrees")) != NULL) { rlparams->subtreecount = ldap_count_values(values); rlparams->subtree = (char **) malloc(sizeof(char *) * (rlparams->subtreecount + 1)); if (rlparams->subtree == NULL) { st = ENOMEM; goto cleanup; } for (x=0; x<rlparams->subtreecount; x++) { rlparams->subtree[x] = strdup(values[x]); if (rlparams->subtree[x] == NULL) { st = ENOMEM; goto cleanup; } } rlparams->subtree[rlparams->subtreecount] = NULL; *mask |= LDAP_REALM_SUBTREE; ldap_value_free(values); } if((values=ldap_get_values(ld, ent, "krbPrincContainerRef")) != NULL) { rlparams->containerref = strdup(values[0]); if(rlparams->containerref == NULL) { st = ENOMEM; goto cleanup; } *mask |= LDAP_REALM_CONTREF; ldap_value_free(values); } if ((values=ldap_get_values(ld, ent, "krbSearchScope")) != NULL) { rlparams->search_scope=atoi(values[0]); /* searchscope can be ONE-LEVEL or SUBTREE, else default to SUBTREE */ if (!(rlparams->search_scope==1 || rlparams->search_scope==2)) rlparams->search_scope = LDAP_SCOPE_SUBTREE; *mask |= LDAP_REALM_SEARCHSCOPE; ldap_value_free(values); } if ((values=ldap_get_values(ld, ent, "krbMaxTicketLife")) != NULL) { rlparams->max_life = atoi(values[0]); *mask |= LDAP_REALM_MAXTICKETLIFE; ldap_value_free(values); } if ((values=ldap_get_values(ld, ent, "krbMaxRenewableAge")) != NULL) { rlparams->max_renewable_life = atoi(values[0]); *mask |= LDAP_REALM_MAXRENEWLIFE; ldap_value_free(values); } if ((values=ldap_get_values(ld, ent, "krbTicketFlags")) != NULL) { rlparams->tktflags = atoi(values[0]); *mask |= LDAP_REALM_KRBTICKETFLAGS; ldap_value_free(values); } } rlparams->mask = *mask; *rlparamp = rlparams; st = store_tl_data(rlparams->tl_data, KDB_TL_MASK, mask); cleanup: /* if there is an error, free allocated structures */ if (st != 0) { krb5_ldap_free_realm_params(rlparams); *rlparamp=NULL; } ldap_msgfree(result); krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle); return st; }
/* * 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(config.c_ldap_bind_dn); striplt(config.c_ldap_bind_pw); syslog(LOG_DEBUG, "LDAP bind DN: %s", config.c_ldap_bind_dn); i = ldap_simple_bind_s(ldserver, (!IsEmptyStr(config.c_ldap_bind_dn) ? config.c_ldap_bind_dn : NULL), (!IsEmptyStr(config.c_ldap_bind_pw) ? config.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 */ }
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_count_values_len( struct berval **vals ) { return( ldap_count_values( (char **) vals ) ); }
// 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; }
static krb5_error_code LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, LDAPMessage * msg, LDAPMod *** pmods) { krb5_error_code ret; krb5_boolean is_new_entry; char *tmp = NULL; LDAPMod **mods = NULL; hdb_entry orig; unsigned long oflags, nflags; int i; krb5_boolean is_samba_account = FALSE; krb5_boolean is_account = FALSE; krb5_boolean is_heimdal_entry = FALSE; krb5_boolean is_heimdal_principal = FALSE; char **values; *pmods = NULL; if (msg != NULL) { ret = LDAP_message2entry(context, db, msg, &orig); if (ret) goto out; is_new_entry = FALSE; values = ldap_get_values(HDB2LDAP(db), msg, "objectClass"); if (values) { int num_objectclasses = ldap_count_values(values); for (i=0; i < num_objectclasses; i++) { if (strcasecmp(values[i], "sambaSamAccount") == 0) { is_samba_account = TRUE; } else if (strcasecmp(values[i], structural_object) == 0) { is_account = TRUE; } else if (strcasecmp(values[i], "krb5Principal") == 0) { is_heimdal_principal = TRUE; } else if (strcasecmp(values[i], "krb5KDCEntry") == 0) { is_heimdal_entry = TRUE; } } ldap_value_free(values); } /* * If this is just a "account" entry and no other objectclass * is hanging on this entry, its really a new entry. */ if (is_samba_account == FALSE && is_heimdal_principal == FALSE && is_heimdal_entry == FALSE) { if (is_account == TRUE) { is_new_entry = TRUE; } else { ret = HDB_ERR_NOENTRY; goto out; } } } else is_new_entry = TRUE; if (is_new_entry) { /* to make it perfectly obvious we're depending on * orig being intiialized to zero */ memset(&orig, 0, sizeof(orig)); ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "top"); if (ret) goto out; /* account is the structural object class */ if (is_account == FALSE) { ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", structural_object); is_account = TRUE; if (ret) goto out; } ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "krb5Principal"); is_heimdal_principal = TRUE; if (ret) goto out; ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "krb5KDCEntry"); is_heimdal_entry = TRUE; if (ret) goto out; } if (is_new_entry || krb5_principal_compare(context, ent->principal, orig.principal) == FALSE) { if (is_heimdal_principal || is_heimdal_entry) { ret = krb5_unparse_name(context, ent->principal, &tmp); if (ret) goto out; ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5PrincipalName", tmp); if (ret) { free(tmp); goto out; } free(tmp); } if (is_account || is_samba_account) { ret = krb5_unparse_name_short(context, ent->principal, &tmp); if (ret) goto out; ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "uid", tmp); if (ret) { free(tmp); goto out; } free(tmp); } } if (is_heimdal_entry && (ent->kvno != orig.kvno || is_new_entry)) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5KeyVersionNumber", ent->kvno); if (ret) goto out; } if (is_heimdal_entry && ent->valid_start) { if (orig.valid_end == NULL || (*(ent->valid_start) != *(orig.valid_start))) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5ValidStart", ent->valid_start); if (ret) goto out; } } if (ent->valid_end) { if (orig.valid_end == NULL || (*(ent->valid_end) != *(orig.valid_end))) { if (is_heimdal_entry) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5ValidEnd", ent->valid_end); if (ret) goto out; } if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaKickoffTime", *(ent->valid_end)); if (ret) goto out; } } } if (ent->pw_end) { if (orig.pw_end == NULL || (*(ent->pw_end) != *(orig.pw_end))) { if (is_heimdal_entry) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5PasswordEnd", ent->pw_end); if (ret) goto out; } if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaPwdMustChange", *(ent->pw_end)); if (ret) goto out; } } } #if 0 /* we we have last_pw_change */ if (is_samba_account && ent->last_pw_change) { if (orig.last_pw_change == NULL || (*(ent->last_pw_change) != *(orig.last_pw_change))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaPwdLastSet", *(ent->last_pw_change)); if (ret) goto out; } } #endif if (is_heimdal_entry && ent->max_life) { if (orig.max_life == NULL || (*(ent->max_life) != *(orig.max_life))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5MaxLife", *(ent->max_life)); if (ret) goto out; } } if (is_heimdal_entry && ent->max_renew) { if (orig.max_renew == NULL || (*(ent->max_renew) != *(orig.max_renew))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5MaxRenew", *(ent->max_renew)); if (ret) goto out; } } oflags = HDBFlags2int(orig.flags); nflags = HDBFlags2int(ent->flags); if (is_heimdal_entry && oflags != nflags) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5KDCFlags", nflags); if (ret) goto out; } /* Remove keys if they exists, and then replace keys. */ if (!is_new_entry && orig.keys.len > 0) { values = ldap_get_values(HDB2LDAP(db), msg, "krb5Key"); if (values) { ldap_value_free(values); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5Key", NULL); if (ret) goto out; } } for (i = 0; i < ent->keys.len; i++) { if (is_samba_account && ent->keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { char *ntHexPassword; char *nt; /* the key might have been 'sealed', but samba passwords are clear in the directory */ ret = hdb_unseal_key(context, db, &ent->keys.val[i]); if (ret) goto out; nt = ent->keys.val[i].key.keyvalue.data; /* store in ntPassword, not krb5key */ ret = hex_encode(nt, 16, &ntHexPassword); if (ret < 0) { krb5_set_error_string(context, "hdb-ldap: failed to " "hex encode key"); ret = ENOMEM; goto out; } ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "sambaNTPassword", ntHexPassword); free(ntHexPassword); if (ret) goto out; /* have to kill the LM passwod if it exists */ values = ldap_get_values(HDB2LDAP(db), msg, "sambaLMPassword"); if (values) { ldap_value_free(values); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "sambaLMPassword", NULL); if (ret) goto out; } } else if (is_heimdal_entry) { unsigned char *buf; size_t len, buf_size; ASN1_MALLOC_ENCODE(Key, buf, buf_size, &ent->keys.val[i], &len, ret); if (ret) goto out; if(buf_size != len) krb5_abortx(context, "internal error in ASN.1 encoder"); /* addmod_len _owns_ the key, doesn't need to copy it */ ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5Key", buf, len); if (ret) goto out; } } if (ent->etypes) { /* clobber and replace encryption types. */ if (!is_new_entry) { values = ldap_get_values(HDB2LDAP(db), msg, "krb5EncryptionType"); if (values) { ldap_value_free(values); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5EncryptionType", NULL); if (ret) goto out; } } for (i = 0; i < ent->etypes->len; i++) { if (is_samba_account && ent->keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { ; } else if (is_heimdal_entry) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_ADD, "krb5EncryptionType", ent->etypes->val[i]); if (ret) goto out; } } } /* for clarity */ ret = 0; out: if (ret == 0) *pmods = mods; else if (mods != NULL) { ldap_mods_free(mods, 1); *pmods = NULL; } if (msg) hdb_free_entry(context, &orig); return ret; }
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); } } }
/* * Construct an hdb_entry from a directory entry. */ static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, hdb_entry * ent) { char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL; char *samba_acct_flags = NULL; int ret; unsigned long tmp; struct berval **keys; char **values; int tmp_time; memset(ent, 0, sizeof(*ent)); ent->flags = int2HDBFlags(0); ret = LDAP_get_string_value(db, msg, "krb5PrincipalName", &unparsed_name); if (ret == 0) { ret = krb5_parse_name(context, unparsed_name, &ent->principal); if (ret) goto out; } else { ret = LDAP_get_string_value(db, msg, "uid", &unparsed_name); if (ret == 0) { ret = krb5_parse_name(context, unparsed_name, &ent->principal); if (ret) goto out; } else { krb5_set_error_string(context, "hdb-ldap: ldap entry missing" "principal name"); return HDB_ERR_NOENTRY; } } ret = LDAP_get_integer_value(db, msg, "krb5KeyVersionNumber", &ent->kvno); if (ret) ent->kvno = 0; keys = ldap_get_values_len(HDB2LDAP(db), msg, "krb5Key"); if (keys != NULL) { int i; size_t l; ent->keys.len = ldap_count_values_len(keys); ent->keys.val = (Key *) calloc(ent->keys.len, sizeof(Key)); if (ent->keys.val == NULL) { krb5_set_error_string(context, "calloc: out of memory"); ret = ENOMEM; goto out; } for (i = 0; i < ent->keys.len; i++) { decode_Key((unsigned char *) keys[i]->bv_val, (size_t) keys[i]->bv_len, &ent->keys.val[i], &l); } ber_bvecfree(keys); } else { #if 1 /* * This violates the ASN1 but it allows a principal to * be related to a general directory entry without creating * the keys. Hopefully it's OK. */ ent->keys.len = 0; ent->keys.val = NULL; #else ret = HDB_ERR_NOENTRY; goto out; #endif } values = ldap_get_values(HDB2LDAP(db), msg, "krb5EncryptionType"); if (values != NULL) { int i; ent->etypes = malloc(sizeof(*(ent->etypes))); if (ent->etypes == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ent->etypes->len = ldap_count_values(values); ent->etypes->val = calloc(ent->etypes->len, sizeof(int)); if (ent->etypes->val == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } for (i = 0; i < ent->etypes->len; i++) { ent->etypes->val[i] = atoi(values[i]); } ldap_value_free(values); } /* manually construct the NT (type 23) key */ ret = LDAP_get_string_value(db, msg, "sambaNTPassword", &ntPasswordIN); if (ret == 0) { int *etypes; Key *keys; keys = realloc(ent->keys.val, (ent->keys.len + 1) * sizeof(ent->keys.val[0])); if (keys == NULL) { free(ntPasswordIN); krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ent->keys.val = keys; memset(&ent->keys.val[ent->keys.len], 0, sizeof(Key)); ent->keys.val[ent->keys.len].key.keytype = ETYPE_ARCFOUR_HMAC_MD5; ret = krb5_data_alloc (&ent->keys.val[ent->keys.len].key.keyvalue, 16); if (ret) { krb5_set_error_string(context, "malloc: out of memory"); free(ntPasswordIN); ret = ENOMEM; goto out; } ret = hex_decode(ntPasswordIN, ent->keys.val[ent->keys.len].key.keyvalue.data, 16); ent->keys.len++; if (ent->etypes == NULL) { ent->etypes = malloc(sizeof(*(ent->etypes))); if (ent->etypes == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ent->etypes->val = NULL; ent->etypes->len = 0; } etypes = realloc(ent->etypes->val, (ent->etypes->len + 1) * sizeof(ent->etypes->val[0])); if (etypes == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ent->etypes->val = etypes; ent->etypes->val[ent->etypes->len] = ETYPE_ARCFOUR_HMAC_MD5; ent->etypes->len++; } ret = LDAP_get_generalized_time_value(db, msg, "createTimestamp", &ent->created_by.time); if (ret) ent->created_by.time = time(NULL); ent->created_by.principal = NULL; ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); if (ret == 0) { if (LDAP_dn2principal(context, db, dn, &ent->created_by.principal) != 0) { ent->created_by.principal = NULL; } free(dn); } ent->modified_by = (Event *) malloc(sizeof(Event)); if (ent->modified_by == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", &ent->modified_by->time); if (ret == 0) { ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); if (LDAP_dn2principal(context, db, dn, &ent->modified_by->principal)) ent->modified_by->principal = NULL; free(dn); } else { free(ent->modified_by); ent->modified_by = NULL; } ent->valid_start = malloc(sizeof(*ent->valid_start)); if (ent->valid_start == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidStart", ent->valid_start); if (ret) { /* OPTIONAL */ free(ent->valid_start); ent->valid_start = NULL; } ent->valid_end = malloc(sizeof(*ent->valid_end)); if (ent->valid_end == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd", ent->valid_end); if (ret) { /* OPTIONAL */ free(ent->valid_end); ent->valid_end = NULL; } ret = LDAP_get_integer_value(db, msg, "sambaKickoffTime", &tmp_time); if (ret == 0) { if (ent->valid_end == NULL) { ent->valid_end = malloc(sizeof(*ent->valid_end)); if (ent->valid_end == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } } *ent->valid_end = tmp_time; } ent->pw_end = malloc(sizeof(*ent->pw_end)); if (ent->pw_end == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd", ent->pw_end); if (ret) { /* OPTIONAL */ free(ent->pw_end); ent->pw_end = NULL; } ret = LDAP_get_integer_value(db, msg, "sambaPwdMustChange", &tmp_time); if (ret == 0) { if (ent->pw_end == NULL) { ent->pw_end = malloc(sizeof(*ent->pw_end)); if (ent->pw_end == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } } *ent->pw_end = tmp_time; } #if 0 /* we we have last_pw_change */ ent->last_pw_change = malloc(sizeof(*ent->last_pw_change)); if (ent->last_pw_change == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_integer_value(db, msg, "sambaPwdLastSet", &tmp_time); if (ret) { /* OPTIONAL */ free(ent->last_pw_change); ent->last_pw_change = NULL; } else *ent->last_pw_change = tmp_time; #endif ent->max_life = malloc(sizeof(*ent->max_life)); if (ent->max_life == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxLife", ent->max_life); if (ret) { free(ent->max_life); ent->max_life = NULL; } ent->max_renew = malloc(sizeof(*ent->max_renew)); if (ent->max_renew == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", ent->max_renew); if (ret) { free(ent->max_renew); ent->max_renew = NULL; } values = ldap_get_values(HDB2LDAP(db), msg, "krb5KDCFlags"); if (values != NULL) { errno = 0; tmp = strtoul(values[0], (char **) NULL, 10); if (tmp == ULONG_MAX && errno == ERANGE) { krb5_set_error_string(context, "strtoul: could not convert flag"); ret = ERANGE; goto out; } } else { tmp = 0; } ent->flags = int2HDBFlags(tmp); /* Try and find Samba flags to put into the mix */ ret = LDAP_get_string_value(db, msg, "sambaAcctFlags", &samba_acct_flags); if (ret == 0) { /* parse the [UXW...] string: 'N' No password 'D' Disabled 'H' Homedir required 'T' Temp account. 'U' User account (normal) 'M' MNS logon user account - what is this ? 'W' Workstation account 'S' Server account 'L' Locked account 'X' No Xpiry on password 'I' Interdomain trust account */ int i; int flags_len = strlen(samba_acct_flags); if (flags_len < 2) goto out2; if (samba_acct_flags[0] != '[' || samba_acct_flags[flags_len - 1] != ']') goto out2; /* Allow forwarding */ if (samba_forwardable) ent->flags.forwardable = TRUE; for (i=0; i < flags_len; i++) { switch (samba_acct_flags[i]) { case ' ': case '[': case ']': break; case 'N': /* how to handle no password in kerberos? */ break; case 'D': ent->flags.invalid = TRUE; break; case 'H': break; case 'T': /* temp duplicate */ ent->flags.invalid = TRUE; break; case 'U': ent->flags.client = TRUE; break; case 'M': break; case 'W': case 'S': ent->flags.server = TRUE; ent->flags.client = TRUE; break; case 'L': ent->flags.invalid = TRUE; break; case 'X': if (ent->pw_end) { free(ent->pw_end); ent->pw_end = NULL; } break; case 'I': ent->flags.server = TRUE; ent->flags.client = TRUE; break; } } out2: free(samba_acct_flags); } ret = 0; out: if (unparsed_name) free(unparsed_name); if (ret) hdb_free_entry(context, ent); return ret; }
/* * 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; }
STDMETHODIMP CLDAPQuery::nextResults( /* [in] */ LONG results_id, /* [in] */ ULONG num_results, /* [retval][out] */ SAFEARRAY** result) { CComSafeArray<VARIANT> dnList(0UL); ÑConnectInfo *cinfo = NULL; ÑResultsInfo *presinfo = NULL; m_errorCode = 0L; for(int i = 0; i < m_connections.GetSize(); i++) { ÑConnectInfo * const currentConnectInfo = m_connections.GetValueAt(i); if(currentConnectInfo) { ÑResultsInfo * const resInfo = currentConnectInfo->findResult(results_id); if(resInfo) { cinfo = currentConnectInfo; presinfo = resInfo; break; } } } if(cinfo && presinfo && presinfo->pages()) { const PLDAP ld = cinfo->ld(); const PLDAPSearch pPages = presinfo->pages(); PLDAPMessage pMsg = NULL; const BOOL allResults = (num_results == 0UL); while((allResults || num_results > 0UL) && (m_errorCode = ldap_get_next_page_s(ld, pPages, NULL, (num_results < 1000UL && num_results > 0UL ? num_results : 1000UL), NULL, &pMsg)) == LDAP_SUCCESS) //not more the 1k results per query { if(pMsg) { for(PLDAPMessage entry = ldap_first_entry(ld, pMsg); entry != NULL && (allResults || num_results-- > 0UL); entry = ldap_next_entry(ld, entry)) { CComObject<CAssocObject> *obj; CComObject<CAssocObject>::CreateInstance(&obj); const PTCHAR dn = ldap_get_dn(ld, entry); obj->AddValue(_T("dn"), CComVariant(dn)); PTCHAR attr; BerElement* berElem = NULL; for(attr = ldap_first_attribute(ld, entry, &berElem); attr != NULL; attr = ldap_next_attribute(ld, entry, berElem)) { bool single = false; const AttrSchema* const schema = cinfo->attrSchemaLookup(attr); if(schema) { single = schema->single; if(schema->type == OctetString) //we need to work different only with binary data { PBERVAL *vals; if((vals = ldap_get_values_len(ld, entry, attr)) != NULL) { if(!single) { CComSafeArray<VARIANT> attrValues(ldap_count_values_len(vals)); for(LONG i = 0L; vals[i] != NULL; i++) { attrValues[i] = CAttributesSchema::getAttributeVariant(vals[i], schema->type); } obj->AddValue(attr, CComVariant(attrValues)); } else { obj->AddValue(attr, CAttributesSchema::getAttributeVariant(vals[0], schema->type)); } ldap_value_free_len(vals); } ldap_memfree(attr); continue; } } PTCHAR *vals; if((vals = ldap_get_values(ld, entry, attr)) != NULL && ldap_count_values(vals) > 0UL) { if(!single) { CComSafeArray<VARIANT> attrValues(ldap_count_values(vals)); for(LONG i = 0L; vals[i] != NULL; i++) { attrValues[i] = CComVariant(vals[i]); } obj->AddValue(attr, CComVariant(attrValues)); } else { obj->AddValue(attr, CComVariant(vals[0])); } ldap_value_free(vals); } else { BOOL last = FALSE; LONG start = 0L; CComSafeArray<VARIANT> attrValues(0UL); do { CString attrWithRange; if(last) attrWithRange.Format(_T("%s;range=%ld-*"), attr, start); else attrWithRange.Format(_T("%s;range=%ld-%ld"), attr, start, start+999L); CSimpleArray<PTCHAR> a; a.Add(attrWithRange.GetBuffer()); a.Add(NULL); PLDAPMessage pItemMsg = NULL; if(ldap_search_s(ld, dn, LDAP_SCOPE_BASE, _T("(objectClass=*)"), a.GetData(), 0, &pItemMsg) == LDAP_SUCCESS) { PLDAPMessage const itemEntry = ldap_first_entry(ld, pItemMsg); if(itemEntry) { if((vals = ldap_get_values(ld, itemEntry, attrWithRange.GetBuffer())) != NULL) { if(ldap_count_values(vals) == 0) { if(last) start = -1L; //leave loop if already last last = TRUE; } else { for(LONG i = 0L; vals[i] != NULL; i++) { attrValues.Add(CComVariant(vals[i])); } if(last) start = -1L; //leave loop else start += 1000L; //next results } ldap_value_free(vals); } else { if(last) start = -1L; //leave loop if already last last = TRUE; } } else { start = -1L; //leave loop } ldap_msgfree(pItemMsg); } else { start = -1L; //leave loop } } while (start >= 0L); obj->AddValue(attr, CComVariant(attrValues)); } ldap_memfree(attr); } dnList.Add(CComVariant(obj)); ldap_memfree(dn); } ldap_msgfree(pMsg); } } if(m_errorCode != LDAP_SUCCESS && m_errorCode != LDAP_SIZELIMIT_EXCEEDED) { cinfo->removeResult(results_id); } if(m_errorCode == LDAP_NO_RESULTS_RETURNED || m_errorCode == LDAP_MORE_RESULTS_TO_RETURN || m_errorCode == LDAP_SIZELIMIT_EXCEEDED) m_errorCode = LDAP_SUCCESS; } *result = dnList.Detach(); return S_OK; }
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); } }
DWORD LwLdapGetStringsWithExtDnResult( IN HANDLE hDirectory, IN LDAPMessage* pMessage, IN PCSTR pszFieldName, IN BOOLEAN bDoSidParsing, OUT PSTR** pppszValues, OUT PDWORD pdwNumValues ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; PSTR *ppszLDAPValues = NULL; PSTR *ppszValues = NULL; INT iNum = 0; DWORD dwNumValues = 0; int iValue = 0; LW_BAIL_ON_INVALID_HANDLE(hDirectory); pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; LW_BAIL_ON_INVALID_POINTER(pMessage); ppszLDAPValues = (PSTR*)ldap_get_values(pDirectory->ld, pMessage, pszFieldName); if (ppszLDAPValues) { iNum = ldap_count_values(ppszLDAPValues); if (iNum < 0) { dwError = LW_ERROR_LDAP_ERROR; BAIL_ON_LW_ERROR(dwError); } else if (iNum > 0) { dwError = LwAllocateMemory((iNum+1)*sizeof(PSTR), OUT_PPVOID(&ppszValues)); BAIL_ON_LW_ERROR(dwError); dwNumValues = 0; for (iValue = 0; iValue < iNum; iValue++) { if (bDoSidParsing) { dwError = LwLdapParseExtendedDNResult(ppszLDAPValues[iValue], &ppszValues[dwNumValues]); BAIL_ON_LW_ERROR(dwError); } else { dwError = LwAllocateString(ppszLDAPValues[iValue], &ppszValues[dwNumValues]); BAIL_ON_LW_ERROR(dwError); } if (ppszValues[dwNumValues]) { dwNumValues++; } } } } *pppszValues = ppszValues; *pdwNumValues = dwNumValues; cleanup: if (ppszLDAPValues) { ldap_value_free(ppszLDAPValues); } return dwError; error: LwFreeNullTerminatedStringArray(ppszValues); *pppszValues = NULL; *pdwNumValues = 0; goto cleanup; }