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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <nss_common.h>
31 #include <libscf_priv.h>
34 #include "nscd_switch.h"
39 * _nscd_nss_finders is used to replace the nss_default_finders in libc
40 * to allow nscd to have more control over the dl handles when using
41 * dlsym to get the address of the nss backend instance constructors
43 static nss_backend_constr_t
_nscd_per_src_lookup(void *,
44 const char *, const char *, void **);
45 static void _nscd_per_src_delete(void *, nss_backend_constr_t
);
47 static nss_backend_finder_t _nscd_per_src
= {
53 nss_backend_finder_t
*_nscd_nss_finders
= &_nscd_per_src
;
56 * nscd database for each source. It contains backend
57 * info (nscd_be_info_t) for each naming database.
58 * Protected by nscd_src_backend_db_lock.
60 nscd_db_t
***nscd_src_backend_db
;
61 int *nscd_src_backend_db_loaded
;
62 static rwlock_t nscd_src_backend_db_lock
= DEFAULTRWLOCK
;
65 * nsswitch config monitored by nscd. Protected by
66 * readers/writer lock nscd_nsw_config_lock
68 nscd_nsw_config_t
***nscd_nsw_config
;
69 static rwlock_t nscd_nsw_config_lock
= DEFAULTRWLOCK
;
72 * nsswitch source index/name array
73 * (allow 32 foreign nsswitch sources/backends)
75 #define NSCD_NUM_SRC_FOREIGN 32
76 nscd_cfg_id_t
*_nscd_cfg_nsw_src_all
;
77 int _nscd_cfg_num_nsw_src_all
;
81 nscd_acc_data_t
*data
)
84 nscd_nsw_config_t
*nsw_cfg
= *(nscd_nsw_config_t
**)data
;
85 char *me
= "free_nscd_nsw_config";
87 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
88 (me
, "freeing nscd nsw config %p \n", nsw_cfg
);
92 if (nsw_cfg
->db_name
!= NULL
)
93 free(nsw_cfg
->db_name
);
94 if (nsw_cfg
->nsw_cfg_str
!= NULL
)
95 free(nsw_cfg
->nsw_cfg_str
);
96 if (nsw_cfg
->nsw_config
!= NULL
)
97 (void) __nsw_freeconfig_v1(nsw_cfg
->nsw_config
);
98 if (nsw_cfg
->src_idx
!= NULL
)
99 free(nsw_cfg
->src_idx
);
106 _nscd_free_nsw_config(
107 nscd_nsw_config_t
*nswcfg
)
109 free_nscd_nsw_config((nscd_acc_data_t
*)&nswcfg
);
113 _nscd_free_all_nsw_config()
116 nscd_nsw_config_t
**nsw_cfg
;
118 char *me
= "_nscd_free_all_nsw_config";
120 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
121 (me
, "freeing all nscd nsw config \n");
123 (void) rw_wrlock(&nscd_nsw_config_lock
);
124 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
126 if ((nsw_cfg
= nscd_nsw_config
[i
]) == NULL
)
129 nscd_nsw_config
[i
] = (nscd_nsw_config_t
**)_nscd_set(
130 (nscd_acc_data_t
*)nsw_cfg
, NULL
);
132 (void) rw_unlock(&nscd_nsw_config_lock
);
137 free_nsw_backend_info_db(nscd_acc_data_t
*data
)
140 nscd_db_t
*db
= *(nscd_db_t
**)data
;
141 char *me
= "free_nsw_backend_info_db";
143 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
144 (me
, "freeing nsw backend info db %p\n", db
);
154 _nscd_free_all_nsw_backend_info_db()
159 char *me
= " _nscd_free_all_nsw_backend_info_db";
161 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
162 (me
, "freeing all nsw backend info db\n");
164 (void) rw_wrlock(&nscd_src_backend_db_lock
);
165 for (i
= 0; i
< NSCD_NUM_SRC
; i
++) {
167 if ((db
= nscd_src_backend_db
[i
]) == NULL
)
170 nscd_src_backend_db
[i
] = (nscd_db_t
**)_nscd_set(
171 (nscd_acc_data_t
*)db
, NULL
);
172 nscd_src_backend_db_loaded
[i
] = 0;
174 (void) rw_unlock(&nscd_src_backend_db_lock
);
178 * Populate the backend info db for the 'NSCD_NSW_SRC_NAME(srci)'
179 * source. Create one entry for each source/database pair
180 * (e.g., ldap:passwd, nis:hosts, etc).
183 _nscd_populate_nsw_backend_info_db(int srci
)
185 nscd_be_info_t be_info
, *bi
;
186 nss_backend_finder_t
*bf
;
187 nscd_nsw_config_t
*nsw_cfg
;
189 nscd_db_entry_t
*db_entry
;
190 char *src
= NSCD_NSW_SRC_NAME(srci
);
192 char *me
= "_nscd_populate_nsw_backend_info_db";
194 nss_backend_constr_t c
;
195 void *be_version
= &_nscd_be_version
;
197 /* get the version number of the backend (if available) */
198 if (srci
>= _nscd_cfg_num_nsw_src
) { /* a foreign backend */
199 c
= _nscd_per_src_lookup(handle
, NULL
, src
, &handle
);
203 be_version
= (void *)c
;
205 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
206 (me
, "foreign backend: _nss_%s_version = %p ", src
, be_version
);
209 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
211 /* no nsswitch configuration, no backend info db population */
212 if (nscd_nsw_config
[i
] == NULL
|| *nscd_nsw_config
[i
] == NULL
)
215 nsw_cfg
= *nscd_nsw_config
[i
];
216 dbn
= NSCD_NSW_DB_NAME(i
);
217 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
218 (me
, "adding backend info for <%s : %s>\n", src
, dbn
);
220 (void) memset(&be_info
, 0, sizeof (be_info
));
222 for (bf
= nsw_cfg
->fe_params
.finders
; bf
!= 0; bf
= bf
->next
) {
224 c
= (*bf
->lookup
)(handle
, dbn
, src
, &handle
);
227 be_info
.be_constr
= c
;
229 be_info
.finder_priv
= handle
;
230 be_info
.be_version
= be_version
;
234 if (be_info
.be_constr
== NULL
) {
236 * Couldn't find the backend anywhere.
237 * This is fine, some backend just don't
238 * support certain databases.
240 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
241 (me
, "unable to find backend info "
242 "for <%s : %s>\n", src
, dbn
);
245 size
= sizeof (nscd_be_info_t
);
247 db_entry
= _nscd_alloc_db_entry(NSCD_DATA_BACKEND_INFO
,
250 if (db_entry
== NULL
) {
251 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
252 (me
, "unable to allocate db entry for "
253 "<%s : %s>\n", src
, dbn
);
254 return (NSCD_NO_MEMORY
);
257 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
258 (me
, "adding be db entry %p for <%s : %s> to db %p: "
259 "constr = %p\n", db_entry
, src
, dbn
,
260 *nscd_src_backend_db
[srci
], be_info
.be_constr
);
262 bi
= (nscd_be_info_t
*)*(db_entry
->data_array
);
265 (void) _nscd_wrlock((nscd_acc_data_t
*)
266 nscd_src_backend_db
[srci
]);
267 nscd_src_backend_db_loaded
[srci
] = 1;
268 (void) _nscd_add_db_entry(*nscd_src_backend_db
[srci
],
269 dbn
, db_entry
, NSCD_ADD_DB_ENTRY_LAST
);
270 (void) _nscd_rw_unlock((nscd_acc_data_t
*)
271 nscd_src_backend_db
[srci
]);
274 return (NSCD_SUCCESS
);
278 * create data structures (used by the switch engine) based
279 * on the input switch policy configuration and database
283 _nscd_create_sw_struct(
289 nscd_nsw_params_t
*params
)
291 char *me
= "_nscd_create_sw_struct";
292 nscd_rc_t rc
= NSCD_SUCCESS
;
293 nscd_nsw_config_t
*nsw_cfg
= NULL
;
294 nscd_nsw_config_t
**nsw_cfg_p
= NULL
;
295 struct __nsw_switchconfig_v1
*swcfg
= NULL
;
296 struct __nsw_lookup_v1
*lkp
;
297 enum __nsw_parse_err err
;
299 int *src_idx_a
= NULL
;
303 * if the nsw config string has been parsed into
304 * a struct __nsw_switchconfig_v1, use it. If not,
308 swcfg
= (struct __nsw_switchconfig_v1
*)swcfgv1
;
312 cstr
= strdup(cfgstr
);
314 return (NSCD_NO_MEMORY
);
317 * parse the nsw config string and create
318 * a struct __nsw_switchconfig_v1
320 swcfg
= _nsw_getoneconfig_v1(dbn
, cstr
, &err
);
323 rc
= NSCD_CFG_SYNTAX_ERROR
;
324 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
325 (me
, "error: unable to process nsw config string\n");
330 /* allocate the space for a nscd_nsw_config_t */
331 nsw_cfg
= calloc(1, sizeof (nscd_nsw_config_t
));
332 if (nsw_cfg
== NULL
) {
334 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
335 (me
, "error: unable to allocate an nscd_nsw_config_t\n");
339 /* need to know how many backends (sources) */
340 maxsrc
= swcfg
->num_lookups
;
341 nsw_cfg
->max_src
= maxsrc
;
344 * allocate an array to store the index for each
347 src_idx_a
= calloc(1, maxsrc
* sizeof (int));
348 if (src_idx_a
== NULL
) {
350 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
351 (me
, "error: unable to allocate an array for source index\n");
356 * set the index for each backend (source)
358 lkp
= swcfg
->lookups
;
359 for (j
= 0; j
< maxsrc
; j
++) {
362 for (k
= 0; k
< NSCD_NUM_SRC
&& NSCD_NSW_SRC_NAME(k
) != NULL
&&
363 strcmp(lkp
->service_name
, NSCD_NSW_SRC_NAME(k
)) != 0;
368 if (k
< NSCD_NUM_SRC
&& nscd_src_backend_db_loaded
[k
] == 0) {
369 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
370 (me
, "unknown nsw source name %s\n", lkp
->service_name
);
371 usrc
= strdup(lkp
->service_name
);
374 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
375 (me
, "unable to strdup() source name\n");
378 NSCD_NSW_SRC_NAME(k
) = usrc
;
380 rc
= _nscd_populate_nsw_backend_info_db(k
);
381 if (rc
!= NSCD_SUCCESS
) {
383 NSCD_NSW_SRC_NAME(k
) = NULL
;
386 } else if (NSCD_NSW_SRC_NAME(k
) == NULL
) {
388 * number of user-defined source exceeded
390 rc
= NSCD_CFG_SYNTAX_ERROR
;
391 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
392 (me
, "error: number of user_defined source exceeded\n");
397 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
398 (me
, "setting source index array [%d] = %d (%s)\n",
399 j
, k
, lkp
->service_name
);
404 if (lkp
== NULL
) break;
406 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
407 (me
, "number of nsw sources = %d\n", nsw_cfg
->max_src
);
408 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
409 (me
, "next nsw source is %s\n", lkp
->service_name
);
412 /* set it up to reference count the switch policy config */
413 nsw_cfg_p
= (nscd_nsw_config_t
**)_nscd_alloc(NSCD_DATA_NSW_CONFIG
,
414 sizeof (nscd_nsw_config_t
**), free_nscd_nsw_config
,
417 if (nsw_cfg_p
== NULL
) {
419 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
420 (me
, "unable to allocate a new nsw config DB\n");
423 *nsw_cfg_p
= nsw_cfg
;
425 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
426 (me
, "new nsw config DB %p allocated\n", nsw_cfg_p
);
428 /* save all the data in the new nscd_nsw_config_t */
429 nsw_cfg
->db_name
= strdup(dbn
);
430 nsw_cfg
->nsw_cfg_str
= strdup(cfgstr
);
431 if (nsw_cfg
->db_name
== NULL
|| nsw_cfg
->nsw_cfg_str
== NULL
) {
436 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
437 (me
, "switch policy \"%s\" for database is \"%s\"\n",
438 nsw_cfg
->db_name
, nsw_cfg
->nsw_cfg_str
);
440 nsw_cfg
->nsw_config
= swcfg
;
441 nsw_cfg
->src_idx
= src_idx_a
;
444 * set default frontend params and if necessary call initf()
445 * to initialize or override
447 nsw_cfg
->fe_params
.max_active_per_src
= 10;
448 nsw_cfg
->fe_params
.max_dormant_per_src
= 1;
449 nsw_cfg
->fe_params
.finders
= _nscd_nss_finders
;
450 if (params
!= NULL
) {
451 nsw_cfg
->fe_params
= params
->p
;
453 if (params
->p
.flags
& NSS_USE_DEFAULT_CONFIG
) {
454 params
->nswcfg
= nsw_cfg_p
;
456 * this nsw_cfg is not meant to last long, no need
457 * to set up the nsw state and getent bases, just
458 * exit with NSCD_SUCCESS
464 (void) (nscd_nss_db_initf
[dbi
])(&nsw_cfg
->fe_params
);
467 * also create a new nsw state base
469 if ((rc
= _nscd_init_nsw_state_base(dbi
, compat_basei
, 1)) !=
471 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
472 (me
, "unable to initialize a nsw state base(%d)\n", dbi
);
476 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
477 (me
, "new nsw state base(%d) %p created\n", dbi
,
478 nscd_nsw_state_base
[dbi
]);
481 * also create a new getent context base
483 if ((rc
= _nscd_init_getent_ctx_base(dbi
, 1)) != NSCD_SUCCESS
) {
484 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
485 (me
, "unable to initialize a getent context base(%d)\n", dbi
);
489 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
490 (me
, "new getent context base(%d) %p created\n", dbi
,
491 nscd_getent_ctx_base
[dbi
]);
493 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
494 (me
, "new nsw config created (database = %s, "
495 "config = %s)\n", dbn
, cfgstr
);
498 * Activate the new nscd_nsw_config_t and make it the
499 * current nsswitch config. The old one pointed to by
500 * nscd_nsw_config[dbi] will either be destroyed
501 * immediately or left on the side line (and be
502 * destroyed eventually). __nscd_set() will set the
503 * associated flags to make it happen.
505 nscd_nsw_config
[dbi
] = (nscd_nsw_config_t
**)_nscd_set(
506 (nscd_acc_data_t
*)nscd_nsw_config
[dbi
],
507 (nscd_acc_data_t
*)nsw_cfg_p
);
511 if (rc
!= NSCD_SUCCESS
) {
513 if (swcfgv1
== NULL
&& swcfg
!= NULL
)
514 (void) __nsw_freeconfig_v1(swcfg
);
515 if (src_idx_a
!= NULL
)
519 if (nsw_cfg
!= NULL
) {
520 if (nsw_cfg
->db_name
!= NULL
)
521 free(nsw_cfg
->db_name
);
522 if (nsw_cfg
->nsw_cfg_str
!= NULL
)
523 free(nsw_cfg
->nsw_cfg_str
);
529 return (NSCD_SUCCESS
);
533 create_nsw_config(int dbi
)
536 nscd_nsw_config_t
*nsw_cfg
= NULL
;
537 nscd_nsw_config_t
**nsw_cfg_p
= NULL
;
538 char *me
= "create_nsw_config";
541 * Allocate a pointer space for saving a pointer to a
542 * nscd_nsw_config_t. _nscd_alloc() will also create
543 * a nscd_access_t header with a rwlock_t and mutex_t
544 * for controlling later access to the data pointed
547 nsw_cfg_p
= (nscd_nsw_config_t
**)_nscd_alloc(NSCD_DATA_NSW_CONFIG
,
548 sizeof (nscd_nsw_config_t
**), free_nscd_nsw_config
,
549 NSCD_ALLOC_RWLOCK
| NSCD_ALLOC_MUTEX
);
551 if (nsw_cfg_p
== NULL
) {
552 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
553 (me
, "unable to allocate a space for a nsw config pointer\n");
554 return (NSCD_NO_MEMORY
);
556 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
557 (me
, "addr for saving nsw config pointer = %p\n", nsw_cfg_p
);
560 * If pseudo-databases (initf function not defined),
561 * no need to create a nscd_nsw_config_t yet,
562 * so put a NULL pointer in the pointer space.
564 if (nscd_nss_db_initf
[dbi
] == NULL
) {
566 nscd_nsw_config
[dbi
] = (nscd_nsw_config_t
**)_nscd_set(
567 (nscd_acc_data_t
*)nscd_nsw_config
[dbi
],
568 (nscd_acc_data_t
*)nsw_cfg_p
);
570 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
571 (me
, "pointer to nsw config has been set to NULL\n");
573 return (NSCD_SUCCESS
);
576 /* allocate the space for a nscd_nsw_config_t */
577 nsw_cfg
= calloc(1, sizeof (nscd_nsw_config_t
));
578 if (nsw_cfg
== NULL
) {
579 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
580 (me
, "unable to allocate a nsw config structure\n");
581 return (NSCD_NO_MEMORY
);
583 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
584 (me
, "nsw config structure %pallocated\n", nsw_cfg
);
586 nsw_cfg
->db_name
= strdup(NSCD_NSW_DB_NAME(dbi
));
587 if (nsw_cfg
->db_name
== NULL
) {
588 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
589 (me
, "unable to strdup the db name\n");
590 return (NSCD_NO_MEMORY
);
594 * set default frontend params and then call initf()
595 * to initialize or override
597 nsw_cfg
->fe_params
.max_active_per_src
= 10;
598 nsw_cfg
->fe_params
.max_dormant_per_src
= 1;
599 nsw_cfg
->fe_params
.finders
= _nscd_nss_finders
;
600 (void) (nscd_nss_db_initf
[dbi
])(&nsw_cfg
->fe_params
);
603 * activate the new nscd_nsw_config_t
605 *nsw_cfg_p
= nsw_cfg
;
606 nscd_nsw_config
[dbi
] = (nscd_nsw_config_t
**)_nscd_set(
607 (nscd_acc_data_t
*)nscd_nsw_config
[dbi
],
608 (nscd_acc_data_t
*)nsw_cfg_p
);
610 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
611 (me
, "nsw config %p activated\n", nsw_cfg
);
613 return (NSCD_SUCCESS
);
617 _nscd_init_all_nsw_config(void)
621 char *me
= "_nscd_init_all_nsw_config";
623 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
624 (me
, "initializing all nsw config\n");
626 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
627 if ((rc
= create_nsw_config(i
)) != NSCD_SUCCESS
)
631 return (NSCD_SUCCESS
);
635 init_nsw_be_info_db(int srci
)
637 nscd_db_t
*ret
, **db_p
;
638 char *me
= "init_nsw_be_info_db";
640 ret
= _nscd_alloc_db(NSCD_DB_SIZE_SMALL
);
643 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
644 (me
, "unable to allocate a nsw be info database\n");
645 return (NSCD_NO_MEMORY
);
648 /* set up to reference count the backend info db */
649 db_p
= (nscd_db_t
**)_nscd_alloc(NSCD_DATA_BACKEND_INFO_DB
,
650 sizeof (nscd_db_t
**), free_nsw_backend_info_db
,
654 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
655 (me
, "unable to allocate the pointer to the nsw "
656 "be info database\n");
657 return (NSCD_NO_MEMORY
);
661 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
662 (me
, "backend database (db_p = %p, db = %p)\n", db_p
, *db_p
);
664 nscd_src_backend_db
[srci
] = (nscd_db_t
**)_nscd_set(
665 (nscd_acc_data_t
*)nscd_src_backend_db
[srci
],
666 (nscd_acc_data_t
*)db_p
);
668 return (NSCD_SUCCESS
);
672 _nscd_init_all_nsw_be_info_db(void)
677 char *me
= "_nscd_init_all_nsw_be_info_db";
679 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
680 (me
, "initializing all nsw be info databases\n");
682 for (i
= 0; i
< NSCD_NUM_SRC
; i
++) {
683 if ((rc
= init_nsw_be_info_db(i
)) != NSCD_SUCCESS
)
687 return (NSCD_SUCCESS
);
692 _nscd_alloc_nsw_config()
694 nscd_nsw_config
= calloc(NSCD_NUM_DB
, sizeof (nscd_nsw_config_t
**));
695 if (nscd_nsw_config
== NULL
)
696 return (NSCD_NO_MEMORY
);
698 return (NSCD_SUCCESS
);
702 _nscd_alloc_nsw_be_info_db()
706 _nscd_cfg_num_nsw_src_all
= _nscd_cfg_num_nsw_src
+
707 NSCD_NUM_SRC_FOREIGN
;
708 nscd_src_backend_db
= calloc(NSCD_NUM_SRC
, sizeof (nscd_db_t
**));
709 if (nscd_src_backend_db
== NULL
)
710 return (NSCD_NO_MEMORY
);
711 nscd_src_backend_db_loaded
= calloc(NSCD_NUM_SRC
, sizeof (int));
712 if (nscd_src_backend_db_loaded
== NULL
) {
713 free(nscd_src_backend_db
);
714 return (NSCD_NO_MEMORY
);
717 /* also allocate/init the nsswitch source index/name array */
718 _nscd_cfg_nsw_src_all
= (nscd_cfg_id_t
*)calloc(
719 _nscd_cfg_num_nsw_src_all
+ 1, sizeof (nscd_cfg_id_t
));
720 for (i
= 0; i
< _nscd_cfg_num_nsw_src_all
+ 1; i
++)
721 (_nscd_cfg_nsw_src_all
+ i
)->index
= -1;
723 (void) memcpy(_nscd_cfg_nsw_src_all
, _nscd_cfg_nsw_src
,
724 _nscd_cfg_num_nsw_src
* sizeof (nscd_cfg_id_t
));
725 return (NSCD_SUCCESS
);
729 _nscd_populate_nsw_backend_info()
734 for (i
= 0; i
< NSCD_NUM_SRC
; i
++) {
735 if (NSCD_NSW_SRC_NAME(i
) == NULL
)
737 rc
= _nscd_populate_nsw_backend_info_db(i
);
738 if (rc
!= NSCD_SUCCESS
)
742 return (NSCD_SUCCESS
);
746 * The following defines nscd's own lookup and delete functions
747 * that are to be stored in nss_backend_finder_t which is used
748 * by _nscd_populate_nsw_backend_info_db() to initialize the
749 * various nss backend instances
752 static const int dlopen_version
= 1;
753 #ifndef NSS_DLOPEN_FORMAT
754 #define NSS_DLOPEN_FORMAT "nss_%s.so.%d"
756 #ifndef NSS_DLSYM_FORMAT
757 #define NSS_DLSYM_FORMAT "_nss_%s_%s_constr"
758 #define NSS_DLSYM_FORMAT_V "_nss_%s_version"
760 static const char dlopen_format
[] = NSS_DLOPEN_FORMAT
;
761 static const char dlsym_format
[] = NSS_DLSYM_FORMAT
;
762 static const char dlsym_format_v
[] = NSS_DLSYM_FORMAT_V
;
763 static const size_t format_maxlen
= sizeof (dlsym_format
);
766 static nss_backend_constr_t
767 _nscd_per_src_lookup(void *handle
, const char *db_name
, const char *src_name
,
774 nss_backend_constr_t res
= NULL
;
776 len
= format_maxlen
+ strlen(src_name
);
778 len
+= strlen(db_name
);
781 if ((dlhandle
= handle
) == NULL
) {
782 (void) sprintf(name
, dlopen_format
, src_name
, dlopen_version
);
783 dlhandle
= dlopen(name
, RTLD_LAZY
);
786 if (dlhandle
!= NULL
) {
788 (void) sprintf(name
, dlsym_format
, src_name
, db_name
);
790 (void) sprintf(name
, dlsym_format_v
, src_name
);
791 if ((sym
= dlsym(dlhandle
, name
)) == 0) {
793 (void) dlclose(dlhandle
);
795 *delete_privp
= dlhandle
;
796 res
= (nss_backend_constr_t
)sym
;
804 _nscd_per_src_delete(void *delete_priv
, nss_backend_constr_t dummy
)
806 (void) dlclose(delete_priv
);