4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
27 * Initialization routines
37 #include <sys/types.h>
39 #include <rpcsvc/daemon_utils.h>
47 if ((rc
= load_config()) < 0)
50 (void) setegid(DAEMON_GID
);
51 (void) seteuid(DAEMON_UID
);
54 fini_mapping_system();
72 if ((_idmapdstate
.cfg
= idmap_cfg_init()) == NULL
) {
73 degrade_svc(0, "failed to initialize config");
77 rc
= idmap_cfg_upgrade(_idmapdstate
.cfg
);
79 degrade_svc(0, "fatal error while upgrading configuration");
83 rc
= idmap_cfg_load(_idmapdstate
.cfg
, 0);
86 degrade_svc(0, "fatal error while loading configuration");
92 idmapdlog(LOG_ERR
, "Various errors occurred while loading "
93 "the configuration; check the logs");
95 if ((rc
= idmap_cfg_start_updates()) < 0) {
97 degrade_svc(0, "could not start config updater");
102 idmapdlog(LOG_DEBUG
, "Initial configuration loaded");
112 adutils_ad_t
**new_gcs
;
113 adutils_ad_t
**old_gcs
= _idmapdstate
.gcs
;
115 int old_num_gcs
= _idmapdstate
.num_gcs
;
116 idmap_pg_config_t
*pgcfg
= &_idmapdstate
.cfg
->pgcfg
;
117 idmap_trustedforest_t
*trustfor
= pgcfg
->trusted_forests
;
118 int num_trustfor
= pgcfg
->num_trusted_forests
;
119 ad_disc_domainsinforest_t
*domain_in_forest
;
121 if (pgcfg
->use_ads
== B_FALSE
||
122 pgcfg
->domain_name
== NULL
) {
124 * ADS disabled, or no domain name specified.
125 * Not using adutils. (but still can use lsa)
132 if (pgcfg
->global_catalog
== NULL
||
133 pgcfg
->global_catalog
[0].host
[0] == '\0') {
135 * No GCs. Continue to use the previous AD config in case
136 * that's still good but auto-discovery had a transient failure.
137 * If that stops working we'll go into degraded mode anyways
141 "Global Catalog servers not configured/discoverable");
145 new_num_gcs
= 1 + num_trustfor
;
146 new_gcs
= calloc(new_num_gcs
, sizeof (adutils_ad_t
*));
147 if (new_gcs
== NULL
) {
148 degrade_svc(0, "could not allocate AD context array "
153 if (adutils_ad_alloc(&new_gcs
[0], NULL
, ADUTILS_AD_GLOBAL_CATALOG
) !=
156 degrade_svc(0, "could not initialize AD context "
161 for (i
= 0; pgcfg
->global_catalog
[i
].host
[0] != '\0'; i
++) {
162 if (idmap_add_ds(new_gcs
[0],
163 pgcfg
->global_catalog
[i
].host
,
164 pgcfg
->global_catalog
[i
].port
) != 0) {
165 adutils_ad_free(&new_gcs
[0]);
167 degrade_svc(0, "could not set AD hosts "
173 if (pgcfg
->domains_in_forest
!= NULL
) {
174 for (i
= 0; pgcfg
->domains_in_forest
[i
].domain
[0] != '\0';
176 if (adutils_add_domain(new_gcs
[0],
177 pgcfg
->domains_in_forest
[i
].domain
,
178 pgcfg
->domains_in_forest
[i
].sid
) != 0) {
179 adutils_ad_free(&new_gcs
[0]);
181 degrade_svc(0, "could not set AD domains "
188 for (i
= 0; i
< num_trustfor
; i
++) {
189 if (adutils_ad_alloc(&new_gcs
[i
+ 1], NULL
,
190 ADUTILS_AD_GLOBAL_CATALOG
) != ADUTILS_SUCCESS
) {
191 degrade_svc(0, "could not initialize trusted AD "
192 "context (out of memory)");
196 for (j
= 0; trustfor
[i
].global_catalog
[j
].host
[0] != '\0';
198 if (idmap_add_ds(new_gcs
[i
+ 1],
199 trustfor
[i
].global_catalog
[j
].host
,
200 trustfor
[i
].global_catalog
[j
].port
) != 0) {
201 adutils_ad_free(&new_gcs
[i
+ 1]);
202 degrade_svc(0, "could not set trusted "
203 "AD hosts (out of memory)");
208 for (j
= 0; trustfor
[i
].domains_in_forest
[j
].domain
[0] != '\0';
210 domain_in_forest
= &trustfor
[i
].domains_in_forest
[j
];
211 /* Only add domains which are marked */
212 if (domain_in_forest
->trusted
) {
213 if (adutils_add_domain(new_gcs
[i
+ 1],
214 domain_in_forest
->domain
,
215 domain_in_forest
->sid
) != 0) {
216 adutils_ad_free(&new_gcs
[i
+ 1]);
217 degrade_svc(0, "could not set trusted "
218 "AD domains (out of memory)");
227 _idmapdstate
.gcs
= new_gcs
;
228 _idmapdstate
.num_gcs
= new_num_gcs
;
230 if (old_gcs
!= NULL
) {
231 for (i
= 0; i
< old_num_gcs
; i
++)
232 adutils_ad_free(&old_gcs
[i
]);
238 * NEEDSWORK: This should load entries for domain servers for all known
239 * domains - the joined domain, other domains in the forest, and trusted
240 * domains in other forests. However, we don't yet discover any DCs other
241 * than the DCs for the joined domain.
248 adutils_ad_t
**new_dcs
;
249 adutils_ad_t
**old_dcs
= _idmapdstate
.dcs
;
251 int old_num_dcs
= _idmapdstate
.num_dcs
;
252 idmap_pg_config_t
*pgcfg
= &_idmapdstate
.cfg
->pgcfg
;
254 if (pgcfg
->use_ads
== B_FALSE
||
255 pgcfg
->domain_name
== NULL
) {
257 * ADS disabled, or no domain name specified.
258 * Not using adutils. (but still can use lsa)
265 if (pgcfg
->domain_controller
== NULL
||
266 pgcfg
->domain_controller
[0].host
[0] == '\0') {
268 * No DCs. Continue to use the previous AD config in case
269 * that's still good but auto-discovery had a transient failure.
270 * If that stops working we'll go into degraded mode anyways
274 "Domain controller servers not configured/discoverable");
279 new_dcs
= calloc(new_num_dcs
, sizeof (adutils_ad_t
*));
283 if (adutils_ad_alloc(&new_dcs
[0], pgcfg
->domain_name
,
284 ADUTILS_AD_DATA
) != ADUTILS_SUCCESS
)
287 for (i
= 0; pgcfg
->domain_controller
[i
].host
[0] != '\0'; i
++) {
288 if (idmap_add_ds(new_dcs
[0],
289 pgcfg
->domain_controller
[i
].host
,
290 pgcfg
->domain_controller
[i
].port
) != 0)
295 * NEEDSWORK: All we need here is to add the domain and SID for
296 * this DC to the list of domains supported by this entry. Isn't
297 * there an easier way to find the SID than to walk through the list
298 * of all of the domains in the forest?
300 ad_disc_domainsinforest_t
*dif
= pgcfg
->domains_in_forest
;
302 for (; dif
->domain
[0] != '\0'; dif
++) {
303 if (domain_eq(pgcfg
->domain_name
, dif
->domain
)) {
304 if (adutils_add_domain(new_dcs
[0],
305 dif
->domain
, dif
->sid
) != 0)
313 _idmapdstate
.dcs
= new_dcs
;
314 _idmapdstate
.num_dcs
= new_num_dcs
;
316 if (old_dcs
!= NULL
) {
317 for (i
= 0; i
< old_num_dcs
; i
++)
318 adutils_ad_free(&old_dcs
[i
]);
325 degrade_svc(0, "out of memory");
327 if (new_dcs
!= NULL
) {
328 if (new_dcs
[0] != NULL
)
329 adutils_ad_free(&new_dcs
[0]);
343 print_idmapdstate(void)
346 idmap_pg_config_t
*pgcfg
;
347 idmap_trustedforest_t
*tf
;
351 if (_idmapdstate
.cfg
== NULL
) {
352 idmapdlog(LOG_INFO
, "Null configuration");
357 pgcfg
= &_idmapdstate
.cfg
->pgcfg
;
359 idmapdlog(LOG_DEBUG
, "list_size_limit=%llu", pgcfg
->list_size_limit
);
360 idmapdlog(LOG_DEBUG
, "default_domain=%s",
361 CHECK_NULL(pgcfg
->default_domain
));
362 idmapdlog(LOG_DEBUG
, "domain_name=%s", CHECK_NULL(pgcfg
->domain_name
));
363 idmapdlog(LOG_DEBUG
, "machine_sid=%s", CHECK_NULL(pgcfg
->machine_sid
));
364 if (pgcfg
->domain_controller
== NULL
||
365 pgcfg
->domain_controller
[0].host
[0] == '\0') {
366 idmapdlog(LOG_DEBUG
, "No domain controllers known");
368 for (i
= 0; pgcfg
->domain_controller
[i
].host
[0] != '\0'; i
++)
369 idmapdlog(LOG_DEBUG
, "domain_controller=%s port=%d",
370 pgcfg
->domain_controller
[i
].host
,
371 pgcfg
->domain_controller
[i
].port
);
373 idmapdlog(LOG_DEBUG
, "forest_name=%s", CHECK_NULL(pgcfg
->forest_name
));
374 idmapdlog(LOG_DEBUG
, "site_name=%s", CHECK_NULL(pgcfg
->site_name
));
375 if (pgcfg
->global_catalog
== NULL
||
376 pgcfg
->global_catalog
[0].host
[0] == '\0') {
377 idmapdlog(LOG_DEBUG
, "No global catalog servers known");
379 for (i
= 0; pgcfg
->global_catalog
[i
].host
[0] != '\0'; i
++)
380 idmapdlog(LOG_DEBUG
, "global_catalog=%s port=%d",
381 pgcfg
->global_catalog
[i
].host
,
382 pgcfg
->global_catalog
[i
].port
);
384 if (pgcfg
->domains_in_forest
== NULL
||
385 pgcfg
->domains_in_forest
[0].domain
[0] == '\0') {
386 idmapdlog(LOG_DEBUG
, "No domains in forest %s known",
387 CHECK_NULL(pgcfg
->forest_name
));
389 for (i
= 0; pgcfg
->domains_in_forest
[i
].domain
[0] != '\0'; i
++)
390 idmapdlog(LOG_DEBUG
, "domains in forest %s = %s",
391 CHECK_NULL(pgcfg
->forest_name
),
392 pgcfg
->domains_in_forest
[i
].domain
);
394 if (pgcfg
->trusted_domains
== NULL
||
395 pgcfg
->trusted_domains
[0].domain
[0] == '\0') {
396 idmapdlog(LOG_DEBUG
, "No trusted domains known");
398 for (i
= 0; pgcfg
->trusted_domains
[i
].domain
[0] != '\0'; i
++)
399 idmapdlog(LOG_DEBUG
, "trusted domain = %s",
400 pgcfg
->trusted_domains
[i
].domain
);
403 for (i
= 0; i
< pgcfg
->num_trusted_forests
; i
++) {
404 tf
= &pgcfg
->trusted_forests
[i
];
405 for (j
= 0; tf
->global_catalog
[j
].host
[0] != '\0'; j
++)
407 "trusted forest %s global_catalog=%s port=%d",
409 tf
->global_catalog
[j
].host
,
410 tf
->global_catalog
[j
].port
);
411 for (j
= 0; tf
->domains_in_forest
[j
].domain
[0] != '\0'; j
++) {
412 if (tf
->domains_in_forest
[j
].trusted
) {
414 "trusted forest %s domain=%s",
416 tf
->domains_in_forest
[j
].domain
);
421 idmapdlog(LOG_DEBUG
, "directory_based_mapping=%s",
422 enum_lookup(pgcfg
->directory_based_mapping
, directory_mapping_map
));
423 idmapdlog(LOG_DEBUG
, "ad_unixuser_attr=%s",
424 CHECK_NULL(pgcfg
->ad_unixuser_attr
));
425 idmapdlog(LOG_DEBUG
, "ad_unixgroup_attr=%s",
426 CHECK_NULL(pgcfg
->ad_unixgroup_attr
));
427 idmapdlog(LOG_DEBUG
, "nldap_winname_attr=%s",
428 CHECK_NULL(pgcfg
->nldap_winname_attr
));
434 create_directory(const char *path
, uid_t uid
, gid_t gid
)
438 if ((rc
= mkdir(path
, 0700)) < 0 && errno
!= EEXIST
) {
439 idmapdlog(LOG_ERR
, "Error creating directory %s (%s)",
440 path
, strerror(errno
));
444 if (lchown(path
, uid
, gid
) < 0) {
445 idmapdlog(LOG_ERR
, "Error creating directory %s (%s)",
446 path
, strerror(errno
));