/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <nss_common.h>
#include <dlfcn.h>
#include <alloca.h>
#include <stdlib.h>
#include <libscf_priv.h>
#include <string.h>
#include <assert.h>
#include "nscd_switch.h"
#include "nscd_log.h"
#include "nscd_db.h"
/*
* _nscd_nss_finders is used to replace the nss_default_finders in libc
* to allow nscd to have more control over the dl handles when using
* dlsym to get the address of the nss backend instance constructors
*/
static nss_backend_constr_t _nscd_per_src_lookup(void *,
const char *, const char *, void **);
static void _nscd_per_src_delete(void *, nss_backend_constr_t);
0,
0 };
/*
* nscd database for each source. It contains backend
* info (nscd_be_info_t) for each naming database.
* Protected by nscd_src_backend_db_lock.
*/
/*
* nsswitch config monitored by nscd. Protected by
*/
/*
*/
static void
{
return;
}
void
{
}
void
{
int i;
(me, "freeing all nscd nsw config \n");
(void) rw_wrlock(&nscd_nsw_config_lock);
for (i = 0; i < NSCD_NUM_DB; i++) {
continue;
}
(void) rw_unlock(&nscd_nsw_config_lock);
}
static void
{
return;
}
void
{
int i;
(me, "freeing all nsw backend info db\n");
(void) rw_wrlock(&nscd_src_backend_db_lock);
for (i = 0; i < NSCD_NUM_SRC; i++) {
continue;
nscd_src_backend_db_loaded[i] = 0;
}
(void) rw_unlock(&nscd_src_backend_db_lock);
}
/*
* Populate the backend info db for the 'NSCD_NSW_SRC_NAME(srci)'
* (e.g., ldap:passwd, nis:hosts, etc).
*/
static nscd_rc_t
{
int i, size;
const char *dbn;
/* get the version number of the backend (if available) */
if (c == NULL)
be_version = NULL;
else
be_version = (void *)c;
}
for (i = 0; i < NSCD_NUM_DB; i++) {
/* no nsswitch configuration, no backend info db population */
continue;
nsw_cfg = *nscd_nsw_config[i];
dbn = NSCD_NSW_DB_NAME(i);
if (c != 0) {
break;
}
}
/*
* Couldn't find the backend anywhere.
* This is fine, some backend just don't
* support certain databases.
*/
(me, "unable to find backend info "
}
size = sizeof (nscd_be_info_t);
(me, "unable to allocate db entry for "
return (NSCD_NO_MEMORY);
}
(me, "adding be db entry %p for <%s : %s> to db %p: "
(void) _nscd_wrlock((nscd_acc_data_t *)
(void) _nscd_rw_unlock((nscd_acc_data_t *)
}
return (NSCD_SUCCESS);
}
/*
* create data structures (used by the switch engine) based
* on the input switch policy configuration and database
* name and indexes
*/
int dbi,
int compat_basei,
const char *dbn,
const char *cfgstr,
void *swcfgv1,
{
int maxsrc;
int j, k;
/*
* if the nsw config string has been parsed into
* a struct __nsw_switchconfig_v1, use it. If not,
* create the struct.
*/
else {
char *cstr;
return (NSCD_NO_MEMORY);
/*
* parse the nsw config string and create
* a struct __nsw_switchconfig_v1
*/
(me, "error: unable to process nsw config string\n");
goto error_exit;
}
}
/* allocate the space for a nscd_nsw_config_t */
rc = NSCD_NO_MEMORY;
(me, "error: unable to allocate an nscd_nsw_config_t\n");
goto error_exit;
}
/* need to know how many backends (sources) */
/*
* allocate an array to store the index for each
* backend (source)
*/
rc = NSCD_NO_MEMORY;
(me, "error: unable to allocate an array for source index\n");
goto error_exit;
}
/*
* set the index for each backend (source)
*/
for (j = 0; j < maxsrc; j++) {
char *usrc;
k++) {
/* empty */
}
if (k < NSCD_NUM_SRC && nscd_src_backend_db_loaded[k] == 0) {
rc = NSCD_NO_MEMORY;
(me, "unable to strdup() source name\n");
goto error_exit;
}
NSCD_NSW_SRC_NAME(k) = usrc;
if (rc != NSCD_SUCCESS) {
NSCD_NSW_SRC_NAME(k) = NULL;
goto error_exit;
}
} else if (NSCD_NSW_SRC_NAME(k) == NULL) {
/*
* number of user-defined source exceeded
*/
(me, "error: number of user_defined source exceeded\n");
goto error_exit;
}
(me, "setting source index array [%d] = %d (%s)\n",
j, k, lkp->service_name);
src_idx_a[j] = k;
}
/* set it up to reference count the switch policy config */
sizeof (nscd_nsw_config_t **), free_nscd_nsw_config,
rc = NSCD_NO_MEMORY;
(me, "unable to allocate a new nsw config DB\n");
goto error_exit;
}
/* save all the data in the new nscd_nsw_config_t */
rc = NSCD_NO_MEMORY;
goto error_exit;
}
(me, "switch policy \"%s\" for database is \"%s\"\n",
/*
* set default frontend params and if necessary call initf()
* to initialize or override
*/
/*
* this nsw_cfg is not meant to last long, no need
* to set up the nsw state and getent bases, just
* exit with NSCD_SUCCESS
*/
goto error_exit;
}
} else
/*
* also create a new nsw state base
*/
NSCD_SUCCESS) {
goto error_exit;
}
/*
* also create a new getent context base
*/
goto error_exit;
}
(me, "new nsw config created (database = %s, "
/*
* Activate the new nscd_nsw_config_t and make it the
* current nsswitch config. The old one pointed to by
* nscd_nsw_config[dbi] will either be destroyed
* immediately or left on the side line (and be
* destroyed eventually). __nscd_set() will set the
* associated flags to make it happen.
*/
(nscd_acc_data_t *)nsw_cfg_p);
if (rc != NSCD_SUCCESS) {
(void) __nsw_freeconfig_v1(swcfg);
if (nsw_cfg_p)
}
return (rc);
} else
return (NSCD_SUCCESS);
}
static nscd_rc_t
{
/*
* Allocate a pointer space for saving a pointer to a
* nscd_nsw_config_t. _nscd_alloc() will also create
* a nscd_access_t header with a rwlock_t and mutex_t
* for controlling later access to the data pointed
* to by the pointer.
*/
sizeof (nscd_nsw_config_t **), free_nscd_nsw_config,
(me, "unable to allocate a space for a nsw config pointer\n");
return (NSCD_NO_MEMORY);
}
/*
* If pseudo-databases (initf function not defined),
* no need to create a nscd_nsw_config_t yet,
* so put a NULL pointer in the pointer space.
*/
(nscd_acc_data_t *)nsw_cfg_p);
(me, "pointer to nsw config has been set to NULL\n");
return (NSCD_SUCCESS);
}
/* allocate the space for a nscd_nsw_config_t */
(me, "unable to allocate a nsw config structure\n");
return (NSCD_NO_MEMORY);
}
(me, "unable to strdup the db name\n");
return (NSCD_NO_MEMORY);
}
/*
* set default frontend params and then call initf()
* to initialize or override
*/
/*
* activate the new nscd_nsw_config_t
*/
(nscd_acc_data_t *)nsw_cfg_p);
return (NSCD_SUCCESS);
}
{
int i;
(me, "initializing all nsw config\n");
for (i = 0; i < NSCD_NUM_DB; i++) {
return (rc);
}
return (NSCD_SUCCESS);
}
static nscd_rc_t
{
(me, "unable to allocate a nsw be info database\n");
return (NSCD_NO_MEMORY);
}
/* set up to reference count the backend info db */
sizeof (nscd_db_t **), free_nsw_backend_info_db,
(me, "unable to allocate the pointer to the nsw "
"be info database\n");
return (NSCD_NO_MEMORY);
}
(nscd_acc_data_t *)db_p);
return (NSCD_SUCCESS);
}
{
int i;
(me, "initializing all nsw be info databases\n");
for (i = 0; i < NSCD_NUM_SRC; i++) {
return (rc);
}
return (NSCD_SUCCESS);
}
{
if (nscd_nsw_config == NULL)
return (NSCD_NO_MEMORY);
return (NSCD_SUCCESS);
}
{
int i;
if (nscd_src_backend_db == NULL)
return (NSCD_NO_MEMORY);
if (nscd_src_backend_db_loaded == NULL) {
return (NSCD_NO_MEMORY);
}
for (i = 0; i < _nscd_cfg_num_nsw_src_all + 1; i++)
_nscd_cfg_num_nsw_src * sizeof (nscd_cfg_id_t));
return (NSCD_SUCCESS);
}
{
int i;
for (i = 0; i < NSCD_NUM_SRC; i++) {
if (NSCD_NSW_SRC_NAME(i) == NULL)
continue;
if (rc != NSCD_SUCCESS)
return (rc);
}
return (NSCD_SUCCESS);
}
/*
* The following defines nscd's own lookup and delete functions
* that are to be stored in nss_backend_finder_t which is used
* by _nscd_populate_nsw_backend_info_db() to initialize the
* various nss backend instances
*/
#ifndef NSS_DLOPEN_FORMAT
#endif
#ifndef NSS_DLSYM_FORMAT
#endif
/*ARGSUSED*/
static nss_backend_constr_t
void **delete_privp)
{
char *name;
void *dlhandle;
void *sym;
}
else
} else {
*delete_privp = dlhandle;
}
}
return (res);
}
/*ARGSUSED*/
static void
{
(void) dlclose(delete_priv);
}