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