Exemple #1
0
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;
}
Exemple #2
0
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);
        }

    }
}
Exemple #3
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);
}
Exemple #4
0
 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;
}
Exemple #5
0
/** 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;
}
Exemple #7
0
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);
}
Exemple #8
0
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;
}
Exemple #11
0
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);
}
Exemple #12
0
/*% 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);
}
Exemple #13
0
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;
}
Exemple #14
0
/*
 * Learn LDAP attributes and stuff them into the vCard.
 * Returns nonzero if we changed anything.
 */
int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v)
{
	int changed_something = 0;
	LDAP *ldserver = NULL;
	int i;
	struct timeval tv;
	LDAPMessage *search_result = NULL;
	LDAPMessage *entry = NULL;
	char **givenName;
	char **sn;
	char **cn;
	char **initials;
	char **o;
	char **street;
	char **l;
	char **st;
	char **postalCode;
	char **telephoneNumber;
	char **mobile;
	char **homePhone;
	char **facsimileTelephoneNumber;
	char **mail;
	char **uid;
	char **homeDirectory;
	char **uidNumber;
	char **loginShell;
	char **gidNumber;
	char **c;
	char **title;
	char **uuid;
	char *attrs[] = { "*","+",NULL};

	if (!ldap_dn) return(0);
	if (!v) return(0);

	if (ctdl_ldap_initialize(&ldserver) != LDAP_SUCCESS) {
		return(0);
	}

	ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version);
	ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);

	striplt(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 */
}
Exemple #15
0
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 );
}
Exemple #16
0
int
ldap_count_values_len( struct berval **vals )
{
	return( ldap_count_values( (char **) vals ) );
}
Exemple #17
0
// 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;
}
Exemple #18
0
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;
}
Exemple #19
0
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);
        }
    }
}
Exemple #20
0
/*
 * 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;
}
Exemple #21
0
/*
 * 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;
}
Exemple #22
0
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;
}
Exemple #23
0
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);
	}
}
Exemple #24
0
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;
}