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