summaryrefslogtreecommitdiff
path: root/usr/src/cmd/idmap/idmapd/adutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/idmap/idmapd/adutils.c')
-rw-r--r--usr/src/cmd/idmap/idmapd/adutils.c1422
1 files changed, 118 insertions, 1304 deletions
diff --git a/usr/src/cmd/idmap/idmapd/adutils.c b/usr/src/cmd/idmap/idmapd/adutils.c
index d22ce169c9..f19706822e 100644
--- a/usr/src/cmd/idmap/idmapd/adutils.c
+++ b/usr/src/cmd/idmap/idmapd/adutils.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Processes name2sid & sid2name batched lookups for a given user or
* computer from an AD Directory server using GSSAPI authentication
@@ -47,14 +45,12 @@
#include <errno.h>
#include <assert.h>
#include <limits.h>
+#include <time.h>
#include <sys/u8_textprep.h>
+#include "libadutils.h"
#include "nldaputils.h"
#include "idmapd.h"
-/*
- * Internal data structures for this code
- */
-
/* Attribute names and filter format strings */
#define SAN "sAMAccountName"
#define OBJSID "objectSid"
@@ -62,58 +58,8 @@
#define SANFILTER "(sAMAccountName=%.*s)"
#define OBJSIDFILTER "(objectSid=%s)"
-/*
- * This should really be in some <sys/sid.h> file or so; we have a
- * private version of sid_t, and so must other components of ON until we
- * rationalize this.
- */
-typedef struct sid {
- uchar_t version;
- uchar_t sub_authority_count;
- uint64_t authority; /* really, 48-bits */
- rid_t sub_authorities[SID_MAX_SUB_AUTHORITIES];
-} sid_t;
-
-/* A single DS */
-typedef struct ad_host {
- struct ad_host *next;
- ad_t *owner; /* ad_t to which this belongs */
- pthread_mutex_t lock;
- LDAP *ld; /* LDAP connection */
- uint32_t ref; /* ref count */
- time_t idletime; /* time since last activity */
- int dead; /* error on LDAP connection */
- /*
- * Used to distinguish between different instances of LDAP
- * connections to this same DS. We need this so we never mix up
- * results for a given msgID from one connection with those of
- * another earlier connection where two batch state structures
- * share this ad_host object but used different LDAP connections
- * to send their LDAP searches.
- */
- uint64_t generation;
-
- /* LDAP DS info */
- char *host;
- int port;
-
- /* hardwired to SASL GSSAPI only for now */
- char *saslmech;
- unsigned saslflags;
-
- /* Number of outstanding search requests */
- uint32_t max_requests;
- uint32_t num_requests;
-} ad_host_t;
-
-/* A set of DSs for a given AD partition; ad_t typedef comes from adutil.h */
-struct ad {
- char *dflt_w2k_dom; /* used to qualify bare names */
- pthread_mutex_t lock;
- uint32_t ref;
- ad_host_t *last_adh;
- idmap_ad_partition_t partition; /* Data or global catalog? */
-};
+void idmap_ldap_res_search_cb(LDAP *ld, LDAPMessage **res, int rc,
+ int qid, void *argp);
/*
* A place to put the results of a batched (async) query
@@ -140,9 +86,9 @@ typedef struct idmap_q {
char **attr; /* Attr for name mapping */
char **value; /* value for name mapping */
idmap_retcode *rc;
+ adutils_rc ad_rc;
+ adutils_result_t *result;
- /* lookup state */
- int msgid; /* LDAP message ID */
/*
* The LDAP search entry result is placed here to be processed
* when the search done result is received.
@@ -152,185 +98,21 @@ typedef struct idmap_q {
/* Batch context structure; typedef is in header file */
struct idmap_query_state {
- idmap_query_state_t *next;
+ adutils_query_state_t *qs;
int qcount; /* how many queries */
- int ref_cnt; /* reference count */
- pthread_cond_t cv; /* Condition wait variable */
uint32_t qlastsent;
- uint32_t qinflight; /* how many queries in flight */
- uint16_t qdead; /* oops, lost LDAP connection */
- ad_host_t *qadh; /* LDAP connection */
- uint64_t qadh_gen; /* same as qadh->generation */
const char *ad_unixuser_attr;
const char *ad_unixgroup_attr;
idmap_q_t queries[1]; /* array of query results */
};
-/*
- * List of query state structs -- needed so we can "route" LDAP results
- * to the right context if multiple threads should be using the same
- * connection concurrently
- */
-static idmap_query_state_t *qstatehead = NULL;
-static pthread_mutex_t qstatelock = PTHREAD_MUTEX_INITIALIZER;
-
-/*
- * List of DSs, needed by the idle connection reaper thread
- */
-static ad_host_t *host_head = NULL;
static pthread_t reaperid = 0;
-static pthread_mutex_t adhostlock = PTHREAD_MUTEX_INITIALIZER;
-
-
-static void
-idmap_lookup_unlock_batch(idmap_query_state_t **state);
-
-static void
-delete_ds(ad_t *ad, const char *host, int port);
-
-/*ARGSUSED*/
-static int
-idmap_saslcallback(LDAP *ld, unsigned flags, void *defaults, void *prompts)
-{
- sasl_interact_t *interact;
-
- if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
- return (LDAP_PARAM_ERROR);
-
- /* There should be no extra arguemnts for SASL/GSSAPI authentication */
- for (interact = prompts; interact->id != SASL_CB_LIST_END;
- interact++) {
- interact->result = NULL;
- interact->len = 0;
- }
- return (LDAP_SUCCESS);
-}
-
-
-/*
- * Turn "dc=foo,dc=bar,dc=com" into "foo.bar.com"; ignores any other
- * attributes (CN, etc...). We don't need the reverse, for now.
- */
-static
-char *
-dn2dns(const char *dn)
-{
- char **rdns = NULL;
- char **attrs = NULL;
- char **labels = NULL;
- char *dns = NULL;
- char **rdn, **attr, **label;
- int maxlabels = 5;
- int nlabels = 0;
- int dnslen;
-
- /*
- * There is no reverse of ldap_dns_to_dn() in our libldap, so we
- * have to do the hard work here for now.
- */
-
- /*
- * This code is much too liberal: it looks for "dc" attributes
- * in all RDNs of the DN. In theory this could cause problems
- * if people were to use "dc" in nodes other than the root of
- * the tree, but in practice noone, least of all Active
- * Directory, does that.
- *
- * On the other hand, this code is much too conservative: it
- * does not make assumptions about ldap_explode_dn(), and _that_
- * is the true for looking at every attr of every RDN.
- *
- * Since we only ever look at dc and those must be DNS labels,
- * at least until we get around to supporting IDN here we
- * shouldn't see escaped labels from AD nor from libldap, though
- * the spec (RFC2253) does allow libldap to escape things that
- * don't need escaping -- if that should ever happen then
- * libldap will need a spanking, and we can take care of that.
- */
-
- /* Explode a DN into RDNs */
- if ((rdns = ldap_explode_dn(dn, 0)) == NULL)
- return (NULL);
-
- labels = calloc(maxlabels + 1, sizeof (char *));
- label = labels;
-
- for (rdn = rdns; *rdn != NULL; rdn++) {
- if (attrs != NULL)
- ldap_value_free(attrs);
-
- /* Explode each RDN, look for DC attr, save val as DNS label */
- if ((attrs = ldap_explode_rdn(rdn[0], 0)) == NULL)
- goto done;
-
- for (attr = attrs; *attr != NULL; attr++) {
- if (strncasecmp(*attr, "dc=", 3) != 0)
- continue;
-
- /* Found a DNS label */
- labels[nlabels++] = strdup((*attr) + 3);
-
- if (nlabels == maxlabels) {
- char **tmp;
- tmp = realloc(labels,
- sizeof (char *) * (maxlabels + 1));
-
- if (tmp == NULL)
- goto done;
-
- labels = tmp;
- labels[nlabels] = NULL;
- }
-
- /* There should be just one DC= attr per-RDN */
- break;
- }
- }
-
- /*
- * Got all the labels, now join with '.'
- *
- * We need room for nlabels - 1 periods ('.'), one nul
- * terminator, and the strlen() of each label.
- */
- dnslen = nlabels;
- for (label = labels; *label != NULL; label++)
- dnslen += strlen(*label);
-
- if ((dns = malloc(dnslen)) == NULL)
- goto done;
-
- *dns = '\0';
-
- for (label = labels; *label != NULL; label++) {
- (void) strlcat(dns, *label, dnslen);
- /*
- * NOTE: the last '.' won't be appended -- there's no room
- * for it!
- */
- (void) strlcat(dns, ".", dnslen);
- }
-
-done:
- if (labels != NULL) {
- for (label = labels; *label != NULL; label++)
- free(*label);
- free(labels);
- }
- if (attrs != NULL)
- ldap_value_free(attrs);
- if (rdns != NULL)
- ldap_value_free(rdns);
-
- return (dns);
-}
/*
* Keep connection management simple for now, extend or replace later
* with updated libsldap code.
*/
#define ADREAPERSLEEP 60
-#define ADCONN_TIME 300
/*
* Idle connection reaping side of connection management
@@ -343,8 +125,6 @@ static
void
adreaper(void *arg)
{
- ad_host_t *adh;
- time_t now;
timespec_t ts;
ts.tv_sec = ADREAPERSLEEP;
@@ -356,270 +136,8 @@ adreaper(void *arg)
* portable than usleep(3C)
*/
(void) nanosleep(&ts, NULL);
- (void) pthread_mutex_lock(&adhostlock);
- now = time(NULL);
- for (adh = host_head; adh != NULL; adh = adh->next) {
- (void) pthread_mutex_lock(&adh->lock);
- if (adh->ref == 0 && adh->idletime != 0 &&
- adh->idletime + ADCONN_TIME < now) {
- if (adh->ld) {
- (void) ldap_unbind(adh->ld);
- adh->ld = NULL;
- adh->idletime = 0;
- adh->ref = 0;
- }
- }
- (void) pthread_mutex_unlock(&adh->lock);
- }
- (void) pthread_mutex_unlock(&adhostlock);
- }
-}
-
-int
-idmap_ad_alloc(ad_t **new_ad, const char *default_domain,
- idmap_ad_partition_t part)
-{
- ad_t *ad;
-
- *new_ad = NULL;
-
- if ((default_domain == NULL || *default_domain == '\0') &&
- part != IDMAP_AD_GLOBAL_CATALOG)
- return (-1);
-
- if ((ad = calloc(1, sizeof (ad_t))) == NULL)
- return (-1);
-
- ad->ref = 1;
- ad->partition = part;
-
- if (default_domain == NULL)
- default_domain = "";
-
- if ((ad->dflt_w2k_dom = strdup(default_domain)) == NULL)
- goto err;
-
- if (pthread_mutex_init(&ad->lock, NULL) != 0)
- goto err;
-
- *new_ad = ad;
-
- return (0);
-err:
- if (ad->dflt_w2k_dom != NULL)
- free(ad->dflt_w2k_dom);
- free(ad);
- return (-1);
-}
-
-
-void
-idmap_ad_free(ad_t **ad)
-{
- ad_host_t *p;
- ad_host_t *prev;
-
- if (ad == NULL || *ad == NULL)
- return;
-
- (void) pthread_mutex_lock(&(*ad)->lock);
-
- if (atomic_dec_32_nv(&(*ad)->ref) > 0) {
- (void) pthread_mutex_unlock(&(*ad)->lock);
- *ad = NULL;
- return;
- }
-
- (void) pthread_mutex_lock(&adhostlock);
- prev = NULL;
- p = host_head;
- while (p != NULL) {
- if (p->owner != (*ad)) {
- prev = p;
- p = p->next;
- continue;
- } else {
- delete_ds((*ad), p->host, p->port);
- if (prev == NULL)
- p = host_head;
- else
- p = prev->next;
- }
- }
- (void) pthread_mutex_unlock(&adhostlock);
-
- (void) pthread_mutex_unlock(&(*ad)->lock);
- (void) pthread_mutex_destroy(&(*ad)->lock);
-
- free((*ad)->dflt_w2k_dom);
- free(*ad);
-
- *ad = NULL;
-}
-
-
-static
-int
-idmap_open_conn(ad_host_t *adh, int timeoutsecs)
-{
- int zero = 0;
- int ldversion, rc;
- int timeoutms = timeoutsecs * 1000;
-
- if (adh == NULL)
- return (0);
-
- (void) pthread_mutex_lock(&adh->lock);
-
- if (!adh->dead && adh->ld != NULL)
- /* done! */
- goto out;
-
- if (adh->ld != NULL) {
- (void) ldap_unbind(adh->ld);
- adh->ld = NULL;
- }
- adh->num_requests = 0;
-
- atomic_inc_64(&adh->generation);
-
- /* Open and bind an LDAP connection */
- adh->ld = ldap_init(adh->host, adh->port);
- if (adh->ld == NULL) {
- idmapdlog(LOG_INFO, "ldap_init() to server "
- "%s port %d failed. (%s)", adh->host,
- adh->port, strerror(errno));
- goto out;
- }
- ldversion = LDAP_VERSION3;
- (void) ldap_set_option(adh->ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion);
- (void) ldap_set_option(adh->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- (void) ldap_set_option(adh->ld, LDAP_OPT_TIMELIMIT, &zero);
- (void) ldap_set_option(adh->ld, LDAP_OPT_SIZELIMIT, &zero);
- (void) ldap_set_option(adh->ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeoutms);
- (void) ldap_set_option(adh->ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
- rc = ldap_sasl_interactive_bind_s(adh->ld, "" /* binddn */,
- adh->saslmech, NULL, NULL, adh->saslflags, &idmap_saslcallback,
- NULL);
-
- if (rc != LDAP_SUCCESS) {
- (void) ldap_unbind(adh->ld);
- adh->ld = NULL;
- idmapdlog(LOG_INFO, "ldap_sasl_interactive_bind_s() to server "
- "%s port %d failed. (%s)", adh->host, adh->port,
- ldap_err2string(rc));
+ adutils_reap_idle_connections();
}
-
- idmapdlog(LOG_DEBUG, "Using global catalog server %s:%d",
- adh->host, adh->port);
-
-out:
- if (adh->ld != NULL) {
- atomic_inc_32(&adh->ref);
- adh->idletime = time(NULL);
- adh->dead = 0;
- (void) pthread_mutex_unlock(&adh->lock);
- return (1);
- }
-
- (void) pthread_mutex_unlock(&adh->lock);
- return (0);
-}
-
-
-/*
- * Connection management: find an open connection or open one
- */
-static
-ad_host_t *
-idmap_get_conn(ad_t *ad)
-{
- ad_host_t *adh = NULL;
- int tries;
- int dscount = 0;
- int timeoutsecs = IDMAPD_LDAP_OPEN_TIMEOUT;
-
-retry:
- (void) pthread_mutex_lock(&adhostlock);
-
- if (host_head == NULL) {
- (void) pthread_mutex_unlock(&adhostlock);
- goto out;
- }
-
- if (dscount == 0) {
- /*
- * First try: count the number of DSes.
- *
- * Integer overflow is not an issue -- we can't have so many
- * DSes because they won't fit even DNS over TCP, and SMF
- * shouldn't let you set so many.
- */
- for (adh = host_head, tries = 0; adh != NULL; adh = adh->next) {
- if (adh->owner == ad)
- dscount++;
- }
-
- if (dscount == 0) {
- (void) pthread_mutex_unlock(&adhostlock);
- goto out;
- }
-
- tries = dscount * 3; /* three tries per-ds */
-
- /*
- * Begin round-robin at the next DS in the list after the last
- * one that we had a connection to, else start with the first
- * DS in the list.
- */
- adh = ad->last_adh;
- }
-
- /*
- * Round-robin -- pick the next one on the list; if the list
- * changes on us, no big deal, we'll just potentially go
- * around the wrong number of times.
- */
- for (;;) {
- if (adh != NULL && adh->ld != NULL && !adh->dead)
- break;
- if (adh == NULL || (adh = adh->next) == NULL)
- adh = host_head;
- if (adh->owner == ad)
- break;
- }
-
- ad->last_adh = adh;
- (void) pthread_mutex_unlock(&adhostlock);
-
-
- /* Found suitable DS, open it if not already opened */
- if (idmap_open_conn(adh, timeoutsecs))
- return (adh);
-
- tries--;
-
- if ((tries % dscount) == 0)
- timeoutsecs *= 2;
-
- if (tries > 0)
- goto retry;
-
-out:
- idmapdlog(LOG_NOTICE, "Couldn't open an LDAP connection to any global "
- "catalog server!");
-
- return (NULL);
-}
-
-static
-void
-idmap_release_conn(ad_host_t *adh)
-{
- (void) pthread_mutex_lock(&adh->lock);
- if (atomic_dec_32_nv(&adh->ref) == 0)
- adh->idletime = time(NULL);
- (void) pthread_mutex_unlock(&adh->lock);
}
/*
@@ -628,415 +146,69 @@ idmap_release_conn(ad_host_t *adh)
*/
int
-idmap_add_ds(ad_t *ad, const char *host, int port)
+idmap_add_ds(adutils_ad_t *ad, const char *host, int port)
{
- ad_host_t *p;
- ad_host_t *new = NULL;
- int ret = -1;
-
- if (port == 0)
- port = (int)ad->partition;
-
- (void) pthread_mutex_lock(&adhostlock);
- for (p = host_head; p != NULL; p = p->next) {
- if (p->owner != ad)
- continue;
-
- if (strcmp(host, p->host) == 0 && p->port == port) {
- /* already added */
- ret = 0;
- goto err;
- }
- }
-
- /* add new entry */
- new = (ad_host_t *)calloc(1, sizeof (ad_host_t));
- if (new == NULL)
- goto err;
- new->owner = ad;
- new->port = port;
- new->dead = 0;
- new->max_requests = 80;
- new->num_requests = 0;
- if ((new->host = strdup(host)) == NULL)
- goto err;
-
- /* default to SASL GSSAPI only for now */
- new->saslflags = LDAP_SASL_INTERACTIVE;
- new->saslmech = "GSSAPI";
-
- if ((ret = pthread_mutex_init(&new->lock, NULL)) != 0) {
- free(new->host);
- new->host = NULL;
- errno = ret;
- ret = -1;
- goto err;
- }
+ int ret = -1;
- /* link in */
- new->next = host_head;
- host_head = new;
+ if (adutils_add_ds(ad, host, port) == ADUTILS_SUCCESS)
+ ret = 0;
/* Start reaper if it doesn't exist */
- if (reaperid == 0)
+ if (ret == 0 && reaperid == 0)
(void) pthread_create(&reaperid, NULL,
(void *(*)(void *))adreaper, (void *)NULL);
-
-err:
- (void) pthread_mutex_unlock(&adhostlock);
-
- if (ret != 0 && new != NULL) {
- if (new->host != NULL) {
- (void) pthread_mutex_destroy(&new->lock);
- free(new->host);
- }
- free(new);
- }
-
return (ret);
}
-/*
- * Free a DS configuration.
- * Caller must lock the adhostlock mutex
- */
-static void
-delete_ds(ad_t *ad, const char *host, int port)
-{
- ad_host_t **p, *q;
-
- for (p = &host_head; *p != NULL; p = &((*p)->next)) {
- if ((*p)->owner != ad || strcmp(host, (*p)->host) != 0 ||
- (*p)->port != port)
- continue;
- /* found */
- if ((*p)->ref > 0)
- break; /* still in use */
-
- q = *p;
- *p = (*p)->next;
-
- (void) pthread_mutex_destroy(&q->lock);
-
- if (q->ld)
- (void) ldap_unbind(q->ld);
- if (q->host)
- free(q->host);
- free(q);
- break;
- }
-
-}
-
-
-/*
- * Convert a binary SID in a BerValue to a sid_t
- */
-static
-int
-idmap_getsid(BerValue *bval, sid_t *sidp)
-{
- int i, j;
- uchar_t *v;
- uint32_t a;
-
- /*
- * The binary format of a SID is as follows:
- *
- * byte #0: version, always 0x01
- * byte #1: RID count, always <= 0x0f
- * bytes #2-#7: SID authority, big-endian 48-bit unsigned int
- *
- * followed by RID count RIDs, each a little-endian, unsigned
- * 32-bit int.
- */
- /*
- * Sanity checks: must have at least one RID, version must be
- * 0x01, and the length must be 8 + rid count * 4
- */
- if (bval->bv_len > 8 && bval->bv_val[0] == 0x01 &&
- bval->bv_len == 1 + 1 + 6 + bval->bv_val[1] * 4) {
- v = (uchar_t *)bval->bv_val;
- sidp->version = v[0];
- sidp->sub_authority_count = v[1];
- sidp->authority =
- /* big endian -- so start from the left */
- ((u_longlong_t)v[2] << 40) |
- ((u_longlong_t)v[3] << 32) |
- ((u_longlong_t)v[4] << 24) |
- ((u_longlong_t)v[5] << 16) |
- ((u_longlong_t)v[6] << 8) |
- (u_longlong_t)v[7];
- for (i = 0; i < sidp->sub_authority_count; i++) {
- j = 8 + (i * 4);
- /* little endian -- so start from the right */
- a = (v[j + 3] << 24) | (v[j + 2] << 16) |
- (v[j + 1] << 8) | (v[j]);
- sidp->sub_authorities[i] = a;
- }
- return (0);
- }
- return (-1);
-}
-
-/*
- * Convert a sid_t to S-1-...
- */
-static
-char *
-idmap_sid2txt(sid_t *sidp)
-{
- int rlen, i, len;
- char *str, *cp;
-
- if (sidp->version != 1)
- return (NULL);
-
- len = sizeof ("S-1-") - 1;
-
- /*
- * We could optimize like so, but, why?
- * if (sidp->authority < 10)
- * len += 2;
- * else if (sidp->authority < 100)
- * len += 3;
- * else
- * len += snprintf(NULL, 0"%llu", sidp->authority);
- */
- len += snprintf(NULL, 0, "%llu", sidp->authority);
-
- /* Max length of a uint32_t printed out in ASCII is 10 bytes */
- len += 1 + (sidp->sub_authority_count + 1) * 10;
-
- if ((cp = str = malloc(len)) == NULL)
- return (NULL);
-
- rlen = snprintf(str, len, "S-1-%llu", sidp->authority);
-
- cp += rlen;
- len -= rlen;
-
- for (i = 0; i < sidp->sub_authority_count; i++) {
- assert(len > 0);
- rlen = snprintf(cp, len, "-%u", sidp->sub_authorities[i]);
- cp += rlen;
- len -= rlen;
- assert(len >= 0);
- }
-
- return (str);
-}
-
-/*
- * Convert a sid_t to on-the-wire encoding
- */
static
-int
-idmap_sid2binsid(sid_t *sid, uchar_t *binsid, int binsidlen)
-{
- uchar_t *p;
- int i;
- uint64_t a;
- uint32_t r;
-
- if (sid->version != 1 ||
- binsidlen != (1 + 1 + 6 + sid->sub_authority_count * 4))
- return (-1);
-
- p = binsid;
- *p++ = 0x01; /* version */
- /* sub authority count */
- *p++ = sid->sub_authority_count;
- /* Authority */
- a = sid->authority;
- /* big-endian -- start from left */
- *p++ = (a >> 40) & 0xFF;
- *p++ = (a >> 32) & 0xFF;
- *p++ = (a >> 24) & 0xFF;
- *p++ = (a >> 16) & 0xFF;
- *p++ = (a >> 8) & 0xFF;
- *p++ = a & 0xFF;
-
- /* sub-authorities */
- for (i = 0; i < sid->sub_authority_count; i++) {
- r = sid->sub_authorities[i];
- /* little-endian -- start from right */
- *p++ = (r & 0x000000FF);
- *p++ = (r & 0x0000FF00) >> 8;
- *p++ = (r & 0x00FF0000) >> 16;
- *p++ = (r & 0xFF000000) >> 24;
- }
-
- return (0);
-}
-
-/*
- * Convert a stringified SID (S-1-...) into a hex-encoded version of the
- * on-the-wire encoding, but with each pair of hex digits pre-pended
- * with a '\', so we can pass this to libldap.
- */
-static
-int
-idmap_txtsid2hexbinsid(const char *txt, const rid_t *rid,
- char *hexbinsid, int hexbinsidlen)
+idmap_retcode
+map_adrc2idmaprc(adutils_rc adrc)
{
- sid_t sid = { 0 };
- int i, j;
- const char *cp;
- char *ecp;
- u_longlong_t a;
- unsigned long r;
- uchar_t *binsid, b, hb;
-
- /* Only version 1 SIDs please */
- if (strncmp(txt, "S-1-", strlen("S-1-")) != 0)
- return (-1);
-
- if (strlen(txt) < (strlen("S-1-") + 1))
- return (-1);
-
- /* count '-'s */
- for (j = 0, cp = strchr(txt, '-');
- cp != NULL && *cp != '\0';
- j++, cp = strchr(cp + 1, '-')) {
- /* can't end on a '-' */
- if (*(cp + 1) == '\0')
- return (-1);
- }
-
- /* Adjust count for version and authority */
- j -= 2;
-
- /* we know the version number and RID count */
- sid.version = 1;
- sid.sub_authority_count = (rid != NULL) ? j + 1 : j;
-
- /* must have at least one RID, but not too many */
- if (sid.sub_authority_count < 1 ||
- sid.sub_authority_count > SID_MAX_SUB_AUTHORITIES)
- return (-1);
-
- /* check that we only have digits and '-' */
- if (strspn(txt + 1, "0123456789-") < (strlen(txt) - 1))
- return (-1);
-
- cp = txt + strlen("S-1-");
-
- /* 64-bit safe parsing of unsigned 48-bit authority value */
- errno = 0;
- a = strtoull(cp, &ecp, 10);
-
- /* errors parsing the authority or too many bits */
- if (cp == ecp || (a == 0 && errno == EINVAL) ||
- (a == ULLONG_MAX && errno == ERANGE) ||
- (a & 0x0000ffffffffffffULL) != a)
- return (-1);
-
- cp = ecp;
-
- sid.authority = (uint64_t)a;
-
- for (i = 0; i < j; i++) {
- if (*cp++ != '-')
- return (-1);
- /* 64-bit safe parsing of unsigned 32-bit RID */
- errno = 0;
- r = strtoul(cp, &ecp, 10);
- /* errors parsing the RID or too many bits */
- if (cp == ecp || (r == 0 && errno == EINVAL) ||
- (r == ULONG_MAX && errno == ERANGE) ||
- (r & 0xffffffffUL) != r)
- return (-1);
- sid.sub_authorities[i] = (uint32_t)r;
- cp = ecp;
- }
-
- /* check that all of the string SID has been consumed */
- if (*cp != '\0')
- return (-1);
-
- if (rid != NULL)
- sid.sub_authorities[j] = *rid;
-
- j = 1 + 1 + 6 + sid.sub_authority_count * 4;
-
- if (hexbinsidlen < (j * 3))
- return (-2);
-
- /* binary encode the SID */
- binsid = (uchar_t *)alloca(j);
- (void) idmap_sid2binsid(&sid, binsid, j);
-
- /* hex encode, with a backslash before each byte */
- for (ecp = hexbinsid, i = 0; i < j; i++) {
- b = binsid[i];
- *ecp++ = '\\';
- hb = (b >> 4) & 0xF;
- *ecp++ = (hb <= 0x9 ? hb + '0' : hb - 10 + 'A');
- hb = b & 0xF;
- *ecp++ = (hb <= 0x9 ? hb + '0' : hb - 10 + 'A');
+ switch (adrc) {
+ case ADUTILS_SUCCESS:
+ return (IDMAP_SUCCESS);
+ case ADUTILS_ERR_NOTFOUND:
+ return (IDMAP_ERR_NOTFOUND);
+ case ADUTILS_ERR_MEMORY:
+ return (IDMAP_ERR_MEMORY);
+ case ADUTILS_ERR_DOMAIN:
+ return (IDMAP_ERR_DOMAIN);
+ case ADUTILS_ERR_OTHER:
+ return (IDMAP_ERR_OTHER);
+ case ADUTILS_ERR_RETRIABLE_NET_ERR:
+ return (IDMAP_ERR_RETRIABLE_NET_ERR);
+ default:
+ return (IDMAP_ERR_INTERNAL);
}
- *ecp = '\0';
-
- return (0);
+ /* NOTREACHED */
}
-static
-char *
-convert_bval2sid(BerValue *bval, rid_t *rid)
-{
- sid_t sid;
-
- if (idmap_getsid(bval, &sid) < 0)
- return (NULL);
-
- /*
- * If desired and if the SID is what should be a domain/computer
- * user or group SID (i.e., S-1-5-w-x-y-z-<user/group RID>) then
- * save the last RID and truncate the SID
- */
- if (rid != NULL && sid.authority == 5 && sid.sub_authority_count == 5)
- *rid = sid.sub_authorities[--sid.sub_authority_count];
- return (idmap_sid2txt(&sid));
-}
-
-
idmap_retcode
-idmap_lookup_batch_start(ad_t *ad, int nqueries, idmap_query_state_t **state)
+idmap_lookup_batch_start(adutils_ad_t *ad, int nqueries,
+ idmap_query_state_t **state)
{
- idmap_query_state_t *new_state;
- ad_host_t *adh = NULL;
+ idmap_query_state_t *new_state;
+ adutils_rc rc;
*state = NULL;
if (ad == NULL)
return (IDMAP_ERR_INTERNAL);
- adh = idmap_get_conn(ad);
- if (adh == NULL)
- return (IDMAP_ERR_RETRIABLE_NET_ERR);
-
new_state = calloc(1, sizeof (idmap_query_state_t) +
(nqueries - 1) * sizeof (idmap_q_t));
-
if (new_state == NULL)
return (IDMAP_ERR_MEMORY);
- new_state->ref_cnt = 1;
- new_state->qadh = adh;
- new_state->qcount = nqueries;
- new_state->qadh_gen = adh->generation;
- /* should be -1, but the atomic routines want unsigned */
- new_state->qlastsent = 0;
- (void) pthread_cond_init(&new_state->cv, NULL);
-
- (void) pthread_mutex_lock(&qstatelock);
- new_state->next = qstatehead;
- qstatehead = new_state;
- (void) pthread_mutex_unlock(&qstatelock);
+ if ((rc = adutils_lookup_batch_start(ad, nqueries,
+ idmap_ldap_res_search_cb, new_state, &new_state->qs))
+ != ADUTILS_SUCCESS) {
+ free(new_state);
+ return (map_adrc2idmaprc(rc));
+ }
+ new_state->qcount = nqueries;
*state = new_state;
-
return (IDMAP_SUCCESS);
}
@@ -1052,83 +224,6 @@ idmap_lookup_batch_set_unixattr(idmap_query_state_t *state,
}
/*
- * Find the idmap_query_state_t to which a given LDAP result msgid on a
- * given connection belongs. This routine increaments the reference count
- * so that the object can not be freed. idmap_lookup_unlock_batch()
- * must be called to decreament the reference count.
- */
-static
-int
-idmap_msgid2query(ad_host_t *adh, int msgid,
- idmap_query_state_t **state, int *qid)
-{
- idmap_query_state_t *p;
- int i;
- int ret;
-
- (void) pthread_mutex_lock(&qstatelock);
- for (p = qstatehead; p != NULL; p = p->next) {
- if (p->qadh != adh || adh->generation != p->qadh_gen)
- continue;
- for (i = 0; i < p->qcount; i++) {
- if ((p->queries[i]).msgid == msgid) {
- if (!p->qdead) {
- p->ref_cnt++;
- *state = p;
- *qid = i;
- ret = 1;
- } else
- ret = 0;
- (void) pthread_mutex_unlock(&qstatelock);
- return (ret);
- }
- }
- }
- (void) pthread_mutex_unlock(&qstatelock);
- return (0);
-}
-
-/*
- * Put the the search result onto the correct idmap_q_t given the LDAP result
- * msgid
- * Returns: 0 success
- * -1 already has a search result
- * -2 cant find message id
- */
-static
-int
-idmap_quesearchresbymsgid(ad_host_t *adh, int msgid, LDAPMessage *search_res)
-{
- idmap_query_state_t *p;
- int i;
- int res;
-
- (void) pthread_mutex_lock(&qstatelock);
- for (p = qstatehead; p != NULL; p = p->next) {
- if (p->qadh != adh || adh->generation != p->qadh_gen)
- continue;
- for (i = 0; i < p->qcount; i++) {
- if ((p->queries[i]).msgid == msgid) {
- if (p->queries[i].search_res == NULL) {
- if (!p->qdead) {
- p->queries[i].search_res =
- search_res;
- res = 0;
- } else
- res = -2;
- } else
- res = -1;
- (void) pthread_mutex_unlock(&qstatelock);
- return (res);
- }
- }
- }
- (void) pthread_mutex_unlock(&qstatelock);
- return (-2);
-}
-
-
-/*
* Take parsed attribute values from a search result entry and check if
* it is the result that was desired and, if so, set the result fields
* of the given idmap_q_t.
@@ -1145,7 +240,7 @@ idmap_setqresults(idmap_q_t *q, char *san, char *dn, const char *attr,
assert(dn != NULL);
- if ((domain = dn2dns(dn)) == NULL)
+ if ((domain = adutils_dn2dns(dn)) == NULL)
goto out;
if (q->ecanonname != NULL && san != NULL) {
@@ -1201,8 +296,7 @@ idmap_setqresults(idmap_q_t *q, char *san, char *dn, const char *attr,
san = NULL;
}
- /* Always have q->rc; idmap_extract_object() asserts this */
- *q->rc = IDMAP_SUCCESS;
+ q->ad_rc = ADUTILS_SUCCESS;
out:
/* Free unused attribute values */
@@ -1212,56 +306,6 @@ out:
free(unixname);
}
-/*
- * The following three functions extract objectSid, sAMAccountName and
- * objectClass attribute values and, in the case of objectSid and
- * objectClass, parse them.
- *
- * idmap_setqresults() takes care of dealing with the result entry's DN.
- */
-
-/*
- * Return a NUL-terminated stringified SID from the value of an
- * objectSid attribute and put the last RID in *rid.
- */
-static
-char *
-idmap_bv_objsid2sidstr(BerValue **bvalues, rid_t *rid)
-{
- char *sid;
-
- if (bvalues == NULL)
- return (NULL);
- /* objectSid is single valued */
- if ((sid = convert_bval2sid(bvalues[0], rid)) == NULL)
- return (NULL);
- return (sid);
-}
-
-/*
- * Return a NUL-terminated string from the value of a sAMAccountName
- * or unixname attribute.
- */
-static
-char *
-idmap_bv_name2str(BerValue **bvalues)
-{
- char *s;
-
- if (bvalues == NULL || bvalues[0] == NULL ||
- bvalues[0]->bv_val == NULL)
- return (NULL);
-
- if ((s = malloc(bvalues[0]->bv_len + 1)) == NULL)
- return (NULL);
-
- (void) snprintf(s, bvalues[0]->bv_len + 1, "%.*s", bvalues[0]->bv_len,
- bvalues[0]->bv_val);
-
- return (s);
-}
-
-
#define BVAL_CASEEQ(bv, str) \
(((*(bv))->bv_len == (sizeof (str) - 1)) && \
strncasecmp((*(bv))->bv_val, str, (*(bv))->bv_len) == 0)
@@ -1309,12 +353,11 @@ idmap_bv_objclass2sidtype(BerValue **bvalues, int *sid_type)
*/
static
void
-idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
+idmap_extract_object(idmap_query_state_t *state, idmap_q_t *q,
+ LDAPMessage *res, LDAP *ld)
{
BerElement *ber = NULL;
BerValue **bvalues;
- ad_host_t *adh;
- idmap_q_t *q;
char *attr;
const char *unixuser_attr = NULL;
const char *unixgroup_attr = NULL;
@@ -1327,24 +370,11 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
int sid_type = _IDMAP_T_UNDEF;
int has_class, has_san, has_sid;
int has_unixuser, has_unixgroup;
- int num;
-
- adh = state->qadh;
-
- (void) pthread_mutex_lock(&adh->lock);
-
- q = &(state->queries[qid]);
assert(q->rc != NULL);
- if (adh->dead || (dn = ldap_get_dn(adh->ld, res)) == NULL) {
- num = adh->num_requests;
- (void) pthread_mutex_unlock(&adh->lock);
- idmapdlog(LOG_DEBUG,
- "AD error decoding search result - %d queued requests",
- num);
+ if ((dn = ldap_get_dn(ld, res)) == NULL)
return;
- }
assert(q->domain == NULL || *q->domain == NULL);
@@ -1384,8 +414,8 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
}
has_class = has_san = has_sid = has_unixuser = has_unixgroup = 0;
- for (attr = ldap_first_attribute(adh->ld, res, &ber); attr != NULL;
- attr = ldap_next_attribute(adh->ld, res, ber)) {
+ for (attr = ldap_first_attribute(ld, res, &ber); attr != NULL;
+ attr = ldap_next_attribute(ld, res, ber)) {
bvalues = NULL; /* for memory management below */
/*
@@ -1394,15 +424,20 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
*/
if (q->sid != NULL && !has_sid &&
strcasecmp(attr, OBJSID) == 0) {
- bvalues = ldap_get_values_len(adh->ld, res, attr);
- sid = idmap_bv_objsid2sidstr(bvalues, &rid);
- has_sid = (sid != NULL);
+ bvalues = ldap_get_values_len(ld, res, attr);
+ if (bvalues != NULL) {
+ sid = adutils_bv_objsid2sidstr(
+ bvalues[0], &rid);
+ has_sid = (sid != NULL);
+ }
} else if (!has_san && strcasecmp(attr, SAN) == 0) {
- bvalues = ldap_get_values_len(adh->ld, res, attr);
- san = idmap_bv_name2str(bvalues);
- has_san = (san != NULL);
+ bvalues = ldap_get_values_len(ld, res, attr);
+ if (bvalues != NULL) {
+ san = adutils_bv_name2str(bvalues[0]);
+ has_san = (san != NULL);
+ }
} else if (!has_class && strcasecmp(attr, OBJCLASS) == 0) {
- bvalues = ldap_get_values_len(adh->ld, res, attr);
+ bvalues = ldap_get_values_len(ld, res, attr);
has_class = idmap_bv_objclass2sidtype(bvalues,
&sid_type);
if (has_class && q->unixname != NULL &&
@@ -1431,15 +466,19 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
}
} else if (!has_unixuser && unixuser_attr != NULL &&
strcasecmp(attr, unixuser_attr) == 0) {
- bvalues = ldap_get_values_len(adh->ld, res, attr);
- unixuser = idmap_bv_name2str(bvalues);
- has_unixuser = (unixuser != NULL);
+ bvalues = ldap_get_values_len(ld, res, attr);
+ if (bvalues != NULL) {
+ unixuser = adutils_bv_name2str(bvalues[0]);
+ has_unixuser = (unixuser != NULL);
+ }
} else if (!has_unixgroup && unixgroup_attr != NULL &&
strcasecmp(attr, unixgroup_attr) == 0) {
- bvalues = ldap_get_values_len(adh->ld, res, attr);
- unixgroup = idmap_bv_name2str(bvalues);
- has_unixgroup = (unixgroup != NULL);
+ bvalues = ldap_get_values_len(ld, res, attr);
+ if (bvalues != NULL) {
+ unixgroup = adutils_bv_name2str(bvalues[0]);
+ has_unixgroup = (unixgroup != NULL);
+ }
}
if (bvalues != NULL)
@@ -1455,8 +494,6 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
}
}
- (void) pthread_mutex_unlock(&adh->lock);
-
if (!has_class) {
/*
* Didn't find objectclass. Something's wrong with our
@@ -1485,140 +522,31 @@ idmap_extract_object(idmap_query_state_t *state, int qid, LDAPMessage *res)
ldap_memfree(dn);
}
-/*
- * Try to get a result; if there is one, find the corresponding
- * idmap_q_t and process the result.
- *
- * Returns: 0 success
- * -1 error
- * -2 queue empty
- */
-static
-int
-idmap_get_adobject_batch(ad_host_t *adh, struct timeval *timeout)
+void
+idmap_ldap_res_search_cb(LDAP *ld, LDAPMessage **res, int rc, int qid,
+ void *argp)
{
- idmap_query_state_t *query_state;
- LDAPMessage *res = NULL;
- int rc, ret, msgid, qid;
- idmap_q_t *que;
- int num;
-
- (void) pthread_mutex_lock(&adh->lock);
- if (adh->dead || adh->num_requests == 0) {
- if (adh->dead)
- ret = -1;
- else
- ret = -2;
- (void) pthread_mutex_unlock(&adh->lock);
- return (ret);
- }
+ idmap_query_state_t *state = (idmap_query_state_t *)argp;
+ idmap_q_t *q = &(state->queries[qid]);
- /* Get one result */
- rc = ldap_result(adh->ld, LDAP_RES_ANY, 0,
- timeout, &res);
- if ((timeout != NULL && timeout->tv_sec > 0 && rc == LDAP_SUCCESS) ||
- rc < 0)
- adh->dead = 1;
-
- if (rc == LDAP_RES_SEARCH_RESULT && adh->num_requests > 0)
- adh->num_requests--;
-
- if (adh->dead) {
- num = adh->num_requests;
- (void) pthread_mutex_unlock(&adh->lock);
- idmapdlog(LOG_DEBUG,
- "AD ldap_result error - %d queued requests", num);
- return (-1);
- }
switch (rc) {
case LDAP_RES_SEARCH_RESULT:
- /* We should have the LDAP replies for some search... */
- msgid = ldap_msgid(res);
- if (idmap_msgid2query(adh, msgid, &query_state, &qid)) {
- (void) pthread_mutex_unlock(&adh->lock);
- que = &(query_state->queries[qid]);
- if (que->search_res != NULL) {
- idmap_extract_object(query_state, qid,
- que->search_res);
- (void) ldap_msgfree(que->search_res);
- que->search_res = NULL;
- } else
- *que->rc = IDMAP_ERR_NOTFOUND;
- /* ...so we can decrement qinflight */
- atomic_dec_32(&query_state->qinflight);
- idmap_lookup_unlock_batch(&query_state);
- } else {
- num = adh->num_requests;
- (void) pthread_mutex_unlock(&adh->lock);
- idmapdlog(LOG_DEBUG,
- "AD cannot find message ID - %d queued requests",
- num);
- }
- (void) ldap_msgfree(res);
- ret = 0;
+ if (q->search_res != NULL) {
+ idmap_extract_object(state, q, q->search_res, ld);
+ (void) ldap_msgfree(q->search_res);
+ q->search_res = NULL;
+ } else
+ q->ad_rc = ADUTILS_ERR_NOTFOUND;
break;
-
- case LDAP_RES_SEARCH_REFERENCE:
- /*
- * We have no need for these at the moment. Eventually,
- * when we query things that we can't expect to find in
- * the Global Catalog then we'll need to learn to follow
- * references.
- */
- (void) pthread_mutex_unlock(&adh->lock);
- (void) ldap_msgfree(res);
- ret = 0;
- break;
-
case LDAP_RES_SEARCH_ENTRY:
- /* Got a result - queue it */
- msgid = ldap_msgid(res);
- rc = idmap_quesearchresbymsgid(adh, msgid, res);
- num = adh->num_requests;
- (void) pthread_mutex_unlock(&adh->lock);
- if (rc == -1) {
- idmapdlog(LOG_DEBUG,
- "AD already has search result - %d queued requests",
- num);
- (void) ldap_msgfree(res);
- } else if (rc == -2) {
- idmapdlog(LOG_DEBUG,
- "AD cannot queue by message ID "
- "- %d queued requests", num);
- (void) ldap_msgfree(res);
+ if (q->search_res == NULL) {
+ q->search_res = *res;
+ *res = NULL;
}
- ret = 0;
break;
-
default:
- /* timeout or error; treat the same */
- (void) pthread_mutex_unlock(&adh->lock);
- ret = -1;
break;
}
-
- return (ret);
-}
-
-/*
- * This routine decreament the reference count of the
- * idmap_query_state_t
- */
-static void
-idmap_lookup_unlock_batch(idmap_query_state_t **state)
-{
- /*
- * Decrement reference count with qstatelock locked
- */
- (void) pthread_mutex_lock(&qstatelock);
- (*state)->ref_cnt--;
- /*
- * If there are no references wakup the allocating thread
- */
- if ((*state)->ref_cnt <= 1)
- (void) pthread_cond_signal(&(*state)->cv);
- (void) pthread_mutex_unlock(&qstatelock);
- *state = NULL;
}
static
@@ -1639,96 +567,38 @@ idmap_cleanup_batch(idmap_query_state_t *batch)
/*
* This routine frees the idmap_query_state_t structure
- * If the reference count is greater than 1 it waits
- * for the other threads to finish using it.
*/
void
idmap_lookup_release_batch(idmap_query_state_t **state)
{
- idmap_query_state_t **p;
-
- /*
- * Set state to dead to stop further operations.
- * Wait for reference count with qstatelock locked
- * to get to one.
- */
- (void) pthread_mutex_lock(&qstatelock);
- (*state)->qdead = 1;
- while ((*state)->ref_cnt > 1) {
- (void) pthread_cond_wait(&(*state)->cv, &qstatelock);
- }
-
- /* Remove this state struct from the list of state structs */
- for (p = &qstatehead; *p != NULL; p = &(*p)->next) {
- if (*p == (*state)) {
- *p = (*state)->next;
- break;
- }
- }
- (void) pthread_mutex_unlock(&qstatelock);
-
+ if (state == NULL || *state == NULL)
+ return;
+ adutils_lookup_batch_release(&(*state)->qs);
idmap_cleanup_batch(*state);
-
- (void) pthread_cond_destroy(&(*state)->cv);
-
- idmap_release_conn((*state)->qadh);
-
free(*state);
*state = NULL;
}
-
-/*
- * This routine waits for other threads using the
- * idmap_query_state_t structure to finish.
- * If the reference count is greater than 1 it waits
- * for the other threads to finish using it.
- */
-static
-void
-idmap_lookup_wait_batch(idmap_query_state_t *state)
-{
- /*
- * Set state to dead to stop further operation.
- * stating.
- * Wait for reference count to get to one
- * with qstatelock locked.
- */
- (void) pthread_mutex_lock(&qstatelock);
- state->qdead = 1;
- while (state->ref_cnt > 1) {
- (void) pthread_cond_wait(&state->cv, &qstatelock);
- }
- (void) pthread_mutex_unlock(&qstatelock);
-}
-
-
idmap_retcode
idmap_lookup_batch_end(idmap_query_state_t **state)
{
- int rc = LDAP_SUCCESS;
- idmap_retcode retcode = IDMAP_SUCCESS;
- struct timeval timeout;
+ adutils_rc ad_rc;
+ int i;
+ idmap_query_state_t *id_qs = *state;
- timeout.tv_sec = IDMAPD_SEARCH_TIMEOUT;
- timeout.tv_usec = 0;
+ ad_rc = adutils_lookup_batch_end(&id_qs->qs);
- /* Process results until done or until timeout, if given */
- while ((*state)->qinflight > 0) {
- if ((rc = idmap_get_adobject_batch((*state)->qadh,
- &timeout)) != 0)
- break;
+ /*
+ * Map adutils rc to idmap_retcode in each
+ * query because consumers in dbutils.c
+ * expects idmap_retcode.
+ */
+ for (i = 0; i < id_qs->qcount; i++) {
+ *id_qs->queries[i].rc =
+ map_adrc2idmaprc(id_qs->queries[i].ad_rc);
}
- (*state)->qdead = 1;
- /* Wait for other threads proceesing search result to finish */
- idmap_lookup_wait_batch(*state);
-
- if (rc == -1 || (*state)->qinflight != 0)
- retcode = IDMAP_ERR_RETRIABLE_NET_ERR;
-
idmap_lookup_release_batch(state);
-
- return (retcode);
+ return (map_adrc2idmaprc(ad_rc));
}
/*
@@ -1744,11 +614,8 @@ idmap_batch_add1(idmap_query_state_t *state, const char *filter,
char **sid, rid_t *rid, int *sid_type, char **unixname,
idmap_retcode *rc)
{
- idmap_retcode retcode = IDMAP_SUCCESS;
- int lrc, qid, i;
- int num;
- int dead;
- struct timeval tv;
+ adutils_rc ad_rc;
+ int qid, i;
idmap_q_t *q;
static char *attrs[] = {
SAN,
@@ -1760,12 +627,11 @@ idmap_batch_add1(idmap_query_state_t *state, const char *filter,
};
qid = atomic_inc_32_nv(&state->qlastsent) - 1;
-
q = &(state->queries[qid]);
/*
- * Remember the expected canonname so we can check the results
- * agains it
+ * Remember the expected canonname, domainname and unix type
+ * so we can check the results * against it
*/
q->ecanonname = ecanonname;
q->edomain = edomain;
@@ -1821,69 +687,19 @@ idmap_batch_add1(idmap_query_state_t *state, const char *filter,
if (value != NULL)
*value = NULL;
- /* Check the number of queued requests first */
- tv.tv_sec = IDMAPD_SEARCH_TIMEOUT;
- tv.tv_usec = 0;
- while (!state->qadh->dead &&
- state->qadh->num_requests > state->qadh->max_requests) {
- if (idmap_get_adobject_batch(state->qadh, &tv) != 0)
- break;
- }
-
/*
* Don't set *canonname to NULL because it may be pointing to the
* given winname. Later on if we get a canonical name from AD the
* old name if any will be freed before assigning the new name.
*/
- /* Send this lookup, don't wait for a result here */
- lrc = LDAP_SUCCESS;
- (void) pthread_mutex_lock(&state->qadh->lock);
-
- if (!state->qadh->dead) {
- state->qadh->idletime = time(NULL);
- lrc = ldap_search_ext(state->qadh->ld, "",
- LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL,
- NULL, -1, &q->msgid);
-
- if (lrc == LDAP_SUCCESS) {
- state->qadh->num_requests++;
- } else if (lrc == LDAP_BUSY || lrc == LDAP_UNAVAILABLE ||
- lrc == LDAP_CONNECT_ERROR || lrc == LDAP_SERVER_DOWN ||
- lrc == LDAP_UNWILLING_TO_PERFORM) {
- retcode = IDMAP_ERR_RETRIABLE_NET_ERR;
- state->qadh->dead = 1;
- } else {
- retcode = IDMAP_ERR_OTHER;
- state->qadh->dead = 1;
- }
- }
- dead = state->qadh->dead;
- num = state->qadh->num_requests;
- (void) pthread_mutex_unlock(&state->qadh->lock);
-
- if (dead) {
- if (lrc != LDAP_SUCCESS)
- idmapdlog(LOG_DEBUG,
- "AD ldap_search_ext error (%s) "
- "- %d queued requests",
- ldap_err2string(lrc), num);
- return (retcode);
- }
-
- atomic_inc_32(&state->qinflight);
-
/*
- * Reap as many requests as we can _without_ waiting
- *
- * We do this to prevent any possible TCP socket buffer
- * starvation deadlocks.
+ * Invoke the mother of all APIs i.e. the adutils API
*/
- (void) memset(&tv, 0, sizeof (tv));
- while (idmap_get_adobject_batch(state->qadh, &tv) == 0)
- ;
-
- return (IDMAP_SUCCESS);
+ ad_rc = adutils_lookup_batch_add(state->qs, filter,
+ (const char **)attrs,
+ edomain, &q->result, &q->ad_rc);
+ return (map_adrc2idmaprc(ad_rc));
}
idmap_retcode
@@ -1928,17 +744,15 @@ idmap_name2sid_batch_add1(idmap_query_state_t *state,
}
*strchr(ecanonname, '@') = '\0';
} else {
- /*
- * 'name' not qualified and dname not given
- *
- * Note: ad->dflt_w2k_dom cannot be NULL - see
- * idmap_ad_alloc()
- */
- if (*state->qadh->owner->dflt_w2k_dom == '\0') {
+ /* 'name' not qualified and dname not given */
+ dname = adutils_lookup_batch_getdefdomain(
+ state->qs);
+ assert(dname != NULL);
+ if (*dname == '\0') {
free(ecanonname);
return (IDMAP_ERR_DOMAIN);
}
- edomain = strdup(state->qadh->owner->dflt_w2k_dom);
+ edomain = strdup(dname);
if (edomain == NULL) {
free(ecanonname);
return (IDMAP_ERR_MEMORY);
@@ -1990,7 +804,7 @@ idmap_sid2name_batch_add1(idmap_query_state_t *state,
idmap_retcode retcode;
int flen, ret;
char *filter = NULL;
- char cbinsid[MAXHEXBINSID + 1];
+ char cbinsid[ADUTILS_MAXHEXBINSID + 1];
/*
* Strategy: search [the global catalog] for user/group by
@@ -2000,7 +814,7 @@ idmap_sid2name_batch_add1(idmap_query_state_t *state,
* computer.
*/
- ret = idmap_txtsid2hexbinsid(sid, rid, &cbinsid[0], sizeof (cbinsid));
+ ret = adutils_txtsid2hexbinsid(sid, rid, &cbinsid[0], sizeof (cbinsid));
if (ret != 0)
return (IDMAP_ERR_SID);