cleanup
[unix-history] / usr / src / local / kerberosIV / register / register.c
CommitLineData
50e594a9
KF
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18#ifndef lint
01c28675 19static char sccsid[] = "@(#)register.c 1.11 (Berkeley) %G%";
50e594a9
KF
20#endif /* not lint */
21
b2c38480 22#include <sys/types.h>
01c28675 23#include <sys/param.h>
b2c38480
KF
24#include <sys/time.h>
25#include <sys/resource.h>
26#include <sys/socket.h>
01c28675
KF
27#include <sys/file.h>
28#include <sys/signal.h>
29#include <netinet/in.h>
30#include <pwd.h>
b2c38480
KF
31#include <stdio.h>
32#include <netdb.h>
ebdd4892
KF
33#include <kerberosIV/des.h>
34#include <kerberosIV/krb.h>
a1d20505 35#include "pathnames.h"
b2c38480
KF
36#include "register_proto.h"
37
01c28675 38#define SERVICE "krbupdate" /* service to add to KDC's database */
b2c38480 39#define PROTO "tcp"
b2c38480
KF
40
41char realm[REALM_SZ];
42char krbhst[MAX_HSTNM];
43
44static char pname[ANAME_SZ];
45static char iname[INST_SZ];
01c28675 46static char password[_PASSWORD_LEN];
b2c38480 47
01c28675 48/* extern char *sys_errlist; */
5f41c295 49int die();
01c28675 50void setup_key(), type_info(), cleanup();
b2c38480
KF
51
52main(argc, argv)
01c28675
KF
53 int argc;
54 char **argv;
b2c38480
KF
55{
56 struct servent *se;
57 struct hostent *host;
58 struct sockaddr_in sin, local;
59 int rval;
60 int sock, llen;
61 u_char code;
62 static struct rlimit rl = { 0, 0 };
63
5f41c295
KF
64 signal(SIGPIPE, die);
65
50e594a9 66 if (setrlimit(RLIMIT_CORE, &rl) < 0) {
b2c38480
KF
67 perror("rlimit");
68 exit(1);
69 }
70
50e594a9 71 if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
b2c38480
KF
72 fprintf(stderr, "couldn't find entry for service %s\n",
73 SERVICE);
74 exit(1);
75 }
50e594a9 76 if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
b2c38480
KF
77 fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
78 krb_err_txt[rval]);
79 exit(1);
80 }
81
50e594a9 82 if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
b2c38480
KF
83 fprintf(stderr, "couldn't get Kerberos host: %s\n",
84 krb_err_txt[rval]);
85 exit(1);
86 }
87
50e594a9 88 if ((host = gethostbyname(krbhst)) == NULL) {
b2c38480
KF
89 fprintf(stderr, "couldn't get host entry for host %s\n",
90 krbhst);
91 exit(1);
92 }
93
94 sin.sin_family = host->h_addrtype;
01c28675 95 (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
b2c38480
KF
96 sin.sin_port = se->s_port;
97
50e594a9 98 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
b2c38480
KF
99 perror("socket");
100 exit(1);
101 }
102
50e594a9 103 if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
b2c38480 104 perror("connect");
01c28675 105 (void)close(sock);
b2c38480
KF
106 exit(1);
107 }
108
109 llen = sizeof(local);
50e594a9 110 if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
b2c38480 111 perror("getsockname");
01c28675 112 (void)close(sock);
b2c38480
KF
113 exit(1);
114 }
115
116 setup_key(local);
117
118 type_info();
50e594a9
KF
119
120 if (!get_user_info()) {
121 code = ABORT;
122 (void)des_write(sock, &code, 1);
123 cleanup();
124 exit(1);
125 }
b2c38480
KF
126
127 code = APPEND_DB;
a1d20505 128 if (des_write(sock, &code, 1) != 1) {
b2c38480
KF
129 perror("write 1");
130 cleanup();
131 exit(1);
132 }
133
a1d20505 134 if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
b2c38480
KF
135 perror("write principal name");
136 cleanup();
137 exit(1);
138 }
139
a1d20505 140 if (des_write(sock, iname, INST_SZ) != INST_SZ) {
b2c38480
KF
141 perror("write instance name");
142 cleanup();
143 exit(1);
144 }
145
a1d20505 146 if (des_write(sock, password, 255) != 255) {
b2c38480
KF
147 perror("write password");
148 cleanup();
149 exit(1);
150 }
151
152 /* get return message */
153
154 {
155 int cc;
156 char msgbuf[BUFSIZ];
157
4ba59782
KF
158 cc = read(sock, msgbuf, BUFSIZ);
159 if (cc <= 0) {
160 fprintf(stderr, "protocol error during key verification\n");
161 cleanup();
162 exit(1);
163 }
50e594a9 164 if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
4ba59782
KF
165 fprintf(stderr, "%s: %s", krbhst, msgbuf);
166 cleanup();
167 exit(1);
168 }
169
b2c38480 170 cc = des_read(sock, msgbuf, BUFSIZ);
a1d20505 171 if (cc <= 0) {
b2c38480
KF
172 fprintf(stderr, "protocol error during read\n");
173 cleanup();
174 exit(1);
175 } else {
176 printf("%s: %s", krbhst, msgbuf);
177 }
178 }
179
180 cleanup();
01c28675 181 (void)close(sock);
b2c38480
KF
182}
183
01c28675 184void
b2c38480
KF
185cleanup()
186{
187 bzero(password, 255);
188}
189
b2c38480
KF
190extern char *crypt();
191extern char *getpass();
50e594a9
KF
192
193int
b2c38480
KF
194get_user_info()
195{
196 int uid = getuid();
197 int valid = 0, i;
198 struct passwd *pw;
199 char *pas, *namep;
200
01c28675
KF
201 /* NB: we must run setuid-root to get at the real pw file */
202
a1d20505 203 if ((pw = getpwuid(uid)) == NULL) {
b2c38480 204 fprintf(stderr, "Who are you?\n");
50e594a9 205 return(0);
b2c38480 206 }
01c28675
KF
207 (void)seteuid(uid);
208 (void)strcpy(pname, pw->pw_name); /* principal name */
209
210 for (i = 1; i < 3; i++) {
b2c38480
KF
211 pas = getpass("login password:");
212 namep = crypt(pas, pw->pw_passwd);
a1d20505 213 if (strcmp(namep, pw->pw_passwd)) {
b2c38480
KF
214 fprintf(stderr, "Password incorrect\n");
215 continue;
216 } else {
217 valid = 1;
218 break;
219 }
220 }
a1d20505 221 if (!valid)
50e594a9 222 return(0);
b2c38480 223 pas = getpass("Kerberos password (may be the same):");
01c28675 224 while (*pas == NULL) {
4ba59782
KF
225 printf("<NULL> password not allowed\n");
226 pas = getpass("Kerberos password (may be the same):");
227 }
01c28675 228 (void)strcpy(password, pas); /* password */
b2c38480 229 pas = getpass("Retype Kerberos password:");
a1d20505 230 if (strcmp(password, pas)) {
b2c38480 231 fprintf(stderr, "Password mismatch -- aborted\n");
50e594a9 232 return(0);
b2c38480
KF
233 }
234
235 iname[0] = NULL; /* null instance name */
50e594a9 236 return(1);
b2c38480
KF
237}
238
01c28675 239void
b2c38480
KF
240setup_key(local)
241 struct sockaddr_in local;
242{
243 static struct keyfile_data kdata;
244 static Key_schedule schedule;
245 int fd;
246 char namebuf[MAXPATHLEN];
247 extern int errno;
248
41d7916d 249 (void) sprintf(namebuf, "%s%s",
a1d20505
KF
250 CLIENT_KEYFILE,
251 inet_ntoa(local.sin_addr));
252
b2c38480 253 fd = open(namebuf, O_RDONLY);
a1d20505 254 if (fd < 0) {
6d6747a2
KF
255 fprintf(stderr, "couldn't open key file %s for local host: ",
256 namebuf);
257 perror("");
b2c38480
KF
258 exit(1);
259 }
260
a1d20505 261 if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
b2c38480
KF
262 fprintf(stderr,"size error reading key file for local host %s\n",
263 inet_ntoa(local.sin_addr));
264 exit(1);
265 }
266 key_sched(kdata.kf_key, schedule);
267 des_set_key(kdata.kf_key, schedule);
01c28675 268 return;
b2c38480
KF
269}
270
01c28675 271void
b2c38480
KF
272type_info()
273{
274 printf("Kerberos user registration (realm %s)\n\n", realm);
275 printf("Please enter your login password followed by your new Kerberos password.\n");
276 printf("The Kerberos password you enter now will be used in the future\n");
4ba59782 277 printf("as your Kerberos password for all machines in the %s realm.\n", realm);
b2c38480 278 printf("You will only be allowed to perform this operation once, although you may run\n");
a1d20505 279 printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
5f41c295
KF
280}
281
01c28675 282int
5f41c295
KF
283die()
284{
a1d20505 285 fprintf(stderr, "\nServer no longer listening\n");
5f41c295
KF
286 fflush(stderr);
287 cleanup();
288 exit(1);
b2c38480 289}