summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/nscd/cache.c4
-rw-r--r--usr/src/cmd/nscd/nscd_cfgdef.h6
-rw-r--r--usr/src/cmd/nscd/nscd_common.h2
-rw-r--r--usr/src/cmd/nscd/nscd_config.c22
-rw-r--r--usr/src/cmd/nscd/nscd_db.h6
-rw-r--r--usr/src/cmd/nscd/nscd_frontend.c48
-rw-r--r--usr/src/cmd/nscd/nscd_frontend.h3
-rw-r--r--usr/src/cmd/nscd/nscd_getentctx.c44
-rw-r--r--usr/src/cmd/nscd/nscd_init.c43
-rw-r--r--usr/src/cmd/nscd/nscd_selfcred.c6
-rw-r--r--usr/src/cmd/nscd/nscd_seqnum.c20
-rw-r--r--usr/src/cmd/nscd/nscd_switch.c243
-rw-r--r--usr/src/cmd/nscd/nscd_switch.h23
-rw-r--r--usr/src/lib/libc/port/gen/getgrnam_r.c4
-rw-r--r--usr/src/lib/libc/port/gen/nss_common.c45
-rw-r--r--usr/src/lib/libc/port/gen/nss_dbdefs.c88
-rw-r--r--usr/src/lib/nsswitch/compat/common/compat_common.c12
-rw-r--r--usr/src/lib/nsswitch/files/common/gethostent.c2
18 files changed, 339 insertions, 282 deletions
diff --git a/usr/src/cmd/nscd/cache.c b/usr/src/cmd/nscd/cache.c
index f39484aa96..7430fb8a39 100644
--- a/usr/src/cmd/nscd/cache.c
+++ b/usr/src/cmd/nscd/cache.c
@@ -1214,7 +1214,7 @@ copy_result(void *rbuf, void *cbuf)
*(dst + rphdr->data_len) = '\0';
_NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
- (me, "cache data (len = %lld): %s\n",
+ (me, "cache data (len = %lld): >>%s<<\n",
cphdr->data_len, (char *)cphdr + cphdr->data_off);
return (NSS_SUCCESS);
@@ -1753,7 +1753,7 @@ nsc_lookup(nsc_lookup_args_t *largs, int flag) {
break;
case NOSERVER:
- NSCD_RETURN_STATUS(phdr, NSS_UNAVAIL, -1);
+ NSCD_RETURN_STATUS(phdr, NSS_TRYLOCAL, -1);
break;
}
}
diff --git a/usr/src/cmd/nscd/nscd_cfgdef.h b/usr/src/cmd/nscd/nscd_cfgdef.h
index bf666f86b9..228314161b 100644
--- a/usr/src/cmd/nscd/nscd_cfgdef.h
+++ b/usr/src/cmd/nscd/nscd_cfgdef.h
@@ -750,8 +750,8 @@ static nscd_cfg_global_data_t nscd_cfg_global_default = {
{
NSCD_CFG_GROUP_INFO_GLOBAL_FRONTEND,
- 20, /* common_worker_threads */
- 20, /* cache_hit_threads */
+ 100, /* common_worker_threads */
+ 100, /* cache_hit_threads */
},
@@ -796,7 +796,7 @@ static nscd_cfg_nsw_db_data_t nscd_cfg_nsw_db_data_default = {
{
NSCD_CFG_GROUP_INFO_FRONTEND,
- 10, /* worker_thread_per_nsw_db */
+ 50, /* worker_thread_per_nsw_db */
},
diff --git a/usr/src/cmd/nscd/nscd_common.h b/usr/src/cmd/nscd/nscd_common.h
index 7b2ccffd91..8d7de7478c 100644
--- a/usr/src/cmd/nscd/nscd_common.h
+++ b/usr/src/cmd/nscd/nscd_common.h
@@ -95,6 +95,8 @@ typedef uint8_t nscd_bool_t;
#define nscd_false 0
/* common functions */
+void _nscd_set_start_time(int reset);
+time_t _nscd_get_start_time();
nscd_rc_t _nscd_init(char *cfgfile);
nscd_rc_t _nscd_refresh();
diff --git a/usr/src/cmd/nscd/nscd_config.c b/usr/src/cmd/nscd/nscd_config.c
index 02e3375ab0..18d0d81c3e 100644
--- a/usr/src/cmd/nscd/nscd_config.c
+++ b/usr/src/cmd/nscd/nscd_config.c
@@ -510,14 +510,14 @@ _nscd_cfg_init_param()
if (gdesc->nfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(gdesc->nfunc_name,
&gdesc->notify, NULL, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
nfunc = (void *)gdesc->notify;
}
if (gdesc->vfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(gdesc->vfunc_name,
&gdesc->verify, NULL, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
vfunc = (void *)gdesc->verify;
}
@@ -548,13 +548,13 @@ _nscd_cfg_init_param()
if (desc->nfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(desc->nfunc_name,
&desc->notify, &nfunc, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
}
if (desc->vfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(desc->vfunc_name,
&desc->verify, &vfunc, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
}
}
@@ -653,7 +653,7 @@ _nscd_cfg_init_stat()
if (gdesc->gsfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(gdesc->gsfunc_name,
&gdesc->get_stat, NULL, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
gsfunc = (void *)gdesc->get_stat;
}
@@ -684,7 +684,7 @@ _nscd_cfg_init_stat()
if (desc->gsfunc_name != NULL) {
rc = _nscd_cfg_get_funcp(desc->gsfunc_name,
&desc->get_stat, &gsfunc, NULL);
- if (rc != NULL)
+ if (rc != NSCD_SUCCESS)
return (rc);
}
}
@@ -1320,13 +1320,15 @@ _nscd_cfg_notify_init(
&skip, errorp);
} else { /* send data once for each nsw db */
- for (j = 0; j < _nscd_cfg_num_nsw_db;
- j++) {
+ for (j = 0; j < _nscd_cfg_num_nsw_db; j++) {
nswdb = &_nscd_cfg_nsw_db[j];
rc = _nscd_cfg_notify_i(desc,
nswdb, &skip, errorp);
+
+ if (rc != NSCD_SUCCESS)
+ break;
}
}
}
@@ -1497,7 +1499,7 @@ _nscd_cfg_init(
rc = _nscd_cfg_set_vlen_data_int(
&nscd_cfg_nsw_db_data_default,
- &nscd_cfg_nsw_alldb_current, nscd_false);
+ nscd_cfg_nsw_alldb_current, nscd_false);
if (rc != NSCD_SUCCESS)
return (rc);
@@ -2802,6 +2804,8 @@ gettext("vaule of \'%s\' not changeable, change that of \'%s\' instead"),
rc = _nscd_cfg_get_handle(param_name, dbl,
&hl, errorp);
+ if (rc != NSCD_SUCCESS)
+ return (rc);
rc = _nscd_cfg_set(hl, data, errorp);
_nscd_cfg_free_handle(hl);
if (rc != NSCD_SUCCESS)
diff --git a/usr/src/cmd/nscd/nscd_db.h b/usr/src/cmd/nscd/nscd_db.h
index 7186f0d0dd..9695fdcee6 100644
--- a/usr/src/cmd/nscd/nscd_db.h
+++ b/usr/src/cmd/nscd/nscd_db.h
@@ -87,7 +87,7 @@ typedef struct nscd_db_entry {
* sequence number attached to nscd data
*/
typedef nssuint_t nscd_seq_num_t;
-typedef nssuint_t nscd_cookie_t;
+typedef nssuint_t nscd_cookie_num_t;
/*
* The nscd_access_s datatype represents a nscd
@@ -127,8 +127,8 @@ typedef struct nscd_db_s nscd_db_t;
nscd_seq_num_t
_nscd_get_seq_num();
-nscd_cookie_t
-_nscd_get_cookie();
+nscd_cookie_num_t
+_nscd_get_cookie_num();
nscd_acc_data_t *
_nscd_get(
diff --git a/usr/src/cmd/nscd/nscd_frontend.c b/usr/src/cmd/nscd/nscd_frontend.c
index 7f718111e9..fe42fecb90 100644
--- a/usr/src/cmd/nscd/nscd_frontend.c
+++ b/usr/src/cmd/nscd/nscd_frontend.c
@@ -326,46 +326,55 @@ N2N_check_priv(
NSCD_RETURN_STATUS_SUCCESS(phdr);
}
-static void
-APP_check_cred(
+void
+_nscd_APP_check_cred(
void *buf,
pid_t *pidp,
- char *dc_str)
+ char *dc_str,
+ int log_comp,
+ int log_level)
{
nss_pheader_t *phdr = (nss_pheader_t *)buf;
ucred_t *uc = NULL;
uid_t ruid;
uid_t euid;
+ pid_t pid;
int errnum;
- char *me = "APP_check_cred";
+ char *me = "_nscd_APP_check_cred";
if (door_ucred(&uc) != 0) {
errnum = errno;
- _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
+ _NSCD_LOG(log_comp, NSCD_LOG_LEVEL_ERROR)
(me, "door_ucred: %s\n", strerror(errno));
NSCD_RETURN_STATUS(phdr, NSS_ERROR, errnum);
}
+ NSCD_SET_STATUS_SUCCESS(phdr);
+ pid = ucred_getpid(uc);
if (NSS_PACKED_CRED_CHECK(buf, ruid = ucred_getruid(uc),
euid = ucred_geteuid(uc))) {
- if (pidp != NULL)
- *pidp = ucred_getpid(uc);
- ucred_free(uc);
-
- NSCD_RETURN_STATUS_SUCCESS(phdr);
+ if (pidp != NULL) {
+ if (*pidp == (pid_t)-1)
+ *pidp = pid;
+ else if (*pidp != pid) {
+ NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
+ }
+ }
+ } else {
+ NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
}
- _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
- (me, "%s call failed: caller pid %d, ruid %d, "
- "euid %d, header ruid %d, header euid %d\n", dc_str,
- (pidp != NULL) ? *pidp : -1, ruid, euid,
- ((nss_pheader_t *)(buf))->p_ruid, ((nss_pheader_t *)(buf))->p_euid);
-
-
ucred_free(uc);
- NSCD_RETURN_STATUS(phdr, NSS_ERROR, EACCES);
+ if (NSCD_STATUS_IS_NOT_OK(phdr)) {
+ _NSCD_LOG(log_comp, log_level)
+ (me, "%s call failed: caller pid %d (input pid = %d), ruid %d, "
+ "euid %d, header ruid %d, header euid %d\n", dc_str,
+ pid, (pidp != NULL) ? *pidp : -1, ruid, euid,
+ ((nss_pheader_t *)(buf))->p_ruid,
+ ((nss_pheader_t *)(buf))->p_euid);
+ }
}
static void
@@ -589,7 +598,8 @@ switcher(void *cookie, char *argp, size_t arg_size,
case NSCD_SETENT:
- APP_check_cred(argp, &ent_pid, "NSCD_SETENT");
+ _nscd_APP_check_cred(argp, &ent_pid, "NSCD_SETENT",
+ NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT);
if (NSCD_STATUS_IS_OK(phdr)) {
if_selfcred_return_per_user_door(argp, arg_size,
dp, _whoami);
diff --git a/usr/src/cmd/nscd/nscd_frontend.h b/usr/src/cmd/nscd/nscd_frontend.h
index 73c0fa1d68..e917db99bd 100644
--- a/usr/src/cmd/nscd/nscd_frontend.h
+++ b/usr/src/cmd/nscd/nscd_frontend.h
@@ -76,7 +76,8 @@ int _nscd_get_clearance(sema_t *sema);
int _nscd_release_clearance(sema_t *sema);
void _nscd_init_cache_sema(sema_t *sema, char *cache_name);
nscd_rc_t _nscd_alloc_frontend_cfg();
-
+void _nscd_APP_check_cred(void *buf, pid_t *pidp, char *dc_str,
+ int log_comp, int log_level);
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/nscd/nscd_getentctx.c b/usr/src/cmd/nscd/nscd_getentctx.c
index fcf58cc3b1..db2e16d684 100644
--- a/usr/src/cmd/nscd/nscd_getentctx.c
+++ b/usr/src/cmd/nscd/nscd_getentctx.c
@@ -48,7 +48,7 @@ static nscd_db_t *getent_ctxDB = NULL;
typedef struct nscd_getent_ctx {
int to_delete; /* this ctx no longer valid */
nscd_getent_context_t *ptr;
- nscd_cookie_t cookie;
+ nscd_cookie_num_t cookie_num;
} nscd_getent_ctx_t;
/*
@@ -99,17 +99,17 @@ _nscd_create_getent_ctxDB()
static nscd_rc_t
_nscd_add_getent_ctx(
nscd_getent_context_t *ptr,
- nscd_cookie_t cookie)
+ nscd_cookie_num_t cookie_num)
{
int size;
- char buf[2 * sizeof (cookie) + 1];
+ char buf[2 * sizeof (cookie_num) + 1];
nscd_db_entry_t *db_entry;
nscd_getent_ctx_t *gnctx;
if (ptr == NULL)
return (NSCD_INVALID_ARGUMENT);
- (void) snprintf(buf, sizeof (buf), "%lld", cookie);
+ (void) snprintf(buf, sizeof (buf), "%lld", cookie_num);
size = sizeof (*gnctx);
@@ -120,7 +120,7 @@ _nscd_add_getent_ctx(
gnctx = (nscd_getent_ctx_t *)*(db_entry->data_array);
gnctx->ptr = ptr;
- gnctx->cookie = cookie;
+ gnctx->cookie_num = cookie_num;
(void) rw_wrlock(&getent_ctxDB_rwlock);
(void) _nscd_add_db_entry(getent_ctxDB, buf, db_entry,
@@ -138,13 +138,13 @@ _nscd_add_getent_ctx(
*/
nscd_getent_context_t *
_nscd_is_getent_ctx(
- nscd_cookie_t cookie)
+ nscd_cookie_num_t cookie_num)
{
- char ptrstr[1 + 2 * sizeof (cookie)];
+ char ptrstr[1 + 2 * sizeof (cookie_num)];
const nscd_db_entry_t *db_entry;
nscd_getent_context_t *ret = NULL;
- (void) snprintf(ptrstr, sizeof (ptrstr), "%lld", cookie);
+ (void) snprintf(ptrstr, sizeof (ptrstr), "%lld", cookie_num);
(void) rw_rdlock(&getent_ctxDB_rwlock);
@@ -161,7 +161,7 @@ _nscd_is_getent_ctx(
* the cookie numbers match, return the ctx.
* Otherwise return NULL.
*/
- if (gnctx->to_delete == 0 && gnctx->cookie == cookie)
+ if (gnctx->to_delete == 0 && gnctx->cookie_num == cookie_num)
ret = gnctx->ptr;
}
@@ -178,16 +178,16 @@ _nscd_is_getent_ctx(
static void
_nscd_del_getent_ctx(
nscd_getent_context_t *ptr,
- nscd_cookie_t cookie)
+ nscd_cookie_num_t cookie_num)
{
- char ptrstr[1 + 2 * sizeof (cookie)];
+ char ptrstr[1 + 2 * sizeof (cookie_num)];
nscd_getent_ctx_t *gnctx;
const nscd_db_entry_t *db_entry;
if (ptr == NULL)
return;
- (void) snprintf(ptrstr, sizeof (ptrstr), "%lld", cookie);
+ (void) snprintf(ptrstr, sizeof (ptrstr), "%lld", cookie_num);
(void) rw_rdlock(&getent_ctxDB_rwlock);
/*
@@ -201,7 +201,7 @@ _nscd_del_getent_ctx(
NSCD_GET_FIRST_DB_ENTRY, 0);
if (db_entry != NULL) {
gnctx = (nscd_getent_ctx_t *)*(db_entry->data_array);
- if (gnctx->ptr == ptr && gnctx->cookie == cookie) {
+ if (gnctx->ptr == ptr && gnctx->cookie_num == cookie_num) {
(void) rw_unlock(&getent_ctxDB_rwlock);
(void) rw_wrlock(&getent_ctxDB_rwlock);
@@ -226,7 +226,7 @@ _nscd_free_getent_ctx(
(me, "getent context %p\n", gnctx);
_nscd_put_nsw_state(gnctx->nsw_state);
- _nscd_del_getent_ctx(gnctx, gnctx->cookie);
+ _nscd_del_getent_ctx(gnctx, gnctx->cookie_num);
free(gnctx);
}
@@ -294,7 +294,7 @@ _nscd_create_getent_ctx(
}
gnctx->dbi = params->dbi;
- gnctx->cookie = _nscd_get_cookie();
+ gnctx->cookie_num = _nscd_get_cookie_num();
gnctx->pid = -1;
if (_nscd_get_nsw_state(&db_root, params) != NSCD_SUCCESS) {
@@ -390,9 +390,9 @@ _nscd_get_getent_ctx(
_nscd_mutex_unlock((nscd_acc_data_t *)base);
_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_DEBUG)
- (me, "adding new ctx %p, cookie = %lld\n", c, c->cookie);
+ (me, "adding new ctx %p, cookie # = %lld\n", c, c->cookie_num);
- if ((rc = _nscd_add_getent_ctx(c, c->cookie)) != NSCD_SUCCESS) {
+ if ((rc = _nscd_add_getent_ctx(c, c->cookie_num)) != NSCD_SUCCESS) {
_nscd_put_getent_ctx(c);
return (rc);
}
@@ -444,11 +444,11 @@ _nscd_put_getent_ctx(
_nscd_put_nsw_state(gnctx->nsw_state);
gnctx->nsw_state = NULL;
- _nscd_del_getent_ctx(gnctx, gnctx->cookie);
+ _nscd_del_getent_ctx(gnctx, gnctx->cookie_num);
_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_DEBUG)
- (me, "ctx (%p seq# = %lld) removed from getent ctx DB\n",
- gnctx, gnctx->cookie);
+ (me, "ctx (%p, cookie # = %lld) removed from getent ctx DB\n",
+ gnctx, gnctx->cookie_num);
if (base->num_waiter > 0) {
_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_DEBUG)
@@ -598,10 +598,10 @@ reclaim_getent_ctx(void *arg)
NSCD_LOG_LEVEL_DEBUG)
(me, "process %d exited, "
"getent context = %p, "
- "db index = %d, cookie = %lld, "
+ "db index = %d, cookie # = %lld, "
"sequence # = %lld\n",
gctx->pid, gctx, gctx->dbi,
- gctx->cookie, gctx->seq_num);
+ gctx->cookie_num, gctx->seq_num);
if (first != NULL) {
last->next = gctx;
diff --git a/usr/src/cmd/nscd/nscd_init.c b/usr/src/cmd/nscd/nscd_init.c
index 991d31a9ff..639b0c9d15 100644
--- a/usr/src/cmd/nscd/nscd_init.c
+++ b/usr/src/cmd/nscd/nscd_init.c
@@ -28,6 +28,7 @@
#include <locale.h>
#include <unistd.h>
#include <string.h>
+#include <time.h>
#include "nscd_common.h"
#include "nscd_config.h"
#include "nscd_log.h"
@@ -35,6 +36,23 @@
#include "nscd_frontend.h"
static char *cfgfile_save = NULL;
+static mutex_t time_mutex = DEFAULTMUTEX;
+static time_t start_time = 0;
+
+void
+_nscd_set_start_time(int reset)
+{
+ (void) mutex_lock(&time_mutex);
+ if (start_time == 0 || reset == 1)
+ start_time = time(NULL);
+ (void) mutex_unlock(&time_mutex);
+}
+
+time_t
+_nscd_get_start_time()
+{
+ return (start_time);
+}
nscd_rc_t
_nscd_init(
@@ -45,24 +63,27 @@ _nscd_init(
nscd_cfg_error_t *err;
/*
+ * remember when main or forker nscd starts.
+ */
+ _nscd_set_start_time(0);
+
+ /*
* allocate the space for tables
*/
- rc = _nscd_alloc_nsw_config();
- rc = _nscd_alloc_service_state_table();
- rc = _nscd_alloc_nsw_state_base();
- rc = _nscd_alloc_nsw_be_info_db();
- rc = _nscd_alloc_getent_ctx_base();
- if (rc != NSCD_SUCCESS)
+ if ((rc = _nscd_alloc_nsw_config()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_service_state_table()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_nsw_state_base()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_nsw_be_info_db()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_getent_ctx_base()) != NSCD_SUCCESS)
return (rc);
/*
* allocate the space for local configuration
* and statistics
*/
- rc = _nscd_alloc_switch_cfg();
- rc = _nscd_alloc_frontend_cfg();
- rc = _nscd_alloc_switch_stats();
- if (rc != NSCD_SUCCESS)
+ if ((rc = _nscd_alloc_switch_cfg()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_frontend_cfg()) != NSCD_SUCCESS ||
+ (rc = _nscd_alloc_switch_stats()) != NSCD_SUCCESS)
return (rc);
/*
@@ -171,7 +192,7 @@ _nscd_init(
*/
if (cfgfile != NULL) {
cfgfile_save = strdup(cfgfile);
- if (cfgfile == NULL)
+ if (cfgfile_save == NULL)
return (NSCD_NO_MEMORY);
}
diff --git a/usr/src/cmd/nscd/nscd_selfcred.c b/usr/src/cmd/nscd/nscd_selfcred.c
index 08e8e7839e..be26414ee6 100644
--- a/usr/src/cmd/nscd/nscd_selfcred.c
+++ b/usr/src/cmd/nscd/nscd_selfcred.c
@@ -823,6 +823,12 @@ _nscd_proc_fork(
if ((cid = fork1()) == 0) {
_whoami = NSCD_CHILD;
+ /*
+ * remember when this child nscd starts
+ * (replace the forker start time)
+ */
+ _nscd_set_start_time(1);
+
/* close all except the log file */
if (_logfd > 0) {
int i;
diff --git a/usr/src/cmd/nscd/nscd_seqnum.c b/usr/src/cmd/nscd/nscd_seqnum.c
index bf1c1d9e39..00d1820dce 100644
--- a/usr/src/cmd/nscd/nscd_seqnum.c
+++ b/usr/src/cmd/nscd/nscd_seqnum.c
@@ -27,10 +27,10 @@
#include "nscd_db.h"
-static nscd_seq_num_t acc_seq = 1;
-static mutex_t seq_mutex = DEFAULTMUTEX;
-static nscd_cookie_t cookie = 1234;
-static mutex_t cookie_mutex = DEFAULTMUTEX;
+static nscd_seq_num_t acc_seq = 1;
+static mutex_t seq_mutex = DEFAULTMUTEX;
+static nscd_cookie_num_t cookie_num = 1234;
+static mutex_t cookie_mutex = DEFAULTMUTEX;
nscd_seq_num_t
_nscd_get_seq_num()
@@ -39,20 +39,20 @@ _nscd_get_seq_num()
(void) mutex_lock(&seq_mutex);
seq_num = acc_seq;
- acc_seq += 1;
+ acc_seq++;
(void) mutex_unlock(&seq_mutex);
return (seq_num);
}
-nscd_cookie_t
-_nscd_get_cookie()
+nscd_cookie_num_t
+_nscd_get_cookie_num()
{
- nscd_cookie_t ret;
+ nscd_cookie_num_t ret;
(void) mutex_lock(&cookie_mutex);
- ret = cookie;
- cookie += 1;
+ ret = cookie_num;
+ cookie_num++;
(void) mutex_unlock(&cookie_mutex);
return (ret);
diff --git a/usr/src/cmd/nscd/nscd_switch.c b/usr/src/cmd/nscd/nscd_switch.c
index d55fbb27e5..d9ffd06e7e 100644
--- a/usr/src/cmd/nscd/nscd_switch.c
+++ b/usr/src/cmd/nscd/nscd_switch.c
@@ -394,7 +394,7 @@ trace_result(
if (res == NSS_SUCCESS) {
_nscd_logit(me,
-"%s: database: %s, operation: %d, source: %s returned \"%s\", length = %d\n",
+"%s: database: %s, operation: %d, source: %s returned >>%s<<, length = %d\n",
res_str, db, op, src, arg->buf.buffer, arg->returnlen);
return;
@@ -691,7 +691,7 @@ nss_search(nss_db_root_t *rootp, nss_db_initf_t initf, int search_fnum,
}
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "database = %s, config = [ %s ]\n", NSCD_NSW_DB_NAME(dbi),
+ (me, "database = %s, config = >>%s<<\n", NSCD_NSW_DB_NAME(dbi),
(*s->nsw_cfg_p)->nsw_cfg_str);
for (n_src = 0; n_src < s->max_src; n_src++) {
@@ -1333,62 +1333,69 @@ nss_psearch(void *buffer, size_t length)
static void
nscd_map_contextp(void *buffer, nss_getent_t *contextp,
- nssuint_t **cookie_p, nssuint_t **seqnum_p, int setent)
+ nssuint_t **cookie_num_p, nssuint_t **seqnum_p, int setent)
{
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
nssuint_t off;
nscd_getent_context_t *ctx;
char *me = "nscd_map_contextp";
-
- struct cookie_seqnum {
- nssuint_t cookie;
- nssuint_t seqnum;
- } *csp;
+ nscd_getent_p1_cookie_t *cookie;
if (buffer == NULL) {
NSCD_RETURN_STATUS(pbuf, NSS_ERROR, EFAULT);
}
off = pbuf->key_off;
- csp = (struct cookie_seqnum *)((void *)((char *)buffer + off));
+ cookie = (nscd_getent_p1_cookie_t *)((void *)((char *)buffer + off));
if (seqnum_p != NULL)
- *seqnum_p = &csp->seqnum;
+ *seqnum_p = &cookie->p1_seqnum;
/*
- * if called by nss_psetent, and the passed in cookie is
- * NSCD_NEW_COOKIE, then there is no cookie yet, return
- * a pointer pointing to where the cookie will be stored.
- * Also because there is no cookie to validate, just
- * return success.
+ * if called by nss_psetent, and the passed in cookie number
+ * is NSCD_NEW_COOKIE, then there is no cookie yet, return a
+ * pointer pointing to where the cookie number will be stored.
+ * Also because there is no cookie to validate, just return
+ * success.
*
- * On the other hand, if a cookie is passed in, we need
- * to validate the cookie before returning.
+ * On the other hand, if a cookie number is passed in, we need
+ * to validate the cookie number before returning.
+ */
+ if (cookie_num_p != NULL)
+ *cookie_num_p = &cookie->p1_cookie_num;
+ if (setent == 1 && cookie->p1_cookie_num == NSCD_NEW_COOKIE) {
+ NSCD_RETURN_STATUS_SUCCESS(pbuf);
+ }
+
+ /*
+ * If the sequence number and start time match nscd's p0 cookie,
+ * then either setent was done twice in a row or this is the
+ * first getent after the setent, return success as well.
*/
- if (cookie_p != NULL)
- *cookie_p = &csp->cookie;
- if (setent == 1 && csp->cookie == NSCD_NEW_COOKIE) {
- NSCD_RETURN_STATUS_SUCCESS(pbuf);
+ if (cookie->p1_seqnum == NSCD_P0_COOKIE_SEQNUM) {
+ nscd_getent_p0_cookie_t *p0c =
+ (nscd_getent_p0_cookie_t *)cookie;
+ if (p0c->p0_time == _nscd_get_start_time())
+ NSCD_RETURN_STATUS_SUCCESS(pbuf);
}
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "cookie = %lld, sequence number = %lld\n",
- csp->cookie, csp->seqnum);
+ (me, "cookie # = %lld, sequence # = %lld\n",
+ cookie->p1_cookie_num, cookie->p1_seqnum);
- ctx = _nscd_is_getent_ctx(csp->cookie);
+ ctx = _nscd_is_getent_ctx(cookie->p1_cookie_num);
if (ctx == NULL) {
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "invalid cookie (%lld)\n", csp->cookie);
+ (me, "invalid cookie # (%lld)\n", cookie->p1_cookie_num);
NSCD_RETURN_STATUS(pbuf, NSS_ERROR, EFAULT);
}
- if (setent == 1) {
- /* if called by nss_psetent, reset the seq number */
- ctx->seq_num = 1;
- } else if (ctx->seq_num != (nscd_seq_num_t)csp->seqnum) {
+ /* if not called by nss_psetent, verify sequence number */
+ if (setent != 1 && ctx->seq_num !=
+ (nscd_seq_num_t)cookie->p1_seqnum) {
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "invalid sequence number (%lld)\n", csp->seqnum);
+ (me, "invalid sequence # (%lld)\n", cookie->p1_seqnum);
NSCD_RETURN_STATUS(pbuf, NSS_ERROR, EFAULT);
}
@@ -1401,17 +1408,12 @@ nscd_map_contextp(void *buffer, nss_getent_t *contextp,
void
nss_psetent(void *buffer, size_t length, pid_t pid)
{
- /* inputs */
- nss_db_initf_t initf;
nss_getent_t context = { 0 };
nss_getent_t *contextp = &context;
- nss_status_t status;
- nssuint_t *cookiep;
- nssuint_t *seqnump;
- nscd_getent_context_t *ctx;
- int rc;
+ nssuint_t *cookie_num_p;
+ nssuint_t *seqnum_p;
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
- nscd_sw_return_t swret = { 0 }, *swrp = &swret;
+ nscd_getent_p0_cookie_t *p0c;
char *me = "nss_psetent";
if (buffer == NULL || length == 0) {
@@ -1442,68 +1444,97 @@ nss_psetent(void *buffer, size_t length, pid_t pid)
}
}
- status = nss_packed_context_init(buffer, length,
- NULL, &initf, &contextp, (nss_XbyY_args_t *)NULL);
- if (status != NSS_SUCCESS) {
- NSCD_RETURN_STATUS(pbuf, status, -1);
+ /* check cookie number */
+ nscd_map_contextp(buffer, contextp, &cookie_num_p, &seqnum_p, 1);
+ if (NSCD_STATUS_IS_NOT_OK(pbuf))
+ return;
+
+ /* set cookie number and sequence number */
+ p0c = (nscd_getent_p0_cookie_t *)cookie_num_p;
+ if (contextp->ctx == NULL) {
+ /*
+ * first setent (no existing getent context),
+ * return a p0 cookie
+ */
+ _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+ (me, "first setent, no getent context yet\n");
+ } else {
+ /*
+ * doing setent on an existing getent context,
+ * release resources allocated and return a
+ * p0 cookie
+ */
+ _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+ (me, "setent resetting sequence number = %lld\n", *seqnum_p);
+
+ _nscd_put_getent_ctx((nscd_getent_context_t *)contextp->ctx);
+ contextp->ctx = NULL;
}
+ p0c->p0_pid = pid;
+ p0c->p0_time = _nscd_get_start_time();
+ p0c->p0_seqnum = NSCD_P0_COOKIE_SEQNUM;
+ _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+ (me, "returning a p0 cookie: pid = %ld, time = %ld, seq #= %llx\n",
+ p0c->p0_pid, p0c->p0_time, p0c->p0_seqnum);
+
+ NSCD_RETURN_STATUS(pbuf, NSS_SUCCESS, 0);
+}
+
+static void
+delayed_setent(nss_pheader_t *pbuf, nss_db_initf_t initf,
+ nss_getent_t *contextp, nssuint_t *cookie_num_p,
+ nssuint_t *seqnum_p, pid_t pid)
+{
+ nscd_getent_context_t *ctx;
+ nscd_sw_return_t swret = { 0 }, *swrp = &swret;
+ char *me = "delayed_setent";
+
/*
- * use the generic nscd_initf for all the setent requests
- * (the TSD key is the pointer to the packed header)
+ * check credential
*/
- rc = set_initf_key(pbuf);
- if (rc != 0) {
- NSCD_RETURN_STATUS(pbuf, NSS_UNAVAIL, EINVAL);
+ _nscd_APP_check_cred(pbuf, &pid, "NSCD_DELAYED_SETENT",
+ NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_ERROR);
+ if (NSCD_STATUS_IS_NOT_OK(pbuf)) {
+ _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+ (me, "invalid credential\n");
+ return;
}
- initf = nscd_initf;
- /* get address of cookie and seqnum for later updates */
- nscd_map_contextp(buffer, contextp, &cookiep, &seqnump, 1);
- if (NSCD_STATUS_IS_NOT_OK(pbuf))
- return;
/*
* pass the packed header buffer pointer to nss_setent
*/
(void) memcpy(&pbuf->nscdpriv, &swrp, sizeof (swrp));
- swret.pbuf = buffer;
+ swret.pbuf = pbuf;
/* Perform local setent and set context */
nss_setent(NULL, initf, contextp);
- /* insert cookie info into buffer and return */
+ /* insert cookie info into packed buffer header */
ctx = (nscd_getent_context_t *)contextp->ctx;
if (ctx != NULL) {
- *cookiep = ctx->cookie;
- *seqnump = (nssuint_t)ctx->seq_num;
+ *cookie_num_p = ctx->cookie_num;
+ *seqnum_p = ctx->seq_num;
ctx->pid = pid;
} else {
/*
* not able to allocate a getent context, the
* client should try the enumeration locally
*/
- *cookiep = NSCD_LOCAL_COOKIE;
- *seqnump = 0;
- }
-
- _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "cookie = %lld, sequence number = %lld\n",
- *cookiep, *seqnump);
+ *cookie_num_p = NSCD_LOCAL_COOKIE;
+ *seqnum_p = 0;
- if (ctx != NULL) {
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "cookie = %lld, sequence number = %lld\n",
- ctx->cookie, ctx->seq_num);
+ (me, "NSS_TRYLOCAL: cookie # = %lld, sequence # = %lld\n",
+ *cookie_num_p, *seqnum_p);
+ NSCD_RETURN_STATUS(pbuf, NSS_TRYLOCAL, 0);
}
- /* clear the TSD key used by the generic initf */
- clear_initf_key();
+ _NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
+ (me, "NSS_SUCCESS: cookie # = %lld, sequence # = %lld\n",
+ ctx->cookie_num, ctx->seq_num);
- if (*cookiep == NSCD_LOCAL_COOKIE) {
- NSCD_RETURN_STATUS(pbuf, NSS_TRYLOCAL, 0);
- } else {
- NSCD_RETURN_STATUS(pbuf, NSS_SUCCESS, 0);
- }
+ NSCD_RETURN_STATUS(pbuf, NSS_SUCCESS, 0);
}
void
@@ -1511,12 +1542,12 @@ nss_pgetent(void *buffer, size_t length)
{
/* inputs */
nss_db_initf_t initf;
- nss_getent_t context;
+ nss_getent_t context = { 0 };
nss_getent_t *contextp = &context;
- nss_XbyY_args_t arg;
+ nss_XbyY_args_t arg = { 0};
nss_status_t status;
- nssuint_t *cookiep;
- nssuint_t *seqnump;
+ nssuint_t *cookie_num_p;
+ nssuint_t *seqnum_p;
nscd_getent_context_t *ctx;
int rc;
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
@@ -1526,12 +1557,10 @@ nss_pgetent(void *buffer, size_t length)
NSCD_RETURN_STATUS(pbuf, NSS_ERROR, EFAULT);
}
- status = nss_packed_context_init(buffer, length,
- NULL, &initf, &contextp, &arg);
- if (status != NSS_SUCCESS) {
- NSCD_RETURN_STATUS(pbuf, status, -1);
- }
-
+ /* verify the cookie passed in */
+ nscd_map_contextp(buffer, contextp, &cookie_num_p, &seqnum_p, 0);
+ if (NSCD_STATUS_IS_NOT_OK(pbuf))
+ return;
/*
* use the generic nscd_initf for all the getent requests
* (the TSD key is the pointer to the packed header)
@@ -1542,11 +1571,24 @@ nss_pgetent(void *buffer, size_t length)
}
initf = nscd_initf;
+ /* if no context yet, get one */
+ if (contextp->ctx == NULL) {
+ nscd_getent_p0_cookie_t *p0c =
+ (nscd_getent_p0_cookie_t *)cookie_num_p;
- /* verify the cookie passed in */
- nscd_map_contextp(buffer, contextp, &cookiep, &seqnump, 0);
- if (NSCD_STATUS_IS_NOT_OK(pbuf))
- return;
+ delayed_setent(pbuf, initf, contextp, cookie_num_p,
+ seqnum_p, p0c->p0_pid);
+ if (NSCD_STATUS_IS_NOT_OK(pbuf)) {
+ clear_initf_key();
+ return;
+ }
+ }
+
+ status = nss_packed_context_init(buffer, length,
+ NULL, &initf, &contextp, &arg);
+ if (status != NSS_SUCCESS) {
+ NSCD_RETURN_STATUS(pbuf, status, -1);
+ }
/* Perform local search and pack results into return buffer */
status = nss_getent(NULL, initf, contextp, &arg);
@@ -1557,12 +1599,12 @@ nss_pgetent(void *buffer, size_t length)
if (status == NSS_SUCCESS) {
ctx = (nscd_getent_context_t *)contextp->ctx;
ctx->seq_num++;
- *seqnump = ctx->seq_num;
- *cookiep = ctx->cookie;
+ *seqnum_p = ctx->seq_num;
+ *cookie_num_p = ctx->cookie_num;
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "getent OK, new sequence number = %lld, len = %lld,"
- " data = [ %s ]\n", *seqnump,
+ (me, "getent OK, new sequence # = %lld, len = %lld,"
+ " data = >>%s<<\n", *seqnum_p,
pbuf->data_len, (char *)buffer + pbuf->data_off);
} else {
/* release the resources used */
@@ -1572,8 +1614,8 @@ nss_pgetent(void *buffer, size_t length)
contextp->ctx = NULL;
}
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "getent failed, status = %d, sequence number = %lld\n",
- status, *seqnump);
+ (me, "getent failed, status = %d, sequence # = %lld\n",
+ status, *seqnum_p);
}
/* clear the TSD key used by the generic initf */
@@ -1583,10 +1625,10 @@ nss_pgetent(void *buffer, size_t length)
void
nss_pendent(void *buffer, size_t length)
{
- nss_getent_t context;
+ nss_getent_t context = { 0 };
nss_getent_t *contextp = &context;
- nssuint_t *seqnump;
- nssuint_t *cookiep;
+ nssuint_t *seqnum_p;
+ nssuint_t *cookie_num_p;
nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
char *me = "nss_pendent";
@@ -1595,13 +1637,16 @@ nss_pendent(void *buffer, size_t length)
}
/* map the contextp from the cookie information */
- nscd_map_contextp(buffer, contextp, &cookiep, &seqnump, 0);
+ nscd_map_contextp(buffer, contextp, &cookie_num_p, &seqnum_p, 0);
if (NSCD_STATUS_IS_NOT_OK(pbuf))
return;
+ if (contextp->ctx == NULL)
+ return;
+
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "endent, cookie = %lld, sequence number = %lld\n",
- *cookiep, *seqnump);
+ (me, "endent, cookie = %lld, sequence # = %lld\n",
+ *cookie_num_p, *seqnum_p);
/* Perform local endent and reset context */
nss_endent(NULL, NULL, contextp);
diff --git a/usr/src/cmd/nscd/nscd_switch.h b/usr/src/cmd/nscd/nscd_switch.h
index 6a9b177d05..aebb9176eb 100644
--- a/usr/src/cmd/nscd/nscd_switch.h
+++ b/usr/src/cmd/nscd/nscd_switch.h
@@ -137,7 +137,7 @@ typedef struct nscd_getent_ctx_base {
typedef struct nscd_getent_context {
int dbi;
nscd_seq_num_t seq_num;
- nscd_cookie_t cookie;
+ nscd_cookie_num_t cookie_num;
pid_t pid; /* door client's pid */
int n_src; /* >=max_src: end of sequence */
nscd_nsw_state_t *nsw_state;
@@ -202,6 +202,25 @@ typedef struct {
} nscd_sw_return_t;
/*
+ * nscd cookies used for setent/getent/endent
+ * - p0 cookie: returned by nscd to indicate
+ * the start of the enumeration position
+ * - p1 cookie: returned/updated by nscd to indicate
+ * the current enumeration position
+ */
+#define NSCD_P0_COOKIE_SEQNUM -1
+typedef struct {
+ pid_t p0_pid;
+ time_t p0_time;
+ nscd_seq_num_t p0_seqnum;
+} nscd_getent_p0_cookie_t;
+
+typedef struct {
+ nscd_cookie_num_t p1_cookie_num;
+ nscd_seq_num_t p1_seqnum;
+} nscd_getent_p1_cookie_t;
+
+/*
* static tables or global data defined in other files
*/
extern int _nscd_cfg_num_nsw_src;
@@ -316,7 +335,7 @@ _nscd_get_new_service_state(
nscd_getent_context_t *
_nscd_is_getent_ctx(
- nscd_cookie_t cookie);
+ nscd_cookie_num_t cookie_num);
nscd_rc_t
_nscd_create_sw_struct(
diff --git a/usr/src/lib/libc/port/gen/getgrnam_r.c b/usr/src/lib/libc/port/gen/getgrnam_r.c
index 2432e4a275..17b8ed6f0e 100644
--- a/usr/src/lib/libc/port/gen/getgrnam_r.c
+++ b/usr/src/lib/libc/port/gen/getgrnam_r.c
@@ -249,7 +249,7 @@ fgetgrent_r(FILE *f, struct group *result, char *buffer, int buflen)
* values in the array are unique.
*/
-static nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *);
+extern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *);
int
_getgroupsbymember(const char *username, gid_t gid_array[],
@@ -422,7 +422,7 @@ str2group(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
return (NSS_STR_PARSE_ERANGE);
}
-static nss_status_t
+nss_status_t
process_cstr(const char *instr, int instr_len, struct nss_groupsbymem *gbm)
{
/*
diff --git a/usr/src/lib/libc/port/gen/nss_common.c b/usr/src/lib/libc/port/gen/nss_common.c
index 2fa1fbf3dc..2f4349770f 100644
--- a/usr/src/lib/libc/port/gen/nss_common.c
+++ b/usr/src/lib/libc/port/gen/nss_common.c
@@ -1259,6 +1259,7 @@ struct nss_getent_context {
struct nss_db_state *s;
nssuint_t cookie;
nssuint_t seq_num;
+ nssuint_t cookie_setent;
nss_db_params_t param;
};
@@ -1359,12 +1360,16 @@ nss_setent_u(nss_db_root_t *rootp, nss_db_initf_t initf,
s = 0;
} else {
s = contextp->s;
+ if (contextp->cookie != NSCD_LOCAL_COOKIE)
+ contextp->cookie = NSCD_NEW_COOKIE;
}
/* name service cache daemon divert */
- status = _nsc_setent_u(rootp, initf, contextpp);
- if (status != NSS_TRYLOCAL)
- return;
+ if (contextp->cookie == NSCD_NEW_COOKIE) {
+ status = _nsc_setent_u(rootp, initf, contextpp);
+ if (status != NSS_TRYLOCAL)
+ return;
+ }
/* fall through - process locally */
if (s == 0) {
@@ -1632,7 +1637,6 @@ nss_pack(void *buffer, size_t bufsize, nss_db_root_t *rootp,
const char *dbn;
size_t blen, len, off = 0;
char *bptr;
- nssuint_t *uptr;
struct nss_groupsbymem *gbm;
if (pbuf == NULL || in == NULL || initf == (nss_db_initf_t)NULL) {
@@ -1715,8 +1719,9 @@ nss_pack(void *buffer, size_t bufsize, nss_db_root_t *rootp,
gbm = (struct nss_groupsbymem *)search_args;
if (search_fnum == NSS_DBOP_GROUP_BYMEMBER &&
strcmp(dbn, NSS_DBNAM_GROUP) == 0 && gbm->numgids == 1) {
- uptr = (nssuint_t *)((void *)((char *)buffer + off));
- *uptr = (nssuint_t)gbm->gid_array[0];
+ gid_t *gidp;
+ gidp = (gid_t *)((void *)((char *)buffer + off));
+ *gidp = gbm->gid_array[0];
}
errno = 0; /* just in case ... */
@@ -1818,7 +1823,7 @@ nss_unpack(void *buffer, size_t bufsize, nss_db_root_t *rootp,
int i;
int fmt_type;
gid_t *gidp;
- nssuint_t *uptr;
+ gid_t *gptr;
struct nss_groupsbymem *arg;
@@ -1857,16 +1862,15 @@ nss_unpack(void *buffer, size_t bufsize, nss_db_root_t *rootp,
if (fmt_type == 1) {
arg = (struct nss_groupsbymem *)in;
/* copy returned gid array from returned nscd buffer */
- i = len / sizeof (nssuint_t);
+ i = len / sizeof (gid_t);
/* not enough buffer */
if (i > arg->maxgids) {
i = arg->maxgids;
}
arg->numgids = i;
gidp = arg->gid_array;
- uptr = (nssuint_t *)((void *)buf);
- while (--i >= 0)
- *gidp++ = (gid_t)*uptr++;
+ gptr = (gid_t *)((void *)buf);
+ memcpy(gidp, gptr, len);
return (NSS_SUCCESS);
}
if (fmt_type == 2) {
@@ -1934,8 +1938,13 @@ nss_unpack_ent(void *buffer, size_t bufsize, nss_db_root_t *rootp,
nptr = (nssuint_t *)((void *)((char *)buffer + pbuf->key_off));
cookie = contextp->cookie;
- if (cookie != NSCD_NEW_COOKIE && cookie != *nptr) {
- /* Should either be new or a match, else error */
+ if (cookie != NSCD_NEW_COOKIE && cookie != contextp->cookie_setent &&
+ cookie != *nptr) {
+ /*
+ * Should either be new, or the cookie returned by the last
+ * setent (i.e., this is the first getent after the setent)
+ * or a match, else error
+ */
return (NSS_NOTFOUND);
}
/* save away for the next ent request */
@@ -2112,6 +2121,8 @@ _nsc_setent_u(nss_db_root_t *rootp, nss_db_initf_t initf,
/* unpack returned cookie stash it away */
status = nss_unpack_ent((void *)doorptr, bufsize, rootp,
initf, contextpp, NULL);
+ /* save the setent cookie for later use */
+ contextp->cookie_setent = contextp->cookie;
/*
* check if doors reallocated the memory underneath us
* if they did munmap it or suffer a memory leak
@@ -2165,8 +2176,14 @@ _nsc_getent_u(nss_db_root_t *rootp, nss_db_initf_t initf,
/* If fallback to standard nss logic (door failure) if possible */
if (status != NSS_SUCCESS) {
- if (contextp->cookie == NSCD_NEW_COOKIE) {
+ if (status == NSS_TRYLOCAL ||
+ contextp->cookie == NSCD_NEW_COOKIE) {
contextp->cookie = NSCD_LOCAL_COOKIE;
+
+ /* init the local cookie */
+ nss_setent_u(rootp, initf, contextpp);
+ if (contextpp->ctx == 0)
+ return (NSS_UNAVAIL);
return (NSS_TRYLOCAL);
}
return (NSS_UNAVAIL);
diff --git a/usr/src/lib/libc/port/gen/nss_dbdefs.c b/usr/src/lib/libc/port/gen/nss_dbdefs.c
index 687c3a9711..61a2bbf6dd 100644
--- a/usr/src/lib/libc/port/gen/nss_dbdefs.c
+++ b/usr/src/lib/libc/port/gen/nss_dbdefs.c
@@ -181,6 +181,8 @@ _nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen)
}
+extern nss_status_t process_cstr(const char *, int, struct nss_groupsbymem *);
+
/*
* pack well known getXbyY keys to packed buffer prior to the door_call
* to nscd. Some consideration is given to ordering the tests based on
@@ -773,7 +775,7 @@ nss_packed_set_status(void *buffer, size_t length, nss_status_t status,
if (in->numgids >= 0) {
pbuf->p_status = NSS_SUCCESS;
pbuf->data_len = in->numgids *
- sizeof (nssuint_t);
+ sizeof (gid_t);
pbuf->p_herrno = 0;
} else {
pbuf->p_status = status;
@@ -977,9 +979,9 @@ nss_upack_key2arg(void *buffer, size_t length, char **dbname,
gbm->numgids = (int)(*uptr++);
if (gbm->numgids == 1) {
/* insert initial group into data area */
- ((nssuint_t *)
- ((void *)gbm->gid_array))[0] = *uptr++;
- }
+ gbm->gid_array[0] = (gid_t)(*uptr++);
+ } else
+ uptr++;
gbm->username = (const char *)uptr;
break;
case 't':
@@ -1110,82 +1112,6 @@ str2packent(
}
/*
- * getgroupsbymem format interposed cstr2X function
- * This are similar to the API in getgrnam_r EXCEPT, this API
- * store values in nssuint_t quantities in the buffer, not gid_t
- * quantities. The unpacker in nss_common.c knows how to unpack
- * into gid_t quantities.
- */
-
-static nss_status_t
-pack_cstr(const char *instr, int instr_len, struct nss_groupsbymem *gbm)
-{
- /*
- * It's possible to do a much less inefficient version of this by
- * selectively duplicating code from str2group(). For now,
- * however, we'll take the easy way out and implement this on
- * top of str2group().
- */
-
- const char *username = gbm->username;
- nss_XbyY_buf_t *buf;
- struct group *grp;
- char **memp;
- char *mem;
- int parsestat;
-
- /* TODO FIX THIS - with getdoorbsize type call */
- buf = _nss_XbyY_buf_alloc(sizeof (struct group), NSS_BUFLEN_GROUP);
- if (buf == 0)
- return (NSS_UNAVAIL);
-
- grp = (struct group *)buf->result;
-
- parsestat = (*gbm->str2ent)(instr, instr_len,
- grp, buf->buffer, buf->buflen);
-
- if (parsestat != NSS_STR_PARSE_SUCCESS) {
- _nss_XbyY_buf_free(buf);
- return (NSS_NOTFOUND); /* === ? */
- }
-
- if (grp->gr_mem) {
- for (memp = grp->gr_mem; (memp) && ((mem = *memp) != 0);
- memp++) {
- if (strcmp(mem, username) == 0) {
- gid_t gid = grp->gr_gid;
- nssuint_t *gidp;
- int numgids;
- int i;
-
- gidp = (nssuint_t *)((void *)gbm->gid_array);
- numgids = gbm->numgids;
-
- _nss_XbyY_buf_free(buf);
-
- for (i = 0; i < numgids &&
- *gidp != (nssuint_t)gid;
- i++, gidp++) {
- ;
- }
- if (i >= numgids) {
- if (i >= gbm->maxgids) {
- /* Filled the array; stop searching */
- return (NSS_SUCCESS);
- }
- *gidp = (nssuint_t)gid;
- gbm->numgids = numgids + 1;
- }
- return (NSS_NOTFOUND); /* Explained in */
- /* <nss_dbdefs.h> */
- }
- }
- }
- _nss_XbyY_buf_free(buf);
- return (NSS_NOTFOUND);
-}
-
-/*
* Initialize db_root, initf, dbop and arg from a packed buffer
*/
@@ -1237,7 +1163,7 @@ nss_packed_arg_init(void *buffer, size_t length, nss_db_root_t *db_root,
if (nss_pinit_funcs(index, initf, &real_s2e) != NSS_SUCCESS)
return (NSS_ERROR);
((struct nss_groupsbymem *)arg)->str2ent = real_s2e;
- ((struct nss_groupsbymem *)arg)->process_cstr = pack_cstr;
+ ((struct nss_groupsbymem *)arg)->process_cstr = process_cstr;
return (NSS_SUCCESS);
}
if (pbuf->nss_dbop == NSS_DBOP_NETGROUP_IN &&
diff --git a/usr/src/lib/nsswitch/compat/common/compat_common.c b/usr/src/lib/nsswitch/compat/common/compat_common.c
index 49e30e9eb7..903a2e9e40 100644
--- a/usr/src/lib/nsswitch/compat/common/compat_common.c
+++ b/usr/src/lib/nsswitch/compat/common/compat_common.c
@@ -401,6 +401,8 @@ _nss_compat_setent(be, dummy)
else
be->state = GETENT_FILE;
+ be->return_string_data = 0;
+
/* ===> ?? netgroup stuff? */
return (NSS_SUCCESS);
}
@@ -553,8 +555,10 @@ _attrdb_compat_XY_all(be, argp, netdb, check, op_num)
*/
argp->buf.result = be->workarea;
func = be->str2ent_alt;
- } else
+ } else {
+ be->return_string_data = 0;
func = argp->str2ent;
+ }
/*CONSTCOND*/
while (1) {
@@ -718,7 +722,8 @@ _nss_compat_XY_all(be, args, check, op_num)
be->str2ent_save = args->str2ent;
args->str2ent = be->str2ent_alt;
- }
+ } else
+ be->return_string_data = 0;
/*CONSTCOND*/
while (1) {
@@ -946,7 +951,8 @@ _nss_compat_getent(be, a)
* as working area
*/
args->buf.result = be->workarea;
- }
+ } else
+ be->return_string_data = 0;
/*CONSTCOND*/
while (1) {
diff --git a/usr/src/lib/nsswitch/files/common/gethostent.c b/usr/src/lib/nsswitch/files/common/gethostent.c
index f7cd99af44..f389a56885 100644
--- a/usr/src/lib/nsswitch/files/common/gethostent.c
+++ b/usr/src/lib/nsswitch/files/common/gethostent.c
@@ -615,7 +615,7 @@ __nss_files_XY_hostbyname(be, args, filter, type)
*/
continue;
} else if (nhosts) {
- break;
+ continue;
}
}