update.c revision 344746
1189251Ssam/* 2189251Ssam * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3337817Scy * unrestricted use provided that this legend is included on all tape 4189251Ssam * media and as a part of the software program in whole or part. Users 5252726Srpaulo * may copy or modify Sun RPC without charge, but are not authorized 6252726Srpaulo * to license or distribute it to anyone else except as part of a product or 7189251Ssam * program developed by the user or with the express written consent of 8189251Ssam * Sun Microsystems, Inc. 9189251Ssam * 10189251Ssam * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11189251Ssam * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12214734Srpaulo * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13214734Srpaulo * 14252726Srpaulo * Sun RPC is provided with no support and without any obligation on the 15214734Srpaulo * part of Sun Microsystems, Inc. to assist in its use, correction, 16252726Srpaulo * modification or enhancement. 17189251Ssam * 18189251Ssam * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19189251Ssam * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20189251Ssam * OR ANY PART THEREOF. 21189251Ssam * 22189251Ssam * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23189251Ssam * or profits or other special, indirect and consequential damages, even if 24189251Ssam * Sun has been advised of the possibility of such damages. 25189251Ssam * 26189251Ssam * Sun Microsystems, Inc. 27189251Ssam * 2550 Garcia Avenue 28189251Ssam * Mountain View, California 94043 29189251Ssam */ 30189251Ssam 31189251Ssam#ifndef lint 32189251Ssam#if 0 33189251Ssamstatic char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro"; 34189251Ssam#endif 35189251Ssamstatic const char rcsid[] = 36189251Ssam "$FreeBSD: stable/10/usr.sbin/rpc.ypupdated/update.c 344746 2019-03-04 03:30:39Z avos $"; 37189251Ssam#endif /* not lint */ 38189251Ssam 39189251Ssam/* 40189251Ssam * Copyright (C) 1986, 1989, Sun Microsystems, Inc. 41189251Ssam */ 42189251Ssam 43189251Ssam/* 44189251Ssam * Administrative tool to add a new user to the publickey database 45189251Ssam */ 46189251Ssam#include <stdio.h> 47189251Ssam#include <stdlib.h> 48189251Ssam#include <unistd.h> 49189251Ssam#include <rpc/rpc.h> 50337817Scy#include <rpc/key_prot.h> 51337817Scy#ifdef YP 52189251Ssam#include <rpcsvc/yp_prot.h> 53337817Scy#include <rpcsvc/ypclnt.h> 54337817Scy#include <sys/wait.h> 55337817Scy#include <netdb.h> 56337817Scy#endif /* YP */ 57337817Scy#include <pwd.h> 58337817Scy#include <string.h> 59337817Scy#include <sys/resource.h> 60337817Scy#include "ypupdated_extern.h" 61337817Scy 62337817Scy#ifdef YP 63337817Scy#define MAXMAPNAMELEN 256 64337817Scy#else 65337817Scy#define YPOP_CHANGE 1 /* change, do not add */ 66337817Scy#define YPOP_INSERT 2 /* add, do not change */ 67337817Scy#define YPOP_DELETE 3 /* delete this entry */ 68337817Scy#define YPOP_STORE 4 /* add, or change */ 69337817Scy#endif 70337817Scy 71337817Scy#ifdef YP 72189251Ssamstatic char SHELL[] = "/bin/sh"; 73189251Ssamstatic char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 74189251Ssamstatic char PKMAP[] = "publickey.byname"; 75346981Scystatic char UPDATEFILE[] = "updaters"; 76346981Scystatic char PKFILE[] = "/etc/publickey"; 77346981Scy#endif /* YP */ 78189251Ssam 79252726Srpaulo#ifdef YP 80189251Ssamstatic int _openchild(char *, FILE **, FILE **); 81189251Ssam 82189251Ssam/* 83189251Ssam * Determine if requester is allowed to update the given map, 84189251Ssam * and update it if so. Returns the yp status, which is zero 85189251Ssam * if there is no access violation. 86189251Ssam */ 87337817Scyint 88189251Ssammapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key, 89189251Ssam u_int datalen, char *data) 90189251Ssam{ 91189251Ssam char updater[MAXMAPNAMELEN + 40]; 92189251Ssam FILE *childargs; 93189251Ssam FILE *childrslt; 94189251Ssam#ifdef WEXITSTATUS 95189251Ssam int status; 96189251Ssam#else 97189251Ssam union wait status; 98189251Ssam#endif 99189251Ssam pid_t pid; 100189251Ssam u_int yperrno; 101189251Ssam 102189251Ssam 103189251Ssam#ifdef DEBUG 104189251Ssam printf("%s %s\n", key, data); 105189251Ssam#endif 106189251Ssam (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 107337817Scy UPDATEFILE, mapname); 108189251Ssam pid = _openchild(updater, &childargs, &childrslt); 109189251Ssam if (pid < 0) { 110189251Ssam return (YPERR_YPERR); 111189251Ssam } 112189251Ssam 113189251Ssam /* 114189251Ssam * Write to child 115189251Ssam */ 116189251Ssam (void)fprintf(childargs, "%s\n", requester); 117189251Ssam (void)fprintf(childargs, "%u\n", op); 118189251Ssam (void)fprintf(childargs, "%u\n", keylen); 119189251Ssam (void)fwrite(key, (int)keylen, 1, childargs); 120189251Ssam (void)fprintf(childargs, "\n"); 121189251Ssam (void)fprintf(childargs, "%u\n", datalen); 122189251Ssam (void)fwrite(data, (int)datalen, 1, childargs); 123189251Ssam (void)fprintf(childargs, "\n"); 124189251Ssam (void)fclose(childargs); 125189251Ssam 126189251Ssam /* 127337817Scy * Read from child 128337817Scy */ 129337817Scy (void)fscanf(childrslt, "%d", &yperrno); 130337817Scy (void)fclose(childrslt); 131337817Scy 132337817Scy (void)wait(&status); 133337817Scy#ifdef WEXITSTATUS 134337817Scy if (WEXITSTATUS(status) != 0) 135337817Scy#else 136337817Scy if (status.w_retcode != 0) 137337817Scy#endif 138337817Scy return (YPERR_YPERR); 139337817Scy return (yperrno); 140337817Scy} 141337817Scy 142337817Scy/* 143337817Scy * returns pid, or -1 for failure 144337817Scy */ 145337817Scystatic int 146337817Scy_openchild(char *command, FILE **fto, FILE **ffrom) 147337817Scy{ 148337817Scy int i; 149337817Scy pid_t pid; 150337817Scy int pdto[2]; 151337817Scy int pdfrom[2]; 152337817Scy char *com; 153337817Scy struct rlimit rl; 154337817Scy 155337817Scy if (pipe(pdto) < 0) { 156189251Ssam goto error1; 157189251Ssam } 158189251Ssam if (pipe(pdfrom) < 0) { 159189251Ssam goto error2; 160189251Ssam } 161189251Ssam switch (pid = fork()) { 162337817Scy case -1: 163337817Scy goto error3; 164337817Scy 165337817Scy case 0: 166337817Scy /* 167337817Scy * child: read from pdto[0], write into pdfrom[1] 168337817Scy */ 169337817Scy (void)close(0); 170337817Scy (void)dup(pdto[0]); 171337817Scy (void)close(1); 172337817Scy (void)dup(pdfrom[1]); 173337817Scy getrlimit(RLIMIT_NOFILE, &rl); 174337817Scy for (i = rl.rlim_max - 1; i >= 3; i--) { 175337817Scy (void) close(i); 176337817Scy } 177337817Scy com = malloc((unsigned) strlen(command) + 6); 178337817Scy if (com == NULL) { 179337817Scy _exit(~0); 180337817Scy } 181337817Scy (void)sprintf(com, "exec %s", command); 182337817Scy execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); 183337817Scy _exit(~0); 184337817Scy 185337817Scy default: 186337817Scy /* 187337817Scy * parent: write into pdto[1], read from pdfrom[0] 188337817Scy */ 189337817Scy *fto = fdopen(pdto[1], "w"); 190337817Scy (void)close(pdto[0]); 191337817Scy *ffrom = fdopen(pdfrom[0], "r"); 192337817Scy (void)close(pdfrom[1]); 193337817Scy break; 194337817Scy } 195337817Scy return (pid); 196337817Scy 197337817Scy /* 198337817Scy * error cleanup and return 199337817Scy */ 200337817Scyerror3: 201337817Scy (void)close(pdfrom[0]); 202337817Scy (void)close(pdfrom[1]); 203337817Scyerror2: 204337817Scy (void)close(pdto[0]); 205337817Scy (void)close(pdto[1]); 206337817Scyerror1: 207337817Scy return (-1); 208337817Scy} 209337817Scy 210337817Scystatic char * 211337817Scybasename(char *path) 212337817Scy{ 213337817Scy char *p; 214337817Scy 215337817Scy p = strrchr(path, '/'); 216337817Scy if (p == NULL) { 217337817Scy return (path); 218337817Scy } else { 219337817Scy return (p + 1); 220337817Scy } 221337817Scy} 222337817Scy 223337817Scy#else /* YP */ 224337817Scy 225337817Scystatic int match(char *, char *); 226337817Scy 227337817Scy/* 228337817Scy * Determine if requester is allowed to update the given map, 229337817Scy * and update it if so. Returns the status, which is zero 230337817Scy * if there is no access violation. This function updates 231337817Scy * the local file and then shuts up. 232337817Scy */ 233337817Scyint 234337817Scylocalupdate(char *name, char *filename, u_int op, u_int keylen __unused, 235337817Scy char *key, u_int datalen __unused, char *data) 236337817Scy{ 237337817Scy char line[256]; 238337817Scy FILE *rf; 239337817Scy FILE *wf; 240337817Scy char *tmpname; 241337817Scy int err; 242337817Scy 243337817Scy /* 244337817Scy * Check permission 245189251Ssam */ 246189251Ssam if (strcmp(name, key) != 0) { 247189251Ssam return (ERR_ACCESS); 248189251Ssam } 249252726Srpaulo if (strcmp(name, "nobody") == 0) { 250252726Srpaulo /* 251189251Ssam * Can't change "nobody"s key. 252189251Ssam */ 253189251Ssam return (ERR_ACCESS); 254189251Ssam } 255189251Ssam 256189251Ssam /* 257189251Ssam * Open files 258189251Ssam */ 259189251Ssam tmpname = malloc(strlen(filename) + 4); 260189251Ssam if (tmpname == NULL) { 261189251Ssam return (ERR_MALLOC); 262189251Ssam } 263189251Ssam sprintf(tmpname, "%s.tmp", filename); 264189251Ssam rf = fopen(filename, "r"); 265189251Ssam if (rf == NULL) { 266189251Ssam err = ERR_READ; 267189251Ssam goto cleanup; 268189251Ssam } 269189251Ssam wf = fopen(tmpname, "w"); 270189251Ssam if (wf == NULL) { 271189251Ssam fclose(rf); 272337817Scy err = ERR_WRITE; 273337817Scy goto cleanup; 274337817Scy } 275337817Scy err = -1; 276337817Scy while (fgets(line, sizeof (line), rf)) { 277189251Ssam if (err < 0 && match(line, name)) { 278189251Ssam switch (op) { 279189251Ssam case YPOP_INSERT: 280189251Ssam err = ERR_KEY; 281189251Ssam break; 282189251Ssam case YPOP_STORE: 283189251Ssam case YPOP_CHANGE: 284189251Ssam fprintf(wf, "%s %s\n", key, data); 285189251Ssam err = 0; 286189251Ssam break; 287189251Ssam case YPOP_DELETE: 288189251Ssam /* do nothing */ 289189251Ssam err = 0; 290189251Ssam break; 291189251Ssam } 292189251Ssam } else { 293189251Ssam fputs(line, wf); 294189251Ssam } 295189251Ssam } 296189251Ssam if (err < 0) { 297337817Scy switch (op) { 298189251Ssam case YPOP_CHANGE: 299189251Ssam case YPOP_DELETE: 300189251Ssam err = ERR_KEY; 301189251Ssam break; 302189251Ssam case YPOP_INSERT: 303189251Ssam case YPOP_STORE: 304189251Ssam err = 0; 305189251Ssam fprintf(wf, "%s %s\n", key, data); 306189251Ssam break; 307189251Ssam } 308189251Ssam } 309189251Ssam fclose(wf); 310189251Ssam fclose(rf); 311189251Ssam if (err == 0) { 312189251Ssam if (rename(tmpname, filename) < 0) { 313189251Ssam err = ERR_DBASE; 314189251Ssam goto cleanup; 315189251Ssam } 316189251Ssam } else { 317189251Ssam if (unlink(tmpname) < 0) { 318189251Ssam err = ERR_DBASE; 319189251Ssam goto cleanup; 320189251Ssam } 321189251Ssam } 322189251Ssamcleanup: 323189251Ssam free(tmpname); 324189251Ssam return (err); 325189251Ssam} 326189251Ssam 327189251Ssamstatic int 328189251Ssammatch(char *line, char *name) 329189251Ssam{ 330189251Ssam int len; 331252726Srpaulo 332252726Srpaulo len = strlen(name); 333189251Ssam return (strncmp(line, name, len) == 0 && 334189251Ssam (line[len] == ' ' || line[len] == '\t')); 335189251Ssam} 336189251Ssam#endif /* !YP */ 337189251Ssam