summaryrefslogtreecommitdiff
path: root/usr/src/cmd/idmap
diff options
context:
space:
mode:
authornw141292 <none@none>2008-02-27 22:59:10 -0800
committernw141292 <none@none>2008-02-27 22:59:10 -0800
commit349d5d8f2e43f7f425bc3d025dda555187160ab7 (patch)
tree0ef7fe61a83ceb76914587f3dee231422d146b52 /usr/src/cmd/idmap
parent6d1d45ee7157107ef92303ea769d6d3fcf5dfcc8 (diff)
downloadillumos-joyent-349d5d8f2e43f7f425bc3d025dda555187160ab7.tar.gz
6647804 idmapd logs "AD lookup disabled" even before attempting AD auto-discovery
6666405 a few messages still go to LOG_ERR/INFO that should go to DEBUG 6668095 setting config/default_domain to "" doesn't work
Diffstat (limited to 'usr/src/cmd/idmap')
-rw-r--r--usr/src/cmd/idmap/idmapd/addisc.c2
-rw-r--r--usr/src/cmd/idmap/idmapd/adutils.c20
-rw-r--r--usr/src/cmd/idmap/idmapd/dbutils.c16
-rw-r--r--usr/src/cmd/idmap/idmapd/idmap_config.c510
-rw-r--r--usr/src/cmd/idmap/idmapd/idmap_config.h7
-rw-r--r--usr/src/cmd/idmap/idmapd/idmapd.c14
-rw-r--r--usr/src/cmd/idmap/idmapd/idmapd.h4
-rw-r--r--usr/src/cmd/idmap/idmapd/init.c54
8 files changed, 300 insertions, 327 deletions
diff --git a/usr/src/cmd/idmap/idmapd/addisc.c b/usr/src/cmd/idmap/idmapd/addisc.c
index 505f0efcef..e1ddf8459b 100644
--- a/usr/src/cmd/idmap/idmapd/addisc.c
+++ b/usr/src/cmd/idmap/idmapd/addisc.c
@@ -620,7 +620,7 @@ srv_query(res_state state, const char *svc_name, const char *dname,
query_type, svc_name);
if (len < 0) {
- idmapdlog(LOG_ERR, "DNS %s for '%s' failed (%s)",
+ idmapdlog(LOG_DEBUG, "DNS %s for '%s' failed (%s)",
query_type, svc_name, hstrerror(state->res_h_errno));
return (NULL);
}
diff --git a/usr/src/cmd/idmap/idmapd/adutils.c b/usr/src/cmd/idmap/idmapd/adutils.c
index 93b2389c9a..b5c5731810 100644
--- a/usr/src/cmd/idmap/idmapd/adutils.c
+++ b/usr/src/cmd/idmap/idmapd/adutils.c
@@ -380,13 +380,6 @@ idmap_ad_alloc(ad_t **new_ad, const char *default_domain,
ad->ref = 1;
ad->partition = part;
- /*
- * If default_domain is NULL, deal, deferring errors until
- * idmap_lookup_batch_start() -- this makes it easier on the
- * caller, who can simply observe lookups failing as opposed to
- * having to conditionalize calls to lookups according to
- * whether it has a non-NULL ad_t *.
- */
if (default_domain == NULL)
default_domain = "";
@@ -1000,8 +993,7 @@ idmap_lookup_batch_start(ad_t *ad, int nqueries, idmap_query_state_t **state)
*state = NULL;
- /* Note: ad->dflt_w2k_dom cannot be NULL - see idmap_ad_alloc() */
- if (ad == NULL || *ad->dflt_w2k_dom == '\0')
+ if (ad == NULL)
return (IDMAP_ERR_INTERNAL);
adh = idmap_get_conn(ad);
@@ -1747,9 +1739,13 @@ idmap_name2sid_batch_add1(idmap_query_state_t *state,
}
*strchr(ecanonname, '@') = '\0';
} else {
- /* 'name' not qualified and dname not given */
- if (state->qadh->owner->dflt_w2k_dom == NULL ||
- *state->qadh->owner->dflt_w2k_dom == '\0') {
+ /*
+ * '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') {
free(ecanonname);
return (IDMAP_ERR_DOMAIN);
}
diff --git a/usr/src/cmd/idmap/idmapd/dbutils.c b/usr/src/cmd/idmap/idmapd/dbutils.c
index fb00df1d7c..76ac2466b2 100644
--- a/usr/src/cmd/idmap/idmapd/dbutils.c
+++ b/usr/src/cmd/idmap/idmapd/dbutils.c
@@ -1671,7 +1671,7 @@ retry:
if (retcode != IDMAP_SUCCESS) {
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
- degrade_svc("failed to create batch for AD lookup");
+ degrade_svc(1, "failed to create batch for AD lookup");
goto out;
}
@@ -1793,7 +1793,7 @@ retry:
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
else if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR)
- degrade_svc("some AD lookups timed out repeatedly");
+ degrade_svc(1, "some AD lookups timed out repeatedly");
if (retcode != IDMAP_SUCCESS)
idmapdlog(LOG_NOTICE, "Failed to batch AD lookup requests");
@@ -3112,7 +3112,7 @@ retry:
if (retcode != IDMAP_SUCCESS) {
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
- degrade_svc("failed to create request for AD lookup "
+ degrade_svc(1, "failed to create request for AD lookup "
"by winname");
return (retcode);
}
@@ -3134,7 +3134,7 @@ retry:
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
else if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR)
- degrade_svc("some AD lookups timed out repeatedly");
+ degrade_svc(1, "some AD lookups timed out repeatedly");
if (retcode != IDMAP_SUCCESS) {
idmapdlog(LOG_NOTICE, "AD lookup by winname failed");
@@ -3588,7 +3588,7 @@ retry:
if (retcode != IDMAP_SUCCESS) {
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
- degrade_svc("failed to create request for AD lookup by SID");
+ degrade_svc(1, "failed to create request for AD lookup by SID");
return (retcode);
}
@@ -3609,7 +3609,7 @@ retry:
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
else if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR)
- degrade_svc("some AD lookups timed out repeatedly");
+ degrade_svc(1, "some AD lookups timed out repeatedly");
if (retcode != IDMAP_SUCCESS) {
idmapdlog(LOG_NOTICE, "AD lookup by SID failed");
@@ -3945,7 +3945,7 @@ retry:
if (retcode != IDMAP_SUCCESS) {
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
- degrade_svc("failed to create request for AD lookup "
+ degrade_svc(1, "failed to create request for AD lookup "
"by unixname");
return (IDMAP_ERR_INTERNAL);
}
@@ -3967,7 +3967,7 @@ retry:
if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR && retries++ < 2)
goto retry;
else if (retcode == IDMAP_ERR_RETRIABLE_NET_ERR)
- degrade_svc("some AD lookups timed out repeatedly");
+ degrade_svc(1, "some AD lookups timed out repeatedly");
if (retcode != IDMAP_SUCCESS) {
idmapdlog(LOG_NOTICE, "AD lookup by unixname failed");
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.c b/usr/src/cmd/idmap/idmapd/idmap_config.c
index 1537d6e35a..2dca835e7f 100644
--- a/usr/src/cmd/idmap/idmapd/idmap_config.c
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.c
@@ -428,12 +428,12 @@ static int
update_value(char **value, char **new, char *name)
{
if (*new == NULL)
- return (FALSE);
+ return (0);
if (*value != NULL && strcmp(*new, *value) == 0) {
free(*new);
*new = NULL;
- return (FALSE);
+ return (0);
}
idmapdlog(LOG_INFO, "change %s=%s", name, CHECK_NULL(*new));
@@ -441,7 +441,7 @@ update_value(char **value, char **new, char *name)
free(*value);
*value = *new;
*new = NULL;
- return (TRUE);
+ return (1);
}
static int
@@ -451,13 +451,13 @@ update_dirs(ad_disc_ds_t **value, ad_disc_ds_t **new, char *name)
if (*value == *new)
/* Nothing to do */
- return (FALSE);
+ return (0);
if (*value != NULL && *new != NULL &&
ad_disc_compare_ds(*value, *new) == 0) {
free(*new);
*new = NULL;
- return (FALSE);
+ return (0);
}
if (*value)
@@ -469,14 +469,14 @@ update_dirs(ad_disc_ds_t **value, ad_disc_ds_t **new, char *name)
if (*value == NULL) {
/* We're unsetting this DS property */
idmapdlog(LOG_INFO, "change %s=<none>", name);
- return (TRUE);
+ return (1);
}
/* List all the new DSs */
for (i = 0; (*value)[i].host[0] != '\0'; i++)
idmapdlog(LOG_INFO, "change %s=%s port=%d", name,
(*value)[i].host, (*value)[i].port);
- return (TRUE);
+ return (1);
}
@@ -529,13 +529,13 @@ pfroute_event_is_interesting(int rt_sock)
*/
static
int
-wait_for_event(int poke_is_interesting, struct timespec *timeout)
+wait_for_event(int poke_is_interesting, struct timespec *timeoutp)
{
port_event_t pe;
retry:
memset(&pe, 0, sizeof (pe));
- if (port_get(idmapd_ev_port, &pe, timeout) != 0) {
+ if (port_get(idmapd_ev_port, &pe, timeoutp) != 0) {
switch (errno) {
case EINTR:
goto retry;
@@ -583,20 +583,17 @@ retry:
(void) unlink(IDMAP_CACHEDIR "/ccache");
/* HUP is the refresh method, so re-read SMF config */
(void) idmapdlog(LOG_INFO, "SMF refresh");
- WRLOCK_CONFIG();
- (void) idmap_cfg_unload(&_idmapdstate.cfg->pgcfg);
- rc = idmap_cfg_load(&_idmapdstate.cfg->handles,
- &_idmapdstate.cfg->pgcfg, 1);
- if (rc < -1)
- (void) idmapdlog(LOG_ERR,
- "Various errors re-loading configuration "
- "will cause AD lookups to fail");
- else if (rc == -1)
- (void) idmapdlog(LOG_WARNING,
- "Various errors re-loading configuration "
- "may cause AD lookups to fail");
- UNLOCK_CONFIG();
- return (TRUE);
+ rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER|CFG_LOG);
+ if (rc < -1) {
+ (void) idmapdlog(LOG_ERR, "Fatal errors while reading "
+ "SMF properties");
+ exit(1);
+ } else if (rc == -1) {
+ (void) idmapdlog(LOG_WARNING, "Various errors "
+ "re-loading configuration may cause AD lookups "
+ "to fail");
+ }
+ return (FALSE);
}
return (FALSE);
@@ -606,23 +603,24 @@ void *
idmap_cfg_update_thread(void *arg)
{
- idmap_pg_config_t new_cfg;
int ttl, changed, poke_is_interesting;
idmap_cfg_handles_t *handles = &_idmapdstate.cfg->handles;
- idmap_pg_config_t *live_cfg = &_idmapdstate.cfg->pgcfg;
ad_disc_t ad_ctx = handles->ad_ctx;
- struct timespec timeout;
-
- (void) memset(&new_cfg, 0, sizeof (new_cfg));
+ struct timespec timeout, *timeoutp;
poke_is_interesting = 1;
for (ttl = 0, changed = TRUE; ; ttl = ad_disc_get_TTL(ad_ctx)) {
- if (ttl < 0 || ttl > MAX_CHECK_TIME) {
+ /*
+ * If ttl < 0 then we can wait for an event without timing out.
+ * If idmapd needs to notice that the system has been joined to
+ * a Windows domain then idmapd needs to be refreshed.
+ */
+ timeoutp = (ttl < 0) ? NULL : &timeout;
+ if (ttl > MAX_CHECK_TIME)
ttl = MAX_CHECK_TIME;
- }
timeout.tv_sec = ttl;
timeout.tv_nsec = 0;
- changed = wait_for_event(poke_is_interesting, &timeout);
+ changed = wait_for_event(poke_is_interesting, timeoutp);
/*
* If there are no interesting events, and this is not the first
@@ -634,118 +632,17 @@ idmap_cfg_update_thread(void *arg)
(void) ad_disc_SubnetChanged(ad_ctx);
- /*
- * Load configuration data into a private copy.
- *
- * The fixed values (i.e., from SMF) have already been set in AD
- * auto discovery, so if all values have been set in SMF and
- * they haven't been changed or the service been refreshed then
- * the rest of this loop's body is one big no-op.
- */
- ad_disc_refresh(ad_ctx);
- new_cfg.default_domain = ad_disc_get_DomainName(ad_ctx);
- if (new_cfg.default_domain == NULL)
- idmapdlog(LOG_INFO,
- "unable to discover Default Domain");
-
- new_cfg.domain_name = ad_disc_get_DomainName(ad_ctx);
- if (new_cfg.domain_name == NULL)
- idmapdlog(LOG_INFO,
- "unable to discover Domain Name");
-
- new_cfg.domain_controller =
- ad_disc_get_DomainController(ad_ctx, AD_DISC_PREFER_SITE);
- if (new_cfg.domain_controller == NULL)
- idmapdlog(LOG_INFO,
- "unable to discover Domain Controller");
-
- new_cfg.forest_name = ad_disc_get_ForestName(ad_ctx);
- if (new_cfg.forest_name == NULL)
- idmapdlog(LOG_INFO,
- "unable to discover Forest Name");
-
- new_cfg.site_name = ad_disc_get_SiteName(ad_ctx);
- if (new_cfg.site_name == NULL)
- idmapdlog(LOG_INFO,
- "unable to discover Site Name");
+ if (idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER) < -1) {
+ (void) idmapdlog(LOG_ERR, "Fatal errors while reading "
+ "SMF properties");
+ exit(1);
+ }
- new_cfg.global_catalog =
- ad_disc_get_GlobalCatalog(ad_ctx, AD_DISC_PREFER_SITE);
- if (new_cfg.global_catalog == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Global Catalog");
+ if (_idmapdstate.cfg->pgcfg.global_catalog == NULL ||
+ _idmapdstate.cfg->pgcfg.global_catalog[0].host[0] == '\0')
poke_is_interesting = 1;
- } else {
+ else
poke_is_interesting = 0;
- }
-
- if (new_cfg.default_domain == NULL &&
- new_cfg.domain_name == NULL &&
- new_cfg.domain_controller == NULL &&
- new_cfg.forest_name == NULL &&
- new_cfg.global_catalog == NULL) {
- idmapdlog(LOG_NOTICE, "Could not auto-discover AD "
- "domain and forest names nor domain controllers "
- "and global catalog servers");
- }
-
- /*
- * Update the live configuration
- */
- WRLOCK_CONFIG();
-
- if (live_cfg->list_size_limit != new_cfg.list_size_limit) {
- idmapdlog(LOG_INFO, "change list_size=%d",
- new_cfg.list_size_limit);
- live_cfg->list_size_limit = new_cfg.list_size_limit;
- }
-
- /*
- * Update running config and decide whether we want to call
- * reload_ad() (i.e., if the default_domain changed or the GC
- * list changed).
- *
- * If default_domain came from SMF then we must not
- * auto-discover it.
- */
- changed = FALSE;
- if (live_cfg->dflt_dom_set_in_smf == FALSE &&
- update_value(&live_cfg->default_domain,
- &new_cfg.default_domain, "default_domain") == TRUE)
- changed = TRUE;
-
- (void) update_value(&live_cfg->domain_name,
- &new_cfg.domain_name, "domain_name");
-
- (void) update_dirs(&live_cfg->domain_controller,
- &new_cfg.domain_controller, "domain_controller");
-
- (void) update_value(&live_cfg->forest_name,
- &new_cfg.forest_name, "forest_name");
-
- (void) update_value(&live_cfg->site_name,
- &new_cfg.site_name, "site_name");
-
- if (update_dirs(&live_cfg->global_catalog,
- &new_cfg.global_catalog, "global_catalog") == TRUE)
- changed = TRUE;
- UNLOCK_CONFIG();
-
- idmap_cfg_unload(&new_cfg);
-
-
- /*
- * Re-create the ad_t/ad_host_t objects if
- * either the default domain or the global
- * catalog server list changed.
- */
-
- if (changed) {
- RDLOCK_CONFIG();
- (void) reload_ad();
- UNLOCK_CONFIG();
- print_idmapdstate();
- }
}
/*NOTREACHED*/
return (NULL);
@@ -797,47 +694,33 @@ idmap_cfg_start_updates(void)
return (0);
}
-
+/*
+ * This is the half of idmap_cfg_load() that loads property values from
+ * SMF (using the config/ property group of the idmap FMRI).
+ *
+ * Return values: 0 -> success, -1 -> failure, -2 -> hard failures
+ * reading from SMF.
+ */
+static
int
-idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
- int discover)
+idmap_cfg_load_smf(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
+ int *errors)
{
int rc;
- int errors = 0;
uint8_t bool_val;
char *str = NULL;
bool_t new_debug_mode;
- ad_disc_t ad_ctx = handles->ad_ctx;
-
- pgcfg->list_size_limit = 0;
- pgcfg->default_domain = NULL;
- pgcfg->domain_name = NULL;
- pgcfg->machine_sid = NULL;
- pgcfg->domain_controller = NULL;
- pgcfg->forest_name = NULL;
- pgcfg->site_name = NULL;
- pgcfg->global_catalog = NULL;
- pgcfg->ad_unixuser_attr = NULL;
- pgcfg->ad_unixgroup_attr = NULL;
- pgcfg->nldap_winname_attr = NULL;
- pgcfg->ds_name_mapping_enabled = FALSE;
-
- pthread_mutex_lock(&handles->mutex);
-
- ad_disc_refresh(handles->ad_ctx);
if (scf_pg_update(handles->config_pg) < 0) {
idmapdlog(LOG_ERR, "scf_pg_update() failed: %s",
scf_strerror(scf_error()));
- rc = -2;
- goto exit;
+ return (-2);
}
if (scf_pg_update(handles->general_pg) < 0) {
idmapdlog(LOG_ERR, "scf_pg_update() failed: %s",
scf_strerror(scf_error()));
- rc = -2;
- goto exit;
+ return (-2);
}
new_debug_mode = prop_exists(handles, "debug");
@@ -863,7 +746,8 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
if (rc != 0)
errors++;
else
- (void) ad_disc_set_DomainName(ad_ctx, pgcfg->domain_name);
+ (void) ad_disc_set_DomainName(handles->ad_ctx,
+ pgcfg->domain_name);
rc = get_val_astring(handles, "default_domain",
&pgcfg->default_domain);
@@ -873,8 +757,7 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
* as fatal as they may leave ID mapping rules that
* match unqualified winnames flapping in the wind.
*/
- rc = -2;
- goto exit;
+ return (-2);
}
rc = get_val_astring(handles, "mapping_domain", &str);
@@ -918,10 +801,8 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
errors++;
if (pgcfg->machine_sid == NULL) {
/* If machine_sid not configured, generate one */
- if (generate_machine_sid(&pgcfg->machine_sid) < 0) {
- rc = -2;
- goto exit;
- }
+ if (generate_machine_sid(&pgcfg->machine_sid) < 0)
+ return (-2);
rc = set_val_astring(handles, "machine_sid",
pgcfg->machine_sid);
if (rc != 0)
@@ -934,20 +815,21 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
if (rc != 0)
errors++;
else
- (void) ad_disc_set_DomainController(ad_ctx,
+ (void) ad_disc_set_DomainController(handles->ad_ctx,
pgcfg->domain_controller);
rc = get_val_astring(handles, "forest_name", &pgcfg->forest_name);
if (rc != 0)
errors++;
else
- (void) ad_disc_set_ForestName(ad_ctx, pgcfg->forest_name);
+ (void) ad_disc_set_ForestName(handles->ad_ctx,
+ pgcfg->forest_name);
rc = get_val_astring(handles, "site_name", &pgcfg->site_name);
if (rc != 0)
errors++;
else
- (void) ad_disc_set_SiteName(ad_ctx, pgcfg->site_name);
+ (void) ad_disc_set_SiteName(handles->ad_ctx, pgcfg->site_name);
str = NULL;
rc = get_val_ds(handles, "global_catalog", 3268,
@@ -955,7 +837,8 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
if (rc != 0)
errors++;
else
- (void) ad_disc_set_GlobalCatalog(ad_ctx, pgcfg->global_catalog);
+ (void) ad_disc_set_GlobalCatalog(handles->ad_ctx,
+ pgcfg->global_catalog);
/*
* Read directory-based name mappings related SMF properties
@@ -963,113 +846,212 @@ idmap_cfg_load(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
bool_val = 0;
rc = get_val_int(handles, "ds_name_mapping_enabled",
&bool_val, SCF_TYPE_BOOLEAN);
- if (rc != 0) {
- rc = -2;
- goto exit;
- } else if (bool_val) {
- pgcfg->ds_name_mapping_enabled = TRUE;
- rc = get_val_astring(handles, "ad_unixuser_attr",
- &pgcfg->ad_unixuser_attr);
- if (rc != 0) {
- rc = -2;
- goto exit;
- }
+ if (rc != 0)
+ return (-2);
- rc = get_val_astring(handles, "ad_unixgroup_attr",
- &pgcfg->ad_unixgroup_attr);
- if (rc != 0) {
- rc = -2;
- goto exit;
- }
+ if (!bool_val)
+ return (rc);
- rc = get_val_astring(handles, "nldap_winname_attr",
- &pgcfg->nldap_winname_attr);
- if (rc != 0) {
- rc = -2;
- goto exit;
- }
+ pgcfg->ds_name_mapping_enabled = TRUE;
+ rc = get_val_astring(handles, "ad_unixuser_attr",
+ &pgcfg->ad_unixuser_attr);
+ if (rc != 0)
+ return (-2);
- if (pgcfg->nldap_winname_attr != NULL) {
- idmapdlog(LOG_ERR,
- "native LDAP based name mapping not supported "
- "at this time. Please unset "
- "config/nldap_winname_attr and restart idmapd.");
- rc = -3;
- goto exit;
- }
+ rc = get_val_astring(handles, "ad_unixgroup_attr",
+ &pgcfg->ad_unixgroup_attr);
+ if (rc != 0)
+ return (-2);
- if (pgcfg->ad_unixuser_attr == NULL &&
- pgcfg->ad_unixgroup_attr == NULL) {
- idmapdlog(LOG_ERR,
- "If config/ds_name_mapping_enabled property "
- "is set to true then atleast one of the following "
- "name mapping attributes must be specified. "
- "(config/ad_unixuser_attr OR "
- "config/ad_unixgroup_attr)");
- rc = -3;
- goto exit;
- }
+ rc = get_val_astring(handles, "nldap_winname_attr",
+ &pgcfg->nldap_winname_attr);
+ if (rc != 0)
+ return (-2);
+
+ if (pgcfg->nldap_winname_attr != NULL) {
+ idmapdlog(LOG_ERR,
+ "Native LDAP based name mapping not supported at this "
+ "time. Please unset config/nldap_winname_attr and restart "
+ "idmapd.");
+ return (-3);
}
+ if (pgcfg->ad_unixuser_attr == NULL &&
+ pgcfg->ad_unixgroup_attr == NULL) {
+ idmapdlog(LOG_ERR,
+ "If config/ds_name_mapping_enabled property is set to "
+ "true then atleast one of the following name mapping "
+ "attributes must be specified. (config/ad_unixuser_attr OR "
+ "config/ad_unixgroup_attr)");
+ return (-3);
+ }
- if (!discover)
- goto exit;
+ return (rc);
- /*
- * Auto Discover the rest
- */
- if (pgcfg->default_domain == NULL) {
+}
+
+/*
+ * This is the half of idmap_cfg_load() that auto-discovers values of
+ * discoverable properties that weren't already set via SMF properties.
+ *
+ * idmap_cfg_discover() is called *after* idmap_cfg_load_smf(), so it
+ * needs to be careful not to overwrite any properties set in SMF.
+ */
+static
+void
+idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg)
+{
+ ad_disc_t ad_ctx = handles->ad_ctx;
+
+ ad_disc_refresh(ad_ctx);
+
+ if (pgcfg->default_domain == NULL)
pgcfg->default_domain = ad_disc_get_DomainName(ad_ctx);
- if (pgcfg->default_domain == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Default Domain");
- }
- }
- if (pgcfg->domain_name == NULL) {
+ if (pgcfg->domain_name == NULL)
pgcfg->domain_name = ad_disc_get_DomainName(ad_ctx);
- if (pgcfg->domain_name == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Domain Name");
- }
- }
- if (pgcfg->domain_controller == NULL) {
+ if (pgcfg->domain_controller == NULL)
pgcfg->domain_controller =
ad_disc_get_DomainController(ad_ctx, AD_DISC_PREFER_SITE);
- if (pgcfg->domain_controller == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Domain Controller");
- }
- }
- if (pgcfg->forest_name == NULL) {
+ if (pgcfg->forest_name == NULL)
pgcfg->forest_name = ad_disc_get_ForestName(ad_ctx);
- if (pgcfg->forest_name == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Forest Name");
- }
- }
- if (pgcfg->site_name == NULL) {
+ if (pgcfg->site_name == NULL)
pgcfg->site_name = ad_disc_get_SiteName(ad_ctx);
- if (pgcfg->site_name == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Site Name");
- }
- }
- if (pgcfg->global_catalog == NULL) {
+ if (pgcfg->global_catalog == NULL)
pgcfg->global_catalog =
ad_disc_get_GlobalCatalog(ad_ctx, AD_DISC_PREFER_SITE);
- if (pgcfg->global_catalog == NULL) {
- idmapdlog(LOG_INFO,
- "unable to discover Global Catalog");
- }
+
+ if (pgcfg->domain_name == NULL)
+ idmapdlog(LOG_DEBUG, "unable to discover Domain Name");
+ if (pgcfg->domain_controller == NULL)
+ idmapdlog(LOG_DEBUG, "unable to discover Domain Controller");
+ if (pgcfg->forest_name == NULL)
+ idmapdlog(LOG_DEBUG, "unable to discover Forest Name");
+ if (pgcfg->site_name == NULL)
+ idmapdlog(LOG_DEBUG, "unable to discover Site Name");
+ if (pgcfg->global_catalog == NULL)
+ idmapdlog(LOG_DEBUG, "unable to discover Global Catalog");
+}
+
+/*
+ * idmap_cfg_load() is called at startup, and periodically via the
+ * update thread when the auto-discovery TTLs expire, as well as part of
+ * the refresh method, to update the current configuration. It always
+ * reads from SMF, but you still have to refresh the service after
+ * changing the config pg in order for the changes to take effect.
+ *
+ * There are two flags:
+ *
+ * - CFG_DISCOVER
+ * - CFG_LOG
+ *
+ * If CFG_DISCOVER is set then idmap_cfg_load() calls
+ * idmap_cfg_discover() to discover, via DNS and LDAP lookups, property
+ * values that weren't set in SMF.
+ *
+ * If CFG_LOG is set then idmap_cfg_load() will log (to LOG_NOTICE)
+ * whether the configuration changed. This should be used only from the
+ * refresh method.
+ *
+ * Return values: 0 -> success, -1 -> failure, -2 -> hard failures
+ * reading from SMF.
+ */
+int
+idmap_cfg_load(idmap_cfg_t *cfg, int flags)
+{
+ int rc = 0;
+ int errors = 0;
+ int changed = 0;
+ idmap_pg_config_t new_pgcfg, *live_pgcfg;
+
+ live_pgcfg = &cfg->pgcfg;
+ (void) memset(&new_pgcfg, 0, sizeof (new_pgcfg));
+
+ pthread_mutex_lock(&cfg->handles.mutex);
+
+ if ((rc = idmap_cfg_load_smf(&cfg->handles, &new_pgcfg, &errors)) < -1)
+ goto err;
+
+ if (flags & CFG_DISCOVER)
+ idmap_cfg_discover(&cfg->handles, &new_pgcfg);
+
+ WRLOCK_CONFIG();
+ if (live_pgcfg->list_size_limit != new_pgcfg.list_size_limit) {
+ idmapdlog(LOG_INFO, "change list_size=%d",
+ new_pgcfg.list_size_limit);
+ live_pgcfg->list_size_limit = new_pgcfg.list_size_limit;
+ }
+
+ /* Non-discoverable props updated here */
+ changed += update_value(&live_pgcfg->machine_sid,
+ &new_pgcfg.machine_sid, "machine_sid");
+
+ changed += live_pgcfg->ds_name_mapping_enabled !=
+ new_pgcfg.ds_name_mapping_enabled;
+ live_pgcfg->ds_name_mapping_enabled =
+ new_pgcfg.ds_name_mapping_enabled;
+
+ changed += update_value(&live_pgcfg->ad_unixuser_attr,
+ &new_pgcfg.ad_unixuser_attr, "ad_unixuser_attr");
+
+ changed += update_value(&live_pgcfg->ad_unixgroup_attr,
+ &new_pgcfg.ad_unixgroup_attr, "ad_unixgroup_attr");
+
+ changed += update_value(&live_pgcfg->nldap_winname_attr,
+ &new_pgcfg.nldap_winname_attr, "nldap_winname_attr");
+
+ /* Props that can be discovered and set in SMF updated here */
+ if (live_pgcfg->dflt_dom_set_in_smf == FALSE)
+ changed += update_value(&live_pgcfg->default_domain,
+ &new_pgcfg.default_domain, "default_domain");
+
+ changed += update_value(&live_pgcfg->domain_name,
+ &new_pgcfg.domain_name, "domain_name");
+
+ changed += update_dirs(&live_pgcfg->domain_controller,
+ &new_pgcfg.domain_controller, "domain_controller");
+
+ changed += update_value(&live_pgcfg->forest_name,
+ &new_pgcfg.forest_name, "forest_name");
+
+ changed += update_value(&live_pgcfg->site_name,
+ &new_pgcfg.site_name, "site_name");
+
+ if (update_dirs(&live_pgcfg->global_catalog,
+ &new_pgcfg.global_catalog, "global_catalog")) {
+ changed++;
+ /*
+ * Right now we only update the ad_t used for AD lookups
+ * when the GC list is updated. When we add mixed
+ * ds-based mapping we'll also need to update the ad_t
+ * used to talk to the domain, not just the one used to
+ * talk to the GC.
+ */
+ if (live_pgcfg->global_catalog != NULL &&
+ live_pgcfg->global_catalog[0].host[0] != '\0')
+ reload_ad();
+ }
+
+ idmap_cfg_unload(&new_pgcfg);
+
+ if (flags & CFG_LOG) {
+ /*
+ * If the config changes as a result of a refresh of the
+ * service, then logging about it can provide useful
+ * feedback to the sysadmin.
+ */
+ idmapdlog(LOG_NOTICE, "Configuration %schanged",
+ changed ? "" : "un");
}
-exit:
- pthread_mutex_unlock(&handles->mutex);
+ UNLOCK_CONFIG();
+
+err:
+ pthread_mutex_unlock(&cfg->handles.mutex);
if (rc < -1)
return (rc);
@@ -1216,12 +1198,14 @@ idmap_cfg_fini(idmap_cfg_t *cfg)
void
idmap_cfg_poke_updates(void)
{
- (void) port_send(idmapd_ev_port, POKE_AUTO_DISCOVERY, NULL);
+ if (idmapd_ev_port != -1)
+ (void) port_send(idmapd_ev_port, POKE_AUTO_DISCOVERY, NULL);
}
/*ARGSUSED*/
void
-idmap_cfg_hup_handler(int sig) {
+idmap_cfg_hup_handler(int sig)
+{
if (idmapd_ev_port >= 0)
(void) port_send(idmapd_ev_port, RECONFIGURE, NULL);
}
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.h b/usr/src/cmd/idmap/idmapd/idmap_config.h
index bf3038fbca..3fb2b4abad 100644
--- a/usr/src/cmd/idmap/idmapd/idmap_config.h
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.h
@@ -86,18 +86,21 @@ typedef struct idmap_pg_config {
typedef struct idmap_cfg {
idmap_pg_config_t pgcfg; /* live AD/ID mapping config */
idmap_cfg_handles_t handles;
+ int initialized;
} idmap_cfg_t;
extern void idmap_cfg_unload(idmap_pg_config_t *);
-extern int idmap_cfg_load(idmap_cfg_handles_t *,
- idmap_pg_config_t *, int);
+extern int idmap_cfg_load(idmap_cfg_t *, int);
extern idmap_cfg_t *idmap_cfg_init(void);
extern int idmap_cfg_fini(idmap_cfg_t *);
extern int idmap_cfg_start_updates(void);
extern void idmap_cfg_poke_updates(void);
extern void idmap_cfg_hup_handler(int);
+#define CFG_DISCOVER 0x1
+#define CFG_LOG 0x2
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/idmap/idmapd/idmapd.c b/usr/src/cmd/idmap/idmapd/idmapd.c
index ac58ec4f98..a819650a45 100644
--- a/usr/src/cmd/idmap/idmapd/idmapd.c
+++ b/usr/src/cmd/idmap/idmapd/idmapd.c
@@ -370,7 +370,7 @@ get_fmri(void)
* have a successful AD name<->SID lookup.
*/
void
-degrade_svc(const char *reason)
+degrade_svc(int poke_discovery, const char *reason)
{
const char *fmri;
@@ -378,18 +378,22 @@ degrade_svc(const char *reason)
* If the config update thread is in a state where auto-discovery could
* be re-tried, then this will make it try it -- a sort of auto-refresh.
*/
- idmap_cfg_poke_updates();
+ if (poke_discovery)
+ idmap_cfg_poke_updates();
membar_consumer();
if (degraded)
return;
+
+ idmapdlog(LOG_ERR, "Degraded operation (%s). If you are running an "
+ "SMB server in workgroup mode, or if you're not running an SMB "
+ "server, then you can ignore this message", reason);
+
membar_producer();
degraded = 1;
if ((fmri = get_fmri()) != NULL)
(void) smf_degrade_instance(fmri, 0);
-
- idmapdlog(LOG_ERR, "Degraded operation (%s)", reason);
}
void
@@ -406,7 +410,7 @@ restore_svc(void)
membar_producer();
degraded = 0;
- idmapdlog(LOG_INFO, "Normal operation restored");
+ idmapdlog(LOG_NOTICE, "Normal operation restored");
}
void
diff --git a/usr/src/cmd/idmap/idmapd/idmapd.h b/usr/src/cmd/idmap/idmapd/idmapd.h
index 1c050a3415..5acb7a6a69 100644
--- a/usr/src/cmd/idmap/idmapd/idmapd.h
+++ b/usr/src/cmd/idmap/idmapd/idmapd.h
@@ -223,9 +223,9 @@ extern void fini_mapping_system();
extern void print_idmapdstate();
extern int create_directory(const char *, uid_t, gid_t);
extern int load_config();
-extern int reload_ad();
+extern void reload_ad();
extern int idmap_init_tsd_key(void);
-extern void degrade_svc(const char *);
+extern void degrade_svc(int, const char *);
extern void restore_svc(void);
diff --git a/usr/src/cmd/idmap/idmapd/init.c b/usr/src/cmd/idmap/idmapd/init.c
index 39915bb4a8..5ccb6553a3 100644
--- a/usr/src/cmd/idmap/idmapd/init.c
+++ b/usr/src/cmd/idmap/idmapd/init.c
@@ -73,18 +73,15 @@ int
load_config()
{
int rc;
- idmap_pg_config_t *pgcfg;
if ((_idmapdstate.cfg = idmap_cfg_init()) == NULL) {
- degrade_svc("failed to initialize config");
+ degrade_svc(0, "failed to initialize config");
return (-1);
}
- pgcfg = &_idmapdstate.cfg->pgcfg;
- rc = idmap_cfg_load(&_idmapdstate.cfg->handles,
- &_idmapdstate.cfg->pgcfg, 0);
+ rc = idmap_cfg_load(_idmapdstate.cfg, 0);
if (rc < -1) {
/* Total failure */
- degrade_svc("fatal error while loading configuration");
+ degrade_svc(0, "fatal error while loading configuration");
return (rc);
}
@@ -93,22 +90,9 @@ load_config()
idmapdlog(LOG_ERR, "Various errors occurred while loading "
"the configuration; check the logs");
- if (pgcfg->global_catalog == NULL ||
- pgcfg->global_catalog[0].host[0] == '\0') {
- degrade_svc(
- "global catalog server is not configured; AD lookup "
- "will fail until one or more global catalog server names "
- "are configured or discovered; auto-discovery will begin "
- "shortly");
- } else {
- restore_svc();
- }
-
- (void) reload_ad();
-
if ((rc = idmap_cfg_start_updates()) < 0) {
/* Total failure */
- degrade_svc("could not start config updater");
+ degrade_svc(0, "could not start config updater");
return (rc);
}
@@ -118,7 +102,7 @@ load_config()
}
-int
+void
reload_ad()
{
int i;
@@ -127,21 +111,25 @@ reload_ad()
idmap_pg_config_t *pgcfg = &_idmapdstate.cfg->pgcfg;
- if (pgcfg->default_domain == NULL ||
- pgcfg->global_catalog == NULL) {
- if (_idmapdstate.ad == NULL)
- idmapdlog(LOG_ERR, "AD lookup disabled");
- else
- idmapdlog(LOG_ERR, "cannot update AD context");
- return (-1);
+ if (pgcfg->global_catalog == NULL ||
+ pgcfg->global_catalog[0].host[0] == '\0') {
+ /*
+ * No GCs. Continue to use the previous AD config in case
+ * that's still good but auto-discovery had a transient failure.
+ * If that stops working we'll go into degraded mode anyways
+ * when it does.
+ */
+ degrade_svc(0,
+ "Global Catalog servers not configured/discoverable");
+ return;
}
old = _idmapdstate.ad;
if (idmap_ad_alloc(&new, pgcfg->default_domain,
IDMAP_AD_GLOBAL_CATALOG) != 0) {
- degrade_svc("could not initialize AD context");
- return (-1);
+ degrade_svc(0, "could not initialize AD context");
+ return;
}
for (i = 0; pgcfg->global_catalog[i].host[0] != '\0'; i++) {
@@ -149,8 +137,8 @@ reload_ad()
pgcfg->global_catalog[i].host,
pgcfg->global_catalog[i].port) != 0) {
idmap_ad_free(&new);
- degrade_svc("could not initialize AD GC context");
- return (-1);
+ degrade_svc(0, "could not initialize AD GC context");
+ return;
}
}
@@ -158,8 +146,6 @@ reload_ad()
if (old != NULL)
idmap_ad_free(&old);
-
- return (0);
}