nscd_config.c revision cb5caa98562cf06753163f558cbcfe30b8f4673a
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h> /* gettext */
#include <dlfcn.h>
#include <string.h>
#include <errno.h>
#include "nscd_db.h"
#include "nscd_config.h"
#include "nscd_cfgdef.h"
#include "nscd_log.h"
typedef struct {
static rwlock_t *nscd_cfg_global_rwlock;
static rwlock_t *nscd_cfg_nsw_db_data_rwlock;
static rwlock_t *nscd_cfg_nsw_alldb_rwlock;
extern int _nscd_cfg_num_nsw_src_all;
extern nscd_cfg_id_t *_nscd_cfg_nsw_src_all;
char *msg)
{
return (NULL);
sizeof (nscd_cfg_error_t);
}
return (ret);
}
static nscd_rc_t
{
char *me = "_nscd_cfg_get_list";
nscd_cfg_id_t *l;
void *p;
return (NSCD_INVALID_ARGUMENT);
}
switch (type) {
case NSCD_CFG_LIST_NSW_DB:
l = &_nscd_cfg_nsw_db[0];
break;
case NSCD_CFG_LIST_NSW_SRC:
break;
case NSCD_CFG_LIST_PARAM:
pl = &_nscd_cfg_param_desc[0];
break;
case NSCD_CFG_LIST_STAT:
sl = &_nscd_cfg_stat_desc[0];
break;
default:
return (NSCD_INVALID_ARGUMENT);
break;
}
return (NSCD_NO_MEMORY);
p = (char *)ret + sizeof (nscd_cfg_list_t);
if (type == NSCD_CFG_LIST_PARAM) {
for (i = 0; i <= num; i++)
} else if (type == NSCD_CFG_LIST_STAT) {
for (i = 0; i <= num; i++)
} else {
for (i = 0; i <= num; i++)
}
return (NSCD_SUCCESS);
}
{
}
/* find function pointer in the executable via dlopen(0) */
static nscd_rc_t
char *name,
void **func_p,
{
char *me = "_nscd_cfg_init_funcs";
char msg[NSCD_CFG_MAX_ERR_MSG_LEN];
void *sym;
return (rc);
}
return (rc);
gettext("unable to dlopen the nscd executable: %s"),
dlerror());
goto error_exit;
}
}
if (func_p) {
gettext("unable to get the address of a symbol in the nscd executable: %s"),
dlerror());
goto error_exit;
} else
}
return (rc);
return (rc);
}
/*
* FUNCTION: _nscd_cfg_create_paramDB
*
* Create the internal config parameter database
*/
static nscd_db_t *
{
(void) rw_wrlock(&cfg_paramDB_rwlock);
cfg_paramDB = ret;
(void) rw_unlock(&cfg_paramDB_rwlock);
return (ret);
}
/*
* FUNCTION: _nscd_cfg_add_index_entry
*
* Add a config index entry (a name to index mapping)
* to the internal configuration database.
*/
static nscd_rc_t
char *name,
int index,
{
int *idx;
int size;
int dbe_type;
return (NSCD_INVALID_ARGUMENT);
if (type == NSCD_CFG_LIST_NSW_DB)
else if (type == NSCD_CFG_LIST_NSW_SRC)
else if (type == NSCD_CFG_LIST_PARAM)
else if (type == NSCD_CFG_LIST_STAT)
size = sizeof (int);
return (NSCD_NO_MEMORY);
(void) rw_wrlock(&cfg_paramDB_rwlock);
(void) rw_unlock(&cfg_paramDB_rwlock);
return (NSCD_SUCCESS);
}
/*
* FUNCTION: _nscd_cfg_get_index
*
* Get the index of a config data item by searching the internal config
* database. Do not free the returned data.
*/
static int
char *name,
{
const nscd_db_entry_t *db_entry;
return (-1);
if (type == NSCD_CFG_LIST_NSW_DB)
else if (type == NSCD_CFG_LIST_NSW_SRC)
else if (type == NSCD_CFG_LIST_PARAM)
else if (type == NSCD_CFG_LIST_STAT)
else
return (-1);
(const char *)name, NSCD_GET_FIRST_DB_ENTRY, 0);
return (index);
}
static nscd_rc_t
{
char *me = "_nscd_cfg_verify_group_info";
void *vp;
vp = (char *)&nscd_cfg_global_default +
} else {
vp = (char *)&nscd_cfg_nsw_db_data_default +
}
return (NSCD_SUCCESS);
(me, "ERROR: group (%s) info mismatched: group info "
"(%d, %#6.4x) not equal to that of default configuration data "
return (NSCD_CFG_PARAM_DESC_ERROR);
}
static nscd_rc_t
{
char *me = "_nscd_cfg_init_nsw";
for (j = 0; j < 2; j++) {
if (j == 0)
else
for (i = 0; i < num; i++) {
/*
* _nscd_cfg_nsw_alldb is the id for the
* special ALLDB (defaults for all db)
*/
if (j == 0 && i == _nscd_cfg_num_nsw_db) {
} else {
}
continue;
(me, "unable to add index entry for "
return (rc);
}
}
}
return (NSCD_SUCCESS);
}
/*
* get the address of a function in the nscd executable
* and store it in where 'dest_p' points to
*/
static nscd_rc_t
char *name,
void *dest_p,
void **gfunc_a,
{
void *func;
return (NSCD_SUCCESS);
}
if (rc != NSCD_SUCCESS)
return (rc);
return (NSCD_SUCCESS);
}
static nscd_rc_t
{
char *me = "_nscd_cfg_init_param";
if (_nscd_cfg_create_paramDB() == NULL)
return (NSCD_NO_MEMORY);
desc = &_nscd_cfg_param_desc[0];
/*
* need to loop to the last (+1) param description
* which is a fake group and which marks the end
* of list. It is used to signal the end of the
* previous group so that the proper data will be
* set for that group
*/
if ((rc = _nscd_cfg_verify_group_info(
return (rc);
}
gi = i;
fn = 0;
/*
*/
return (rc);
}
return (rc);
}
} else {
if (i == 0) {
(me, "ERROR: first parameter "
"description is not for a group\n");
return (NSCD_CFG_PARAM_DESC_ERROR);
}
/*
* set bitmap: the rightmost bit represents
* the first member (index = 0) in the group,
* the next bit is for the second member
* (index = 1), and so on
*/
/*
*/
return (rc);
}
return (rc);
}
}
/* if end of list reached, we are done */
if (i == _nscd_cfg_num_param)
break;
i, type)) != NSCD_SUCCESS) {
(me, "unable to add index entry for parameter "
return (rc);
} else {
(me, "index entry for parameter "
}
}
return (_nscd_cfg_init_nsw());
}
static nscd_rc_t
{
char *me = "_nscd_cfg_init_stat";
void *gsfunc;
desc = &_nscd_cfg_stat_desc[0];
/*
* need to loop to the last (+1) stat description
* which is a fake group and which marks the end
* of list. It is used to signal the end of the
* previous group so that the proper data will be
* set for that group
*/
(me, "ERROR: group (%s) "
"info mismatched: "
"group info (%d, %#6.4x) not "
"equal to the predefined one "
exit(1);
return (NSCD_CFG_STAT_DESC_ERROR);
}
}
gi = i;
fn = 0;
/*
* set the get_stat function
*/
return (rc);
}
} else {
if (i == 0) {
(me, "ERROR: first stat "
"description is not for a group\n");
return (NSCD_CFG_STAT_DESC_ERROR);
}
/*
* set bitmap: the rightmost bit represents
* the first member (index = 0) in the group,
* the next bit is for the second member
* (index = 1), and so on
*/
/*
* set the get_stat function
*/
return (rc);
}
}
/* if end of list reached, we are done */
if (i == _nscd_cfg_num_stat)
break;
i, type)) != NSCD_SUCCESS) {
(me, "unable to add index entry for stat "
return (rc);
} else {
(me, "index entry for stat description "
}
}
return (NSCD_SUCCESS);
}
static nscd_rc_t
void *data,
void **new_data_p,
int *data_len,
{
nscd_cfg_vlen_data_t *v = NULL;
*new_data_p = NULL;
*data_len = 0;
/* it is OK if there is nothing to copy */
return (NSCD_SUCCESS);
/*
* if copy to the config store we need to allocate space
* for the extra vlen header
*/
len += sizeof (nscd_cfg_vlen_data_t);
} else {
/*
* should not be here, since for now
* only string variable length data
* is supported
*/
*new_data_p = NULL;
return (NSCD_CFG_PARAM_DESC_ERROR);
}
if (v == NULL) {
*new_data_p = NULL;
return (NSCD_NO_MEMORY);
}
/*
* if copy to the config store, set up
* the extra vlen header in which the
* pointer to, and length of, the real
* data are kept. The pointer to the real
* data, not the vlen header, is returned.
*/
v->ptr = (char *)v + sizeof (nscd_cfg_vlen_data_t);
*new_data_p = v->ptr;
} else {
*new_data_p = v;
}
return (NSCD_SUCCESS);
}
static void
void *data)
{
nscd_cfg_vlen_data_t *v = NULL;
void *p;
return;
p = (char *)data - sizeof (nscd_cfg_vlen_data_t);
v = (nscd_cfg_vlen_data_t *)p;
free(v);
}
static nscd_rc_t
void *src,
void *dest,
{
void *s, *d, *new;
void *cptr;
desc = &_nscd_cfg_param_desc[0];
for (i = 0; i < _nscd_cfg_num_param; i++, desc++) {
continue;
continue;
cptr = *(char **)s;
if (rc != NSCD_SUCCESS)
return (rc);
/* free the old vlen data */
if (*(char **)d == NULL)
_nscd_cfg_free_vlen_data_int(*(char **)d);
*(char **)d = new;
}
}
return (NSCD_SUCCESS);
}
static void *
void *cfg_data,
int *len)
{
*len = 0;
return (NULL);
}
return (ret);
}
static void
{
return;
else
return;
}
}
static void
{
return;
return;
}
}
/*
* If vlen_data_addr is given, it will be set to the
* address of the pointer pointing to the vlen data.
* lock(s) protecting the (group) configuration data.
*/
static nscd_rc_t
void **cfg_data,
void **vlen_data_addr,
int *len,
{
int offset;
*len = 0;
if (vlen_data_addr != NULL)
*vlen_data_addr = NULL;
return (NSCD_NO_MEMORY);
}
/* assume if nswdb is NULL, the param is a global one */
*cfg_data = (char *)nscd_cfg_nsw_alldb_current +
} else {
*cfg_data = (char *)nscd_cfg_nsw_db_data_current +
}
}
/* lock the config data */
if (vlen_data_addr != NULL)
*vlen_data_addr = *cfg_data;
return (NSCD_SUCCESS);
}
else
}
return (NSCD_SUCCESS);
}
/*
* perform the preliminary (range) check on 'data' based on the
* datatype (desc->datatype) of the config parameter
*/
void *data,
{
char *me = "_nscd_cfg_prelim_check";
char msg[NSCD_CFG_MAX_ERR_MSG_LEN];
return (NSCD_SUCCESS);
case NSCD_CFG_DATA_STRING:
break;
gettext("data must be specified for %s"),
break;
}
rc = NSCD_SUCCESS;
break;
}
break;
gettext("length of data (%s) for %s larger than %d"),
break;
}
rc = NSCD_SUCCESS;
break;
case NSCD_CFG_DATA_INTEGER:
break;
gettext("data (%d) for %s out of range (%d - %d)"),
break;
}
rc = NSCD_SUCCESS;
break;
case NSCD_CFG_DATA_BITMAP:
~(bmc->valid_bits)) {
break;
gettext("data (%#6.4x) for %s contain bit not in 0x%x"),
*(nscd_cfg_bitmap_t *)data),
break;
}
rc = NSCD_SUCCESS;
break;
}
}
return (rc);
}
static nscd_rc_t
int *skip,
{
char *me = "_nscd_cfg_notify_i";
*skip = 0;
(me, "ERROR: expect parameter description for group, "
"but receive parameter description is for %s\n",
return (NSCD_CFG_PARAM_DESC_ERROR);
}
/*
* Set data flag going with data to be sent to the
* be exipandable, set the bits one by one.
*/
/* get to the group data in the config store */
if (rc != NSCD_SUCCESS)
goto error;
/*
* the static bitmap associated with the group
* may be replaced before sending to the components,
* so save the bitmap for later use
*/
/*
* the elements in this group will all be handled
* so the caller can skip them
*/
/* send the entire group just once */
num = 1;
else { /* send individual members one by one */
/*
* skip the first desc which is for the group
* and get to the desc for the first member
*/
desc++;
}
/* set the bitmap to select just this member */
/* replace the bitmap in the cfg data */
/*
* send the whole group but with only one
* member selected
*/
} else {
/*
* send param data or group data:
* param data - non-xero desc->p_offset
* group data - zero desc->p_offset
*/
/*
* if variable length data, need to send pointer
* to the data (not the address of the pointer)
*/
}
if (rc != NSCD_SUCCESS)
goto error;
}
if (rc != NSCD_SUCCESS)
goto error;
}
}
rc = NSCD_SUCCESS;
/* restore the bitmap in the cfg data */
return (rc);
}
static nscd_rc_t
{
int i, j, skip;
for (i = 0; i < _nscd_cfg_num_param; i++) {
desc = &_nscd_cfg_param_desc[i];
NSCD_CFG_PFLAG_GLOBAL)) { /* global cfg data */
} else {
/*
* if use defaults for all nsswitch database,
*/
} else { /* send data once for each nsw db */
for (j = 0; j < _nscd_cfg_num_nsw_db;
j++) {
nswdb = &_nscd_cfg_nsw_db[j];
}
}
}
if (rc != NSCD_SUCCESS)
return (rc);
i += skip;
}
return (NSCD_SUCCESS);
}
{
int i, j, datalen;
rc = _nscd_cfg_init_param();
if (rc != NSCD_SUCCESS)
return (rc);
rc = _nscd_cfg_init_stat();
if (rc != NSCD_SUCCESS)
return (rc);
sizeof (nscd_cfg_global_data_t));
if (nscd_cfg_global_current == NULL)
return (NSCD_NO_MEMORY);
sizeof (nscd_cfg_nsw_db_data_t));
if (nscd_cfg_nsw_alldb_current == NULL)
return (NSCD_NO_MEMORY);
sizeof (nscd_cfg_nsw_db_data_t));
if (nscd_cfg_nsw_db_data_current == NULL)
return (NSCD_NO_MEMORY);
if (nscd_cfg_global_rwlock == NULL)
return (NSCD_NO_MEMORY);
if (rc != NSCD_SUCCESS)
return (rc);
sizeof (rwlock_t));
if (nscd_cfg_nsw_db_data_rwlock == NULL)
return (NSCD_NO_MEMORY);
/* set per switch db config to the default for all db's */
for (i = 0; i < _nscd_cfg_num_nsw_db; i++) {
(void) rwlock_init(&nscd_cfg_nsw_db_data_rwlock[i],
}
/* add db specific defaults */
for (i = 0; i < _nscd_cfg_num_nsw_default; i++) {
continue;
for (j = 0; j < _nscd_cfg_num_nsw_db; j++) {
_nscd_cfg_nsw_spc_default[i].db) != 0)
continue;
break;
}
}
}
/* add db specific defaults via links */
for (i = 0; i < _nscd_cfg_num_link_default; i++) {
continue;
for (j = 0; j < _nscd_cfg_num_nsw_db; j++) {
_nscd_cfg_nsw_link_default[i].db) != 0)
continue;
break;
}
}
for (j = 0; j < _nscd_cfg_num_nsw_db; j++) {
_nscd_cfg_nsw_db[j].name) != 0)
continue;
break;
}
}
}
/* fix up variable length fields */
for (i = 0; i < _nscd_cfg_num_nsw_db; i++) {
if (rc != NSCD_SUCCESS)
return (rc);
}
if (nscd_cfg_nsw_alldb_rwlock == NULL)
return (NSCD_NO_MEMORY);
if (rc != NSCD_SUCCESS)
return (rc);
/*
* notify and send the configuration data to
* the nscd components
*/
if (rc != NSCD_SUCCESS)
return (rc);
return (NSCD_SUCCESS);
}
static nscd_rc_t
char *name,
char *nswdb_name,
{
int i, is_global;
char *desc_str;
char *me = "_nscd_cfg_get_handle_common";
char msg[NSCD_CFG_MAX_ERR_MSG_LEN];
gettext("address of handle not specified"));
if (errorp)
return (rc);
}
gettext("name not specified"));
if (errorp)
(me, "invalid argument: %s\n");
return (rc);
}
if (h == NULL)
return (NSCD_NO_MEMORY);
if (type == NSCD_CFG_LIST_PARAM)
else
/* get param or stat descriptor */
if (i != -1) {
if (type == NSCD_CFG_LIST_PARAM) {
pdesc = &_nscd_cfg_param_desc[i];
/* hidden params are not exposed */
i = -1;
(me,
gettext("%s: %s is obsolete and will be ignored\n"),
}
} else {
sdesc = &_nscd_cfg_stat_desc[i];
}
}
if (i == -1) {
if (errorp)
free(h);
return (rc);
}
/*
* know which nsswitch database we are dealing with
*/
if (is_global == 0) {
if (nswdb_name == NULL) {
gettext("%s: switch database name not specified"),
desc_str);
if (errorp)
(me, "%s for non-global param or stat %s\n",
free(h);
return (rc);
}
} else {
if (nswdb_name != NULL) {
gettext("%s: switch database specified for global data"),
desc_str);
if (errorp)
free(h);
return (rc);
}
*handle = h;
return (NSCD_SUCCESS);
}
/* get nsw DB id */
if (i != -1) {
if (i == NSCD_CFG_NSW_ALLDB_INDEX)
h->nswdb = &_nscd_cfg_nsw_alldb;
else
h->nswdb = &_nscd_cfg_nsw_db[i];
(me, "%s: index of %s is %d\n",
desc_str, nswdb_name, i);
} else {
gettext("%s: unknown switch database name \"%s\""),
if (errorp)
free(h);
return (NSCD_CFG_UNSUPPORTED_SWITCH_DB);
}
*handle = h;
return (NSCD_SUCCESS);
}
char *param_name,
char *nswdb_name,
{
}
char *stat_name,
char *nswdb_name,
{
}
void
{
}
static void
void *group_data,
{
int num;
while (num-- > 0) {
desc++;
/* skip fixed length data */
continue;
continue;
else
}
}
void
void *data)
{
return;
}
void
void *data)
{
return;
return;
}
void
{
return;
}
static nscd_rc_t
void *dest,
void *pdata,
{
char *me = "_nscd_cfg_copy_param_data";
void *tmp;
int dlen;
return (NSCD_INVALID_ARGUMENT);
}
/* fixed length data */
goto done;
}
/* variable length data from this point on */
/* make a copy of the variable length data */
if (rc != NSCD_SUCCESS)
goto done;
/* free the variable length data in the config store */
_nscd_cfg_free_vlen_data_int(*(char **)dest);
}
/*
* set the addr of the vlen data
*/
} else {
/*
* copy the data content (not address)
*/
}
done:
return (rc);
}
static nscd_rc_t
void *group_dest,
void *group_src)
{
int i, num;
i = 0;
while (num-- > 0) {
desc++;
/* if member not selected by bitmap, skip */
continue;
/*
* if variable length data, free and replace the old
* with the new
*/
_nscd_cfg_free_vlen_data_int(*(char **)dest);
} else {
/*
* fixed length data, just copy it
*/
}
}
return (NSCD_SUCCESS);
}
static nscd_rc_t
void *group_dest,
void *group_src)
{
char *me = "_nscd_cfg_copy_group_data_out";
int dlen;
int num;
if (group_dest == NULL) {
(me, "input group_dest = NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
while (num-- > 0) {
desc++;
/*
* if variable length data, get the real
* address and length of the data
*/
continue;
}
/*
* The nscd_true asks _nscd_cfg_copy_param_data
* to set addr of the vlen data in 'dest' rather
* than copying the data content
*/
if (rc != NSCD_SUCCESS) {
(me, "unable to copy param data for %s\n",
return (rc);
}
}
/*
* set group bitmap
*/
sizeof (nscd_cfg_group_info_t));
return (rc);
}
/*
* group_cfg is needed always; group_src may be NULL if
* param_index not zero and pdata not NULL; group_cfg and
* pdata should not be both non-NULL
*/
static nscd_rc_t
void **group_dest,
void *group_src,
void *group_cfg,
int param_index,
void *pdata)
{
char *me = "_nscd_cfg_copy_group_data_merge";
int num, i = 0;
if (group_dest == NULL) {
(me, "input **group_dest == NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
(me, "input **group_cfg == NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
return (NSCD_INVALID_ARGUMENT);
}
return (NSCD_NO_MEMORY);
else {
}
while (num-- > 0) {
desc++;
/*
* if member not selected by bitmap in group_src,
* get the member data in group_cfg
*/
} else
/* use the param data in pdata if provided */
}
/*
* if variable length data, get to the data
* instead of pointer to the data
*/
/*
* nscd_true asks _nscd_cfg_copy_param_data to
* set addr of the vlen data in 'dest' rather
* than copying the data content
*/
if (rc != NSCD_SUCCESS) {
(me, "unable to copy param data for %s\n",
return (rc);
}
}
*group_dest = tmp_dest;
/*
* set bitmap: if input is group data, use the one
* given; if input is param data, use the one computed
* above
*/
sizeof (nscd_cfg_group_info_t));
else {
}
return (rc);
}
/* ARGSUSED */
void **data,
int *data_len,
{
char *me = "_nscd_cfg_get";
int dlen;
*data_len = 0;
return (NSCD_INVALID_ARGUMENT);
}
(me, "handle is NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
/*
* locate the current value of the param or group
* and lock the config data for reading
*/
if (rc != NSCD_SUCCESS) {
(me, "unable to locate config data\n");
return (rc);
goto done;
rc = NSCD_NO_MEMORY;
goto error_exit;
}
if (rc != NSCD_SUCCESS) {
(me, "unable to copy group data %p: "
goto error_exit;
}
} else {
/*
* nscd_false asks _nscd_cfg_copy_param_data to
* copy the data content rather than just setting
* the addr of the vlen data in 'ptr'
*/
out, nscd_false);
if (rc != NSCD_SUCCESS) {
(me, "unable to copy param data %p: "
goto error_exit;
}
}
done:
return (NSCD_SUCCESS);
return (rc);
}
/*
* three type of data:
* 1 - single param
* desc is that of the param
* 2 - single param to be sent in a group
* a single bit is set in the bitmap,
* desc is that of the group
* 3 - group data
* one of more bits are set in the bitmap,
* desc is that of the group
*/
static nscd_rc_t
void *data,
{
void *cdata;
/*
* Set data flag going with data to be sent to the
* be exipandable, set the bits one by one.
*/
is_group = 1;
}
/*
* the bitmap in the input data may be replaced before
* sending to the components, so save the bitmap for
* later use
*/
if (is_group == 1) {
/* send the entire group just once */
num = 1;
else { /* send individual members one by one */
/*
* skip the first desc which is for the group
* and get to the desc for the first member
*/
desc++;
}
} else {
/* not group data, send the member once */
num = 1;
}
if (is_group == 0) {
goto verify_data;
}
/* set the bitmap to select just this member */
/* replace the bitmap in the input data */
/*
* send the whole group but with only one
* member selected
*/
} else {
/*
* send param data or group data:
* param data - non-xero desc->p_offset
* group data - zero desc->p_offset
*/
/*
* if variable length data, need to send pointer
* to the data (not the address of the pointer)
*/
}
if (rc != NSCD_SUCCESS)
goto error_exit;
}
if (rc != NSCD_SUCCESS)
goto error_exit;
}
}
rc = NSCD_SUCCESS;
/* restore the bitmap in the input data */
if (bitmap_addr != NULL)
return (rc);
}
/*
* Convert string 'str' to data based on the data type in 'desc'.
* 'data' points to the buffer in which the converted data
* is placed. '*data_p' points to the buffer, or in the case
* of a string data type, points to the untoched string (i.e.,
* 'str').
*/
char *str,
void *data,
void **data_p,
{
char *me = "_nscd_cfg_str_to_data";
char *c;
char msg[NSCD_CFG_MAX_ERR_MSG_LEN];
(me, "ERROR: one of the following is NULL "
"desc = %p, str = %p, data = %p, data_p = %p\n",
return (NSCD_INVALID_ARGUMENT);
}
/* if description is that of a group, return error */
msg);
return (NSCD_INVALID_ARGUMENT);
}
else {
/* remove the " char if quoted string */
if (str[0] == '"') {
if (*c == '"')
*c = '\0';
} else
}
return (NSCD_SUCCESS);
}
msg);
return (NSCD_INVALID_ARGUMENT);
}
case NSCD_CFG_DATA_BOOLEAN:
else {
gettext("data (%s) must be 'yes' or 'no' for %s"),
msg);
return (NSCD_INVALID_ARGUMENT);
}
break;
case NSCD_CFG_DATA_INTEGER:
errno = 0;
gettext("unable to convert data (%s) for %s"),
return (rc);
}
break;
case NSCD_CFG_DATA_BITMAP:
errno = 0;
gettext("unable to convert data (%s) for %s"),
return (rc);
}
break;
}
return (NSCD_SUCCESS);
}
void *data,
{
char *me = "_nscd_cfg_set";
int dlen;
char *nswdb_name, *param_name;
nscd_bool_t get_group = 0;
(me, "handle is NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
nswdb_name = "global";
else
(me, "data == NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
/*
* locate the current value of the param or group
* and lock the config data for writing
*/
if (rc != NSCD_SUCCESS) {
return (rc);
}
(me, "number of parameters in group <%s : %s> not equal: "
"%d in input data, should be %d\n",
goto error_exit;
}
/*
* if variable length data, we want the address
* of the pointer pointing to the data
*/
if (vdata_addr != NULL)
/*
* just copy in the specified data, if no need
* to verify the data or notify the associated
* component
*/
if (rc != NSCD_SUCCESS) {
(me, "unable to copy group data <%s : %s>\n",
goto error_exit;
}
} else
errorp);
if (rc != NSCD_SUCCESS) {
"parameter <%s : %s> failed. %s\n",
goto error_exit;
}
/*
* Move the new config into the config store
*/
} else {
/*
* nscd_true asks _nscd_cfg_copy_param_data to
* set addr of the vlen data in 'cfg_data' rather
* than copying the data content
*/
}
if (rc != NSCD_SUCCESS) {
(me, "unable to make new param data <%s : %s> current\n",
}
return (rc);
}
void *data,
{
char *me = "_nscd_cfg_set_linked";
int i;
char msg[NSCD_CFG_MAX_ERR_MSG_LEN];
(me, "handle is NULL\n");
return (NSCD_INVALID_ARGUMENT);
}
/*
* no need to do the special linking thing,
* if a global param, or a group, or not a linked param
*/
else
/*
* if a param is linked to another, it can not be
* changed directly
*/
for (i = 0; i < _nscd_cfg_num_link_default; i++) {
continue;
nswdb_name) == 0 &&
gettext("vaule of \'%s\' not changeable, change that of \'%s\' instead"),
return (rc);
}
}
/*
* if a param is linked from another, it should be verify
* and changed first
*/
for (i = 0; i < _nscd_cfg_num_link_default; i++) {
continue;
if (rc != NSCD_SUCCESS)
return (rc);
break;
}
}
/*
* then change all those linked to the one that has been changed
*/
for (i = 0; i < _nscd_cfg_num_link_default; i++) {
continue;
if (rc != NSCD_SUCCESS)
return (rc);
}
}
}
/*
* Return a list of space-separated database names that
* have at least one of the input sources appeared in the
* configured nsswitch policy string of the databases.
* The return string should be freed by the caller.
*
* For compat sources (compat_group and compat_passwd),
* "group" will be returned, if the policy string for
* compat_group contains one of the input sources. Same
* for compat_passwd and passwd.
*/
char *
int num_src,
char **srcs)
{
int dlen = 0;
char *dbname;
return (NULL);
sizeof (uint8_t));
return (NULL);
}
for (i = 0; i < _nscd_cfg_num_nsw_db; i++) {
(void) rw_rdlock(&nscd_cfg_nsw_db_data_rwlock[i]);
continue;
for (j = 0; j < num_src; j++) {
NULL) {
db[n++] = i;
"compat") == 0) {
compat_pwd = 1;
dlen += 7;
compat_grp = 1;
dlen += 6;
} else {
}
}
}
(void) rw_unlock(&nscd_cfg_nsw_db_data_rwlock[i]);
}
return (NULL);
}
for (j = 0; j < n; j++) {
if (compat_grp == 1)
dbname = "group";
else
continue;
if (compat_pwd == 1)
dbname = "passwd";
else
continue;
}
}
for (j = 0; j < nc; j++) {
if (compat_pwd == 1) {
}
}
return (outstr);
}