Home | History | Annotate | Line # | Download | only in rpc.pcnfsd
pcnfsd_v2.c revision 1.13
      1  1.13      apb /*	$NetBSD: pcnfsd_v2.c,v 1.13 2014/03/29 18:54:36 apb Exp $	*/
      2   1.2      gwr 
      3   1.1      jtc /* RE_SID: @(%)/usr/dosnfs/shades_SCCS/unix/pcnfsd/v2/src/SCCS/s.pcnfsd_v2.c 1.2 91/12/18 13:26:13 SMI */
      4   1.1      jtc /*
      5   1.1      jtc **=====================================================================
      6   1.1      jtc ** Copyright (c) 1986,1987,1988,1989,1990,1991 by Sun Microsystems, Inc.
      7   1.1      jtc **	@(#)pcnfsd_v2.c	1.2	12/18/91
      8   1.1      jtc **=====================================================================
      9   1.1      jtc */
     10   1.1      jtc /*
     11   1.1      jtc **=====================================================================
     12   1.1      jtc **             I N C L U D E   F I L E   S E C T I O N                *
     13   1.1      jtc **                                                                    *
     14   1.1      jtc ** If your port requires different include files, add a suitable      *
     15   1.1      jtc ** #define in the customization section, and make the inclusion or    *
     16   1.1      jtc ** exclusion of the files conditional on this.                        *
     17   1.1      jtc **=====================================================================
     18   1.1      jtc */
     19   1.1      jtc 
     20   1.1      jtc #include <sys/file.h>
     21   1.6    lukem #include <sys/ioctl.h>
     22   1.1      jtc #include <sys/stat.h>
     23   1.6    lukem 
     24   1.6    lukem #include <grp.h>
     25   1.1      jtc #include <netdb.h>
     26   1.6    lukem #include <pwd.h>
     27   1.6    lukem #include <signal.h>
     28   1.6    lukem #include <stdio.h>
     29   1.6    lukem #include <stdlib.h>
     30   1.1      jtc #include <string.h>
     31   1.6    lukem #include <unistd.h>
     32   1.1      jtc 
     33   1.1      jtc #ifdef USE_YP
     34   1.1      jtc #include <rpcsvc/ypclnt.h>
     35   1.1      jtc #endif
     36   1.1      jtc 
     37   1.1      jtc #ifndef SYSV
     38   1.1      jtc #include <sys/wait.h>
     39   1.1      jtc #endif
     40   1.1      jtc 
     41   1.1      jtc #ifdef ISC_2_0
     42   1.1      jtc #include <sys/fcntl.h>
     43   1.1      jtc #endif
     44   1.1      jtc 
     45   1.1      jtc #ifdef SHADOW_SUPPORT
     46   1.1      jtc #include <shadow.h>
     47   1.1      jtc #endif
     48   1.1      jtc 
     49   1.6    lukem #include "common.h"
     50   1.6    lukem #include "pcnfsd.h"
     51   1.6    lukem #include "extern.h"
     52   1.1      jtc 
     53   1.1      jtc /*
     54   1.1      jtc **=====================================================================
     55   1.4      gwr **                      C O D E   S E C T I O N                       *
     56   1.4      gwr **=====================================================================
     57   1.1      jtc */
     58   1.1      jtc 
     59   1.1      jtc 
     60   1.1      jtc static char no_comment[] = "No comment";
     61   1.1      jtc static char not_supported[] = "Not supported";
     62   1.1      jtc static char pcnfsd_version[] = "@(#)pcnfsd_v2.c	1.2 - rpc.pcnfsd V2.0 (c) 1991 Sun Technology Enterprises, Inc.";
     63   1.1      jtc 
     64   1.1      jtc /*ARGSUSED*/
     65   1.6    lukem void   *
     66   1.6    lukem pcnfsd2_null_2_svc(arg, req)
     67   1.6    lukem 	void   *arg;
     68   1.6    lukem 	struct svc_req *req;
     69   1.6    lukem {
     70   1.6    lukem 	static char dummy;
     71   1.6    lukem 	return ((void *) &dummy);
     72   1.6    lukem }
     73   1.6    lukem 
     74   1.6    lukem v2_auth_results *
     75   1.6    lukem pcnfsd2_auth_2_svc(arg, req)
     76   1.6    lukem 	v2_auth_args *arg;
     77   1.6    lukem 	struct svc_req *req;
     78   1.6    lukem {
     79   1.6    lukem 	static v2_auth_results r;
     80   1.6    lukem 
     81   1.6    lukem 	char    uname[32];
     82   1.6    lukem 	char    pw[64];
     83   1.6    lukem 	int     c1, c2;
     84   1.6    lukem 	struct passwd *p;
     85   1.6    lukem 	static u_int extra_gids[EXTRAGIDLEN];
     86   1.6    lukem 	static char home[256];
     87   1.1      jtc #ifdef USE_YP
     88   1.6    lukem 	char   *yphome;
     89   1.6    lukem 	char   *cp;
     90   1.6    lukem #endif				/* USE_YP */
     91   1.1      jtc 
     92   1.1      jtc 
     93   1.1      jtc 	r.stat = AUTH_RES_FAIL;	/* assume failure */
     94   1.6    lukem 	r.uid = (int) -2;
     95   1.6    lukem 	r.gid = (int) -2;
     96   1.1      jtc 	r.cm = &no_comment[0];
     97   1.1      jtc 	r.gids.gids_len = 0;
     98   1.1      jtc 	r.gids.gids_val = &extra_gids[0];
     99   1.1      jtc 	home[0] = '\0';
    100   1.1      jtc 	r.home = &home[0];
    101   1.1      jtc 	r.def_umask = umask(0);
    102   1.6    lukem 	(void) umask(r.def_umask);	/* or use 022 */
    103   1.1      jtc 
    104   1.1      jtc 	scramble(arg->id, uname);
    105   1.1      jtc 	scramble(arg->pw, pw);
    106   1.1      jtc 
    107   1.1      jtc #ifdef USER_CACHE
    108   1.6    lukem 	if (check_cache(uname, pw, &r.uid, &r.gid)) {
    109   1.6    lukem 		r.stat = AUTH_RES_OK;
    110   1.1      jtc #ifdef WTMP
    111   1.1      jtc 		wlogin(uname, req);
    112   1.1      jtc #endif
    113   1.6    lukem 		fillin_extra_groups
    114   1.6    lukem 		    (uname, r.gid, &r.gids.gids_len, extra_gids);
    115   1.1      jtc #ifdef USE_YP
    116   1.1      jtc 		yphome = find_entry(uname, "auto.home");
    117   1.6    lukem 		if (yphome) {
    118   1.9   itojun 			strlcpy(home, yphome, sizeof(home));
    119   1.1      jtc 			free(yphome);
    120   1.1      jtc 			cp = strchr(home, ':');
    121   1.1      jtc 			cp++;
    122   1.1      jtc 			cp = strchr(cp, ':');
    123   1.6    lukem 			if (cp)
    124   1.1      jtc 				*cp = '/';
    125   1.1      jtc 		}
    126   1.1      jtc #endif
    127   1.6    lukem 		return (&r);
    128   1.6    lukem 	}
    129   1.1      jtc #endif
    130   1.1      jtc 
    131   1.1      jtc 	p = get_password(uname);
    132  1.11   plunky 	if (p == NULL)
    133   1.6    lukem 		return (&r);
    134   1.1      jtc 
    135   1.1      jtc 	c1 = strlen(pw);
    136   1.1      jtc 	c2 = strlen(p->pw_passwd);
    137   1.1      jtc 	if ((c1 && !c2) || (c2 && !c1) ||
    138   1.6    lukem 	    (strcmp(p->pw_passwd, crypt(pw, p->pw_passwd)))) {
    139   1.6    lukem 		return (&r);
    140   1.6    lukem 	}
    141   1.1      jtc 	r.stat = AUTH_RES_OK;
    142   1.1      jtc 	r.uid = p->pw_uid;
    143   1.1      jtc 	r.gid = p->pw_gid;
    144   1.1      jtc #ifdef WTMP
    145   1.1      jtc 	wlogin(uname, req);
    146   1.1      jtc #endif
    147   1.6    lukem 	fillin_extra_groups(uname, r.gid, &r.gids.gids_len, extra_gids);
    148   1.1      jtc 
    149   1.1      jtc #ifdef USE_YP
    150   1.1      jtc 	yphome = find_entry(uname, "auto.home");
    151   1.6    lukem 	if (yphome) {
    152   1.9   itojun 		strlcpy(home, yphome, sizeof(home));
    153   1.1      jtc 		free(yphome);
    154   1.1      jtc 		cp = strchr(home, ':');
    155   1.1      jtc 		cp++;
    156   1.1      jtc 		cp = strchr(cp, ':');
    157   1.6    lukem 		if (cp)
    158   1.1      jtc 			*cp = '/';
    159   1.1      jtc 	}
    160   1.1      jtc #endif
    161   1.1      jtc 
    162   1.1      jtc #ifdef USER_CACHE
    163   1.1      jtc 	add_cache_entry(p);
    164   1.1      jtc #endif
    165   1.1      jtc 
    166   1.6    lukem 	return (&r);
    167   1.1      jtc 
    168   1.1      jtc }
    169   1.1      jtc 
    170   1.6    lukem v2_pr_init_results *
    171   1.6    lukem pcnfsd2_pr_init_2_svc(arg, req)
    172   1.6    lukem 	v2_pr_init_args *arg;
    173   1.6    lukem 	struct svc_req *req;
    174   1.1      jtc {
    175   1.6    lukem 	static v2_pr_init_results res;
    176   1.1      jtc 
    177   1.6    lukem 	res.stat =
    178   1.6    lukem 	    (pirstat) pr_init(arg->system, arg->pn, &res.dir);
    179   1.1      jtc 	res.cm = &no_comment[0];
    180   1.1      jtc 
    181   1.1      jtc 
    182   1.6    lukem 	return (&res);
    183   1.1      jtc }
    184   1.1      jtc 
    185   1.6    lukem v2_pr_start_results *
    186   1.6    lukem pcnfsd2_pr_start_2_svc(arg, req)
    187   1.6    lukem 	v2_pr_start_args *arg;
    188   1.6    lukem 	struct svc_req *req;
    189   1.1      jtc {
    190   1.6    lukem 	static v2_pr_start_results res;
    191   1.1      jtc 
    192   1.1      jtc 	res.stat =
    193   1.6    lukem 	    (psrstat) pr_start2(arg->system, arg->pn, arg->user,
    194   1.6    lukem 	    arg->file, arg->opts, &res.id);
    195   1.1      jtc 	res.cm = &no_comment[0];
    196   1.1      jtc 
    197   1.6    lukem 	return (&res);
    198   1.1      jtc }
    199   1.1      jtc /*ARGSUSED*/
    200   1.6    lukem v2_pr_list_results *
    201   1.6    lukem pcnfsd2_pr_list_2_svc(arg, req)
    202   1.6    lukem 	void   *arg;
    203   1.6    lukem 	struct svc_req *req;
    204   1.1      jtc {
    205   1.6    lukem 	static v2_pr_list_results res;
    206   1.1      jtc 
    207   1.6    lukem 	if (printers == NULL)
    208   1.6    lukem 		(void) build_pr_list();
    209   1.1      jtc 	res.cm = &no_comment[0];
    210   1.1      jtc 	res.printers = printers;
    211   1.1      jtc 
    212   1.6    lukem 	return (&res);
    213   1.1      jtc }
    214   1.1      jtc 
    215   1.6    lukem v2_pr_queue_results *
    216   1.6    lukem pcnfsd2_pr_queue_2_svc(arg, req)
    217   1.6    lukem 	v2_pr_queue_args *arg;
    218   1.6    lukem 	struct svc_req *req;
    219   1.1      jtc {
    220   1.6    lukem 	static v2_pr_queue_results res;
    221   1.1      jtc 
    222   1.1      jtc 	res.stat = build_pr_queue(arg->pn, arg->user,
    223   1.6    lukem 	    arg->just_mine, &res.qlen, &res.qshown);
    224   1.1      jtc 	res.cm = &no_comment[0];
    225   1.1      jtc 	res.just_yours = arg->just_mine;
    226   1.1      jtc 	res.jobs = queue;
    227   1.1      jtc 
    228   1.6    lukem 
    229   1.6    lukem 	return (&res);
    230   1.1      jtc }
    231   1.1      jtc 
    232   1.6    lukem v2_pr_status_results *
    233   1.6    lukem pcnfsd2_pr_status_2_svc(arg, req)
    234   1.6    lukem 	v2_pr_status_args *arg;
    235   1.6    lukem 	struct svc_req *req;
    236   1.1      jtc {
    237   1.6    lukem 	static v2_pr_status_results res;
    238   1.6    lukem 	static char status[128];
    239   1.1      jtc 
    240   1.1      jtc 	res.stat = get_pr_status(arg->pn, &res.avail, &res.printing,
    241  1.13      apb 	    &res.qlen, &res.needs_operator, &status[0], sizeof(status));
    242   1.6    lukem 	res.status = &status[0];
    243   1.1      jtc 	res.cm = &no_comment[0];
    244   1.1      jtc 
    245   1.6    lukem 	return (&res);
    246   1.1      jtc }
    247   1.1      jtc 
    248   1.6    lukem v2_pr_cancel_results *
    249   1.6    lukem pcnfsd2_pr_cancel_2_svc(arg, req)
    250   1.6    lukem 	v2_pr_cancel_args *arg;
    251   1.6    lukem 	struct svc_req *req;
    252   1.1      jtc {
    253   1.6    lukem 	static v2_pr_cancel_results res;
    254   1.1      jtc 
    255   1.1      jtc 	res.stat = pr_cancel(arg->pn, arg->user, arg->id);
    256   1.1      jtc 	res.cm = &no_comment[0];
    257   1.1      jtc 
    258   1.6    lukem 	return (&res);
    259   1.1      jtc }
    260   1.1      jtc /*ARGSUSED*/
    261   1.6    lukem v2_pr_requeue_results *
    262   1.6    lukem pcnfsd2_pr_requeue_2_svc(arg, req)
    263   1.6    lukem 	v2_pr_requeue_args *arg;
    264   1.6    lukem 	struct svc_req *req;
    265   1.1      jtc {
    266   1.6    lukem 	static v2_pr_requeue_results res;
    267   1.1      jtc 	res.stat = PC_RES_FAIL;
    268   1.1      jtc 	res.cm = &not_supported[0];
    269   1.1      jtc 
    270   1.6    lukem 	return (&res);
    271   1.1      jtc }
    272   1.1      jtc /*ARGSUSED*/
    273   1.6    lukem v2_pr_hold_results *
    274   1.6    lukem pcnfsd2_pr_hold_2_svc(arg, req)
    275   1.6    lukem 	v2_pr_hold_args *arg;
    276   1.6    lukem 	struct svc_req *req;
    277   1.1      jtc {
    278   1.6    lukem 	static v2_pr_hold_results res;
    279   1.1      jtc 
    280   1.1      jtc 	res.stat = PC_RES_FAIL;
    281   1.1      jtc 	res.cm = &not_supported[0];
    282   1.1      jtc 
    283   1.6    lukem 	return (&res);
    284   1.1      jtc }
    285   1.1      jtc /*ARGSUSED*/
    286   1.6    lukem v2_pr_release_results *
    287   1.6    lukem pcnfsd2_pr_release_2_svc(arg, req)
    288   1.6    lukem 	v2_pr_release_args *arg;
    289   1.6    lukem 	struct svc_req *req;
    290   1.1      jtc {
    291   1.6    lukem 	static v2_pr_release_results res;
    292   1.1      jtc 
    293   1.1      jtc 	res.stat = PC_RES_FAIL;
    294   1.1      jtc 	res.cm = &not_supported[0];
    295   1.1      jtc 
    296   1.6    lukem 	return (&res);
    297   1.1      jtc }
    298   1.1      jtc /*ARGSUSED*/
    299   1.6    lukem v2_pr_admin_results *
    300   1.6    lukem pcnfsd2_pr_admin_2_svc(arg, req)
    301   1.6    lukem 	v2_pr_admin_args *arg;
    302   1.6    lukem 	struct svc_req *req;
    303   1.1      jtc {
    304   1.6    lukem 	static v2_pr_admin_results res;
    305   1.1      jtc /*
    306   1.1      jtc ** The default action for admin is to fail.
    307   1.1      jtc ** If someone wishes to implement an administration
    308   1.1      jtc ** mechanism, and isn't worried about the security
    309   1.1      jtc ** holes, go right ahead.
    310   1.1      jtc */
    311   1.1      jtc 
    312   1.1      jtc 	res.cm = &not_supported[0];
    313   1.1      jtc 	res.stat = PI_RES_FAIL;
    314   1.1      jtc 
    315   1.6    lukem 	return (&res);
    316   1.1      jtc }
    317   1.1      jtc 
    318   1.1      jtc void
    319   1.1      jtc free_mapreq_results(p)
    320   1.6    lukem 	mapreq_res p;
    321   1.1      jtc {
    322   1.6    lukem 	if (p->mapreq_next)
    323   1.6    lukem 		free_mapreq_results(p->mapreq_next);	/* recurse */
    324   1.6    lukem 	if (p->name)
    325   1.6    lukem 		(void) free(p->name);
    326   1.6    lukem 	(void) free(p);
    327   1.1      jtc 	return;
    328   1.1      jtc }
    329   1.1      jtc 
    330   1.7  mycroft static char *my_strdup __P((const char *));
    331   1.6    lukem 
    332   1.1      jtc static char *
    333   1.1      jtc my_strdup(s)
    334   1.7  mycroft 	const char   *s;
    335   1.1      jtc {
    336  1.12    joerg 	size_t len;
    337   1.6    lukem 	char   *r;
    338  1.12    joerg 	len = strlen(s);
    339  1.12    joerg 	r = (char *) grab(len + 1);
    340  1.12    joerg 	memcpy(r, s, len + 1);
    341   1.6    lukem 	return (r);
    342   1.1      jtc }
    343   1.1      jtc 
    344   1.6    lukem v2_mapid_results *
    345   1.6    lukem pcnfsd2_mapid_2_svc(arg, req)
    346   1.6    lukem 	v2_mapid_args *arg;
    347   1.6    lukem 	struct svc_req *req;
    348   1.1      jtc {
    349   1.6    lukem 	static v2_mapid_results res;
    350   1.6    lukem 	struct passwd *p_passwd;
    351   1.6    lukem 	struct group *p_group;
    352   1.1      jtc 
    353   1.6    lukem 	mapreq_arg a;
    354   1.6    lukem 	mapreq_res next_r;
    355   1.6    lukem 	mapreq_res last_r = NULL;
    356   1.1      jtc 
    357   1.1      jtc 
    358   1.6    lukem 	if (res.res_list) {
    359   1.1      jtc 		free_mapreq_results(res.res_list);
    360   1.1      jtc 		res.res_list = NULL;
    361   1.1      jtc 	}
    362   1.1      jtc 	a = arg->req_list;
    363   1.6    lukem 	while (a) {
    364   1.1      jtc 		next_r = (struct mapreq_res_item *)
    365   1.6    lukem 		    grab(sizeof(struct mapreq_res_item));
    366   1.1      jtc 		next_r->stat = MAP_RES_UNKNOWN;
    367   1.1      jtc 		next_r->req = a->req;
    368   1.1      jtc 		next_r->id = a->id;
    369   1.1      jtc 		next_r->name = NULL;
    370   1.1      jtc 		next_r->mapreq_next = NULL;
    371   1.1      jtc 
    372   1.6    lukem 		if (last_r == NULL)
    373   1.1      jtc 			res.res_list = next_r;
    374   1.1      jtc 		else
    375   1.1      jtc 			last_r->mapreq_next = next_r;
    376   1.1      jtc 		last_r = next_r;
    377   1.6    lukem 		switch (a->req) {
    378   1.1      jtc 		case MAP_REQ_UID:
    379   1.6    lukem 			p_passwd = getpwuid((uid_t) a->id);
    380   1.6    lukem 			if (p_passwd) {
    381   1.1      jtc 				next_r->name = my_strdup(p_passwd->pw_name);
    382   1.1      jtc 				next_r->stat = MAP_RES_OK;
    383   1.1      jtc 			}
    384   1.1      jtc 			break;
    385   1.1      jtc 		case MAP_REQ_GID:
    386   1.6    lukem 			p_group = getgrgid((gid_t) a->id);
    387   1.6    lukem 			if (p_group) {
    388   1.1      jtc 				next_r->name = my_strdup(p_group->gr_name);
    389   1.1      jtc 				next_r->stat = MAP_RES_OK;
    390   1.1      jtc 			}
    391   1.1      jtc 			break;
    392   1.1      jtc 		case MAP_REQ_UNAME:
    393   1.1      jtc 			next_r->name = my_strdup(a->name);
    394   1.1      jtc 			p_passwd = getpwnam(a->name);
    395   1.6    lukem 			if (p_passwd) {
    396   1.1      jtc 				next_r->id = p_passwd->pw_uid;
    397   1.1      jtc 				next_r->stat = MAP_RES_OK;
    398   1.1      jtc 			}
    399   1.1      jtc 			break;
    400   1.1      jtc 		case MAP_REQ_GNAME:
    401   1.1      jtc 			next_r->name = my_strdup(a->name);
    402   1.1      jtc 			p_group = getgrnam(a->name);
    403   1.6    lukem 			if (p_group) {
    404   1.1      jtc 				next_r->id = p_group->gr_gid;
    405   1.1      jtc 				next_r->stat = MAP_RES_OK;
    406   1.1      jtc 			}
    407   1.1      jtc 			break;
    408   1.1      jtc 		}
    409   1.6    lukem 		if (next_r->name == NULL)
    410   1.1      jtc 			next_r->name = my_strdup("");
    411   1.1      jtc 		a = a->mapreq_next;
    412   1.1      jtc 	}
    413   1.1      jtc 
    414   1.1      jtc 	res.cm = &no_comment[0];
    415   1.1      jtc 
    416   1.6    lukem 	return (&res);
    417   1.1      jtc }
    418   1.1      jtc 
    419   1.6    lukem 
    420   1.1      jtc /*ARGSUSED*/
    421   1.6    lukem v2_alert_results *
    422   1.6    lukem pcnfsd2_alert_2_svc(arg, req)
    423   1.6    lukem 	v2_alert_args *arg;
    424   1.6    lukem 	struct svc_req *req;
    425   1.1      jtc {
    426   1.6    lukem 	static v2_alert_results res;
    427   1.1      jtc 
    428   1.1      jtc 	res.stat = ALERT_RES_FAIL;
    429   1.1      jtc 	res.cm = &not_supported[0];
    430   1.1      jtc 
    431   1.6    lukem 	return (&res);
    432   1.1      jtc }
    433   1.1      jtc /*ARGSUSED*/
    434   1.6    lukem v2_info_results *
    435   1.6    lukem pcnfsd2_info_2_svc(arg, req)
    436   1.6    lukem 	v2_info_args *arg;
    437   1.6    lukem 	struct svc_req *req;
    438   1.6    lukem {
    439   1.6    lukem 	static v2_info_results res;
    440   1.6    lukem 	static int facilities[FACILITIESMAX];
    441   1.6    lukem 	static int onetime = 1;
    442   1.1      jtc 
    443   1.1      jtc #define UNSUPPORTED -1
    444   1.1      jtc #define QUICK 100
    445   1.1      jtc #define SLOW 2000
    446   1.1      jtc 
    447   1.6    lukem 	if (onetime) {
    448   1.1      jtc 		onetime = 0;
    449   1.1      jtc 		facilities[PCNFSD2_NULL] = QUICK;
    450   1.1      jtc 		facilities[PCNFSD2_INFO] = QUICK;
    451   1.1      jtc 		facilities[PCNFSD2_PR_INIT] = QUICK;
    452   1.1      jtc 		facilities[PCNFSD2_PR_START] = SLOW;
    453   1.6    lukem 		facilities[PCNFSD2_PR_LIST] = QUICK;	/* except first time */
    454   1.1      jtc 		facilities[PCNFSD2_PR_QUEUE] = SLOW;
    455   1.1      jtc 		facilities[PCNFSD2_PR_STATUS] = SLOW;
    456   1.1      jtc 		facilities[PCNFSD2_PR_CANCEL] = SLOW;
    457   1.1      jtc 		facilities[PCNFSD2_PR_ADMIN] = UNSUPPORTED;
    458   1.1      jtc 		facilities[PCNFSD2_PR_REQUEUE] = UNSUPPORTED;
    459   1.1      jtc 		facilities[PCNFSD2_PR_HOLD] = UNSUPPORTED;
    460   1.1      jtc 		facilities[PCNFSD2_PR_RELEASE] = UNSUPPORTED;
    461   1.1      jtc 		facilities[PCNFSD2_MAPID] = QUICK;
    462   1.1      jtc 		facilities[PCNFSD2_AUTH] = QUICK;
    463   1.1      jtc 		facilities[PCNFSD2_ALERT] = QUICK;
    464   1.1      jtc 	}
    465   1.6    lukem 	res.facilities.facilities_len = PCNFSD2_ALERT + 1;
    466   1.1      jtc 	res.facilities.facilities_val = facilities;
    467   1.6    lukem 
    468   1.1      jtc 	res.vers = &pcnfsd_version[0];
    469   1.1      jtc 	res.cm = &no_comment[0];
    470   1.1      jtc 
    471   1.6    lukem 	return (&res);
    472   1.1      jtc }
    473   1.1      jtc 
    474   1.1      jtc 
    475   1.1      jtc 
    476   1.1      jtc void
    477   1.1      jtc fillin_extra_groups(uname, main_gid, len, extra_gids)
    478   1.6    lukem 	char   *uname;
    479   1.6    lukem 	gid_t   main_gid;
    480   1.6    lukem 	int    *len;
    481   1.6    lukem 	gid_t   extra_gids[EXTRAGIDLEN];
    482   1.6    lukem {
    483   1.6    lukem 	struct group *grp;
    484   1.8  mycroft 	__aconst char *__aconst *members;
    485   1.6    lukem 	int     n = 0;
    486   1.1      jtc 
    487   1.1      jtc 	setgrent();
    488   1.1      jtc 
    489   1.6    lukem 	while (n < EXTRAGIDLEN) {
    490   1.1      jtc 		grp = getgrent();
    491   1.6    lukem 		if (grp == NULL)
    492   1.1      jtc 			break;
    493   1.6    lukem 		if (grp->gr_gid == main_gid)
    494   1.1      jtc 			continue;
    495   1.6    lukem 		for (members = grp->gr_mem; members && *members; members++) {
    496   1.6    lukem 			if (!strcmp(*members, uname)) {
    497   1.1      jtc 				extra_gids[n++] = grp->gr_gid;
    498   1.1      jtc 				break;
    499   1.1      jtc 			}
    500   1.1      jtc 		}
    501   1.1      jtc 	}
    502   1.1      jtc 	endgrent();
    503   1.1      jtc 	*len = n;
    504   1.1      jtc }
    505   1.1      jtc 
    506   1.1      jtc #ifdef USE_YP
    507   1.1      jtc /* the following is from rpcsvc/yp_prot.h */
    508   1.1      jtc #define YPMAXDOMAIN 64
    509   1.6    lukem 
    510   1.1      jtc /*
    511   1.1      jtc  * find_entry returns NULL on any error (printing a message) and
    512   1.1      jtc  * otherwise returns a pointer to the malloc'd result. The caller
    513   1.1      jtc  * is responsible for free()ing the result string.
    514   1.1      jtc  */
    515   1.6    lukem char   *
    516   1.1      jtc find_entry(key, map)
    517  1.10    lukem 	const char   *key;
    518  1.10    lukem 	const char   *map;
    519   1.1      jtc {
    520   1.6    lukem 	int     err;
    521   1.6    lukem 	char   *val = NULL;
    522   1.6    lukem 	char   *cp;
    523   1.6    lukem 	int     len = 0;
    524   1.6    lukem 	static char domain[YPMAXDOMAIN + 1];
    525   1.1      jtc 
    526   1.6    lukem 	if (getdomainname(domain, YPMAXDOMAIN)) {
    527   1.1      jtc 		msg_out("rpc.pcnfsd: getdomainname failed");
    528   1.6    lukem 		return (NULL);
    529   1.1      jtc 	}
    530   1.6    lukem 	if ((err = yp_bind(domain)) != 0) {
    531   1.3      gwr #ifdef	DEBUG
    532   1.1      jtc 		msg_out("rpc.pcnfsd: yp_bind failed");
    533   1.3      gwr #endif
    534   1.6    lukem 		return (NULL);
    535   1.1      jtc 	}
    536   1.1      jtc 	err = yp_match(domain, map, key, strlen(key), &val, &len);
    537   1.1      jtc 
    538   1.1      jtc 	if (err) {
    539   1.1      jtc 		msg_out("rpc.pcnfsd: yp_match failed");
    540   1.5    lukem 		if (val)
    541   1.5    lukem 			free(val);
    542   1.6    lukem 		return (NULL);
    543   1.1      jtc 	}
    544   1.6    lukem 	if ((cp = strchr(val, '\n')) != NULL)
    545   1.6    lukem 		*cp = '\0';	/* in case we get an extra NL at the end */
    546   1.6    lukem 	return (val);
    547   1.1      jtc }
    548   1.1      jtc #endif
    549