update.c revision 26479
14Srgrimes/* 24Srgrimes * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 34Srgrimes * unrestricted use provided that this legend is included on all tape 44Srgrimes * media and as a part of the software program in whole or part. Users 54Srgrimes * may copy or modify Sun RPC without charge, but are not authorized 64Srgrimes * to license or distribute it to anyone else except as part of a product or 74Srgrimes * program developed by the user or with the express written consent of 84Srgrimes * Sun Microsystems, Inc. 94Srgrimes * 104Srgrimes * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 114Srgrimes * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 124Srgrimes * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 134Srgrimes * 144Srgrimes * Sun RPC is provided with no support and without any obligation on the 154Srgrimes * part of Sun Microsystems, Inc. to assist in its use, correction, 164Srgrimes * modification or enhancement. 174Srgrimes * 184Srgrimes * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 194Srgrimes * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 204Srgrimes * OR ANY PART THEREOF. 214Srgrimes * 224Srgrimes * In no event will Sun Microsystems, Inc. be liable for any lost revenue 234Srgrimes * or profits or other special, indirect and consequential damages, even if 244Srgrimes * Sun has been advised of the possibility of such damages. 254Srgrimes * 264Srgrimes * Sun Microsystems, Inc. 274Srgrimes * 2550 Garcia Avenue 284Srgrimes * Mountain View, California 94043 294Srgrimes */ 304Srgrimes#ifndef lint 314Srgrimesstatic char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro"; 324Srgrimes#endif 334Srgrimes 344Srgrimes/* 354Srgrimes * Copyright (C) 1986, 1989, Sun Microsystems, Inc. 36556Srgrimes */ 37975Smartin 384Srgrimes/* 394Srgrimes * Administrative tool to add a new user to the publickey database 404Srgrimes */ 41757Sdg#include <stdio.h> 42757Sdg#include <stdlib.h> 43757Sdg#include <unistd.h> 44757Sdg#include <rpc/rpc.h> 45757Sdg#include <rpc/key_prot.h> 464Srgrimes#ifdef YP 474Srgrimes#include <rpcsvc/yp_prot.h> 48757Sdg#include <rpcsvc/ypclnt.h> 49556Srgrimes#include <sys/wait.h> 50757Sdg#include <netdb.h> 51757Sdg#endif /* YP */ 52757Sdg#include <pwd.h> 534Srgrimes#include <string.h> 54757Sdg#include <sys/resource.h> 554Srgrimes#include <stdlib.h> 56757Sdg#include "ypupdated_extern.h" 57757Sdg 58757Sdg#ifdef YP 594Srgrimes#define MAXMAPNAMELEN 256 60757Sdg#else 614Srgrimes#define YPOP_CHANGE 1 /* change, do not add */ 62757Sdg#define YPOP_INSERT 2 /* add, do not change */ 634Srgrimes#define YPOP_DELETE 3 /* delete this entry */ 644Srgrimes#define YPOP_STORE 4 /* add, or change */ 65757Sdg#endif 66757Sdg 674Srgrimes#ifdef notdef 684Srgrimesextern char *getpass(); 694Srgrimesextern char *malloc(); 704Srgrimes#endif 714Srgrimes 72200Sdg#ifdef YP 734Srgrimes#ifdef notdef 744Srgrimesstatic char *basename(); 754Srgrimes#endif 76592Srgrimesstatic char SHELL[] = "/bin/sh"; 77592Srgrimesstatic char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 78592Srgrimesstatic char PKMAP[] = "publickey.byname"; 79757Sdgstatic char UPDATEFILE[] = "updaters"; 80592Srgrimesstatic char PKFILE[] = "/etc/publickey"; 81757Sdg#endif /* YP */ 82608Srgrimes 834Srgrimes#ifdef YP 844Srgrimesstatic int _openchild __P(( char *, FILE **, FILE ** )); 854Srgrimes 864Srgrimes/* 874Srgrimes * Determine if requester is allowed to update the given map, 88592Srgrimes * and update it if so. Returns the yp status, which is zero 89592Srgrimes * if there is no access violation. 90592Srgrimes */ 91757Sdgmapupdate(requester, mapname, op, keylen, key, datalen, data) 924Srgrimes char *requester; 934Srgrimes char *mapname; 944Srgrimes u_int op; 954Srgrimes u_int keylen; 964Srgrimes char *key; 974Srgrimes u_int datalen; 98570Srgrimes char *data; 99134Sdg{ 1004Srgrimes char updater[MAXMAPNAMELEN + 40]; 101556Srgrimes FILE *childargs; 102556Srgrimes FILE *childrslt; 103556Srgrimes#ifdef WEXITSTATUS 104556Srgrimes int status; 105556Srgrimes#else 106757Sdg union wait status; 107134Sdg#endif 108592Srgrimes pid_t pid; 109134Sdg u_int yperrno; 110592Srgrimes 111757Sdg 112757Sdg#ifdef DEBUG 113757Sdg printf("%s %s\n", key, data); 114757Sdg#endif 1154Srgrimes (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 116757Sdg UPDATEFILE, mapname); 117757Sdg pid = _openchild(updater, &childargs, &childrslt); 118757Sdg if (pid < 0) { 119592Srgrimes return (YPERR_YPERR); 120757Sdg } 121757Sdg 1224Srgrimes /* 123757Sdg * Write to child 124757Sdg */ 125718Swollman (void)fprintf(childargs, "%s\n", requester); 126757Sdg (void)fprintf(childargs, "%u\n", op); 127757Sdg (void)fprintf(childargs, "%u\n", keylen); 128134Sdg (void)fwrite(key, (int)keylen, 1, childargs); 129757Sdg (void)fprintf(childargs, "\n"); 130757Sdg (void)fprintf(childargs, "%u\n", datalen); 131760Srgrimes (void)fwrite(data, (int)datalen, 1, childargs); 132757Sdg (void)fprintf(childargs, "\n"); 133718Swollman (void)fclose(childargs); 134757Sdg 135974Sdg /* 1364Srgrimes * Read from child 137134Sdg */ 138134Sdg (void)fscanf(childrslt, "%d", &yperrno); 139556Srgrimes (void)fclose(childrslt); 140556Srgrimes 141556Srgrimes (void)wait(&status); 1424Srgrimes#ifdef WEXITSTATUS 143134Sdg if (WEXITSTATUS(status) != 0) { 144134Sdg#else 145200Sdg if (status.w_retcode != 0) { 146200Sdg#endif 147134Sdg return (YPERR_YPERR); 148200Sdg } 149757Sdg return (yperrno); 1504Srgrimes} 151757Sdg 1524Srgrimes/* 1534Srgrimes * returns pid, or -1 for failure 154556Srgrimes */ 1554Srgrimesstatic 1564Srgrimes_openchild(command, fto, ffrom) 1574Srgrimes char *command; 1584Srgrimes FILE **fto; 1594Srgrimes FILE **ffrom; 160570Srgrimes{ 1614Srgrimes int i; 162570Srgrimes pid_t pid; 1634Srgrimes int pdto[2]; 164570Srgrimes int pdfrom[2]; 165556Srgrimes char *com; 166570Srgrimes struct rlimit rl; 167570Srgrimes 168975Smartin if (pipe(pdto) < 0) { 169975Smartin goto error1; 170975Smartin } 171975Smartin if (pipe(pdfrom) < 0) { 172975Smartin goto error2; 173975Smartin } 174975Smartin#ifdef VFORK 1754Srgrimes switch (pid = vfork()) { 176556Srgrimes#else 177556Srgrimes switch (pid = fork()) { 178556Srgrimes#endif 179556Srgrimes case -1: 180556Srgrimes goto error3; 181556Srgrimes 182556Srgrimes case 0: 183556Srgrimes /* 184556Srgrimes * child: read from pdto[0], write into pdfrom[1] 185556Srgrimes */ 186556Srgrimes (void)close(0); 187556Srgrimes (void)dup(pdto[0]); 188556Srgrimes (void)close(1); 189556Srgrimes (void)dup(pdfrom[1]); 190556Srgrimes getrlimit(RLIMIT_NOFILE, &rl); 191556Srgrimes for (i = rl.rlim_max - 1; i >= 3; i--) { 192556Srgrimes (void) close(i); 193570Srgrimes } 194556Srgrimes com = malloc((unsigned) strlen(command) + 6); 195570Srgrimes if (com == NULL) { 196556Srgrimes _exit(~0); 197556Srgrimes } 1984Srgrimes (void)sprintf(com, "exec %s", command); 1994Srgrimes execl(SHELL, basename(SHELL), "-c", com, NULL); 2004Srgrimes _exit(~0); 2014Srgrimes 2024Srgrimes default: 2034Srgrimes /* 2044Srgrimes * parent: write into pdto[1], read from pdfrom[0] 2054Srgrimes */ 2064Srgrimes *fto = fdopen(pdto[1], "w"); 2074Srgrimes (void)close(pdto[0]); 2084Srgrimes *ffrom = fdopen(pdfrom[0], "r"); 2094Srgrimes (void)close(pdfrom[1]); 2104Srgrimes break; 2114Srgrimes } 212757Sdg return (pid); 2134Srgrimes 214570Srgrimes /* 215570Srgrimes * error cleanup and return 216570Srgrimes */ 217570Srgrimeserror3: 218974Sdg (void)close(pdfrom[0]); 219570Srgrimes (void)close(pdfrom[1]); 220570Srgrimeserror2: 2214Srgrimes (void)close(pdto[0]); 222570Srgrimes (void)close(pdto[1]); 223757Sdgerror1: 2244Srgrimes return (-1); 225757Sdg} 226757Sdg 2274Srgrimesstatic char * 228757Sdgbasename(path) 229570Srgrimes char *path; 230760Srgrimes{ 231757Sdg char *p; 2324Srgrimes 2334Srgrimes p = strrchr(path, '/'); 2344Srgrimes if (p == NULL) { 2354Srgrimes return (path); 236608Srgrimes } else { 237974Sdg return (p + 1); 238974Sdg } 239974Sdg} 240974Sdg 241757Sdg#else /* YP */ 242757Sdg 243608Srgrimes#ifdef foo 244757Sdg#define ERR_ACCESS 1 245608Srgrimes#define ERR_MALLOC 2 246757Sdg#define ERR_READ 3 247757Sdg#define ERR_WRITE 4 248974Sdg#define ERR_DBASE 5 249757Sdg#define ERR_KEY 6 250757Sdgextern char *malloc(); 251757Sdg#endif 252757Sdg 253757Sdgstatic int match __P(( char * , char * )); 254757Sdg 255570Srgrimes/* 2564Srgrimes * Determine if requester is allowed to update the given map, 257592Srgrimes * and update it if so. Returns the status, which is zero 258592Srgrimes * if there is no access violation. This function updates 259592Srgrimes * the local file and then shuts up. 260592Srgrimes */ 261592Srgrimesint 262592Srgrimeslocalupdate(name, filename, op, keylen, key, datalen, data) 2634Srgrimes char *name; /* Name of the requestor */ 2644Srgrimes char *filename; 265570Srgrimes u_int op; 2664Srgrimes u_int keylen; /* Not used */ 2674Srgrimes char *key; 2684Srgrimes u_int datalen; /* Not used */ 2694Srgrimes char *data; 2704Srgrimes{ 2714Srgrimes char line[256]; 2724Srgrimes FILE *rf; 2734Srgrimes FILE *wf; 274757Sdg char *tmpname; 275757Sdg int err; 276757Sdg 277757Sdg /* 278757Sdg * Check permission 279200Sdg */ 280200Sdg if (strcmp(name, key) != 0) { 281200Sdg return (ERR_ACCESS); 282757Sdg } 283757Sdg if (strcmp(name, "nobody") == 0) { 284757Sdg /* 285757Sdg * Can't change "nobody"s key. 2864Srgrimes */ 2874Srgrimes return (ERR_ACCESS); 288757Sdg } 289757Sdg 290757Sdg /* 291757Sdg * Open files 292757Sdg */ 293757Sdg tmpname = malloc(strlen(filename) + 4); 294757Sdg if (tmpname == NULL) { 295757Sdg return (ERR_MALLOC); 296757Sdg } 297757Sdg sprintf(tmpname, "%s.tmp", filename); 298757Sdg rf = fopen(filename, "r"); 299757Sdg if (rf == NULL) { 300757Sdg return (ERR_READ); 301757Sdg } 302757Sdg wf = fopen(tmpname, "w"); 303757Sdg if (wf == NULL) { 304757Sdg return (ERR_WRITE); 305757Sdg } 306757Sdg err = -1; 307757Sdg while (fgets(line, sizeof (line), rf)) { 308974Sdg if (err < 0 && match(line, name)) { 309757Sdg switch (op) { 310757Sdg case YPOP_INSERT: 311757Sdg err = ERR_KEY; 312757Sdg break; 313757Sdg case YPOP_STORE: 314757Sdg case YPOP_CHANGE: 315757Sdg fprintf(wf, "%s %s\n", key, data); 316757Sdg err = 0; 317757Sdg break; 3184Srgrimes case YPOP_DELETE: 3194Srgrimes /* do nothing */ 320757Sdg err = 0; 321757Sdg break; 322757Sdg } 323757Sdg } else { 324757Sdg fputs(line, wf); 3254Srgrimes } 3264Srgrimes } 3274Srgrimes if (err < 0) { 3284Srgrimes switch (op) { 329757Sdg case YPOP_CHANGE: 330757Sdg case YPOP_DELETE: 331757Sdg err = ERR_KEY; 332757Sdg break; 333757Sdg case YPOP_INSERT: 334757Sdg case YPOP_STORE: 335757Sdg err = 0; 3364Srgrimes fprintf(wf, "%s %s\n", key, data); 3374Srgrimes break; 3384Srgrimes } 339757Sdg } 3404Srgrimes fclose(wf); 3414Srgrimes fclose(rf); 342757Sdg if (err == 0) { 343757Sdg if (rename(tmpname, filename) < 0) { 344757Sdg return (ERR_DBASE); 3454Srgrimes } 346757Sdg } else { 347974Sdg if (unlink(tmpname) < 0) { 348757Sdg return (ERR_DBASE); 3494Srgrimes } 3504Srgrimes } 3514Srgrimes return (err); 352757Sdg} 353757Sdg 354757Sdgstatic int 3554Srgrimesmatch(line, name) 3564Srgrimes char *line; 357757Sdg char *name; 358757Sdg{ 359757Sdg int len; 3604Srgrimes 361757Sdg len = strlen(name); 3624Srgrimes return (strncmp(line, name, len) == 0 && 3634Srgrimes (line[len] == ' ' || line[len] == '\t')); 364757Sdg} 3654Srgrimes#endif /* !YP */ 366570Srgrimes 3674Srgrimes