1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * CDDL HEADER START
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * The contents of this file are subject to the terms of the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Common Development and Distribution License (the "License").
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * You may not use this file except in compliance with the License.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * or http://www.opensolaris.org/os/licensing.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * See the License for the specific language governing permissions
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * and limitations under the License.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * When distributing Covered Code, include this CDDL HEADER in each
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * If applicable, add the following below this CDDL HEADER, with the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * fields enclosed by brackets "[]" replaced with your own identifying
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * information: Portions Copyright [yyyy] [name of copyright owner]
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * CDDL HEADER END
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Retrieve directory information for Active Directory users.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <ldap.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <lber.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <pwd.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <malloc.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <string.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <stdlib.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <netdb.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <libadutils.h>
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh#include <libuutil.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <note.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <assert.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory_private.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "idmapd.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <rpcsvc/idmap_prot.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory_server_impl.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Information required by the function that handles the callback from LDAP
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * when responses are received.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstruct cbinfo {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char * const *attrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *entry;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *domain;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown};
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic void directory_provider_ad_cb(LDAP *ld, LDAPMessage **ldapres, int rc,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int qid, void *argp);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic void directory_provider_ad_cb1(LDAP *ld, LDAPMessage *msg,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct cbinfo *cbinfo);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t bv_list_dav(directory_values_rpc *lvals,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct berval **bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t directory_provider_ad_lookup(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *pent, const char * const * attrs, int nattrs,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *domain, const char *filter);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t get_domain(LDAP *ld, LDAPMessage *ldapres,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char **domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t directory_provider_ad_utils_error(char *func, int rc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#if defined(DUMP_VALUES)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic void dump_bv_list(const char *attr, struct berval **bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#endif
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#define MAX_EXTRA_ATTRS 1 /* sAMAccountName */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Add an entry to a NULL-terminated list, if it's not already there.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Assumes that the list has been allocated large enough for all additions,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * and prefilled with NULL.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownmaybe_add_to_list(const char **list, const char *s)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (; *list != NULL; list++) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (uu_strcaseeq(*list, s))
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *list = s;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Copy a counted attribute list to a NULL-terminated one.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * In the process, examine the requested attributes and augment
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * the list as required to support any synthesized attributes
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * requested.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownconst char **
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browncopy_and_augment_attr_list(char **req_list, int req_list_len)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char **new_list;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown new_list =
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown calloc(req_list_len + MAX_EXTRA_ATTRS + 1, sizeof (*new_list));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (new_list == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) memcpy(new_list, req_list, req_list_len * sizeof (char *));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < req_list_len; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *a = req_list[i];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that you must update MAX_EXTRA_ATTRS above if you
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * add to this list.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (uu_strcaseeq(a, "x-sun-canonicalName")) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown maybe_add_to_list(new_list, "sAMAccountName");
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown continue;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* None needed for x-sun-provider */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (new_list);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Retrieve information by name.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Called indirectly through the Directory_provider_static structure.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_provider_ad_get(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *del,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list *ids,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *types,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list *attrs)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char **attrs2;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * If we don't have any AD servers handy, we can't find anything.
b3700b074e637f8c6991b70754c88a2cfffb246bGordon Ross * XXX: this should be using our DC, not the GC.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (_idmapdstate.num_gcs < 1) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown RDLOCK_CONFIG()
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* 6835280 spurious lint error if the strlen is in the declaration */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int len = strlen(_idmapdstate.cfg->pgcfg.default_domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char default_domain[len + 1];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strcpy(default_domain, _idmapdstate.cfg->pgcfg.default_domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown UNLOCK_CONFIG();
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Turn our counted-array argument into a NULL-terminated array.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * At the same time, add in any attributes that we need to support
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * any requested synthesized attributes.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown attrs2 = copy_and_augment_attr_list(attrs->idmap_utf8str_list_val,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown attrs->idmap_utf8str_list_len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (attrs2 == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < ids->idmap_utf8str_list_len; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *vw[3];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int type;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Extract the type for this particular ID.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Advance to the next type, if it's there, else keep
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * using this type until we run out of IDs.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown type = *types;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (*(types+1) != '\0')
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown types++;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * If this entry has already been handled, one way or another,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * skip it.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (del[i].status != DIRECTORY_NOT_FOUND)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown continue;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *id = ids->idmap_utf8str_list_val[i];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Allow for expanding every character to \xx, plus some
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * space for the query syntax.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int id_len = strlen(id);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char filter[1000 + id_len*3];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (type == DIRECTORY_ID_SID[0]) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Mildly surprisingly, AD appears to allow searching
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * based on text SIDs. Must be a special case on the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * server end.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ldap_build_filter(filter, sizeof (filter),
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "(objectSid=%v)", NULL, NULL, NULL, id, NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_provider_ad_lookup(&del[i], attrs2,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown attrs->idmap_utf8str_list_len, NULL, filter);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_set_error(&del[i], de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown } else {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int id_len = strlen(id);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char name[id_len + 1];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char domain[id_len + 1];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown split_name(name, domain, id);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[0] = name;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (uu_streq(domain, "")) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[1] = default_domain;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown } else {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[1] = domain;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (type == DIRECTORY_ID_USER[0])
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[2] = "user";
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown else if (type == DIRECTORY_ID_GROUP[0])
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[2] = "group";
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown else
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vw[2] = "*";
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Try samAccountName.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that here we rely on checking the returned
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * distinguishedName to make sure that we found an
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * entry from the right domain, because there's no
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * attribute we can straightforwardly filter for to
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * match domain.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Eventually we should perhaps also try
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * userPrincipalName.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ldap_build_filter(filter, sizeof (filter),
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "(&(samAccountName=%v1)(objectClass=%v3))",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NULL, NULL, NULL, NULL, vw);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_provider_ad_lookup(&del[i], attrs2,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown attrs->idmap_utf8str_list_len, vw[1], filter);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_set_error(&del[i], de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto out;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("ENOMEM.AD",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Out of memory during AD lookup", NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownout:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(attrs2);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that attrs is NULL terminated, and that nattrs is the number
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * of attributes requested by the user... which might be fewer than are
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * in attrs because of attributes that we need for our own processing.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_provider_ad_lookup(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *pent,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char * const * attrs,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nattrs,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *domain,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *filter)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown adutils_ad_t *ad;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown adutils_rc batchrc;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct cbinfo cbinfo;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown adutils_query_state_t *qs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int rc;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * NEEDSWORK: Should eventually handle other forests.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * NEEDSWORK: Should eventually handle non-GC attributes.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai ad = _idmapdstate.gcs[0];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* Stash away information for the callback function. */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown cbinfo.attrs = attrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown cbinfo.nattrs = nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown cbinfo.entry = pent;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown cbinfo.domain = domain;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown rc = adutils_lookup_batch_start(ad, 1, directory_provider_ad_cb,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &cbinfo, &qs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (rc != ADUTILS_SUCCESS) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_provider_ad_utils_error(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "adutils_lookup_batch_start", rc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown rc = adutils_lookup_batch_add(qs, filter, attrs, domain,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NULL, &batchrc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (rc != ADUTILS_SUCCESS) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown adutils_lookup_batch_release(&qs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_provider_ad_utils_error(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "adutils_lookup_batch_add", rc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown rc = adutils_lookup_batch_end(&qs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (rc != ADUTILS_SUCCESS) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_provider_ad_utils_error(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "adutils_lookup_batch_end", rc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (batchrc != ADUTILS_SUCCESS) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * NEEDSWORK: We're consistently getting -9997 here.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * What does it mean?
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Callback from the LDAP functions when they get responses.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * We don't really need (nor want) asynchronous handling, but it's
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * what libadutils gives us.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_provider_ad_cb(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAP *ld,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAPMessage **ldapres,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int rc,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int qid,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown void *argp)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NOTE(ARGUNUSED(rc, qid))
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct cbinfo *cbinfo = (struct cbinfo *)argp;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAPMessage *msg = *ldapres;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (msg = ldap_first_entry(ld, msg);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown msg != NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown msg = ldap_next_entry(ld, msg)) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_provider_ad_cb1(ld, msg, cbinfo);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Process a single entry returned by an LDAP callback.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that this performs a function roughly equivalent to the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * directory*Populate() functions in the other providers.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given an LDAP response, populate the directory entry for return to
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * the caller. This one differs primarily in that we're working directly
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * with LDAP, so we don't have to do any attribute translation.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_provider_ad_cb1(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAP *ld,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAPMessage *msg,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct cbinfo *cbinfo)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nattrs = cbinfo->nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char * const *attrs = cbinfo->attrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *pent = cbinfo->entry;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_values_rpc *llvals;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *domain = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * We don't have a way to filter for entries from the right domain
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * in the LDAP query, so we check for it here. Searches based on
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * samAccountName might yield results from the wrong domain.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = get_domain(ld, msg, &domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (cbinfo->domain != NULL && !domain_eq(cbinfo->domain, domain))
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto out;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * If we've already found a match, error.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (pent->status != DIRECTORY_NOT_FOUND) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("Duplicate.AD",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Multiple matching entries found", NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown llvals = calloc(nattrs, sizeof (directory_values_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (llvals == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown pent->directory_entry_rpc_u.attrs.attrs_val = llvals;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown pent->directory_entry_rpc_u.attrs.attrs_len = nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown pent->status = DIRECTORY_FOUND;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < nattrs; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct berval **bv;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *a = attrs[i];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_values_rpc *val = &llvals[i];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown bv = ldap_get_values_len(ld, msg, a);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#if defined(DUMP_VALUES)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dump_bv_list(attrs[i], bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#endif
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (bv != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = bv_list_dav(val, bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ldap_value_free_len(bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh } else if (uu_strcaseeq(a, "x-sun-canonicalName")) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown bv = ldap_get_values_len(ld, msg, "sAMAccountName");
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (bv != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int n = ldap_count_values_len(bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (n > 0) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *tmp;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) asprintf(&tmp, "%.*s@%s",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown bv[0]->bv_len, bv[0]->bv_val,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (tmp == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *ctmp = tmp;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = str_list_dav(val, &ctmp, 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(tmp);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh } else if (uu_strcaseeq(a, "x-sun-provider")) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown const char *provider = "LDAP-AD";
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = str_list_dav(val, &provider, 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto out;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("ENOMEM.users",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "No memory allocating return value for user lookup", NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownerr:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_set_error(pent, de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownout:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(domain);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given a struct berval, populate a directory attribute value (which is a
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * list of values).
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that here we populate the DAV with the exact bytes that LDAP returns.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Back over in the client it appends a \0 so that strings are null
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * terminated.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownbv_list_dav(directory_values_rpc *lvals, struct berval **bv)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_value_rpc *dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int n;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown n = ldap_count_values_len(bv);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav = calloc(n, sizeof (directory_value_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_val = dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_len = n;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->found = TRUE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < n; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav[i].directory_value_rpc_val =
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh uu_memdup(bv[i]->bv_val, bv[i]->bv_len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav[i].directory_value_rpc_val == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav[i].directory_value_rpc_len = bv[i]->bv_len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.bv_list_dav",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying values"));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#if defined(DUMP_VALUES)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndump_bv_list(const char *attr, struct berval **bv)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (bv == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) fprintf(stderr, "%s: (empty)\n", attr);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; bv[i] != NULL; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) fprintf(stderr, "%s[%d] =\n", attr, i);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dump(stderr, " ", bv[i]->bv_val, bv[i]->bv_len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#endif /* DUMP_VALUES */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Return the domain associated with the specified entry.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownget_domain(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAP *ld,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown LDAPMessage *msg,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char **domain)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *domain = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *dn = ldap_get_dn(ld, msg);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dn == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char buf[100]; /* big enough for any int */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *m;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *s;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int err = ldap_get_lderrno(ld, &m, &s);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) snprintf(buf, sizeof (buf), "%d", err);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return directory_error("AD.get_domain.ldap_get_dn",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "ldap_get_dn: %1 (%2)\n"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "matched: %3\n"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "error: %4",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ldap_err2string(err), buf,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown m == NULL ? "(null)" : m,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown s == NULL ? "(null)" : s,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *domain = adutils_dn2dns(dn);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (*domain == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("Unknown.get_domain.adutils_dn2dns",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "get_domain: Unexpected error from adutils_dn2dns(%1)",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dn, NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(dn);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(dn);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given an error report from libadutils, generate a directory_error_t.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_provider_ad_utils_error(char *func, int rc)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char rcstr[100]; /* plenty for any int */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char code[100]; /* plenty for any int */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) snprintf(rcstr, sizeof (rcstr), "%d", rc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) snprintf(code, sizeof (code), "ADUTILS.%d", rc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error(code,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Error %2 from adutils function %1", func, rcstr, NULL));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstruct directory_provider_static directory_provider_ad = {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "AD",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_provider_ad_get,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown};