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 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 181 cleanup() 182 { 183 bzero(password, 255); 184 } 185 186 extern char *crypt(); 187 extern char *getpass(); 188 189 int 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 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 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 279 die() 280 { 281 fprintf(stderr, "\nServer no longer listening\n"); 282 fflush(stderr); 283 cleanup(); 284 exit(1); 285 } 286