136343Skfall #include <sys/types.h> 236343Skfall #include <sys/time.h> 336343Skfall #include <sys/resource.h> 436343Skfall #include <sys/socket.h> 536343Skfall #include <stdio.h> 636343Skfall #include <netdb.h> 736343Skfall #include <netinet/in.h> 836343Skfall #include <kerberos/krb.h> 936343Skfall #include <sys/param.h> 1036343Skfall #include <sys/file.h> 11*36349Skfall #include <sys/signal.h> 1236343Skfall #include "register_proto.h" 1336343Skfall 1436343Skfall #define SERVICE "krbupdate" 1536343Skfall #define PROTO "tcp" 1636343Skfall #define KFILE "/.update.key%s" 1736343Skfall #define KPASSWD "/usr/local/kpasswd" 1836343Skfall 1936343Skfall char realm[REALM_SZ]; 2036343Skfall char krbhst[MAX_HSTNM]; 2136343Skfall 2236343Skfall static char pname[ANAME_SZ]; 2336343Skfall static char iname[INST_SZ]; 2436343Skfall static char password[255]; 2536343Skfall 2636343Skfall extern char *sys_errlist; 2736348Skfall int die(); 2836343Skfall 2936343Skfall main(argc, argv) 3036343Skfall int argc; 3136343Skfall char **argv; 3236343Skfall { 3336343Skfall struct servent *se; 3436343Skfall struct hostent *host; 3536343Skfall struct sockaddr_in sin, local; 3636343Skfall int rval; 3736343Skfall int sock, llen; 3836343Skfall u_char code; 3936343Skfall static struct rlimit rl = { 0, 0 }; 4036343Skfall 4136343Skfall if(geteuid()) { 4236343Skfall fprintf(stderr, "must run set-uid root to access keyfile\n"); 4336343Skfall exit(1); 4436343Skfall } 4536343Skfall 4636348Skfall signal(SIGPIPE, die); 4736348Skfall 4836343Skfall if(setrlimit(RLIMIT_CORE, &rl) < 0) { 4936343Skfall perror("rlimit"); 5036343Skfall exit(1); 5136343Skfall } 5236343Skfall 5336343Skfall if((se = getservbyname(SERVICE, PROTO)) == NULL) { 5436343Skfall fprintf(stderr, "couldn't find entry for service %s\n", 5536343Skfall SERVICE); 5636343Skfall exit(1); 5736343Skfall } 5836343Skfall if((rval = get_krbrlm(realm,1)) != KSUCCESS) { 5936343Skfall fprintf(stderr, "couldn't get local Kerberos realm: %s\n", 6036343Skfall krb_err_txt[rval]); 6136343Skfall exit(1); 6236343Skfall } 6336343Skfall 6436343Skfall if((rval = get_krbhst(krbhst, realm, 1)) != KSUCCESS) { 6536343Skfall fprintf(stderr, "couldn't get Kerberos host: %s\n", 6636343Skfall krb_err_txt[rval]); 6736343Skfall exit(1); 6836343Skfall } 6936343Skfall 7036343Skfall if((host = gethostbyname(krbhst)) == NULL) { 7136343Skfall fprintf(stderr, "couldn't get host entry for host %s\n", 7236343Skfall krbhst); 7336343Skfall exit(1); 7436343Skfall } 7536343Skfall 7636343Skfall sin.sin_family = host->h_addrtype; 7736343Skfall bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length); 7836343Skfall sin.sin_port = se->s_port; 7936343Skfall 8036343Skfall if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 8136343Skfall perror("socket"); 8236343Skfall exit(1); 8336343Skfall } 8436343Skfall 8536343Skfall if(connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { 8636343Skfall perror("connect"); 8736343Skfall close(sock); 8836343Skfall exit(1); 8936343Skfall } 9036343Skfall 9136343Skfall llen = sizeof(local); 9236343Skfall if(getsockname(sock, (struct sockaddr *) &local, &llen) < 0) { 9336343Skfall perror("getsockname"); 9436343Skfall close(sock); 9536343Skfall exit(1); 9636343Skfall } 9736343Skfall 9836343Skfall setup_key(local); 9936343Skfall 10036343Skfall type_info(); 10136343Skfall get_user_info(); 10236343Skfall 10336343Skfall code = APPEND_DB; 10436343Skfall if(des_write(sock, &code, 1) != 1) { 10536343Skfall perror("write 1"); 10636343Skfall cleanup(); 10736343Skfall exit(1); 10836343Skfall } 10936343Skfall 11036343Skfall if(des_write(sock, pname, ANAME_SZ) != ANAME_SZ) { 11136343Skfall perror("write principal name"); 11236343Skfall cleanup(); 11336343Skfall exit(1); 11436343Skfall } 11536343Skfall 11636343Skfall if(des_write(sock, iname, INST_SZ) != INST_SZ) { 11736343Skfall perror("write instance name"); 11836343Skfall cleanup(); 11936343Skfall exit(1); 12036343Skfall } 12136343Skfall 12236343Skfall if(des_write(sock, password, 255) != 255) { 12336343Skfall perror("write password"); 12436343Skfall cleanup(); 12536343Skfall exit(1); 12636343Skfall } 12736343Skfall 12836343Skfall /* get return message */ 12936343Skfall 13036343Skfall { 13136343Skfall int cc; 13236343Skfall char msgbuf[BUFSIZ]; 13336343Skfall 13436343Skfall cc = des_read(sock, msgbuf, BUFSIZ); 13536343Skfall if(cc <= 0) { 13636343Skfall fprintf(stderr, "protocol error during read\n"); 13736343Skfall cleanup(); 13836343Skfall exit(1); 13936343Skfall } else { 14036343Skfall printf("%s: %s", krbhst, msgbuf); 14136343Skfall } 14236343Skfall } 14336343Skfall 14436343Skfall cleanup(); 14536343Skfall close(sock); 14636343Skfall } 14736343Skfall 14836343Skfall cleanup() 14936343Skfall { 15036343Skfall bzero(password, 255); 15136343Skfall } 15236343Skfall 15336343Skfall #include <pwd.h> 15436343Skfall 15536343Skfall extern char *crypt(); 15636343Skfall extern char *getpass(); 15736343Skfall get_user_info() 15836343Skfall { 15936343Skfall int uid = getuid(); 16036343Skfall int valid = 0, i; 16136343Skfall struct passwd *pw; 16236343Skfall char *pas, *namep; 16336343Skfall 16436343Skfall if((pw = getpwuid(uid)) == NULL) { 16536343Skfall fprintf(stderr, "Who are you?\n"); 16636343Skfall exit(1); 16736343Skfall } 16836343Skfall strcpy(pname, pw->pw_name); /* principal name */ 16936343Skfall for(i = 1; i < 3; i++) { 17036343Skfall pas = getpass("login password:"); 17136343Skfall namep = crypt(pas, pw->pw_passwd); 17236343Skfall if(strcmp(namep, pw->pw_passwd)) { 17336343Skfall fprintf(stderr, "Password incorrect\n"); 17436343Skfall continue; 17536343Skfall } else { 17636343Skfall valid = 1; 17736343Skfall break; 17836343Skfall } 17936343Skfall } 18036343Skfall if(!valid) 18136343Skfall exit(1); 18236343Skfall pas = getpass("Kerberos password (may be the same):"); 18336343Skfall strcpy(password, pas); /* password */ 18436343Skfall pas = getpass("Retype Kerberos password:"); 18536343Skfall if(strcmp(password, pas)) { 18636343Skfall fprintf(stderr, "Password mismatch -- aborted\n"); 18736343Skfall cleanup(); 18836343Skfall exit(1); 18936343Skfall } 19036343Skfall 19136343Skfall iname[0] = NULL; /* null instance name */ 19236343Skfall } 19336343Skfall 19436343Skfall setup_key(local) 19536343Skfall struct sockaddr_in local; 19636343Skfall { 19736343Skfall static struct keyfile_data kdata; 19836343Skfall static Key_schedule schedule; 19936343Skfall int fd; 20036343Skfall char namebuf[MAXPATHLEN]; 20136343Skfall extern int errno; 20236343Skfall 20336343Skfall sprintf(namebuf, KFILE, inet_ntoa(local.sin_addr)); 20436343Skfall fd = open(namebuf, O_RDONLY); 20536343Skfall if(fd < 0) { 20636343Skfall fprintf(stderr, "couldn't open key file for local host %s\n", 20736343Skfall inet_ntoa(local.sin_addr)); 20836343Skfall perror("open"); 20936343Skfall exit(1); 21036343Skfall } 21136343Skfall 21236343Skfall if(read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) { 21336343Skfall fprintf(stderr,"size error reading key file for local host %s\n", 21436343Skfall inet_ntoa(local.sin_addr)); 21536343Skfall exit(1); 21636343Skfall } 21736343Skfall key_sched(kdata.kf_key, schedule); 21836343Skfall des_set_key(kdata.kf_key, schedule); 21936343Skfall } 22036343Skfall 22136343Skfall type_info() 22236343Skfall { 22336343Skfall printf("Kerberos user registration (realm %s)\n\n", realm); 22436343Skfall printf("Please enter your login password followed by your new Kerberos password.\n"); 22536343Skfall printf("The Kerberos password you enter now will be used in the future\n"); 22636343Skfall printf("as your login password for all machines in the %s realm.\n", realm); 22736343Skfall printf("You will only be allowed to perform this operation once, although you may run\n"); 22836348Skfall printf("the %s program from now on to change your Kerberos password.\n\n", KPASSWD); 22936343Skfall } 23036348Skfall 23136348Skfall die() 23236348Skfall { 23336348Skfall fprintf(stderr, "\nServer no longer listeninga\n"); 23436348Skfall fflush(stderr); 23536348Skfall cleanup(); 23636348Skfall exit(1); 23736348Skfall } 238