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