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 /*
3240a5f74dSBill Paul * Copyright (C) 1986, 1989, Sun Microsystems, Inc.
3340a5f74dSBill Paul */
3440a5f74dSBill Paul
3540a5f74dSBill Paul /*
3640a5f74dSBill Paul * Administrative tool to add a new user to the publickey database
3740a5f74dSBill Paul */
3840a5f74dSBill Paul #include <stdio.h>
3940a5f74dSBill Paul #include <stdlib.h>
4040a5f74dSBill Paul #include <unistd.h>
4140a5f74dSBill Paul #include <rpc/rpc.h>
4240a5f74dSBill Paul #include <rpc/key_prot.h>
4340a5f74dSBill Paul #ifdef YP
4440a5f74dSBill Paul #include <rpcsvc/yp_prot.h>
4540a5f74dSBill Paul #include <rpcsvc/ypclnt.h>
4640a5f74dSBill Paul #include <sys/wait.h>
4740a5f74dSBill Paul #include <netdb.h>
4840a5f74dSBill Paul #endif /* YP */
4940a5f74dSBill Paul #include <pwd.h>
5040a5f74dSBill Paul #include <string.h>
5140a5f74dSBill Paul #include <sys/resource.h>
5240a5f74dSBill Paul #include "ypupdated_extern.h"
5340a5f74dSBill Paul
5440a5f74dSBill Paul #ifdef YP
5540a5f74dSBill Paul #define MAXMAPNAMELEN 256
5640a5f74dSBill Paul #else
5740a5f74dSBill Paul #define YPOP_CHANGE 1 /* change, do not add */
5840a5f74dSBill Paul #define YPOP_INSERT 2 /* add, do not change */
5940a5f74dSBill Paul #define YPOP_DELETE 3 /* delete this entry */
6040a5f74dSBill Paul #define YPOP_STORE 4 /* add, or change */
6140a5f74dSBill Paul #endif
6240a5f74dSBill Paul
6340a5f74dSBill Paul #ifdef YP
6440a5f74dSBill Paul static char SHELL[] = "/bin/sh";
6540a5f74dSBill Paul static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */
6640a5f74dSBill Paul static char PKMAP[] = "publickey.byname";
6740a5f74dSBill Paul static char UPDATEFILE[] = "updaters";
6840a5f74dSBill Paul static char PKFILE[] = "/etc/publickey";
6940a5f74dSBill Paul #endif /* YP */
7040a5f74dSBill Paul
7140a5f74dSBill Paul #ifdef YP
72ed4d1c46SDag-Erling Smørgrav static int _openchild(char *, FILE **, FILE **);
7340a5f74dSBill Paul
7440a5f74dSBill Paul /*
7540a5f74dSBill Paul * Determine if requester is allowed to update the given map,
7640a5f74dSBill Paul * and update it if so. Returns the yp status, which is zero
7740a5f74dSBill Paul * if there is no access violation.
7840a5f74dSBill Paul */
79dc584ddbSDag-Erling Smørgrav int
mapupdate(char * requester,char * mapname,u_int op,u_int keylen,char * key,u_int datalen,char * data)80dc584ddbSDag-Erling Smørgrav mapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key,
81dc584ddbSDag-Erling Smørgrav u_int datalen, char *data)
8240a5f74dSBill Paul {
8340a5f74dSBill Paul char updater[MAXMAPNAMELEN + 40];
8440a5f74dSBill Paul FILE *childargs;
8540a5f74dSBill Paul FILE *childrslt;
8640a5f74dSBill Paul #ifdef WEXITSTATUS
8740a5f74dSBill Paul int status;
8840a5f74dSBill Paul #else
8940a5f74dSBill Paul union wait status;
9040a5f74dSBill Paul #endif
9140a5f74dSBill Paul pid_t pid;
9240a5f74dSBill Paul u_int yperrno;
9340a5f74dSBill Paul
9440a5f74dSBill Paul
9540a5f74dSBill Paul #ifdef DEBUG
9640a5f74dSBill Paul printf("%s %s\n", key, data);
9740a5f74dSBill Paul #endif
9840a5f74dSBill Paul (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */
9940a5f74dSBill Paul UPDATEFILE, mapname);
10040a5f74dSBill Paul pid = _openchild(updater, &childargs, &childrslt);
10140a5f74dSBill Paul if (pid < 0) {
10240a5f74dSBill Paul return (YPERR_YPERR);
10340a5f74dSBill Paul }
10440a5f74dSBill Paul
10540a5f74dSBill Paul /*
10640a5f74dSBill Paul * Write to child
10740a5f74dSBill Paul */
10840a5f74dSBill Paul (void)fprintf(childargs, "%s\n", requester);
10940a5f74dSBill Paul (void)fprintf(childargs, "%u\n", op);
11040a5f74dSBill Paul (void)fprintf(childargs, "%u\n", keylen);
11140a5f74dSBill Paul (void)fwrite(key, (int)keylen, 1, childargs);
11240a5f74dSBill Paul (void)fprintf(childargs, "\n");
11340a5f74dSBill Paul (void)fprintf(childargs, "%u\n", datalen);
11440a5f74dSBill Paul (void)fwrite(data, (int)datalen, 1, childargs);
11540a5f74dSBill Paul (void)fprintf(childargs, "\n");
11640a5f74dSBill Paul (void)fclose(childargs);
11740a5f74dSBill Paul
11840a5f74dSBill Paul /*
11940a5f74dSBill Paul * Read from child
12040a5f74dSBill Paul */
12140a5f74dSBill Paul (void)fscanf(childrslt, "%d", &yperrno);
12240a5f74dSBill Paul (void)fclose(childrslt);
12340a5f74dSBill Paul
12440a5f74dSBill Paul (void)wait(&status);
12540a5f74dSBill Paul #ifdef WEXITSTATUS
126dc584ddbSDag-Erling Smørgrav if (WEXITSTATUS(status) != 0)
12740a5f74dSBill Paul #else
128dc584ddbSDag-Erling Smørgrav if (status.w_retcode != 0)
12940a5f74dSBill Paul #endif
13040a5f74dSBill Paul return (YPERR_YPERR);
13140a5f74dSBill Paul return (yperrno);
13240a5f74dSBill Paul }
13340a5f74dSBill Paul
13440a5f74dSBill Paul /*
13540a5f74dSBill Paul * returns pid, or -1 for failure
13640a5f74dSBill Paul */
137dc584ddbSDag-Erling Smørgrav static int
_openchild(char * command,FILE ** fto,FILE ** ffrom)138dc584ddbSDag-Erling Smørgrav _openchild(char *command, FILE **fto, FILE **ffrom)
13940a5f74dSBill Paul {
14040a5f74dSBill Paul int i;
14140a5f74dSBill Paul pid_t pid;
14240a5f74dSBill Paul int pdto[2];
14340a5f74dSBill Paul int pdfrom[2];
14440a5f74dSBill Paul char *com;
14540a5f74dSBill Paul struct rlimit rl;
14640a5f74dSBill Paul
14740a5f74dSBill Paul if (pipe(pdto) < 0) {
14840a5f74dSBill Paul goto error1;
14940a5f74dSBill Paul }
15040a5f74dSBill Paul if (pipe(pdfrom) < 0) {
15140a5f74dSBill Paul goto error2;
15240a5f74dSBill Paul }
15340a5f74dSBill Paul switch (pid = fork()) {
15440a5f74dSBill Paul case -1:
15540a5f74dSBill Paul goto error3;
15640a5f74dSBill Paul
15740a5f74dSBill Paul case 0:
15840a5f74dSBill Paul /*
15940a5f74dSBill Paul * child: read from pdto[0], write into pdfrom[1]
16040a5f74dSBill Paul */
16140a5f74dSBill Paul (void)close(0);
16240a5f74dSBill Paul (void)dup(pdto[0]);
16340a5f74dSBill Paul (void)close(1);
16440a5f74dSBill Paul (void)dup(pdfrom[1]);
16540a5f74dSBill Paul getrlimit(RLIMIT_NOFILE, &rl);
16640a5f74dSBill Paul for (i = rl.rlim_max - 1; i >= 3; i--) {
16740a5f74dSBill Paul (void) close(i);
16840a5f74dSBill Paul }
16940a5f74dSBill Paul com = malloc((unsigned) strlen(command) + 6);
17040a5f74dSBill Paul if (com == NULL) {
17140a5f74dSBill Paul _exit(~0);
17240a5f74dSBill Paul }
17340a5f74dSBill Paul (void)sprintf(com, "exec %s", command);
1747bc6d015SBrian Somers execl(SHELL, basename(SHELL), "-c", com, (char *)NULL);
17540a5f74dSBill Paul _exit(~0);
17640a5f74dSBill Paul
17740a5f74dSBill Paul default:
17840a5f74dSBill Paul /*
17940a5f74dSBill Paul * parent: write into pdto[1], read from pdfrom[0]
18040a5f74dSBill Paul */
18140a5f74dSBill Paul *fto = fdopen(pdto[1], "w");
18240a5f74dSBill Paul (void)close(pdto[0]);
18340a5f74dSBill Paul *ffrom = fdopen(pdfrom[0], "r");
18440a5f74dSBill Paul (void)close(pdfrom[1]);
18540a5f74dSBill Paul break;
18640a5f74dSBill Paul }
18740a5f74dSBill Paul return (pid);
18840a5f74dSBill Paul
18940a5f74dSBill Paul /*
19040a5f74dSBill Paul * error cleanup and return
19140a5f74dSBill Paul */
19240a5f74dSBill Paul error3:
19340a5f74dSBill Paul (void)close(pdfrom[0]);
19440a5f74dSBill Paul (void)close(pdfrom[1]);
19540a5f74dSBill Paul error2:
19640a5f74dSBill Paul (void)close(pdto[0]);
19740a5f74dSBill Paul (void)close(pdto[1]);
19840a5f74dSBill Paul error1:
19940a5f74dSBill Paul return (-1);
20040a5f74dSBill Paul }
20140a5f74dSBill Paul
20240a5f74dSBill Paul static char *
basename(char * path)203dc584ddbSDag-Erling Smørgrav basename(char *path)
20440a5f74dSBill Paul {
20540a5f74dSBill Paul char *p;
20640a5f74dSBill Paul
20740a5f74dSBill Paul p = strrchr(path, '/');
20840a5f74dSBill Paul if (p == NULL) {
20940a5f74dSBill Paul return (path);
21040a5f74dSBill Paul } else {
21140a5f74dSBill Paul return (p + 1);
21240a5f74dSBill Paul }
21340a5f74dSBill Paul }
21440a5f74dSBill Paul
21540a5f74dSBill Paul #else /* YP */
21640a5f74dSBill Paul
217ed4d1c46SDag-Erling Smørgrav static int match(char *, char *);
21840a5f74dSBill Paul
21940a5f74dSBill Paul /*
22040a5f74dSBill Paul * Determine if requester is allowed to update the given map,
22140a5f74dSBill Paul * and update it if so. Returns the status, which is zero
22240a5f74dSBill Paul * if there is no access violation. This function updates
22340a5f74dSBill Paul * the local file and then shuts up.
22440a5f74dSBill Paul */
22540a5f74dSBill Paul int
localupdate(char * name,char * filename,u_int op,u_int keylen __unused,char * key,u_int datalen __unused,char * data)226dc584ddbSDag-Erling Smørgrav localupdate(char *name, char *filename, u_int op, u_int keylen __unused,
227dc584ddbSDag-Erling Smørgrav char *key, u_int datalen __unused, char *data)
22840a5f74dSBill Paul {
22940a5f74dSBill Paul char line[256];
23040a5f74dSBill Paul FILE *rf;
23140a5f74dSBill Paul FILE *wf;
23240a5f74dSBill Paul char *tmpname;
23340a5f74dSBill Paul int err;
23440a5f74dSBill Paul
23540a5f74dSBill Paul /*
23640a5f74dSBill Paul * Check permission
23740a5f74dSBill Paul */
23840a5f74dSBill Paul if (strcmp(name, key) != 0) {
23940a5f74dSBill Paul return (ERR_ACCESS);
24040a5f74dSBill Paul }
24140a5f74dSBill Paul if (strcmp(name, "nobody") == 0) {
24240a5f74dSBill Paul /*
24340a5f74dSBill Paul * Can't change "nobody"s key.
24440a5f74dSBill Paul */
24540a5f74dSBill Paul return (ERR_ACCESS);
24640a5f74dSBill Paul }
24740a5f74dSBill Paul
24840a5f74dSBill Paul /*
24940a5f74dSBill Paul * Open files
25040a5f74dSBill Paul */
25140a5f74dSBill Paul tmpname = malloc(strlen(filename) + 4);
25240a5f74dSBill Paul if (tmpname == NULL) {
25340a5f74dSBill Paul return (ERR_MALLOC);
25440a5f74dSBill Paul }
25540a5f74dSBill Paul sprintf(tmpname, "%s.tmp", filename);
25640a5f74dSBill Paul rf = fopen(filename, "r");
25740a5f74dSBill Paul if (rf == NULL) {
258*994558c3SAndriy Voskoboinyk err = ERR_READ;
259*994558c3SAndriy Voskoboinyk goto cleanup;
26040a5f74dSBill Paul }
26140a5f74dSBill Paul wf = fopen(tmpname, "w");
26240a5f74dSBill Paul if (wf == NULL) {
263*994558c3SAndriy Voskoboinyk fclose(rf);
264*994558c3SAndriy Voskoboinyk err = ERR_WRITE;
265*994558c3SAndriy Voskoboinyk goto cleanup;
26640a5f74dSBill Paul }
26740a5f74dSBill Paul err = -1;
26840a5f74dSBill Paul while (fgets(line, sizeof (line), rf)) {
26940a5f74dSBill Paul if (err < 0 && match(line, name)) {
27040a5f74dSBill Paul switch (op) {
27140a5f74dSBill Paul case YPOP_INSERT:
27240a5f74dSBill Paul err = ERR_KEY;
27340a5f74dSBill Paul break;
27440a5f74dSBill Paul case YPOP_STORE:
27540a5f74dSBill Paul case YPOP_CHANGE:
27640a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data);
27740a5f74dSBill Paul err = 0;
27840a5f74dSBill Paul break;
27940a5f74dSBill Paul case YPOP_DELETE:
28040a5f74dSBill Paul /* do nothing */
28140a5f74dSBill Paul err = 0;
28240a5f74dSBill Paul break;
28340a5f74dSBill Paul }
28440a5f74dSBill Paul } else {
28540a5f74dSBill Paul fputs(line, wf);
28640a5f74dSBill Paul }
28740a5f74dSBill Paul }
28840a5f74dSBill Paul if (err < 0) {
28940a5f74dSBill Paul switch (op) {
29040a5f74dSBill Paul case YPOP_CHANGE:
29140a5f74dSBill Paul case YPOP_DELETE:
29240a5f74dSBill Paul err = ERR_KEY;
29340a5f74dSBill Paul break;
29440a5f74dSBill Paul case YPOP_INSERT:
29540a5f74dSBill Paul case YPOP_STORE:
29640a5f74dSBill Paul err = 0;
29740a5f74dSBill Paul fprintf(wf, "%s %s\n", key, data);
29840a5f74dSBill Paul break;
29940a5f74dSBill Paul }
30040a5f74dSBill Paul }
30140a5f74dSBill Paul fclose(wf);
30240a5f74dSBill Paul fclose(rf);
30340a5f74dSBill Paul if (err == 0) {
30440a5f74dSBill Paul if (rename(tmpname, filename) < 0) {
305*994558c3SAndriy Voskoboinyk err = ERR_DBASE;
306*994558c3SAndriy Voskoboinyk goto cleanup;
30740a5f74dSBill Paul }
30840a5f74dSBill Paul } else {
30940a5f74dSBill Paul if (unlink(tmpname) < 0) {
310*994558c3SAndriy Voskoboinyk err = ERR_DBASE;
311*994558c3SAndriy Voskoboinyk goto cleanup;
31240a5f74dSBill Paul }
31340a5f74dSBill Paul }
314*994558c3SAndriy Voskoboinyk cleanup:
315*994558c3SAndriy Voskoboinyk free(tmpname);
31640a5f74dSBill Paul return (err);
31740a5f74dSBill Paul }
31840a5f74dSBill Paul
31940a5f74dSBill Paul static int
match(char * line,char * name)320dc584ddbSDag-Erling Smørgrav match(char *line, char *name)
32140a5f74dSBill Paul {
32240a5f74dSBill Paul int len;
32340a5f74dSBill Paul
32440a5f74dSBill Paul len = strlen(name);
32540a5f74dSBill Paul return (strncmp(line, name, len) == 0 &&
32640a5f74dSBill Paul (line[len] == ' ' || line[len] == '\t'));
32740a5f74dSBill Paul }
32840a5f74dSBill Paul #endif /* !YP */
329