140a5f74dSBill Paul /* 240a5f74dSBill Paul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 340a5f74dSBill Paul * unrestricted use provided that this legend is included on all tape 440a5f74dSBill Paul * media and as a part of the software program in whole or part. Users 540a5f74dSBill Paul * may copy or modify Sun RPC without charge, but are not authorized 640a5f74dSBill Paul * to license or distribute it to anyone else except as part of a product or 740a5f74dSBill Paul * program developed by the user or with the express written consent of 840a5f74dSBill Paul * Sun Microsystems, Inc. 940a5f74dSBill Paul * 1040a5f74dSBill Paul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1140a5f74dSBill Paul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1240a5f74dSBill Paul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1340a5f74dSBill Paul * 1440a5f74dSBill Paul * Sun RPC is provided with no support and without any obligation on the 1540a5f74dSBill Paul * part of Sun Microsystems, Inc. to assist in its use, correction, 1640a5f74dSBill Paul * modification or enhancement. 1740a5f74dSBill Paul * 1840a5f74dSBill Paul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1940a5f74dSBill Paul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2040a5f74dSBill Paul * OR ANY PART THEREOF. 2140a5f74dSBill Paul * 2240a5f74dSBill Paul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2340a5f74dSBill Paul * or profits or other special, indirect and consequential damages, even if 2440a5f74dSBill Paul * Sun has been advised of the possibility of such damages. 2540a5f74dSBill Paul * 2640a5f74dSBill Paul * Sun Microsystems, Inc. 2740a5f74dSBill Paul * 2550 Garcia Avenue 2840a5f74dSBill Paul * Mountain View, California 94043 2940a5f74dSBill Paul */ 301e96bb57SPhilippe Charnier 3140a5f74dSBill Paul #ifndef lint 321e96bb57SPhilippe Charnier #if 0 3340a5f74dSBill Paul static char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro"; 3440a5f74dSBill Paul #endif 351e96bb57SPhilippe Charnier static const char rcsid[] = 361e96bb57SPhilippe Charnier "$Id$"; 371e96bb57SPhilippe Charnier #endif /* not lint */ 3840a5f74dSBill Paul 3940a5f74dSBill Paul /* 4040a5f74dSBill Paul * Copyright (C) 1986, 1989, Sun Microsystems, Inc. 4140a5f74dSBill Paul */ 4240a5f74dSBill Paul 4340a5f74dSBill Paul /* 4440a5f74dSBill Paul * Administrative tool to add a new user to the publickey database 4540a5f74dSBill Paul */ 4640a5f74dSBill Paul #include <stdio.h> 4740a5f74dSBill Paul #include <stdlib.h> 4840a5f74dSBill Paul #include <unistd.h> 4940a5f74dSBill Paul #include <rpc/rpc.h> 5040a5f74dSBill Paul #include <rpc/key_prot.h> 5140a5f74dSBill Paul #ifdef YP 5240a5f74dSBill Paul #include <rpcsvc/yp_prot.h> 5340a5f74dSBill Paul #include <rpcsvc/ypclnt.h> 5440a5f74dSBill Paul #include <sys/wait.h> 5540a5f74dSBill Paul #include <netdb.h> 5640a5f74dSBill Paul #endif /* YP */ 5740a5f74dSBill Paul #include <pwd.h> 5840a5f74dSBill Paul #include <string.h> 5940a5f74dSBill Paul #include <sys/resource.h> 6040a5f74dSBill Paul #include <stdlib.h> 6140a5f74dSBill Paul #include "ypupdated_extern.h" 6240a5f74dSBill Paul 6340a5f74dSBill Paul #ifdef YP 6440a5f74dSBill Paul #define MAXMAPNAMELEN 256 6540a5f74dSBill Paul #else 6640a5f74dSBill Paul #define YPOP_CHANGE 1 /* change, do not add */ 6740a5f74dSBill Paul #define YPOP_INSERT 2 /* add, do not change */ 6840a5f74dSBill Paul #define YPOP_DELETE 3 /* delete this entry */ 6940a5f74dSBill Paul #define YPOP_STORE 4 /* add, or change */ 7040a5f74dSBill Paul #endif 7140a5f74dSBill Paul 7240a5f74dSBill Paul #ifdef YP 7340a5f74dSBill Paul static char SHELL[] = "/bin/sh"; 7440a5f74dSBill Paul static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 7540a5f74dSBill Paul static char PKMAP[] = "publickey.byname"; 7640a5f74dSBill Paul static char UPDATEFILE[] = "updaters"; 7740a5f74dSBill Paul static char PKFILE[] = "/etc/publickey"; 7840a5f74dSBill Paul #endif /* YP */ 7940a5f74dSBill Paul 8040a5f74dSBill Paul #ifdef YP 8140a5f74dSBill Paul static int _openchild __P(( char *, FILE **, FILE ** )); 8240a5f74dSBill Paul 8340a5f74dSBill Paul /* 8440a5f74dSBill Paul * Determine if requester is allowed to update the given map, 8540a5f74dSBill Paul * and update it if so. Returns the yp status, which is zero 8640a5f74dSBill Paul * if there is no access violation. 8740a5f74dSBill Paul */ 8840a5f74dSBill Paul mapupdate(requester, mapname, op, keylen, key, datalen, data) 8940a5f74dSBill Paul char *requester; 9040a5f74dSBill Paul char *mapname; 9140a5f74dSBill Paul u_int op; 9240a5f74dSBill Paul u_int keylen; 9340a5f74dSBill Paul char *key; 9440a5f74dSBill Paul u_int datalen; 9540a5f74dSBill Paul char *data; 9640a5f74dSBill Paul { 9740a5f74dSBill Paul char updater[MAXMAPNAMELEN + 40]; 9840a5f74dSBill Paul FILE *childargs; 9940a5f74dSBill Paul FILE *childrslt; 10040a5f74dSBill Paul #ifdef WEXITSTATUS 10140a5f74dSBill Paul int status; 10240a5f74dSBill Paul #else 10340a5f74dSBill Paul union wait status; 10440a5f74dSBill Paul #endif 10540a5f74dSBill Paul pid_t pid; 10640a5f74dSBill Paul u_int yperrno; 10740a5f74dSBill Paul 10840a5f74dSBill Paul 10940a5f74dSBill Paul #ifdef DEBUG 11040a5f74dSBill Paul printf("%s %s\n", key, data); 11140a5f74dSBill Paul #endif 11240a5f74dSBill Paul (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 11340a5f74dSBill Paul UPDATEFILE, mapname); 11440a5f74dSBill Paul pid = _openchild(updater, &childargs, &childrslt); 11540a5f74dSBill Paul if (pid < 0) { 11640a5f74dSBill Paul return (YPERR_YPERR); 11740a5f74dSBill Paul } 11840a5f74dSBill Paul 11940a5f74dSBill Paul /* 12040a5f74dSBill Paul * Write to child 12140a5f74dSBill Paul */ 12240a5f74dSBill Paul (void)fprintf(childargs, "%s\n", requester); 12340a5f74dSBill Paul (void)fprintf(childargs, "%u\n", op); 12440a5f74dSBill Paul (void)fprintf(childargs, "%u\n", keylen); 12540a5f74dSBill Paul (void)fwrite(key, (int)keylen, 1, childargs); 12640a5f74dSBill Paul (void)fprintf(childargs, "\n"); 12740a5f74dSBill Paul (void)fprintf(childargs, "%u\n", datalen); 12840a5f74dSBill Paul (void)fwrite(data, (int)datalen, 1, childargs); 12940a5f74dSBill Paul (void)fprintf(childargs, "\n"); 13040a5f74dSBill Paul (void)fclose(childargs); 13140a5f74dSBill Paul 13240a5f74dSBill Paul /* 13340a5f74dSBill Paul * Read from child 13440a5f74dSBill Paul */ 13540a5f74dSBill Paul (void)fscanf(childrslt, "%d", &yperrno); 13640a5f74dSBill Paul (void)fclose(childrslt); 13740a5f74dSBill Paul 13840a5f74dSBill Paul (void)wait(&status); 13940a5f74dSBill Paul #ifdef WEXITSTATUS 14040a5f74dSBill Paul if (WEXITSTATUS(status) != 0) { 14140a5f74dSBill Paul #else 14240a5f74dSBill Paul if (status.w_retcode != 0) { 14340a5f74dSBill Paul #endif 14440a5f74dSBill Paul return (YPERR_YPERR); 14540a5f74dSBill Paul } 14640a5f74dSBill Paul return (yperrno); 14740a5f74dSBill Paul } 14840a5f74dSBill Paul 14940a5f74dSBill Paul /* 15040a5f74dSBill Paul * returns pid, or -1 for failure 15140a5f74dSBill Paul */ 15240a5f74dSBill Paul static 15340a5f74dSBill Paul _openchild(command, fto, ffrom) 15440a5f74dSBill Paul char *command; 15540a5f74dSBill Paul FILE **fto; 15640a5f74dSBill Paul FILE **ffrom; 15740a5f74dSBill Paul { 15840a5f74dSBill Paul int i; 15940a5f74dSBill Paul pid_t pid; 16040a5f74dSBill Paul int pdto[2]; 16140a5f74dSBill Paul int pdfrom[2]; 16240a5f74dSBill Paul char *com; 16340a5f74dSBill Paul struct rlimit rl; 16440a5f74dSBill Paul 16540a5f74dSBill Paul if (pipe(pdto) < 0) { 16640a5f74dSBill Paul goto error1; 16740a5f74dSBill Paul } 16840a5f74dSBill Paul if (pipe(pdfrom) < 0) { 16940a5f74dSBill Paul goto error2; 17040a5f74dSBill Paul } 17140a5f74dSBill Paul #ifdef VFORK 17240a5f74dSBill Paul switch (pid = vfork()) { 17340a5f74dSBill Paul #else 17440a5f74dSBill Paul switch (pid = fork()) { 17540a5f74dSBill Paul #endif 17640a5f74dSBill Paul case -1: 17740a5f74dSBill Paul goto error3; 17840a5f74dSBill Paul 17940a5f74dSBill Paul case 0: 18040a5f74dSBill Paul /* 18140a5f74dSBill Paul * child: read from pdto[0], write into pdfrom[1] 18240a5f74dSBill Paul */ 18340a5f74dSBill Paul (void)close(0); 18440a5f74dSBill Paul (void)dup(pdto[0]); 18540a5f74dSBill Paul (void)close(1); 18640a5f74dSBill Paul (void)dup(pdfrom[1]); 18740a5f74dSBill Paul getrlimit(RLIMIT_NOFILE, &rl); 18840a5f74dSBill Paul for (i = rl.rlim_max - 1; i >= 3; i--) { 18940a5f74dSBill Paul (void) close(i); 19040a5f74dSBill Paul } 19140a5f74dSBill Paul com = malloc((unsigned) strlen(command) + 6); 19240a5f74dSBill Paul if (com == NULL) { 19340a5f74dSBill Paul _exit(~0); 19440a5f74dSBill Paul } 19540a5f74dSBill Paul (void)sprintf(com, "exec %s", command); 19640a5f74dSBill Paul execl(SHELL, basename(SHELL), "-c", com, NULL); 19740a5f74dSBill Paul _exit(~0); 19840a5f74dSBill Paul 19940a5f74dSBill Paul default: 20040a5f74dSBill Paul /* 20140a5f74dSBill Paul * parent: write into pdto[1], read from pdfrom[0] 20240a5f74dSBill Paul */ 20340a5f74dSBill Paul *fto = fdopen(pdto[1], "w"); 20440a5f74dSBill Paul (void)close(pdto[0]); 20540a5f74dSBill Paul *ffrom = fdopen(pdfrom[0], "r"); 20640a5f74dSBill Paul (void)close(pdfrom[1]); 20740a5f74dSBill Paul break; 20840a5f74dSBill Paul } 20940a5f74dSBill Paul return (pid); 21040a5f74dSBill Paul 21140a5f74dSBill Paul /* 21240a5f74dSBill Paul * error cleanup and return 21340a5f74dSBill Paul */ 21440a5f74dSBill Paul error3: 21540a5f74dSBill Paul (void)close(pdfrom[0]); 21640a5f74dSBill Paul (void)close(pdfrom[1]); 21740a5f74dSBill Paul error2: 21840a5f74dSBill Paul (void)close(pdto[0]); 21940a5f74dSBill Paul (void)close(pdto[1]); 22040a5f74dSBill Paul error1: 22140a5f74dSBill Paul return (-1); 22240a5f74dSBill Paul } 22340a5f74dSBill Paul 22440a5f74dSBill Paul static char * 22540a5f74dSBill Paul basename(path) 22640a5f74dSBill Paul char *path; 22740a5f74dSBill Paul { 22840a5f74dSBill Paul char *p; 22940a5f74dSBill Paul 23040a5f74dSBill Paul p = strrchr(path, '/'); 23140a5f74dSBill Paul if (p == NULL) { 23240a5f74dSBill Paul return (path); 23340a5f74dSBill Paul } else { 23440a5f74dSBill Paul return (p + 1); 23540a5f74dSBill Paul } 23640a5f74dSBill Paul } 23740a5f74dSBill Paul 23840a5f74dSBill Paul #else /* YP */ 23940a5f74dSBill Paul 24040a5f74dSBill Paul #ifdef foo 24140a5f74dSBill Paul #define ERR_ACCESS 1 24240a5f74dSBill Paul #define ERR_MALLOC 2 24340a5f74dSBill Paul #define ERR_READ 3 24440a5f74dSBill Paul #define ERR_WRITE 4 24540a5f74dSBill Paul #define ERR_DBASE 5 24640a5f74dSBill Paul #define ERR_KEY 6 24740a5f74dSBill Paul extern char *malloc(); 24840a5f74dSBill Paul #endif 24940a5f74dSBill Paul 25040a5f74dSBill Paul static int match __P(( char * , char * )); 25140a5f74dSBill Paul 25240a5f74dSBill Paul /* 25340a5f74dSBill Paul * Determine if requester is allowed to update the given map, 25440a5f74dSBill Paul * and update it if so. Returns the status, which is zero 25540a5f74dSBill Paul * if there is no access violation. This function updates 25640a5f74dSBill Paul * the local file and then shuts up. 25740a5f74dSBill Paul */ 25840a5f74dSBill Paul int 25940a5f74dSBill Paul localupdate(name, filename, op, keylen, key, datalen, data) 26040a5f74dSBill Paul char *name; /* Name of the requestor */ 26140a5f74dSBill Paul char *filename; 26240a5f74dSBill Paul u_int op; 26340a5f74dSBill Paul u_int keylen; /* Not used */ 26440a5f74dSBill Paul char *key; 26540a5f74dSBill Paul u_int datalen; /* Not used */ 26640a5f74dSBill Paul char *data; 26740a5f74dSBill Paul { 26840a5f74dSBill Paul char line[256]; 26940a5f74dSBill Paul FILE *rf; 27040a5f74dSBill Paul FILE *wf; 27140a5f74dSBill Paul char *tmpname; 27240a5f74dSBill Paul int err; 27340a5f74dSBill Paul 27440a5f74dSBill Paul /* 27540a5f74dSBill Paul * Check permission 27640a5f74dSBill Paul */ 27740a5f74dSBill Paul if (strcmp(name, key) != 0) { 27840a5f74dSBill Paul return (ERR_ACCESS); 27940a5f74dSBill Paul } 28040a5f74dSBill Paul if (strcmp(name, "nobody") == 0) { 28140a5f74dSBill Paul /* 28240a5f74dSBill Paul * Can't change "nobody"s key. 28340a5f74dSBill Paul */ 28440a5f74dSBill Paul return (ERR_ACCESS); 28540a5f74dSBill Paul } 28640a5f74dSBill Paul 28740a5f74dSBill Paul /* 28840a5f74dSBill Paul * Open files 28940a5f74dSBill Paul */ 29040a5f74dSBill Paul tmpname = malloc(strlen(filename) + 4); 29140a5f74dSBill Paul if (tmpname == NULL) { 29240a5f74dSBill Paul return (ERR_MALLOC); 29340a5f74dSBill Paul } 29440a5f74dSBill Paul sprintf(tmpname, "%s.tmp", filename); 29540a5f74dSBill Paul rf = fopen(filename, "r"); 29640a5f74dSBill Paul if (rf == NULL) { 29740a5f74dSBill Paul return (ERR_READ); 29840a5f74dSBill Paul } 29940a5f74dSBill Paul wf = fopen(tmpname, "w"); 30040a5f74dSBill Paul if (wf == NULL) { 30140a5f74dSBill Paul return (ERR_WRITE); 30240a5f74dSBill Paul } 30340a5f74dSBill Paul err = -1; 30440a5f74dSBill Paul while (fgets(line, sizeof (line), rf)) { 30540a5f74dSBill Paul if (err < 0 && match(line, name)) { 30640a5f74dSBill Paul switch (op) { 30740a5f74dSBill Paul case YPOP_INSERT: 30840a5f74dSBill Paul err = ERR_KEY; 30940a5f74dSBill Paul break; 31040a5f74dSBill Paul case YPOP_STORE: 31140a5f74dSBill Paul case YPOP_CHANGE: 31240a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data); 31340a5f74dSBill Paul err = 0; 31440a5f74dSBill Paul break; 31540a5f74dSBill Paul case YPOP_DELETE: 31640a5f74dSBill Paul /* do nothing */ 31740a5f74dSBill Paul err = 0; 31840a5f74dSBill Paul break; 31940a5f74dSBill Paul } 32040a5f74dSBill Paul } else { 32140a5f74dSBill Paul fputs(line, wf); 32240a5f74dSBill Paul } 32340a5f74dSBill Paul } 32440a5f74dSBill Paul if (err < 0) { 32540a5f74dSBill Paul switch (op) { 32640a5f74dSBill Paul case YPOP_CHANGE: 32740a5f74dSBill Paul case YPOP_DELETE: 32840a5f74dSBill Paul err = ERR_KEY; 32940a5f74dSBill Paul break; 33040a5f74dSBill Paul case YPOP_INSERT: 33140a5f74dSBill Paul case YPOP_STORE: 33240a5f74dSBill Paul err = 0; 33340a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data); 33440a5f74dSBill Paul break; 33540a5f74dSBill Paul } 33640a5f74dSBill Paul } 33740a5f74dSBill Paul fclose(wf); 33840a5f74dSBill Paul fclose(rf); 33940a5f74dSBill Paul if (err == 0) { 34040a5f74dSBill Paul if (rename(tmpname, filename) < 0) { 34140a5f74dSBill Paul return (ERR_DBASE); 34240a5f74dSBill Paul } 34340a5f74dSBill Paul } else { 34440a5f74dSBill Paul if (unlink(tmpname) < 0) { 34540a5f74dSBill Paul return (ERR_DBASE); 34640a5f74dSBill Paul } 34740a5f74dSBill Paul } 34840a5f74dSBill Paul return (err); 34940a5f74dSBill Paul } 35040a5f74dSBill Paul 35140a5f74dSBill Paul static int 35240a5f74dSBill Paul match(line, name) 35340a5f74dSBill Paul char *line; 35440a5f74dSBill Paul char *name; 35540a5f74dSBill Paul { 35640a5f74dSBill Paul int len; 35740a5f74dSBill Paul 35840a5f74dSBill Paul len = strlen(name); 35940a5f74dSBill Paul return (strncmp(line, name, len) == 0 && 36040a5f74dSBill Paul (line[len] == ' ' || line[len] == '\t')); 36140a5f74dSBill Paul } 36240a5f74dSBill Paul #endif /* !YP */ 36340a5f74dSBill Paul 364