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[] = 3697d92980SPeter Wemm "$FreeBSD$"; 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 "ypupdated_extern.h" 6140a5f74dSBill Paul 6240a5f74dSBill Paul #ifdef YP 6340a5f74dSBill Paul #define MAXMAPNAMELEN 256 6440a5f74dSBill Paul #else 6540a5f74dSBill Paul #define YPOP_CHANGE 1 /* change, do not add */ 6640a5f74dSBill Paul #define YPOP_INSERT 2 /* add, do not change */ 6740a5f74dSBill Paul #define YPOP_DELETE 3 /* delete this entry */ 6840a5f74dSBill Paul #define YPOP_STORE 4 /* add, or change */ 6940a5f74dSBill Paul #endif 7040a5f74dSBill Paul 7140a5f74dSBill Paul #ifdef YP 7240a5f74dSBill Paul static char SHELL[] = "/bin/sh"; 7340a5f74dSBill Paul static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 7440a5f74dSBill Paul static char PKMAP[] = "publickey.byname"; 7540a5f74dSBill Paul static char UPDATEFILE[] = "updaters"; 7640a5f74dSBill Paul static char PKFILE[] = "/etc/publickey"; 7740a5f74dSBill Paul #endif /* YP */ 7840a5f74dSBill Paul 7940a5f74dSBill Paul #ifdef YP 80ed4d1c46SDag-Erling Smørgrav static int _openchild(char *, FILE **, FILE **); 8140a5f74dSBill Paul 8240a5f74dSBill Paul /* 8340a5f74dSBill Paul * Determine if requester is allowed to update the given map, 8440a5f74dSBill Paul * and update it if so. Returns the yp status, which is zero 8540a5f74dSBill Paul * if there is no access violation. 8640a5f74dSBill Paul */ 87dc584ddbSDag-Erling Smørgrav int 88dc584ddbSDag-Erling Smørgrav mapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key, 89dc584ddbSDag-Erling Smørgrav u_int datalen, char *data) 9040a5f74dSBill Paul { 9140a5f74dSBill Paul char updater[MAXMAPNAMELEN + 40]; 9240a5f74dSBill Paul FILE *childargs; 9340a5f74dSBill Paul FILE *childrslt; 9440a5f74dSBill Paul #ifdef WEXITSTATUS 9540a5f74dSBill Paul int status; 9640a5f74dSBill Paul #else 9740a5f74dSBill Paul union wait status; 9840a5f74dSBill Paul #endif 9940a5f74dSBill Paul pid_t pid; 10040a5f74dSBill Paul u_int yperrno; 10140a5f74dSBill Paul 10240a5f74dSBill Paul 10340a5f74dSBill Paul #ifdef DEBUG 10440a5f74dSBill Paul printf("%s %s\n", key, data); 10540a5f74dSBill Paul #endif 10640a5f74dSBill Paul (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 10740a5f74dSBill Paul UPDATEFILE, mapname); 10840a5f74dSBill Paul pid = _openchild(updater, &childargs, &childrslt); 10940a5f74dSBill Paul if (pid < 0) { 11040a5f74dSBill Paul return (YPERR_YPERR); 11140a5f74dSBill Paul } 11240a5f74dSBill Paul 11340a5f74dSBill Paul /* 11440a5f74dSBill Paul * Write to child 11540a5f74dSBill Paul */ 11640a5f74dSBill Paul (void)fprintf(childargs, "%s\n", requester); 11740a5f74dSBill Paul (void)fprintf(childargs, "%u\n", op); 11840a5f74dSBill Paul (void)fprintf(childargs, "%u\n", keylen); 11940a5f74dSBill Paul (void)fwrite(key, (int)keylen, 1, childargs); 12040a5f74dSBill Paul (void)fprintf(childargs, "\n"); 12140a5f74dSBill Paul (void)fprintf(childargs, "%u\n", datalen); 12240a5f74dSBill Paul (void)fwrite(data, (int)datalen, 1, childargs); 12340a5f74dSBill Paul (void)fprintf(childargs, "\n"); 12440a5f74dSBill Paul (void)fclose(childargs); 12540a5f74dSBill Paul 12640a5f74dSBill Paul /* 12740a5f74dSBill Paul * Read from child 12840a5f74dSBill Paul */ 12940a5f74dSBill Paul (void)fscanf(childrslt, "%d", &yperrno); 13040a5f74dSBill Paul (void)fclose(childrslt); 13140a5f74dSBill Paul 13240a5f74dSBill Paul (void)wait(&status); 13340a5f74dSBill Paul #ifdef WEXITSTATUS 134dc584ddbSDag-Erling Smørgrav if (WEXITSTATUS(status) != 0) 13540a5f74dSBill Paul #else 136dc584ddbSDag-Erling Smørgrav if (status.w_retcode != 0) 13740a5f74dSBill Paul #endif 13840a5f74dSBill Paul return (YPERR_YPERR); 13940a5f74dSBill Paul return (yperrno); 14040a5f74dSBill Paul } 14140a5f74dSBill Paul 14240a5f74dSBill Paul /* 14340a5f74dSBill Paul * returns pid, or -1 for failure 14440a5f74dSBill Paul */ 145dc584ddbSDag-Erling Smørgrav static int 146dc584ddbSDag-Erling Smørgrav _openchild(char *command, FILE **fto, FILE **ffrom) 14740a5f74dSBill Paul { 14840a5f74dSBill Paul int i; 14940a5f74dSBill Paul pid_t pid; 15040a5f74dSBill Paul int pdto[2]; 15140a5f74dSBill Paul int pdfrom[2]; 15240a5f74dSBill Paul char *com; 15340a5f74dSBill Paul struct rlimit rl; 15440a5f74dSBill Paul 15540a5f74dSBill Paul if (pipe(pdto) < 0) { 15640a5f74dSBill Paul goto error1; 15740a5f74dSBill Paul } 15840a5f74dSBill Paul if (pipe(pdfrom) < 0) { 15940a5f74dSBill Paul goto error2; 16040a5f74dSBill Paul } 16140a5f74dSBill Paul switch (pid = fork()) { 16240a5f74dSBill Paul case -1: 16340a5f74dSBill Paul goto error3; 16440a5f74dSBill Paul 16540a5f74dSBill Paul case 0: 16640a5f74dSBill Paul /* 16740a5f74dSBill Paul * child: read from pdto[0], write into pdfrom[1] 16840a5f74dSBill Paul */ 16940a5f74dSBill Paul (void)close(0); 17040a5f74dSBill Paul (void)dup(pdto[0]); 17140a5f74dSBill Paul (void)close(1); 17240a5f74dSBill Paul (void)dup(pdfrom[1]); 17340a5f74dSBill Paul getrlimit(RLIMIT_NOFILE, &rl); 17440a5f74dSBill Paul for (i = rl.rlim_max - 1; i >= 3; i--) { 17540a5f74dSBill Paul (void) close(i); 17640a5f74dSBill Paul } 17740a5f74dSBill Paul com = malloc((unsigned) strlen(command) + 6); 17840a5f74dSBill Paul if (com == NULL) { 17940a5f74dSBill Paul _exit(~0); 18040a5f74dSBill Paul } 18140a5f74dSBill Paul (void)sprintf(com, "exec %s", command); 1827bc6d015SBrian Somers execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); 18340a5f74dSBill Paul _exit(~0); 18440a5f74dSBill Paul 18540a5f74dSBill Paul default: 18640a5f74dSBill Paul /* 18740a5f74dSBill Paul * parent: write into pdto[1], read from pdfrom[0] 18840a5f74dSBill Paul */ 18940a5f74dSBill Paul *fto = fdopen(pdto[1], "w"); 19040a5f74dSBill Paul (void)close(pdto[0]); 19140a5f74dSBill Paul *ffrom = fdopen(pdfrom[0], "r"); 19240a5f74dSBill Paul (void)close(pdfrom[1]); 19340a5f74dSBill Paul break; 19440a5f74dSBill Paul } 19540a5f74dSBill Paul return (pid); 19640a5f74dSBill Paul 19740a5f74dSBill Paul /* 19840a5f74dSBill Paul * error cleanup and return 19940a5f74dSBill Paul */ 20040a5f74dSBill Paul error3: 20140a5f74dSBill Paul (void)close(pdfrom[0]); 20240a5f74dSBill Paul (void)close(pdfrom[1]); 20340a5f74dSBill Paul error2: 20440a5f74dSBill Paul (void)close(pdto[0]); 20540a5f74dSBill Paul (void)close(pdto[1]); 20640a5f74dSBill Paul error1: 20740a5f74dSBill Paul return (-1); 20840a5f74dSBill Paul } 20940a5f74dSBill Paul 21040a5f74dSBill Paul static char * 211dc584ddbSDag-Erling Smørgrav basename(char *path) 21240a5f74dSBill Paul { 21340a5f74dSBill Paul char *p; 21440a5f74dSBill Paul 21540a5f74dSBill Paul p = strrchr(path, '/'); 21640a5f74dSBill Paul if (p == NULL) { 21740a5f74dSBill Paul return (path); 21840a5f74dSBill Paul } else { 21940a5f74dSBill Paul return (p + 1); 22040a5f74dSBill Paul } 22140a5f74dSBill Paul } 22240a5f74dSBill Paul 22340a5f74dSBill Paul #else /* YP */ 22440a5f74dSBill Paul 225ed4d1c46SDag-Erling Smørgrav static int match(char *, char *); 22640a5f74dSBill Paul 22740a5f74dSBill Paul /* 22840a5f74dSBill Paul * Determine if requester is allowed to update the given map, 22940a5f74dSBill Paul * and update it if so. Returns the status, which is zero 23040a5f74dSBill Paul * if there is no access violation. This function updates 23140a5f74dSBill Paul * the local file and then shuts up. 23240a5f74dSBill Paul */ 23340a5f74dSBill Paul int 234dc584ddbSDag-Erling Smørgrav localupdate(char *name, char *filename, u_int op, u_int keylen __unused, 235dc584ddbSDag-Erling Smørgrav char *key, u_int datalen __unused, char *data) 23640a5f74dSBill Paul { 23740a5f74dSBill Paul char line[256]; 23840a5f74dSBill Paul FILE *rf; 23940a5f74dSBill Paul FILE *wf; 24040a5f74dSBill Paul char *tmpname; 24140a5f74dSBill Paul int err; 24240a5f74dSBill Paul 24340a5f74dSBill Paul /* 24440a5f74dSBill Paul * Check permission 24540a5f74dSBill Paul */ 24640a5f74dSBill Paul if (strcmp(name, key) != 0) { 24740a5f74dSBill Paul return (ERR_ACCESS); 24840a5f74dSBill Paul } 24940a5f74dSBill Paul if (strcmp(name, "nobody") == 0) { 25040a5f74dSBill Paul /* 25140a5f74dSBill Paul * Can't change "nobody"s key. 25240a5f74dSBill Paul */ 25340a5f74dSBill Paul return (ERR_ACCESS); 25440a5f74dSBill Paul } 25540a5f74dSBill Paul 25640a5f74dSBill Paul /* 25740a5f74dSBill Paul * Open files 25840a5f74dSBill Paul */ 25940a5f74dSBill Paul tmpname = malloc(strlen(filename) + 4); 26040a5f74dSBill Paul if (tmpname == NULL) { 26140a5f74dSBill Paul return (ERR_MALLOC); 26240a5f74dSBill Paul } 26340a5f74dSBill Paul sprintf(tmpname, "%s.tmp", filename); 26440a5f74dSBill Paul rf = fopen(filename, "r"); 26540a5f74dSBill Paul if (rf == NULL) { 266*994558c3SAndriy Voskoboinyk err = ERR_READ; 267*994558c3SAndriy Voskoboinyk goto cleanup; 26840a5f74dSBill Paul } 26940a5f74dSBill Paul wf = fopen(tmpname, "w"); 27040a5f74dSBill Paul if (wf == NULL) { 271*994558c3SAndriy Voskoboinyk fclose(rf); 272*994558c3SAndriy Voskoboinyk err = ERR_WRITE; 273*994558c3SAndriy Voskoboinyk goto cleanup; 27440a5f74dSBill Paul } 27540a5f74dSBill Paul err = -1; 27640a5f74dSBill Paul while (fgets(line, sizeof (line), rf)) { 27740a5f74dSBill Paul if (err < 0 && match(line, name)) { 27840a5f74dSBill Paul switch (op) { 27940a5f74dSBill Paul case YPOP_INSERT: 28040a5f74dSBill Paul err = ERR_KEY; 28140a5f74dSBill Paul break; 28240a5f74dSBill Paul case YPOP_STORE: 28340a5f74dSBill Paul case YPOP_CHANGE: 28440a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data); 28540a5f74dSBill Paul err = 0; 28640a5f74dSBill Paul break; 28740a5f74dSBill Paul case YPOP_DELETE: 28840a5f74dSBill Paul /* do nothing */ 28940a5f74dSBill Paul err = 0; 29040a5f74dSBill Paul break; 29140a5f74dSBill Paul } 29240a5f74dSBill Paul } else { 29340a5f74dSBill Paul fputs(line, wf); 29440a5f74dSBill Paul } 29540a5f74dSBill Paul } 29640a5f74dSBill Paul if (err < 0) { 29740a5f74dSBill Paul switch (op) { 29840a5f74dSBill Paul case YPOP_CHANGE: 29940a5f74dSBill Paul case YPOP_DELETE: 30040a5f74dSBill Paul err = ERR_KEY; 30140a5f74dSBill Paul break; 30240a5f74dSBill Paul case YPOP_INSERT: 30340a5f74dSBill Paul case YPOP_STORE: 30440a5f74dSBill Paul err = 0; 30540a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data); 30640a5f74dSBill Paul break; 30740a5f74dSBill Paul } 30840a5f74dSBill Paul } 30940a5f74dSBill Paul fclose(wf); 31040a5f74dSBill Paul fclose(rf); 31140a5f74dSBill Paul if (err == 0) { 31240a5f74dSBill Paul if (rename(tmpname, filename) < 0) { 313*994558c3SAndriy Voskoboinyk err = ERR_DBASE; 314*994558c3SAndriy Voskoboinyk goto cleanup; 31540a5f74dSBill Paul } 31640a5f74dSBill Paul } else { 31740a5f74dSBill Paul if (unlink(tmpname) < 0) { 318*994558c3SAndriy Voskoboinyk err = ERR_DBASE; 319*994558c3SAndriy Voskoboinyk goto cleanup; 32040a5f74dSBill Paul } 32140a5f74dSBill Paul } 322*994558c3SAndriy Voskoboinyk cleanup: 323*994558c3SAndriy Voskoboinyk free(tmpname); 32440a5f74dSBill Paul return (err); 32540a5f74dSBill Paul } 32640a5f74dSBill Paul 32740a5f74dSBill Paul static int 328dc584ddbSDag-Erling Smørgrav match(char *line, char *name) 32940a5f74dSBill Paul { 33040a5f74dSBill Paul int len; 33140a5f74dSBill Paul 33240a5f74dSBill Paul len = strlen(name); 33340a5f74dSBill Paul return (strncmp(line, name, len) == 0 && 33440a5f74dSBill Paul (line[len] == ' ' || line[len] == '\t')); 33540a5f74dSBill Paul } 33640a5f74dSBill Paul #endif /* !YP */ 337