diff options
Diffstat (limited to 'usr/src/lib/libadutils/common/addisc.c')
-rw-r--r-- | usr/src/lib/libadutils/common/addisc.c | 108 |
1 files changed, 70 insertions, 38 deletions
diff --git a/usr/src/lib/libadutils/common/addisc.c b/usr/src/lib/libadutils/common/addisc.c index b32f9d7694..187981b5a2 100644 --- a/usr/src/lib/libadutils/common/addisc.c +++ b/usr/src/lib/libadutils/common/addisc.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -103,6 +102,16 @@ #include "adutils_impl.h" #include "addisc.h" +/* + * These set some sanity policies for discovery. After a discovery + * cycle, we will consider the results (successful or unsuccessful) + * to be valid for at least MINIMUM_TTL seconds, and for at most + * MAXIMUM_TTL seconds. Note that the caller is free to request + * discovery cycles sooner than MINIMUM_TTL if it has reason to believe + * that the situation has changed. + */ +#define MINIMUM_TTL (5 * 60) +#define MAXIMUM_TTL (20 * 60) enum ad_item_state { AD_STATE_INVALID = 0, /* The value is not valid */ @@ -127,7 +136,7 @@ typedef struct ad_item { enum ad_item_state state; enum ad_data_type type; void *value; - time_t ttl; + time_t expires; unsigned int version; /* Version is only changed */ /* if the value changes */ #define PARAM1 0 @@ -144,6 +153,8 @@ typedef struct ad_disc { ad_subnet_t *subnets; boolean_t subnets_changed; time_t subnets_last_check; + time_t expires_not_before; + time_t expires_not_after; ad_item_t domain_name; /* DNS hostname string */ ad_item_t domain_controller; /* Directory hostname and */ /* port array */ @@ -216,7 +227,7 @@ is_valid(ad_item_t *item) if (item->state == AD_STATE_FIXED) return (B_TRUE); if (item->state == AD_STATE_AUTO && - (item->ttl == 0 || item->ttl > time(NULL))) + (item->expires == 0 || item->expires > time(NULL))) return (B_TRUE); } return (B_FALSE); @@ -247,9 +258,9 @@ update_item(ad_item_t *item, void *value, enum ad_item_state state, item->state = state; if (ttl == 0) - item->ttl = 0; + item->expires = 0; else - item->ttl = time(NULL) + ttl; + item->expires = time(NULL) + ttl; } @@ -593,26 +604,6 @@ DN_to_DNS(const char *dn_name) } -/* Format the DN of an AD LDAP subnet object for some subnet */ -static char * -subnet_to_DN(const char *subnet, const char *baseDN) -{ - char *result; - int len; - - len = snprintf(NULL, 0, - "CN=%s,CN=Subnets,CN=Sites,%s", - subnet, baseDN) + 1; - - result = malloc(len); - if (result != NULL) - (void) snprintf(result, len, - "CN=%s,CN=Subnets,CN=Sites,%s", - subnet, baseDN); - return (result); -} - - /* Make a list of subnet object DNs from a list of subnets */ static char ** subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn) @@ -628,8 +619,9 @@ subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn) return (NULL); for (i = 0; subnets[i].subnet[0] != '\0'; i++) { - if ((results[i] = subnet_to_DN(subnets[i].subnet, base_dn)) - == NULL) { + (void) asprintf(&results[i], "CN=%s,CN=Subnets,CN=Sites,%s", + subnets[i].subnet, base_dn); + if (results[i] == NULL) { for (j = 0; j < i; j++) free(results[j]); free(results); @@ -828,7 +820,8 @@ err: * A utility function to bind to a Directory server */ -static LDAP* +static +LDAP * ldap_lookup_init(idmap_ad_disc_ds_t *ds) { int i; @@ -988,15 +981,17 @@ ldap_lookup_trusted_domains(LDAP **ld, idmap_ad_disc_ds_t *globalCatalog, if (partner != NULL && direction != NULL) { num++; - trusted_domains = realloc(trusted_domains, + void *tmp = realloc(trusted_domains, (num + 1) * sizeof (ad_disc_trusteddomains_t)); - if (trusted_domains == NULL) { + if (tmp == NULL) { + free(trusted_domains); ldap_value_free(partner); ldap_value_free(direction); ldap_msgfree(results); return (NULL); } + trusted_domains = tmp; /* Last element should be zero */ memset(&trusted_domains[num], 0, sizeof (ad_disc_trusteddomains_t)); @@ -1221,6 +1216,22 @@ ad_disc_refresh(ad_disc_t ctx) } +/* + * Called when the discovery cycle is done. Sets a master TTL + * that will avoid doing new time-based discoveries too soon after + * the last discovery cycle. Most interesting when the discovery + * cycle failed, because then the TTLs on the individual items will + * not be updated and may go stale. + */ +void +ad_disc_done(ad_disc_t ctx) +{ + time_t now = time(NULL); + + ctx->expires_not_before = now + MINIMUM_TTL; + ctx->expires_not_after = now + MAXIMUM_TTL; +} + /* Discover joined Active Directory domainName */ static ad_item_t * @@ -1425,12 +1436,13 @@ validate_SiteName(ad_disc_t ctx) return (NULL); if (!is_valid(&ctx->site_name) || - is_changed(&ctx->site_name, PARAM1, &ctx->domain_controller) || + is_changed(&ctx->site_name, PARAM1, domain_controller_item) || ctx->subnets == NULL || ctx->subnets_changed) { subnets = find_subnets(); ctx->subnets_last_check = time(NULL); update_required = B_TRUE; } else if (ctx->subnets_last_check + 60 < time(NULL)) { + /* NEEDSWORK magic constant 60 above */ subnets = find_subnets(); ctx->subnets_last_check = time(NULL); if (cmpsubnets(ctx->subnets, subnets) != 0) @@ -1471,6 +1483,8 @@ validate_SiteName(ad_disc_t ctx) forest_name = DN_to_DNS(config_naming_context + len); update_item(&ctx->forest_name, forest_name, AD_STATE_AUTO, 0); + update_version(&ctx->forest_name, PARAM1, + domain_controller_item); } } @@ -1495,6 +1509,8 @@ validate_SiteName(ad_disc_t ctx) site_name[len] = '\0'; update_item(&ctx->site_name, site_name, AD_STATE_AUTO, 0); + update_version(&ctx->site_name, PARAM1, + domain_controller_item); } } @@ -1997,17 +2013,33 @@ ad_disc_unset(ad_disc_t ctx) int ad_disc_get_TTL(ad_disc_t ctx) { + time_t expires; int ttl; - ttl = MIN_GT_ZERO(ctx->domain_controller.ttl, ctx->global_catalog.ttl); - ttl = MIN_GT_ZERO(ttl, ctx->site_domain_controller.ttl); - ttl = MIN_GT_ZERO(ttl, ctx->site_global_catalog.ttl); + expires = MIN_GT_ZERO(ctx->domain_controller.expires, + ctx->global_catalog.expires); + expires = MIN_GT_ZERO(expires, ctx->site_domain_controller.expires); + expires = MIN_GT_ZERO(expires, ctx->site_global_catalog.expires); - if (ttl == -1) + if (expires == -1) { return (-1); - ttl -= time(NULL); - if (ttl < 0) + } + + if (ctx->expires_not_before != 0 && + expires < ctx->expires_not_before) { + expires = ctx->expires_not_before; + } + + if (ctx->expires_not_after != 0 && + expires > ctx->expires_not_after) { + expires = ctx->expires_not_after; + } + + ttl = expires - time(NULL); + + if (ttl < 0) { return (0); + } return (ttl); } |