126238Swpaul/* 226238Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326238Swpaul * unrestricted use provided that this legend is included on all tape 426238Swpaul * media and as a part of the software program in whole or part. Users 526238Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626238Swpaul * to license or distribute it to anyone else except as part of a product or 726238Swpaul * program developed by the user or with the express written consent of 826238Swpaul * Sun Microsystems, Inc. 926238Swpaul * 1026238Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1126238Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1226238Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1326238Swpaul * 1426238Swpaul * Sun RPC is provided with no support and without any obligation on the 1526238Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1626238Swpaul * modification or enhancement. 1726238Swpaul * 1826238Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1926238Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2026238Swpaul * OR ANY PART THEREOF. 2126238Swpaul * 2226238Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2326238Swpaul * or profits or other special, indirect and consequential damages, even if 2426238Swpaul * Sun has been advised of the possibility of such damages. 2526238Swpaul * 2626238Swpaul * Sun Microsystems, Inc. 2726238Swpaul * 2550 Garcia Avenue 2826238Swpaul * Mountain View, California 94043 2926238Swpaul */ 3095633Smarkm 3126238Swpaul#ifndef lint 3227754Scharnier#if 0 3326238Swpaulstatic char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro"; 3426238Swpaul#endif 3527754Scharnier#endif 3626238Swpaul 3726238Swpaul/* 3826238Swpaul * Copyright (C) 1986, 1989, Sun Microsystems, Inc. 3926238Swpaul */ 4026238Swpaul 4126238Swpaul/* 4226238Swpaul * Administrative tool to add a new user to the publickey database 4326238Swpaul */ 4495633Smarkm#include <sys/cdefs.h> 4595633Smarkm__FBSDID("$FreeBSD$"); 4695633Smarkm 4787204Smarkm#include <sys/types.h> 4887204Smarkm#include <sys/time.h> 4987204Smarkm#include <sys/resource.h> 5095633Smarkm 5126238Swpaul#include <rpc/rpc.h> 5226238Swpaul#include <rpc/key_prot.h> 5395633Smarkm 5426238Swpaul#ifdef YP 5587204Smarkm#include <sys/wait.h> 5626238Swpaul#include <rpcsvc/yp_prot.h> 5726238Swpaul#include <rpcsvc/ypclnt.h> 5826238Swpaul#include <netdb.h> 5926238Swpaul#endif /* YP */ 6095633Smarkm 61200462Sdelphij#include <pwd.h> 6287204Smarkm#include <stdio.h> 6387204Smarkm#include <stdlib.h> 6426238Swpaul#include <string.h> 6527754Scharnier#include <unistd.h> 6626238Swpaul 6787204Smarkm#include "extern.h" 6826238Swpaul 6926238Swpaul#ifdef YP 7026238Swpaulstatic char SHELL[] = "/bin/sh"; 7126238Swpaulstatic char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 7226238Swpaulstatic char UPDATEFILE[] = "updaters"; 7326238Swpaul 7492921Simpstatic int _openchild(char *, FILE **, FILE **); 7592921Simpstatic char *basename(char *path); 7626238Swpaul 7726238Swpaul/* 7826238Swpaul * Determine if requester is allowed to update the given map, 7926238Swpaul * and update it if so. Returns the yp status, which is zero 8026238Swpaul * if there is no access violation. 8126238Swpaul */ 8287204Smarkmint 8395633Smarkmmapupdate(char *requester, char *mapname, u_int op, u_int keylen, 8495633Smarkm char *key, u_int datalen, char *data) 8526238Swpaul{ 8626238Swpaul char updater[MAXMAPNAMELEN + 40]; 8726238Swpaul FILE *childargs; 8826238Swpaul FILE *childrslt; 8926238Swpaul#ifdef WEXITSTATUS 9026238Swpaul int status; 9126238Swpaul#else 9226238Swpaul union wait status; 9326238Swpaul#endif 9426238Swpaul pid_t pid; 9526238Swpaul u_int yperrno; 9626238Swpaul 9726238Swpaul 9826238Swpaul#ifdef DEBUG 9926238Swpaul printf("%s %s\n", key, data); 10026238Swpaul#endif 10126238Swpaul (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 10226238Swpaul UPDATEFILE, mapname); 10326238Swpaul pid = _openchild(updater, &childargs, &childrslt); 10426238Swpaul if (pid < 0) { 10526238Swpaul return (YPERR_YPERR); 10626238Swpaul } 10726238Swpaul 10826238Swpaul /* 10926238Swpaul * Write to child 11026238Swpaul */ 11126238Swpaul (void)fprintf(childargs, "%s\n", requester); 11226238Swpaul (void)fprintf(childargs, "%u\n", op); 11326238Swpaul (void)fprintf(childargs, "%u\n", keylen); 11426238Swpaul (void)fwrite(key, (int)keylen, 1, childargs); 11526238Swpaul (void)fprintf(childargs, "\n"); 11626238Swpaul (void)fprintf(childargs, "%u\n", datalen); 11726238Swpaul (void)fwrite(data, (int)datalen, 1, childargs); 11826238Swpaul (void)fprintf(childargs, "\n"); 11926238Swpaul (void)fclose(childargs); 12026238Swpaul 12126238Swpaul /* 12226238Swpaul * Read from child 12326238Swpaul */ 12426238Swpaul (void)fscanf(childrslt, "%d", &yperrno); 12526238Swpaul (void)fclose(childrslt); 12626238Swpaul 12726238Swpaul (void)wait(&status); 12826238Swpaul#ifdef WEXITSTATUS 12926238Swpaul if (WEXITSTATUS(status) != 0) { 13026238Swpaul#else 13126238Swpaul if (status.w_retcode != 0) { 13226238Swpaul#endif 13326238Swpaul return (YPERR_YPERR); 13426238Swpaul } 13526238Swpaul return (yperrno); 13626238Swpaul} 13726238Swpaul 13826238Swpaul/* 13926238Swpaul * returns pid, or -1 for failure 14026238Swpaul */ 14187204Smarkmstatic pid_t 14295633Smarkm_openchild(char *command, FILE **fto, FILE **ffrom) 14326238Swpaul{ 14426238Swpaul int i; 14526238Swpaul pid_t pid; 14626238Swpaul int pdto[2]; 14726238Swpaul int pdfrom[2]; 14826238Swpaul char *com; 14926238Swpaul struct rlimit rl; 15026238Swpaul 15126238Swpaul if (pipe(pdto) < 0) { 15226238Swpaul goto error1; 15326238Swpaul } 15426238Swpaul if (pipe(pdfrom) < 0) { 15526238Swpaul goto error2; 15626238Swpaul } 15726238Swpaul switch (pid = fork()) { 15826238Swpaul case -1: 15926238Swpaul goto error3; 16026238Swpaul 16126238Swpaul case 0: 16226238Swpaul /* 16326238Swpaul * child: read from pdto[0], write into pdfrom[1] 16426238Swpaul */ 16526238Swpaul (void)close(0); 16626238Swpaul (void)dup(pdto[0]); 16726238Swpaul (void)close(1); 16826238Swpaul (void)dup(pdfrom[1]); 16926238Swpaul getrlimit(RLIMIT_NOFILE, &rl); 17026238Swpaul for (i = rl.rlim_max - 1; i >= 3; i--) { 17126238Swpaul (void) close(i); 17226238Swpaul } 17326238Swpaul com = malloc((unsigned) strlen(command) + 6); 17426238Swpaul if (com == NULL) { 17526238Swpaul _exit(~0); 17626238Swpaul } 17726238Swpaul (void)sprintf(com, "exec %s", command); 17879452Sbrian execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); 17926238Swpaul _exit(~0); 18026238Swpaul 18126238Swpaul default: 18226238Swpaul /* 18326238Swpaul * parent: write into pdto[1], read from pdfrom[0] 18426238Swpaul */ 18526238Swpaul *fto = fdopen(pdto[1], "w"); 18626238Swpaul (void)close(pdto[0]); 18726238Swpaul *ffrom = fdopen(pdfrom[0], "r"); 18826238Swpaul (void)close(pdfrom[1]); 18926238Swpaul break; 19026238Swpaul } 19126238Swpaul return (pid); 19226238Swpaul 19326238Swpaul /* 19426238Swpaul * error cleanup and return 19526238Swpaul */ 19626238Swpaulerror3: 19726238Swpaul (void)close(pdfrom[0]); 19826238Swpaul (void)close(pdfrom[1]); 19926238Swpaulerror2: 20026238Swpaul (void)close(pdto[0]); 20126238Swpaul (void)close(pdto[1]); 20226238Swpaulerror1: 20326238Swpaul return (-1); 20426238Swpaul} 20526238Swpaul 20626238Swpaulstatic char * 20795633Smarkmbasename(char *path) 20826238Swpaul{ 20926238Swpaul char *p; 21026238Swpaul 21126238Swpaul p = strrchr(path, '/'); 21226238Swpaul if (p == NULL) { 21326238Swpaul return (path); 21426238Swpaul } else { 21526238Swpaul return (p + 1); 21626238Swpaul } 21726238Swpaul} 21826238Swpaul 21926238Swpaul#else /* YP */ 22026238Swpaul 22126238Swpaul#define ERR_ACCESS 1 22226238Swpaul#define ERR_MALLOC 2 22326238Swpaul#define ERR_READ 3 22426238Swpaul#define ERR_WRITE 4 22526238Swpaul#define ERR_DBASE 5 22626238Swpaul#define ERR_KEY 6 22726238Swpaul 22895633Smarkmstatic int match(char *, char *); 22926238Swpaul 23026238Swpaul/* 23126238Swpaul * Determine if requester is allowed to update the given map, 23226238Swpaul * and update it if so. Returns the status, which is zero 23326238Swpaul * if there is no access violation. This function updates 23426238Swpaul * the local file and then shuts up. 23526238Swpaul */ 236141482Sstefanfint 237189169Sedlocalupdate(char *name, char *filename, u_int op, u_int keylen __unused, 238189169Sed char *key, u_int datalen __unused, char *data) 23926238Swpaul{ 24026238Swpaul char line[256]; 24126238Swpaul FILE *rf; 24226238Swpaul FILE *wf; 24326238Swpaul char *tmpname; 24426238Swpaul int err; 24526238Swpaul 24626238Swpaul /* 24726238Swpaul * Check permission 24826238Swpaul */ 24926238Swpaul if (strcmp(name, key) != 0) { 25026238Swpaul return (ERR_ACCESS); 25126238Swpaul } 25226238Swpaul if (strcmp(name, "nobody") == 0) { 25326238Swpaul /* 25426238Swpaul * Can't change "nobody"s key. 25526238Swpaul */ 25626238Swpaul return (ERR_ACCESS); 25726238Swpaul } 25826238Swpaul 25926238Swpaul /* 26026238Swpaul * Open files 26126238Swpaul */ 26226238Swpaul tmpname = malloc(strlen(filename) + 4); 26326238Swpaul if (tmpname == NULL) { 26426238Swpaul return (ERR_MALLOC); 26526238Swpaul } 26626238Swpaul sprintf(tmpname, "%s.tmp", filename); 26726238Swpaul rf = fopen(filename, "r"); 26826238Swpaul if (rf == NULL) { 26926238Swpaul return (ERR_READ); 27026238Swpaul } 27126238Swpaul wf = fopen(tmpname, "w"); 27226238Swpaul if (wf == NULL) { 27326238Swpaul return (ERR_WRITE); 27426238Swpaul } 27526238Swpaul err = -1; 27626238Swpaul while (fgets(line, sizeof (line), rf)) { 27726238Swpaul if (err < 0 && match(line, name)) { 27826238Swpaul switch (op) { 27926238Swpaul case YPOP_INSERT: 28026238Swpaul err = ERR_KEY; 28126238Swpaul break; 28226238Swpaul case YPOP_STORE: 28326238Swpaul case YPOP_CHANGE: 28426238Swpaul fprintf(wf, "%s %s\n", key, data); 28526238Swpaul err = 0; 28626238Swpaul break; 28726238Swpaul case YPOP_DELETE: 28826238Swpaul /* do nothing */ 28926238Swpaul err = 0; 29026238Swpaul break; 29126238Swpaul } 29226238Swpaul } else { 29326238Swpaul fputs(line, wf); 29426238Swpaul } 29526238Swpaul } 29626238Swpaul if (err < 0) { 29726238Swpaul switch (op) { 29826238Swpaul case YPOP_CHANGE: 29926238Swpaul case YPOP_DELETE: 30026238Swpaul err = ERR_KEY; 30126238Swpaul break; 30226238Swpaul case YPOP_INSERT: 30326238Swpaul case YPOP_STORE: 30426238Swpaul err = 0; 30526238Swpaul fprintf(wf, "%s %s\n", key, data); 30626238Swpaul break; 30726238Swpaul } 30826238Swpaul } 30926238Swpaul fclose(wf); 31026238Swpaul fclose(rf); 31126238Swpaul if (err == 0) { 31226238Swpaul if (rename(tmpname, filename) < 0) { 31326238Swpaul return (ERR_DBASE); 31426238Swpaul } 31526238Swpaul } else { 31626238Swpaul if (unlink(tmpname) < 0) { 31726238Swpaul return (ERR_DBASE); 31826238Swpaul } 31926238Swpaul } 32026238Swpaul return (err); 32126238Swpaul} 32226238Swpaul 323141482Sstefanfstatic int 32495633Smarkmmatch(char *line, char *name) 32526238Swpaul{ 32626238Swpaul int len; 32726238Swpaul 32826238Swpaul len = strlen(name); 32926238Swpaul return (strncmp(line, name, len) == 0 && 33026238Swpaul (line[len] == ' ' || line[len] == '\t')); 33126238Swpaul} 33226238Swpaul#endif /* !YP */ 333