xref: /illumos-gate/usr/src/cmd/ypcmd/udpublickey.c (revision 82ae1648ab152f127ab6c9a6bdbea9e0a589a488)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /*	  All Rights Reserved   */
28 
29 /*
30  * Portions of this source code were derived from Berkeley
31  * under license from the Regents of the University of
32  * California.
33  */
34 
35 /*
36  * YP updater for public key map
37  */
38 #include <stdio.h>
39 #include <rpc/rpc.h>
40 #include <rpcsvc/ypclnt.h>
41 #include <sys/file.h>
42 
43 extern char *malloc();
44 
45 int
46 main(argc, argv)
47 	int argc;
48 	char *argv[];
49 {
50 	unsigned op;
51 	char name[MAXNETNAMELEN + 1];
52 	char key[256];
53 	char data[256];
54 	char line[256];
55 	unsigned keylen;
56 	unsigned datalen;
57 	FILE *rf;
58 	FILE *wf;
59 	char *fname;
60 	char *tmpname;
61 	int err;
62 
63 
64 	if (argc !=  3) {
65 		exit(YPERR_YPERR);
66 	}
67 	fname = argv[1];
68 	tmpname = malloc(strlen(fname) + 4);
69 	if (tmpname == NULL) {
70 		exit(YPERR_YPERR);
71 	}
72 	sprintf(tmpname, "%s.tmp", fname);
73 
74 	/*
75 	 * Get input
76 	 */
77 	if (! scanf("%s\n", name)) {
78 		exit(YPERR_YPERR);
79 	}
80 	if (! scanf("%u\n", &op)) {
81 		exit(YPERR_YPERR);
82 	}
83 	if (! scanf("%u\n", &keylen)) {
84 		exit(YPERR_YPERR);
85 	}
86 	if (! fread(key, keylen, 1, stdin)) {
87 		exit(YPERR_YPERR);
88 	}
89 	key[keylen] = 0;
90 	if (! scanf("%u\n", &datalen)) {
91 		exit(YPERR_YPERR);
92 	}
93 	if (! fread(data, datalen, 1, stdin)) {
94 		exit(YPERR_YPERR);
95 	}
96 	data[datalen] = 0;
97 
98 	/*
99 	 * Check permission
100 	 */
101 	if (strcmp(name, key) != 0) {
102 		exit(YPERR_ACCESS);
103 	}
104 	if (strcmp(name, "nobody") == 0) {
105 		/*
106 		 * Can't change "nobody"s key.
107 		 */
108 		exit(YPERR_ACCESS);
109 	}
110 
111 	/*
112 	 * Open files
113 	 */
114 	rf = fopen(fname, "r");
115 	if (rf == NULL) {
116 		exit(YPERR_YPERR);
117 	}
118 	wf = fopen(tmpname, "w");
119 	if (wf == NULL) {
120 		exit(YPERR_YPERR);
121 	}
122 	err = -1;
123 	while (fgets(line, sizeof (line), rf)) {
124 		if (err < 0 && match(line, name)) {
125 			switch (op) {
126 			case YPOP_INSERT:
127 				err = YPERR_KEY;
128 				break;
129 			case YPOP_STORE:
130 			case YPOP_CHANGE:
131 				fprintf(wf, "%s %s\n", key, data);
132 				err = 0;
133 				break;
134 			case YPOP_DELETE:
135 				/* do nothing */
136 				err = 0;
137 				break;
138 			}
139 		} else {
140 			fputs(line, wf);
141 		}
142 	}
143 	if (err < 0) {
144 		switch (op) {
145 		case YPOP_CHANGE:
146 		case YPOP_DELETE:
147 			err = YPERR_KEY;
148 			break;
149 		case YPOP_INSERT:
150 		case YPOP_STORE:
151 			err = 0;
152 			fprintf(wf, "%s %s\n", key, data);
153 			break;
154 		}
155 	}
156 	fclose(wf);
157 	fclose(rf);
158 	if (err == 0) {
159 		if (rename(tmpname, fname) < 0) {
160 			exit(YPERR_YPERR);
161 		}
162 	} else {
163 		if (unlink(tmpname) < 0) {
164 			exit(YPERR_YPERR);
165 		}
166 	}
167 	if (fork() == 0) {
168 		close(0); close(1); close(2);
169 		open("/dev/null", O_RDWR, 0);
170 		dup(0); dup(0);
171 		execl("/bin/sh", "sh", "-c", argv[2], NULL);
172 	}
173 	return (err);
174 	/* NOTREACHED */
175 }
176 
177 
178 int
179 match(line, name)
180 	char *line;
181 	char *name;
182 {
183 	int len;
184 
185 	len = strlen(name);
186 	return (strncmp(line, name, len) == 0 &&
187 		(line[len] == ' ' || line[len] == '\t'));
188 }
189