xref: /illumos-gate/usr/src/cmd/ypcmd/udpublickey.c (revision 51396a8ee7fb52fe0ab33bfe7b4f495ad431904a)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
36 
37 /*
38  * YP updater for public key map
39  */
40 #include <stdio.h>
41 #include <rpc/rpc.h>
42 #include <rpcsvc/ypclnt.h>
43 #include <sys/file.h>
44 
45 extern char *malloc();
46 
47 int
48 main(argc, argv)
49 	int argc;
50 	char *argv[];
51 {
52 	unsigned op;
53 	char name[MAXNETNAMELEN + 1];
54 	char key[256];
55 	char data[256];
56 	char line[256];
57 	unsigned keylen;
58 	unsigned datalen;
59 	FILE *rf;
60 	FILE *wf;
61 	char *fname;
62 	char *tmpname;
63 	int err;
64 
65 
66 	if (argc !=  3) {
67 		exit(YPERR_YPERR);
68 	}
69 	fname = argv[1];
70 	tmpname = malloc(strlen(fname) + 4);
71 	if (tmpname == NULL) {
72 		exit(YPERR_YPERR);
73 	}
74 	sprintf(tmpname, "%s.tmp", fname);
75 
76 	/*
77 	 * Get input
78 	 */
79 	if (! scanf("%s\n", name)) {
80 		exit(YPERR_YPERR);
81 	}
82 	if (! scanf("%u\n", &op)) {
83 		exit(YPERR_YPERR);
84 	}
85 	if (! scanf("%u\n", &keylen)) {
86 		exit(YPERR_YPERR);
87 	}
88 	if (! fread(key, keylen, 1, stdin)) {
89 		exit(YPERR_YPERR);
90 	}
91 	key[keylen] = 0;
92 	if (! scanf("%u\n", &datalen)) {
93 		exit(YPERR_YPERR);
94 	}
95 	if (! fread(data, datalen, 1, stdin)) {
96 		exit(YPERR_YPERR);
97 	}
98 	data[datalen] = 0;
99 
100 	/*
101 	 * Check permission
102 	 */
103 	if (strcmp(name, key) != 0) {
104 		exit(YPERR_ACCESS);
105 	}
106 	if (strcmp(name, "nobody") == 0) {
107 		/*
108 		 * Can't change "nobody"s key.
109 		 */
110 		exit(YPERR_ACCESS);
111 	}
112 
113 	/*
114 	 * Open files
115 	 */
116 	rf = fopen(fname, "r");
117 	if (rf == NULL) {
118 		exit(YPERR_YPERR);
119 	}
120 	wf = fopen(tmpname, "w");
121 	if (wf == NULL) {
122 		exit(YPERR_YPERR);
123 	}
124 	err = -1;
125 	while (fgets(line, sizeof (line), rf)) {
126 		if (err < 0 && match(line, name)) {
127 			switch (op) {
128 			case YPOP_INSERT:
129 				err = YPERR_KEY;
130 				break;
131 			case YPOP_STORE:
132 			case YPOP_CHANGE:
133 				fprintf(wf, "%s %s\n", key, data);
134 				err = 0;
135 				break;
136 			case YPOP_DELETE:
137 				/* do nothing */
138 				err = 0;
139 				break;
140 			}
141 		} else {
142 			fputs(line, wf);
143 		}
144 	}
145 	if (err < 0) {
146 		switch (op) {
147 		case YPOP_CHANGE:
148 		case YPOP_DELETE:
149 			err = YPERR_KEY;
150 			break;
151 		case YPOP_INSERT:
152 		case YPOP_STORE:
153 			err = 0;
154 			fprintf(wf, "%s %s\n", key, data);
155 			break;
156 		}
157 	}
158 	fclose(wf);
159 	fclose(rf);
160 	if (err == 0) {
161 		if (rename(tmpname, fname) < 0) {
162 			exit(YPERR_YPERR);
163 		}
164 	} else {
165 		if (unlink(tmpname) < 0) {
166 			exit(YPERR_YPERR);
167 		}
168 	}
169 	if (fork() == 0) {
170 		close(0); close(1); close(2);
171 		open("/dev/null", O_RDWR, 0);
172 		dup(0); dup(0);
173 		execl("/bin/sh", "sh", "-c", argv[2], NULL);
174 	}
175 	return (err);
176 	/* NOTREACHED */
177 }
178 
179 
180 int
181 match(line, name)
182 	char *line;
183 	char *name;
184 {
185 	int len;
186 
187 	len = strlen(name);
188 	return (strncmp(line, name, len) == 0 &&
189 		(line[len] == ' ' || line[len] == '\t'));
190 }
191