diff options
Diffstat (limited to 'usr/src/lib/libadutils/common')
-rw-r--r-- | usr/src/lib/libadutils/common/adutils.c | 98 | ||||
-rw-r--r-- | usr/src/lib/libadutils/common/adutils_impl.h | 19 | ||||
-rw-r--r-- | usr/src/lib/libadutils/common/libadutils.h | 9 | ||||
-rw-r--r-- | usr/src/lib/libadutils/common/mapfile-vers | 3 |
4 files changed, 123 insertions, 6 deletions
diff --git a/usr/src/lib/libadutils/common/adutils.c b/usr/src/lib/libadutils/common/adutils.c index d838858671..d914f109d2 100644 --- a/usr/src/lib/libadutils/common/adutils.c +++ b/usr/src/lib/libadutils/common/adutils.c @@ -66,6 +66,7 @@ static binary_attrs_t binattrs[] = { {NULL, NULL} }; + void adutils_set_log(int pri, bool_t syslog, bool_t degraded) { @@ -74,6 +75,7 @@ adutils_set_log(int pri, bool_t syslog, bool_t degraded) idmap_log_degraded(degraded); } + /* * Turn "foo.bar.com" into "dc=foo,dc=bar,dc=com" */ @@ -85,6 +87,7 @@ adutils_dns2dn(const char *dns) return (ldap_dns_to_dn((char *)dns, &nameparts)); } + /* * Turn "dc=foo,dc=bar,dc=com" into "foo.bar.com"; ignores any other * attributes (CN, etc...). @@ -632,6 +635,8 @@ adutils_ad_free(adutils_ad_t **ad) (void) pthread_mutex_unlock(&(*ad)->lock); (void) pthread_mutex_destroy(&(*ad)->lock); + if ((*ad)->known_domains) + free((*ad)->known_domains); free((*ad)->dflt_w2k_dom); free(*ad); @@ -761,7 +766,8 @@ retry: * around the wrong number of times. */ for (;;) { - if (adh != NULL && adh->ld != NULL && !adh->dead) + if (adh != NULL && adh->owner == ad && adh->ld != NULL && + !adh->dead) break; if (adh == NULL || (adh = adh->next) == NULL) adh = host_head; @@ -919,6 +925,88 @@ delete_ds(adutils_ad_t *ad, const char *host, int port) } } +/* + * Add known domain name and domain SID to AD configuration. + */ + +adutils_rc +adutils_add_domain(adutils_ad_t *ad, const char *domain, const char *sid) +{ + struct known_domain *new; + int num = ad->num_known_domains; + + ad->num_known_domains++; + new = realloc(ad->known_domains, + sizeof (struct known_domain) * ad->num_known_domains); + if (new != NULL) { + ad->known_domains = new; + (void) strlcpy(ad->known_domains[num].name, domain, + sizeof (ad->known_domains[num].name)); + (void) strlcpy(ad->known_domains[num].sid, sid, + sizeof (ad->known_domains[num].sid)); + return (ADUTILS_SUCCESS); + } else { + if (ad->known_domains != NULL) { + free(ad->known_domains); + ad->known_domains = NULL; + } + ad->num_known_domains = 0; + return (ADUTILS_ERR_MEMORY); + } +} + + +/* + * Check that this AD supports this domain. + * If there are no known domains assume that the + * domain is supported by this AD. + * + * Returns 1 if this domain is supported by this AD + * else returns 0; + */ + +int +adutils_lookup_check_domain(adutils_query_state_t *qs, const char *domain) +{ + adutils_ad_t *ad = qs->qadh->owner; + int i, err; + + for (i = 0; i < ad->num_known_domains; i++) { + if (u8_strcmp(domain, ad->known_domains[i].name, 0, + U8_STRCMP_CI_LOWER, U8_UNICODE_LATEST, &err) == 0 && + err == 0) + return (1); + } + + return ((i == 0) ? 1 : 0); +} + + +/* + * Check that this AD supports the SID prefix. + * The SID prefix should match the domain SID. + * If there are no known domains assume that the + * SID prefix is supported by this AD. + * + * Returns 1 if this sid prefix is supported by this AD + * else returns 0; + */ + +int +adutils_lookup_check_sid_prefix(adutils_query_state_t *qs, const char *sid) +{ + adutils_ad_t *ad = qs->qadh->owner; + int i; + + + for (i = 0; i < ad->num_known_domains; i++) { + if (strcmp(sid, ad->known_domains[i].sid) == 0) + return (1); + } + + return ((i == 0) ? 1 : 0); +} + adutils_rc adutils_lookup_batch_start(adutils_ad_t *ad, int nqueries, @@ -964,9 +1052,9 @@ adutils_lookup_batch_start(adutils_ad_t *ad, int nqueries, new_state->ref_cnt = 1; new_state->qadh = adh; - new_state->qcount = nqueries; + new_state->qsize = nqueries; new_state->qadh_gen = adh->generation; - new_state->qlastsent = 0; + new_state->qcount = 0; new_state->ldap_res_search_cb = ldap_res_search_cb; new_state->ldap_res_search_argp = ldap_res_search_argp; (void) pthread_cond_init(&new_state->cv, NULL); @@ -1588,9 +1676,11 @@ adutils_lookup_batch_add(adutils_query_state_t *state, struct timeval tv; adutils_q_t *q; - qid = atomic_inc_32_nv(&state->qlastsent) - 1; + qid = atomic_inc_32_nv(&state->qcount) - 1; q = &(state->queries[qid]); + assert(qid < state->qsize); + /* * Remember the expected domain so we can check the results * against it diff --git a/usr/src/lib/libadutils/common/adutils_impl.h b/usr/src/lib/libadutils/common/adutils_impl.h index 847d5e384d..530e3a2ca3 100644 --- a/usr/src/lib/libadutils/common/adutils_impl.h +++ b/usr/src/lib/libadutils/common/adutils_impl.h @@ -43,6 +43,14 @@ extern "C" { #define ADUTILS_SEARCH_TIMEOUT 3 #define ADUTILS_LDAP_OPEN_TIMEOUT 1 +/* + * Maximum string SID size. 4 bytes for "S-1-", 15 for 2^48 (max authority), + * another '-', and ridcount (max 15) 10-digit RIDs plus '-' in between, plus + * a null. + */ +#define MAXSID 185 +#define MAXDOMAINNAME 256 + typedef struct adutils_sid { uchar_t version; uchar_t sub_authority_count; @@ -52,10 +60,17 @@ typedef struct adutils_sid { struct adutils_host; +struct known_domain { + char name[MAXDOMAINNAME]; + char sid[MAXSID]; +}; + /* A set of DSs for a given AD partition */ struct adutils_ad { char *dflt_w2k_dom; /* used to qualify bare names */ + int num_known_domains; + struct known_domain *known_domains; pthread_mutex_t lock; uint32_t ref; struct adutils_host *last_adh; @@ -124,10 +139,10 @@ typedef struct adutils_q { /* Batch context structure */ struct adutils_query_state { struct adutils_query_state *next; - int qcount; /* how many queries */ + int qsize; /* Size of queries */ int ref_cnt; /* reference count */ pthread_cond_t cv; /* Condition wait variable */ - uint32_t qlastsent; + uint32_t qcount; /* Number of items queued */ uint32_t qinflight; /* how many queries in flight */ uint16_t qdead; /* oops, lost LDAP connection */ adutils_host_t *qadh; /* LDAP connection */ diff --git a/usr/src/lib/libadutils/common/libadutils.h b/usr/src/lib/libadutils/common/libadutils.h index 9a6d82a0b2..8f88e2d27a 100644 --- a/usr/src/lib/libadutils/common/libadutils.h +++ b/usr/src/lib/libadutils/common/libadutils.h @@ -135,6 +135,9 @@ extern adutils_rc adutils_ad_alloc(adutils_ad_t **new_ad, extern void adutils_ad_free(adutils_ad_t **ad); extern adutils_rc adutils_add_ds(adutils_ad_t *ad, const char *host, int port); +extern adutils_rc adutils_add_domain(adutils_ad_t *ad, + const char *domain_name, + const char *domain_sid); extern void adutils_set_log(int pri, bool_t syslog, bool_t degraded); extern void adutils_freeresult(adutils_result_t **result); @@ -169,6 +172,12 @@ extern void adutils_lookup_batch_release( adutils_query_state_t **state); extern const char *adutils_lookup_batch_getdefdomain( adutils_query_state_t *state); +extern int adutils_lookup_check_domain( + adutils_query_state_t *state, + const char *domain); +extern int adutils_lookup_check_sid_prefix( + adutils_query_state_t *state, + const char *sid); #ifdef __cplusplus } diff --git a/usr/src/lib/libadutils/common/mapfile-vers b/usr/src/lib/libadutils/common/mapfile-vers index 07d0065906..da06606624 100644 --- a/usr/src/lib/libadutils/common/mapfile-vers +++ b/usr/src/lib/libadutils/common/mapfile-vers @@ -37,11 +37,14 @@ SUNWprivate { adutils_lookup_batch_end; adutils_lookup_batch_release; adutils_lookup_batch_getdefdomain; + adutils_lookup_check_domain; + adutils_lookup_check_sid_prefix; adutils_dn2dns; adutils_reap_idle_connections; adutils_ad_alloc; adutils_ad_free; adutils_add_ds; + adutils_add_domain; adutils_set_log; local: *; |