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