xref: /titanic_53/usr/src/cmd/nscd/nscd_admin.c (revision cb5caa98562cf06753163f558cbcfe30b8f4673a)
1*cb5caa98Sdjl /*
2*cb5caa98Sdjl  * CDDL HEADER START
3*cb5caa98Sdjl  *
4*cb5caa98Sdjl  * The contents of this file are subject to the terms of the
5*cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6*cb5caa98Sdjl  * You may not use this file except in compliance with the License.
7*cb5caa98Sdjl  *
8*cb5caa98Sdjl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*cb5caa98Sdjl  * or http://www.opensolaris.org/os/licensing.
10*cb5caa98Sdjl  * See the License for the specific language governing permissions
11*cb5caa98Sdjl  * and limitations under the License.
12*cb5caa98Sdjl  *
13*cb5caa98Sdjl  * When distributing Covered Code, include this CDDL HEADER in each
14*cb5caa98Sdjl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*cb5caa98Sdjl  * If applicable, add the following below this CDDL HEADER, with the
16*cb5caa98Sdjl  * fields enclosed by brackets "[]" replaced with your own identifying
17*cb5caa98Sdjl  * information: Portions Copyright [yyyy] [name of copyright owner]
18*cb5caa98Sdjl  *
19*cb5caa98Sdjl  * CDDL HEADER END
20*cb5caa98Sdjl  */
21*cb5caa98Sdjl /*
22*cb5caa98Sdjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*cb5caa98Sdjl  * Use is subject to license terms.
24*cb5caa98Sdjl  */
25*cb5caa98Sdjl 
26*cb5caa98Sdjl #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*cb5caa98Sdjl 
28*cb5caa98Sdjl #include <stdlib.h>
29*cb5caa98Sdjl #include <locale.h>
30*cb5caa98Sdjl #include <string.h>
31*cb5caa98Sdjl #include "cache.h"
32*cb5caa98Sdjl #include "nscd_door.h"
33*cb5caa98Sdjl #include "nscd_log.h"
34*cb5caa98Sdjl #include "nscd_admin.h"
35*cb5caa98Sdjl 
36*cb5caa98Sdjl extern nsc_ctx_t	*cache_ctx_p[];
37*cb5caa98Sdjl extern char 		*cache_name[];
38*cb5caa98Sdjl 
39*cb5caa98Sdjl static nscd_admin_t	admin_c = { 0 };
40*cb5caa98Sdjl static nscd_admin_mod_t	admin_mod = { 0 };
41*cb5caa98Sdjl static mutex_t		mod_lock = DEFAULTMUTEX;
42*cb5caa98Sdjl 
43*cb5caa98Sdjl /*ARGSUSED*/
44*cb5caa98Sdjl int
45*cb5caa98Sdjl _nscd_door_getadmin(void *outbuf)
46*cb5caa98Sdjl {
47*cb5caa98Sdjl 	int			i;
48*cb5caa98Sdjl 	int			data_size = NSCD_N2N_DOOR_BUF_SIZE(admin_c);
49*cb5caa98Sdjl 	nss_pheader_t		*phdr = (nss_pheader_t *)outbuf;
50*cb5caa98Sdjl 	nscd_cfg_cache_t	cfg_default = NSCD_CFG_CACHE_DEFAULTS;
51*cb5caa98Sdjl 
52*cb5caa98Sdjl 	/*
53*cb5caa98Sdjl 	 * if size of buffer is not big enough, tell the caller to
54*cb5caa98Sdjl 	 * increase it to the size returned
55*cb5caa98Sdjl 	 */
56*cb5caa98Sdjl 	if (phdr->pbufsiz < data_size)
57*cb5caa98Sdjl 		return (sizeof (admin_c));
58*cb5caa98Sdjl 
59*cb5caa98Sdjl 	NSCD_SET_STATUS_SUCCESS(phdr);
60*cb5caa98Sdjl 	phdr->data_off = sizeof (nss_pheader_t);
61*cb5caa98Sdjl 	phdr->data_len = sizeof (admin_c);
62*cb5caa98Sdjl 
63*cb5caa98Sdjl 	for (i = 0; i < CACHE_CTX_COUNT; i++) {
64*cb5caa98Sdjl 		if (cache_ctx_p[i] != NULL) {
65*cb5caa98Sdjl 			(void) rw_rdlock(&cache_ctx_p[i]->cfg_rwlp);
66*cb5caa98Sdjl 			admin_c.cache_cfg[i] = cache_ctx_p[i]->cfg;
67*cb5caa98Sdjl 			(void) rw_unlock(&cache_ctx_p[i]->cfg_rwlp);
68*cb5caa98Sdjl 
69*cb5caa98Sdjl 			(void) mutex_lock(&cache_ctx_p[i]->stats_mutex);
70*cb5caa98Sdjl 			admin_c.cache_stats[i] = cache_ctx_p[i]->stats;
71*cb5caa98Sdjl 			(void) mutex_unlock(&cache_ctx_p[i]->stats_mutex);
72*cb5caa98Sdjl 		} else {
73*cb5caa98Sdjl 			admin_c.cache_cfg[i] = cfg_default;
74*cb5caa98Sdjl 			(void) memset(&admin_c.cache_stats[i], 0,
75*cb5caa98Sdjl 				sizeof (admin_c.cache_stats[0]));
76*cb5caa98Sdjl 		}
77*cb5caa98Sdjl 	}
78*cb5caa98Sdjl 	(void) memcpy(((char *)outbuf) + phdr->data_off,
79*cb5caa98Sdjl 		&admin_c, sizeof (admin_c));
80*cb5caa98Sdjl 
81*cb5caa98Sdjl 	return (0);
82*cb5caa98Sdjl }
83*cb5caa98Sdjl 
84*cb5caa98Sdjl void
85*cb5caa98Sdjl _nscd_client_showstats()
86*cb5caa98Sdjl {
87*cb5caa98Sdjl 	(void) printf("nscd configuration:\n\n");
88*cb5caa98Sdjl 	(void) printf("%10d  server debug level\n", admin_c.debug_level);
89*cb5caa98Sdjl 	(void) printf("\"%s\"  is server log file\n", admin_c.logfile);
90*cb5caa98Sdjl 
91*cb5caa98Sdjl 	(void) nsc_info(NULL, NULL, admin_c.cache_cfg, admin_c.cache_stats);
92*cb5caa98Sdjl }
93*cb5caa98Sdjl 
94*cb5caa98Sdjl /*ARGSUSED*/
95*cb5caa98Sdjl nscd_rc_t
96*cb5caa98Sdjl _nscd_server_setadmin(nscd_admin_mod_t *set)
97*cb5caa98Sdjl {
98*cb5caa98Sdjl 	nscd_rc_t		rc = NSCD_ADMIN_FAIL_TO_SET;
99*cb5caa98Sdjl 	nscd_cfg_handle_t	*h;
100*cb5caa98Sdjl 	int			i, j;
101*cb5caa98Sdjl 	char			*group = "param-group-cache";
102*cb5caa98Sdjl 	char			*dbname;
103*cb5caa98Sdjl 	nscd_cfg_error_t	*err = NULL;
104*cb5caa98Sdjl 	char			*me = "_nscd_server_setadmin";
105*cb5caa98Sdjl 
106*cb5caa98Sdjl 	if (set == NULL)
107*cb5caa98Sdjl 		set = &admin_mod;
108*cb5caa98Sdjl 
109*cb5caa98Sdjl 	/* one setadmin at a time */
110*cb5caa98Sdjl 	(void) mutex_lock(&mod_lock);
111*cb5caa98Sdjl 
112*cb5caa98Sdjl 	_NSCD_LOG_IF(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_DEBUG) {
113*cb5caa98Sdjl 
114*cb5caa98Sdjl 		_nscd_logit(me, "total_size = %d\n", set->total_size);
115*cb5caa98Sdjl 
116*cb5caa98Sdjl 		_nscd_logit(me, "debug_level_set = %d, debug_level = %d\n",
117*cb5caa98Sdjl 			set->debug_level_set, set->debug_level);
118*cb5caa98Sdjl 
119*cb5caa98Sdjl 		_nscd_logit(me, "logfile_set = %d, logfile = %s\n",
120*cb5caa98Sdjl 			set->logfile_set, *set->logfile == '\0' ?
121*cb5caa98Sdjl 				"" : set->logfile);
122*cb5caa98Sdjl 
123*cb5caa98Sdjl 		_nscd_logit(me, "cache_cfg_num = %d\n",
124*cb5caa98Sdjl 			set->cache_cfg_num);
125*cb5caa98Sdjl 		_nscd_logit(me, "cache_flush_num = %d\n",
126*cb5caa98Sdjl 			set->cache_flush_num);
127*cb5caa98Sdjl 	}
128*cb5caa98Sdjl 
129*cb5caa98Sdjl 	/*
130*cb5caa98Sdjl 	 *  global admin stuff
131*cb5caa98Sdjl 	 */
132*cb5caa98Sdjl 
133*cb5caa98Sdjl 	if (set->debug_level_set == nscd_true) {
134*cb5caa98Sdjl 		if (_nscd_set_debug_level(set->debug_level)
135*cb5caa98Sdjl 			!= NSCD_SUCCESS) {
136*cb5caa98Sdjl 
137*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
138*cb5caa98Sdjl 			(me, "unable to set debug level %d\n",
139*cb5caa98Sdjl 				set->debug_level);
140*cb5caa98Sdjl 
141*cb5caa98Sdjl 			goto err_exit;
142*cb5caa98Sdjl 		}
143*cb5caa98Sdjl 		admin_c.debug_level = set->debug_level;
144*cb5caa98Sdjl 	}
145*cb5caa98Sdjl 
146*cb5caa98Sdjl 	if (set->logfile_set == nscd_true) {
147*cb5caa98Sdjl 		if (_nscd_set_log_file(set->logfile) != NSCD_SUCCESS) {
148*cb5caa98Sdjl 
149*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
150*cb5caa98Sdjl 			(me, "unable to set log file %s\n", set->logfile);
151*cb5caa98Sdjl 
152*cb5caa98Sdjl 			goto err_exit;
153*cb5caa98Sdjl 		}
154*cb5caa98Sdjl 		(void) strlcpy(admin_c.logfile, set->logfile,
155*cb5caa98Sdjl 				NSCD_LOGFILE_LEN);
156*cb5caa98Sdjl 	}
157*cb5caa98Sdjl 
158*cb5caa98Sdjl 	/*
159*cb5caa98Sdjl 	 *  For caches to be changed
160*cb5caa98Sdjl 	 */
161*cb5caa98Sdjl 	if (set->cache_cfg_num > CACHE_CTX_COUNT) {
162*cb5caa98Sdjl 
163*cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
164*cb5caa98Sdjl 		(me, "number of caches (%d) to change out of bound %s\n",
165*cb5caa98Sdjl 			set->cache_cfg_num);
166*cb5caa98Sdjl 
167*cb5caa98Sdjl 		goto err_exit;
168*cb5caa98Sdjl 	}
169*cb5caa98Sdjl 
170*cb5caa98Sdjl 	for (i = 0; i < set->cache_cfg_num; i++) {
171*cb5caa98Sdjl 
172*cb5caa98Sdjl 		nscd_cfg_cache_t *new_cfg;
173*cb5caa98Sdjl 
174*cb5caa98Sdjl 		j = set->cache_cfg_set[i];
175*cb5caa98Sdjl 		new_cfg = &set->cache_cfg[i];
176*cb5caa98Sdjl 		dbname = cache_name[j];
177*cb5caa98Sdjl 		if (cache_ctx_p[j] == NULL) {
178*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
179*cb5caa98Sdjl 			(me, "unable to find cache context for %s\n",
180*cb5caa98Sdjl 			dbname);
181*cb5caa98Sdjl 		}
182*cb5caa98Sdjl 
183*cb5caa98Sdjl 		rc = _nscd_cfg_get_handle(group, dbname, &h, NULL);
184*cb5caa98Sdjl 		if (rc != NSCD_SUCCESS) {
185*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
186*cb5caa98Sdjl 			(me, "unable to get handle for < %s : %s >\n",
187*cb5caa98Sdjl 			dbname, group);
188*cb5caa98Sdjl 
189*cb5caa98Sdjl 			goto err_exit;
190*cb5caa98Sdjl 		}
191*cb5caa98Sdjl 
192*cb5caa98Sdjl 		rc = _nscd_cfg_set(h, new_cfg, &err);
193*cb5caa98Sdjl 		if (rc != NSCD_SUCCESS) {
194*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
195*cb5caa98Sdjl 			(me, "unable to set admin data for < %s : %s >\n",
196*cb5caa98Sdjl 			dbname, group);
197*cb5caa98Sdjl 
198*cb5caa98Sdjl 			_nscd_cfg_free_handle(h);
199*cb5caa98Sdjl 
200*cb5caa98Sdjl 			goto err_exit;
201*cb5caa98Sdjl 		}
202*cb5caa98Sdjl 		_nscd_cfg_free_handle(h);
203*cb5caa98Sdjl 	}
204*cb5caa98Sdjl 
205*cb5caa98Sdjl 	/*
206*cb5caa98Sdjl 	 *  For caches to be flushed
207*cb5caa98Sdjl 	 */
208*cb5caa98Sdjl 	if (set->cache_flush_num > CACHE_CTX_COUNT) {
209*cb5caa98Sdjl 
210*cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
211*cb5caa98Sdjl 		(me, "number of caches (%d) to flush out of bound %s\n",
212*cb5caa98Sdjl 			set->cache_flush_num);
213*cb5caa98Sdjl 
214*cb5caa98Sdjl 		goto err_exit;
215*cb5caa98Sdjl 	}
216*cb5caa98Sdjl 
217*cb5caa98Sdjl 	for (i = 0; i < set->cache_flush_num; i++) {
218*cb5caa98Sdjl 		int j;
219*cb5caa98Sdjl 
220*cb5caa98Sdjl 		j = set->cache_flush_set[i];
221*cb5caa98Sdjl 
222*cb5caa98Sdjl 		if (cache_ctx_p[j] == NULL) {
223*cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
224*cb5caa98Sdjl 			(me, "unable to find cache context for %s\n",
225*cb5caa98Sdjl 			dbname);
226*cb5caa98Sdjl 		}
227*cb5caa98Sdjl 		nsc_invalidate(cache_ctx_p[j], NULL, NULL);
228*cb5caa98Sdjl 	}
229*cb5caa98Sdjl 
230*cb5caa98Sdjl 	rc = NSCD_SUCCESS;
231*cb5caa98Sdjl 	err_exit:
232*cb5caa98Sdjl 
233*cb5caa98Sdjl 	(void) mutex_unlock(&mod_lock);
234*cb5caa98Sdjl 	return (rc);
235*cb5caa98Sdjl }
236*cb5caa98Sdjl 
237*cb5caa98Sdjl 
238*cb5caa98Sdjl /*ARGSUSED*/
239*cb5caa98Sdjl void
240*cb5caa98Sdjl _nscd_door_setadmin(void *buf)
241*cb5caa98Sdjl {
242*cb5caa98Sdjl 	nscd_rc_t	rc;
243*cb5caa98Sdjl 	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
244*cb5caa98Sdjl 	char		*me = "_nscd_door_setadmin";
245*cb5caa98Sdjl 
246*cb5caa98Sdjl 	rc = _nscd_server_setadmin(NSCD_N2N_DOOR_DATA(nscd_admin_mod_t, buf));
247*cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
248*cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_ADMIN, NSCD_LOG_LEVEL_ERROR)
249*cb5caa98Sdjl 		(me, "SETADMIN call failed\n");
250*cb5caa98Sdjl 
251*cb5caa98Sdjl 		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0, rc);
252*cb5caa98Sdjl 	} else {
253*cb5caa98Sdjl 		NSCD_RETURN_STATUS_SUCCESS(phdr);
254*cb5caa98Sdjl 	}
255*cb5caa98Sdjl }
256*cb5caa98Sdjl 
257*cb5caa98Sdjl /*
258*cb5caa98Sdjl  * for a database 'dbname', add config value 'val' of option 'opt'
259*cb5caa98Sdjl  * to the global admin_mod structure
260*cb5caa98Sdjl  */
261*cb5caa98Sdjl int
262*cb5caa98Sdjl _nscd_add_admin_mod(char *dbname, char opt,
263*cb5caa98Sdjl 	char *val, char *msg, int msglen) {
264*cb5caa98Sdjl 	int			i, j;
265*cb5caa98Sdjl 	nscd_cfg_cache_t	*cfg;
266*cb5caa98Sdjl 	nscd_cfg_group_info_t	gi = NSCD_CFG_GROUP_INFO_CACHE;
267*cb5caa98Sdjl 	char			dbn[64], *cp;
268*cb5caa98Sdjl 
269*cb5caa98Sdjl 	/* set initial admin_mod size; assume no cache config to set */
270*cb5caa98Sdjl 	if (admin_mod.total_size == 0)
271*cb5caa98Sdjl 		admin_mod.total_size = sizeof (admin_mod) -
272*cb5caa98Sdjl 			sizeof (admin_mod.cache_cfg);
273*cb5caa98Sdjl 
274*cb5caa98Sdjl 	/* global admin stuff */
275*cb5caa98Sdjl 	if (opt == 'l' || opt == 'd') {
276*cb5caa98Sdjl 		if (opt == 'l') {
277*cb5caa98Sdjl 			(void) strlcpy(admin_mod.logfile,
278*cb5caa98Sdjl 				val, NSCD_LOGFILE_LEN);
279*cb5caa98Sdjl 			admin_mod.logfile_set = nscd_true;
280*cb5caa98Sdjl 		} else {
281*cb5caa98Sdjl 			admin_mod.debug_level = atoi(val);
282*cb5caa98Sdjl 			admin_mod.debug_level_set = nscd_true;
283*cb5caa98Sdjl 		}
284*cb5caa98Sdjl 		return (0);
285*cb5caa98Sdjl 	}
286*cb5caa98Sdjl 
287*cb5caa98Sdjl 	/* options to be processed next requires cache name */
288*cb5caa98Sdjl 	(void) strlcpy(dbn, dbname, sizeof (dbn));
289*cb5caa98Sdjl 	if ((cp = strchr(dbn, ',')) != NULL)
290*cb5caa98Sdjl 		*cp = '\0';
291*cb5caa98Sdjl 	i = get_cache_idx(dbn);
292*cb5caa98Sdjl 	if (i == -1) {
293*cb5caa98Sdjl 		(void) snprintf(msg, msglen,
294*cb5caa98Sdjl 			gettext("invalid cache name \"%s\""), dbn);
295*cb5caa98Sdjl 		return (-1);
296*cb5caa98Sdjl 	}
297*cb5caa98Sdjl 
298*cb5caa98Sdjl 	/* flush cache ? */
299*cb5caa98Sdjl 	if (opt == 'i') {
300*cb5caa98Sdjl 		admin_mod.cache_flush_set[admin_mod.cache_flush_num++] = i;
301*cb5caa98Sdjl 		return (0);
302*cb5caa98Sdjl 	}
303*cb5caa98Sdjl 
304*cb5caa98Sdjl 	/* options to be processed next requires a param value */
305*cb5caa98Sdjl 	if (val == NULL) {
306*cb5caa98Sdjl 		(void) snprintf(msg, msglen,
307*cb5caa98Sdjl 			gettext("value missing after \"%s\""), dbn);
308*cb5caa98Sdjl 		return (-1);
309*cb5caa98Sdjl 	}
310*cb5caa98Sdjl 
311*cb5caa98Sdjl 	/* try to use an existing cache_cfg in admin_mod */
312*cb5caa98Sdjl 	for (j = 0; j < admin_mod.cache_cfg_num; j++) {
313*cb5caa98Sdjl 		if (admin_mod.cache_cfg_set[j] == i)
314*cb5caa98Sdjl 			break;
315*cb5caa98Sdjl 	}
316*cb5caa98Sdjl 
317*cb5caa98Sdjl 	/* no existing one, set up another one */
318*cb5caa98Sdjl 	if (j == admin_mod.cache_cfg_num) {
319*cb5caa98Sdjl 		admin_mod.cache_cfg_set[j] = i;
320*cb5caa98Sdjl 		admin_mod.cache_cfg_num++;
321*cb5caa98Sdjl 		admin_mod.total_size += sizeof (admin_mod.cache_cfg[0]);
322*cb5caa98Sdjl 	}
323*cb5caa98Sdjl 
324*cb5caa98Sdjl 	cfg = &admin_mod.cache_cfg[j];
325*cb5caa98Sdjl 	cfg->gi.num_param = gi.num_param;
326*cb5caa98Sdjl 
327*cb5caa98Sdjl 	switch (opt) {
328*cb5caa98Sdjl 
329*cb5caa98Sdjl 	case 'e':
330*cb5caa98Sdjl 		/* enable cache */
331*cb5caa98Sdjl 
332*cb5caa98Sdjl 		_nscd_cfg_bitmap_set_nth(cfg->gi.bitmap, 0);
333*cb5caa98Sdjl 		if (strcmp(val, "yes") == 0)
334*cb5caa98Sdjl 		    cfg->enable = nscd_true;
335*cb5caa98Sdjl 		else if (strcmp(val, "no") == 0)
336*cb5caa98Sdjl 		    cfg->enable = nscd_false;
337*cb5caa98Sdjl 		else {
338*cb5caa98Sdjl 			(void) snprintf(msg, msglen,
339*cb5caa98Sdjl 	gettext("\"yes\" or \"no\" not specified after \"%s\""), dbn);
340*cb5caa98Sdjl 			return (-1);
341*cb5caa98Sdjl 		}
342*cb5caa98Sdjl 		break;
343*cb5caa98Sdjl 
344*cb5caa98Sdjl 	case 'c':
345*cb5caa98Sdjl 		/* check files */
346*cb5caa98Sdjl 
347*cb5caa98Sdjl 		_nscd_cfg_bitmap_set_nth(cfg->gi.bitmap, 3);
348*cb5caa98Sdjl 		if (strcmp(val, "yes") == 0)
349*cb5caa98Sdjl 		    cfg->check_files = nscd_true;
350*cb5caa98Sdjl 		else if (strcmp(val, "no") == 0)
351*cb5caa98Sdjl 		    cfg->check_files = nscd_false;
352*cb5caa98Sdjl 		else {
353*cb5caa98Sdjl 			(void) snprintf(msg, msglen,
354*cb5caa98Sdjl 	gettext("\"yes\" or \"no\" not specified after \"%s\""), dbn);
355*cb5caa98Sdjl 			return (-1);
356*cb5caa98Sdjl 		}
357*cb5caa98Sdjl 		break;
358*cb5caa98Sdjl 
359*cb5caa98Sdjl 	case 'p':
360*cb5caa98Sdjl 		/* positive time to live */
361*cb5caa98Sdjl 
362*cb5caa98Sdjl 		_nscd_cfg_bitmap_set_nth(cfg->gi.bitmap, 5);
363*cb5caa98Sdjl 		cfg->pos_ttl = atoi(val);
364*cb5caa98Sdjl 		break;
365*cb5caa98Sdjl 
366*cb5caa98Sdjl 	case 'n':
367*cb5caa98Sdjl 		/* negative time to live */
368*cb5caa98Sdjl 
369*cb5caa98Sdjl 		_nscd_cfg_bitmap_set_nth(cfg->gi.bitmap, 6);
370*cb5caa98Sdjl 		cfg->neg_ttl = atoi(val);
371*cb5caa98Sdjl 		break;
372*cb5caa98Sdjl 
373*cb5caa98Sdjl 	case 'h':
374*cb5caa98Sdjl 		/* keep hot count */
375*cb5caa98Sdjl 
376*cb5caa98Sdjl 		_nscd_cfg_bitmap_set_nth(cfg->gi.bitmap, 7);
377*cb5caa98Sdjl 		cfg->keephot = atoi(val);
378*cb5caa98Sdjl 		break;
379*cb5caa98Sdjl 	}
380*cb5caa98Sdjl 
381*cb5caa98Sdjl 	return (0);
382*cb5caa98Sdjl }
383*cb5caa98Sdjl 
384*cb5caa98Sdjl int
385*cb5caa98Sdjl _nscd_client_getadmin(char opt)
386*cb5caa98Sdjl {
387*cb5caa98Sdjl 	int		callnum;
388*cb5caa98Sdjl 	nss_pheader_t	phdr;
389*cb5caa98Sdjl 
390*cb5caa98Sdjl 	if (opt == 'G')
391*cb5caa98Sdjl 		callnum = NSCD_GETPUADMIN;
392*cb5caa98Sdjl 	else
393*cb5caa98Sdjl 		callnum = NSCD_GETADMIN;
394*cb5caa98Sdjl 
395*cb5caa98Sdjl 	(void) _nscd_doorcall_data(callnum, NULL, sizeof (admin_c),
396*cb5caa98Sdjl 		&admin_c, sizeof (admin_c), &phdr);
397*cb5caa98Sdjl 
398*cb5caa98Sdjl 	if (NSCD_STATUS_IS_NOT_OK(&phdr)) {
399*cb5caa98Sdjl 		return (1);
400*cb5caa98Sdjl 	}
401*cb5caa98Sdjl 
402*cb5caa98Sdjl 	return (0);
403*cb5caa98Sdjl }
404*cb5caa98Sdjl 
405*cb5caa98Sdjl int
406*cb5caa98Sdjl _nscd_client_setadmin()
407*cb5caa98Sdjl {
408*cb5caa98Sdjl 	return (_nscd_doorcall_data(NSCD_SETADMIN, &admin_mod,
409*cb5caa98Sdjl 		sizeof (admin_mod), NULL, 0, NULL));
410*cb5caa98Sdjl }
411