newkey.c revision 26238
1/*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part.  Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
9 *
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 *
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
17 *
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
21 *
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
25 *
26 * Sun Microsystems, Inc.
27 * 2550 Garcia Avenue
28 * Mountain View, California  94043
29 */
30#if !defined(lint) && defined(SCCSIDS)
31static char sccsid[] = "@(#)newkey.c 1.8 91/03/11 Copyr 1986 Sun Micro";
32#endif
33
34/*
35 * Copyright (C) 1986, Sun Microsystems, Inc.
36 */
37
38/*
39 * Administrative tool to add a new user to the publickey database
40 */
41#include <stdio.h>
42#include <rpc/rpc.h>
43#include <rpc/key_prot.h>
44#ifdef YP
45#include <rpcsvc/yp_prot.h>
46#include <rpcsvc/ypclnt.h>
47#include <sys/wait.h>
48#include <netdb.h>
49#endif	/* YP */
50#include <pwd.h>
51#include <string.h>
52#include <sys/resource.h>
53
54#ifdef YP
55#define MAXMAPNAMELEN 256
56#else
57#define	YPOP_CHANGE 1			/* change, do not add */
58#define	YPOP_INSERT 2			/* add, do not change */
59#define	YPOP_DELETE 3			/* delete this entry */
60#define	YPOP_STORE  4			/* add, or change */
61#define	ERR_ACCESS	1
62#define	ERR_MALLOC	2
63#define	ERR_READ	3
64#define	ERR_WRITE	4
65#define	ERR_DBASE	5
66#define	ERR_KEY		6
67#endif
68
69extern char *getpass();
70extern char *malloc();
71
72#ifdef YP
73static char *basename();
74static char SHELL[] = "/bin/sh";
75static char YPDBPATH[]="/var/yp";
76static char PKMAP[] = "publickey.byname";
77static char UPDATEFILE[] = "updaters";
78#else
79static char PKFILE[] = "/etc/publickey";
80static char *err_string();
81#endif	/* YP */
82
83main(argc, argv)
84	int argc;
85	char *argv[];
86{
87	char name[MAXNETNAMELEN + 1];
88	char public[HEXKEYBYTES + 1];
89	char secret[HEXKEYBYTES + 1];
90	char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
91	char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
92	int status;
93	char *pass;
94	struct passwd *pw;
95#ifdef undef
96	struct hostent *h;
97#endif
98
99	if (argc != 3 || !(strcmp(argv[1], "-u") == 0 ||
100		strcmp(argv[1], "-h") == 0)) {
101		(void)fprintf(stderr, "usage: %s [-u username]\n",
102				argv[0]);
103		(void)fprintf(stderr, "usage: %s [-h hostname]\n",
104					argv[0]);
105		exit(1);
106	}
107	if (geteuid() != 0) {
108		(void)fprintf(stderr, "must be superuser to run %s\n", argv[0]);
109		exit(1);
110	}
111
112#ifdef YP
113	if (chdir(YPDBPATH) < 0) {
114		(void)fprintf(stderr, "cannot chdir to ");
115		perror(YPDBPATH);
116	}
117#endif	/* YP */
118	if (strcmp(argv[1], "-u") == 0) {
119		pw = getpwnam(argv[2]);
120		if (pw == NULL) {
121			(void)fprintf(stderr, "unknown user: %s\n", argv[2]);
122			exit(1);
123		}
124		(void)user2netname(name, (int)pw->pw_uid, (char *)NULL);
125	} else {
126#ifdef undef
127		h = gethostbyname(argv[2]);
128		if (h == NULL) {
129			(void)fprintf(stderr, "unknown host: %s\n", argv[1]);
130			exit(1);
131		}
132		(void)host2netname(name, h->h_name, (char *)NULL);
133#else
134		(void)host2netname(name, argv[2], (char *)NULL);
135#endif
136	}
137
138	(void)printf("Adding new key for %s.\n", name);
139	pass = getpass("New password:");
140	genkeys(public, secret, pass);
141
142	memcpy(crypt1, secret, HEXKEYBYTES);
143	memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
144	crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
145	xencrypt(crypt1, pass);
146
147	memcpy(crypt2, crypt1, HEXKEYBYTES + KEYCHECKSUMSIZE + 1);
148	xdecrypt(crypt2, getpass("Retype password:"));
149	if (memcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 ||
150		memcmp(crypt2, secret, HEXKEYBYTES) != 0) {
151		(void)fprintf(stderr, "Password incorrect.\n");
152		exit(1);
153	}
154
155#ifdef YP
156	(void)printf("Please wait for the database to get updated...\n");
157#endif
158	if (status = setpublicmap(name, public, crypt1)) {
159#ifdef YP
160		(void)fprintf(stderr,
161			"%s: unable to update NIS database (%u): %s\n",
162				argv[0], status, yperr_string(status));
163#else
164		(void)fprintf(stderr,
165		"%s: unable to update publickey database (%u): %s\n",
166			argv[0], status, err_string(status));
167#endif
168		exit(1);
169	}
170	(void)printf("Your new key has been successfully stored away.\n");
171	exit(0);
172	/* NOTREACHED */
173}
174
175/*
176 * Set the entry in the public key file
177 */
178setpublicmap(name, public, secret)
179	char *name;
180	char *public;
181	char *secret;
182{
183	char pkent[1024];
184
185	(void)sprintf(pkent, "%s:%s", public, secret);
186#ifdef YP
187	return (mapupdate(name, PKMAP, YPOP_STORE,
188		strlen(name), name, strlen(pkent), pkent));
189#else
190	return (localupdate(name, PKFILE, YPOP_STORE,
191		strlen(name), name, strlen(pkent), pkent));
192#endif
193	}
194
195#ifndef YP
196	/*
197	 * This returns a pointer to an error message string appropriate
198	 * to an input error code.  An input value of zero will return
199	 * a success message.
200	 */
201static char *
202err_string(code)
203	int code;
204{
205	char *pmesg;
206
207	switch (code) {
208	case 0:
209		pmesg = "update operation succeeded";
210		break;
211	case ERR_KEY:
212		pmesg = "no such key in file";
213		break;
214	case ERR_READ:
215		pmesg = "cannot read the database";
216		break;
217	case ERR_WRITE:
218		pmesg = "cannot write to the database";
219		break;
220	case ERR_DBASE:
221		pmesg = "cannot update database";
222		break;
223	case ERR_ACCESS:
224		pmesg = "permission denied";
225		break;
226	case ERR_MALLOC:
227		pmesg = "malloc failed";
228		break;
229	default:
230		pmesg = "unknown error";
231		break;
232	}
233	return (pmesg);
234}
235#endif
236