126236Swpaul/* 226236Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326236Swpaul * unrestricted use provided that this legend is included on all tape 426236Swpaul * media and as a part of the software program in whole or part. Users 526236Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626236Swpaul * to license or distribute it to anyone else except as part of a product or 726236Swpaul * program developed by the user or with the express written consent of 826236Swpaul * Sun Microsystems, Inc. 926236Swpaul * 1026236Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1126236Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1226236Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1326236Swpaul * 1426236Swpaul * Sun RPC is provided with no support and without any obligation on the 1526236Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1626236Swpaul * modification or enhancement. 1726236Swpaul * 1826236Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1926236Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2026236Swpaul * OR ANY PART THEREOF. 2126236Swpaul * 2226236Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2326236Swpaul * or profits or other special, indirect and consequential damages, even if 2426236Swpaul * Sun has been advised of the possibility of such damages. 2526236Swpaul * 2626236Swpaul * Sun Microsystems, Inc. 2726236Swpaul * 2550 Garcia Avenue 2826236Swpaul * Mountain View, California 94043 2926236Swpaul */ 3030378Scharnier 3126236Swpaul#ifndef lint 3230378Scharnier#if 0 3326236Swpaulstatic char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro"; 3426236Swpaul#endif 3530378Scharnierstatic const char rcsid[] = 3650479Speter "$FreeBSD$"; 3730378Scharnier#endif /* not lint */ 3826236Swpaul 3926236Swpaul/* 4026236Swpaul * Copyright (C) 1986, 1989, Sun Microsystems, Inc. 4126236Swpaul */ 4226236Swpaul 4326236Swpaul/* 4426236Swpaul * Administrative tool to add a new user to the publickey database 4526236Swpaul */ 4626236Swpaul#include <stdio.h> 4726236Swpaul#include <stdlib.h> 4826236Swpaul#include <unistd.h> 4926236Swpaul#include <rpc/rpc.h> 5026236Swpaul#include <rpc/key_prot.h> 5126236Swpaul#ifdef YP 5226236Swpaul#include <rpcsvc/yp_prot.h> 5326236Swpaul#include <rpcsvc/ypclnt.h> 5426236Swpaul#include <sys/wait.h> 5526236Swpaul#include <netdb.h> 5626236Swpaul#endif /* YP */ 5726236Swpaul#include <pwd.h> 5826236Swpaul#include <string.h> 5926236Swpaul#include <sys/resource.h> 6026236Swpaul#include "ypupdated_extern.h" 6126236Swpaul 6226236Swpaul#ifdef YP 6326236Swpaul#define MAXMAPNAMELEN 256 6426236Swpaul#else 6526236Swpaul#define YPOP_CHANGE 1 /* change, do not add */ 6626236Swpaul#define YPOP_INSERT 2 /* add, do not change */ 6726236Swpaul#define YPOP_DELETE 3 /* delete this entry */ 6826236Swpaul#define YPOP_STORE 4 /* add, or change */ 6926236Swpaul#endif 7026236Swpaul 7126236Swpaul#ifdef YP 7226236Swpaulstatic char SHELL[] = "/bin/sh"; 7326236Swpaulstatic char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ 7426236Swpaulstatic char PKMAP[] = "publickey.byname"; 7526236Swpaulstatic char UPDATEFILE[] = "updaters"; 7626236Swpaulstatic char PKFILE[] = "/etc/publickey"; 7726236Swpaul#endif /* YP */ 7826236Swpaul 7926236Swpaul#ifdef YP 8090297Sdesstatic int _openchild(char *, FILE **, FILE **); 8126236Swpaul 8226236Swpaul/* 8326236Swpaul * Determine if requester is allowed to update the given map, 8426236Swpaul * and update it if so. Returns the yp status, which is zero 8526236Swpaul * if there is no access violation. 8626236Swpaul */ 8790298Sdesint 8890298Sdesmapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key, 8990298Sdes u_int datalen, char *data) 9026236Swpaul{ 9126236Swpaul char updater[MAXMAPNAMELEN + 40]; 9226236Swpaul FILE *childargs; 9326236Swpaul FILE *childrslt; 9426236Swpaul#ifdef WEXITSTATUS 9526236Swpaul int status; 9626236Swpaul#else 9726236Swpaul union wait status; 9826236Swpaul#endif 9926236Swpaul pid_t pid; 10026236Swpaul u_int yperrno; 10126236Swpaul 10226236Swpaul 10326236Swpaul#ifdef DEBUG 10426236Swpaul printf("%s %s\n", key, data); 10526236Swpaul#endif 10626236Swpaul (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ 10726236Swpaul UPDATEFILE, mapname); 10826236Swpaul pid = _openchild(updater, &childargs, &childrslt); 10926236Swpaul if (pid < 0) { 11026236Swpaul return (YPERR_YPERR); 11126236Swpaul } 11226236Swpaul 11326236Swpaul /* 11426236Swpaul * Write to child 11526236Swpaul */ 11626236Swpaul (void)fprintf(childargs, "%s\n", requester); 11726236Swpaul (void)fprintf(childargs, "%u\n", op); 11826236Swpaul (void)fprintf(childargs, "%u\n", keylen); 11926236Swpaul (void)fwrite(key, (int)keylen, 1, childargs); 12026236Swpaul (void)fprintf(childargs, "\n"); 12126236Swpaul (void)fprintf(childargs, "%u\n", datalen); 12226236Swpaul (void)fwrite(data, (int)datalen, 1, childargs); 12326236Swpaul (void)fprintf(childargs, "\n"); 12426236Swpaul (void)fclose(childargs); 12526236Swpaul 12626236Swpaul /* 12726236Swpaul * Read from child 12826236Swpaul */ 12926236Swpaul (void)fscanf(childrslt, "%d", &yperrno); 13026236Swpaul (void)fclose(childrslt); 13126236Swpaul 13226236Swpaul (void)wait(&status); 13326236Swpaul#ifdef WEXITSTATUS 13490298Sdes if (WEXITSTATUS(status) != 0) 13526236Swpaul#else 13690298Sdes if (status.w_retcode != 0) 13726236Swpaul#endif 13826236Swpaul return (YPERR_YPERR); 13926236Swpaul return (yperrno); 14026236Swpaul} 14126236Swpaul 14226236Swpaul/* 14326236Swpaul * returns pid, or -1 for failure 14426236Swpaul */ 14590298Sdesstatic int 14690298Sdes_openchild(char *command, FILE **fto, FILE **ffrom) 14726236Swpaul{ 14826236Swpaul int i; 14926236Swpaul pid_t pid; 15026236Swpaul int pdto[2]; 15126236Swpaul int pdfrom[2]; 15226236Swpaul char *com; 15326236Swpaul struct rlimit rl; 15426236Swpaul 15526236Swpaul if (pipe(pdto) < 0) { 15626236Swpaul goto error1; 15726236Swpaul } 15826236Swpaul if (pipe(pdfrom) < 0) { 15926236Swpaul goto error2; 16026236Swpaul } 16126236Swpaul switch (pid = fork()) { 16226236Swpaul case -1: 16326236Swpaul goto error3; 16426236Swpaul 16526236Swpaul case 0: 16626236Swpaul /* 16726236Swpaul * child: read from pdto[0], write into pdfrom[1] 16826236Swpaul */ 16926236Swpaul (void)close(0); 17026236Swpaul (void)dup(pdto[0]); 17126236Swpaul (void)close(1); 17226236Swpaul (void)dup(pdfrom[1]); 17326236Swpaul getrlimit(RLIMIT_NOFILE, &rl); 17426236Swpaul for (i = rl.rlim_max - 1; i >= 3; i--) { 17526236Swpaul (void) close(i); 17626236Swpaul } 17726236Swpaul com = malloc((unsigned) strlen(command) + 6); 17826236Swpaul if (com == NULL) { 17926236Swpaul _exit(~0); 18026236Swpaul } 18126236Swpaul (void)sprintf(com, "exec %s", command); 18279452Sbrian execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); 18326236Swpaul _exit(~0); 18426236Swpaul 18526236Swpaul default: 18626236Swpaul /* 18726236Swpaul * parent: write into pdto[1], read from pdfrom[0] 18826236Swpaul */ 18926236Swpaul *fto = fdopen(pdto[1], "w"); 19026236Swpaul (void)close(pdto[0]); 19126236Swpaul *ffrom = fdopen(pdfrom[0], "r"); 19226236Swpaul (void)close(pdfrom[1]); 19326236Swpaul break; 19426236Swpaul } 19526236Swpaul return (pid); 19626236Swpaul 19726236Swpaul /* 19826236Swpaul * error cleanup and return 19926236Swpaul */ 20026236Swpaulerror3: 20126236Swpaul (void)close(pdfrom[0]); 20226236Swpaul (void)close(pdfrom[1]); 20326236Swpaulerror2: 20426236Swpaul (void)close(pdto[0]); 20526236Swpaul (void)close(pdto[1]); 20626236Swpaulerror1: 20726236Swpaul return (-1); 20826236Swpaul} 20926236Swpaul 21026236Swpaulstatic char * 21190298Sdesbasename(char *path) 21226236Swpaul{ 21326236Swpaul char *p; 21426236Swpaul 21526236Swpaul p = strrchr(path, '/'); 21626236Swpaul if (p == NULL) { 21726236Swpaul return (path); 21826236Swpaul } else { 21926236Swpaul return (p + 1); 22026236Swpaul } 22126236Swpaul} 22226236Swpaul 22326236Swpaul#else /* YP */ 22426236Swpaul 22590297Sdesstatic int match(char *, char *); 22626236Swpaul 22726236Swpaul/* 22826236Swpaul * Determine if requester is allowed to update the given map, 22926236Swpaul * and update it if so. Returns the status, which is zero 23026236Swpaul * if there is no access violation. This function updates 23126236Swpaul * the local file and then shuts up. 23226236Swpaul */ 23326236Swpaulint 23490298Sdeslocalupdate(char *name, char *filename, u_int op, u_int keylen __unused, 23590298Sdes char *key, u_int datalen __unused, char *data) 23626236Swpaul{ 23726236Swpaul char line[256]; 23826236Swpaul FILE *rf; 23926236Swpaul FILE *wf; 24026236Swpaul char *tmpname; 24126236Swpaul int err; 24226236Swpaul 24326236Swpaul /* 24426236Swpaul * Check permission 24526236Swpaul */ 24626236Swpaul if (strcmp(name, key) != 0) { 24726236Swpaul return (ERR_ACCESS); 24826236Swpaul } 24926236Swpaul if (strcmp(name, "nobody") == 0) { 25026236Swpaul /* 25126236Swpaul * Can't change "nobody"s key. 25226236Swpaul */ 25326236Swpaul return (ERR_ACCESS); 25426236Swpaul } 25526236Swpaul 25626236Swpaul /* 25726236Swpaul * Open files 25826236Swpaul */ 25926236Swpaul tmpname = malloc(strlen(filename) + 4); 26026236Swpaul if (tmpname == NULL) { 26126236Swpaul return (ERR_MALLOC); 26226236Swpaul } 26326236Swpaul sprintf(tmpname, "%s.tmp", filename); 26426236Swpaul rf = fopen(filename, "r"); 26526236Swpaul if (rf == NULL) { 26626236Swpaul return (ERR_READ); 26726236Swpaul } 26826236Swpaul wf = fopen(tmpname, "w"); 26926236Swpaul if (wf == NULL) { 27026236Swpaul return (ERR_WRITE); 27126236Swpaul } 27226236Swpaul err = -1; 27326236Swpaul while (fgets(line, sizeof (line), rf)) { 27426236Swpaul if (err < 0 && match(line, name)) { 27526236Swpaul switch (op) { 27626236Swpaul case YPOP_INSERT: 27726236Swpaul err = ERR_KEY; 27826236Swpaul break; 27926236Swpaul case YPOP_STORE: 28026236Swpaul case YPOP_CHANGE: 28126236Swpaul fprintf(wf, "%s %s\n", key, data); 28226236Swpaul err = 0; 28326236Swpaul break; 28426236Swpaul case YPOP_DELETE: 28526236Swpaul /* do nothing */ 28626236Swpaul err = 0; 28726236Swpaul break; 28826236Swpaul } 28926236Swpaul } else { 29026236Swpaul fputs(line, wf); 29126236Swpaul } 29226236Swpaul } 29326236Swpaul if (err < 0) { 29426236Swpaul switch (op) { 29526236Swpaul case YPOP_CHANGE: 29626236Swpaul case YPOP_DELETE: 29726236Swpaul err = ERR_KEY; 29826236Swpaul break; 29926236Swpaul case YPOP_INSERT: 30026236Swpaul case YPOP_STORE: 30126236Swpaul err = 0; 30226236Swpaul fprintf(wf, "%s %s\n", key, data); 30326236Swpaul break; 30426236Swpaul } 30526236Swpaul } 30626236Swpaul fclose(wf); 30726236Swpaul fclose(rf); 30826236Swpaul if (err == 0) { 30926236Swpaul if (rename(tmpname, filename) < 0) { 31026236Swpaul return (ERR_DBASE); 31126236Swpaul } 31226236Swpaul } else { 31326236Swpaul if (unlink(tmpname) < 0) { 31426236Swpaul return (ERR_DBASE); 31526236Swpaul } 31626236Swpaul } 31726236Swpaul return (err); 31826236Swpaul} 31926236Swpaul 32026236Swpaulstatic int 32190298Sdesmatch(char *line, char *name) 32226236Swpaul{ 32326236Swpaul int len; 32426236Swpaul 32526236Swpaul len = strlen(name); 32626236Swpaul return (strncmp(line, name, len) == 0 && 32726236Swpaul (line[len] == ' ' || line[len] == '\t')); 32826236Swpaul} 32926236Swpaul#endif /* !YP */ 330