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