146666Sbostic /*-
2*60967Sbostic * Copyright (c) 1989, 1993
3*60967Sbostic * The Regents of the University of California. All rights reserved.
438046Skfall *
546666Sbostic * %sccs.include.redist.c%
638046Skfall */
738046Skfall
838046Skfall #ifndef lint
9*60967Sbostic static char copyright[] =
10*60967Sbostic "@(#) Copyright (c) 1989, 1993\n\
11*60967Sbostic The Regents of the University of California. All rights reserved.\n";
1238046Skfall #endif /* not lint */
1338046Skfall
1446666Sbostic #ifndef lint
15*60967Sbostic static char sccsid[] = "@(#)register.c 8.1 (Berkeley) 06/01/93";
1646666Sbostic #endif /* not lint */
1746666Sbostic
1836343Skfall #include <sys/types.h>
1943461Skfall #include <sys/param.h>
2036343Skfall #include <sys/time.h>
2136343Skfall #include <sys/resource.h>
2236343Skfall #include <sys/socket.h>
2343461Skfall #include <sys/file.h>
2443461Skfall #include <sys/signal.h>
2543461Skfall #include <netinet/in.h>
2643461Skfall #include <pwd.h>
2736343Skfall #include <stdio.h>
2836343Skfall #include <netdb.h>
2941764Skfall #include <kerberosIV/des.h>
3041764Skfall #include <kerberosIV/krb.h>
3138699Skfall #include "pathnames.h"
3236343Skfall #include "register_proto.h"
3336343Skfall
3443461Skfall #define SERVICE "krbupdate" /* service to add to KDC's database */
3536343Skfall #define PROTO "tcp"
3636343Skfall
3736343Skfall char realm[REALM_SZ];
3836343Skfall char krbhst[MAX_HSTNM];
3936343Skfall
4036343Skfall static char pname[ANAME_SZ];
4136343Skfall static char iname[INST_SZ];
4243461Skfall static char password[_PASSWORD_LEN];
4336343Skfall
4443461Skfall /* extern char *sys_errlist; */
4546666Sbostic void die();
4643461Skfall void setup_key(), type_info(), cleanup();
4736343Skfall
main(argc,argv)4836343Skfall main(argc, argv)
4943461Skfall int argc;
5043461Skfall char **argv;
5136343Skfall {
5236343Skfall struct servent *se;
5336343Skfall struct hostent *host;
5436343Skfall struct sockaddr_in sin, local;
5536343Skfall int rval;
5636343Skfall int sock, llen;
5736343Skfall u_char code;
5836343Skfall static struct rlimit rl = { 0, 0 };
5936343Skfall
6036348Skfall signal(SIGPIPE, die);
6136348Skfall
6238046Skfall if (setrlimit(RLIMIT_CORE, &rl) < 0) {
6336343Skfall perror("rlimit");
6436343Skfall exit(1);
6536343Skfall }
6636343Skfall
6738046Skfall if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
6836343Skfall fprintf(stderr, "couldn't find entry for service %s\n",
6936343Skfall SERVICE);
7036343Skfall exit(1);
7136343Skfall }
7245213Skfall if ((rval = krb_get_lrealm(realm,0)) != KSUCCESS) {
7336343Skfall fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
7436343Skfall krb_err_txt[rval]);
7536343Skfall exit(1);
7636343Skfall }
7736343Skfall
7838046Skfall if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
7936343Skfall fprintf(stderr, "couldn't get Kerberos host: %s\n",
8036343Skfall krb_err_txt[rval]);
8136343Skfall exit(1);
8236343Skfall }
8336343Skfall
8438046Skfall if ((host = gethostbyname(krbhst)) == NULL) {
8536343Skfall fprintf(stderr, "couldn't get host entry for host %s\n",
8636343Skfall krbhst);
8736343Skfall exit(1);
8836343Skfall }
8936343Skfall
9036343Skfall sin.sin_family = host->h_addrtype;
9143461Skfall (void)bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
9236343Skfall sin.sin_port = se->s_port;
9336343Skfall
9438046Skfall if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
9536343Skfall perror("socket");
9636343Skfall exit(1);
9736343Skfall }
9836343Skfall
9938046Skfall if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
10036343Skfall perror("connect");
10143461Skfall (void)close(sock);
10236343Skfall exit(1);
10336343Skfall }
10436343Skfall
10536343Skfall llen = sizeof(local);
10638046Skfall if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
10736343Skfall perror("getsockname");
10843461Skfall (void)close(sock);
10936343Skfall exit(1);
11036343Skfall }
11136343Skfall
11236343Skfall setup_key(local);
11336343Skfall
11436343Skfall type_info();
11536343Skfall
11638046Skfall if (!get_user_info()) {
11738046Skfall code = ABORT;
11838046Skfall (void)des_write(sock, &code, 1);
11938046Skfall cleanup();
12038046Skfall exit(1);
12138046Skfall }
12238046Skfall
12336343Skfall code = APPEND_DB;
12438699Skfall if (des_write(sock, &code, 1) != 1) {
12536343Skfall perror("write 1");
12636343Skfall cleanup();
12736343Skfall exit(1);
12836343Skfall }
12936343Skfall
13038699Skfall if (des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
13136343Skfall perror("write principal name");
13236343Skfall cleanup();
13336343Skfall exit(1);
13436343Skfall }
13536343Skfall
13638699Skfall if (des_write(sock, iname, INST_SZ) != INST_SZ) {
13736343Skfall perror("write instance name");
13836343Skfall cleanup();
13936343Skfall exit(1);
14036343Skfall }
14136343Skfall
14238699Skfall if (des_write(sock, password, 255) != 255) {
14336343Skfall perror("write password");
14436343Skfall cleanup();
14536343Skfall exit(1);
14636343Skfall }
14736343Skfall
14836343Skfall /* get return message */
14936343Skfall
15036343Skfall {
15136343Skfall int cc;
15236343Skfall char msgbuf[BUFSIZ];
15336343Skfall
15437170Skfall cc = read(sock, msgbuf, BUFSIZ);
15537170Skfall if (cc <= 0) {
15637170Skfall fprintf(stderr, "protocol error during key verification\n");
15737170Skfall cleanup();
15837170Skfall exit(1);
15937170Skfall }
16038046Skfall if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
16137170Skfall fprintf(stderr, "%s: %s", krbhst, msgbuf);
16237170Skfall cleanup();
16337170Skfall exit(1);
16437170Skfall }
16537170Skfall
16636343Skfall cc = des_read(sock, msgbuf, BUFSIZ);
16738699Skfall if (cc <= 0) {
16836343Skfall fprintf(stderr, "protocol error during read\n");
16936343Skfall cleanup();
17036343Skfall exit(1);
17136343Skfall } else {
17236343Skfall printf("%s: %s", krbhst, msgbuf);
17336343Skfall }
17436343Skfall }
17536343Skfall
17636343Skfall cleanup();
17743461Skfall (void)close(sock);
17836343Skfall }
17936343Skfall
18043461Skfall void
cleanup()18136343Skfall cleanup()
18236343Skfall {
18336343Skfall bzero(password, 255);
18436343Skfall }
18536343Skfall
18636343Skfall extern char *crypt();
18736343Skfall extern char *getpass();
18838046Skfall
18938046Skfall int
get_user_info()19036343Skfall get_user_info()
19136343Skfall {
19236343Skfall int uid = getuid();
19336343Skfall int valid = 0, i;
19436343Skfall struct passwd *pw;
19536343Skfall char *pas, *namep;
19636343Skfall
19743461Skfall /* NB: we must run setuid-root to get at the real pw file */
19843461Skfall
19938699Skfall if ((pw = getpwuid(uid)) == NULL) {
20036343Skfall fprintf(stderr, "Who are you?\n");
20138046Skfall return(0);
20236343Skfall }
20343461Skfall (void)seteuid(uid);
20443461Skfall (void)strcpy(pname, pw->pw_name); /* principal name */
20543461Skfall
20643461Skfall for (i = 1; i < 3; i++) {
20736343Skfall pas = getpass("login password:");
20836343Skfall namep = crypt(pas, pw->pw_passwd);
20938699Skfall if (strcmp(namep, pw->pw_passwd)) {
21036343Skfall fprintf(stderr, "Password incorrect\n");
21136343Skfall continue;
21236343Skfall } else {
21336343Skfall valid = 1;
21436343Skfall break;
21536343Skfall }
21636343Skfall }
21738699Skfall if (!valid)
21838046Skfall return(0);
21936343Skfall pas = getpass("Kerberos password (may be the same):");
22043461Skfall while (*pas == NULL) {
22137170Skfall printf("<NULL> password not allowed\n");
22237170Skfall pas = getpass("Kerberos password (may be the same):");
22337170Skfall }
22443461Skfall (void)strcpy(password, pas); /* password */
22536343Skfall pas = getpass("Retype Kerberos password:");
22638699Skfall if (strcmp(password, pas)) {
22736343Skfall fprintf(stderr, "Password mismatch -- aborted\n");
22838046Skfall return(0);
22936343Skfall }
23036343Skfall
23136343Skfall iname[0] = NULL; /* null instance name */
23238046Skfall return(1);
23336343Skfall }
23436343Skfall
23543461Skfall void
setup_key(local)23636343Skfall setup_key(local)
23736343Skfall struct sockaddr_in local;
23836343Skfall {
23936343Skfall static struct keyfile_data kdata;
24036343Skfall static Key_schedule schedule;
24136343Skfall int fd;
24236343Skfall char namebuf[MAXPATHLEN];
24336343Skfall extern int errno;
24436343Skfall
24538703Skfall (void) sprintf(namebuf, "%s%s",
24638699Skfall CLIENT_KEYFILE,
24738699Skfall inet_ntoa(local.sin_addr));
24838699Skfall
24936343Skfall fd = open(namebuf, O_RDONLY);
25038699Skfall if (fd < 0) {
25141768Skfall fprintf(stderr, "couldn't open key file %s for local host: ",
25241768Skfall namebuf);
25341768Skfall perror("");
25436343Skfall exit(1);
25536343Skfall }
25636343Skfall
25738699Skfall if (read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
25836343Skfall fprintf(stderr,"size error reading key file for local host %s\n",
25936343Skfall inet_ntoa(local.sin_addr));
26036343Skfall exit(1);
26136343Skfall }
26236343Skfall key_sched(kdata.kf_key, schedule);
26336343Skfall des_set_key(kdata.kf_key, schedule);
26443461Skfall return;
26536343Skfall }
26636343Skfall
26743461Skfall void
type_info()26836343Skfall type_info()
26936343Skfall {
27036343Skfall printf("Kerberos user registration (realm %s)\n\n", realm);
27136343Skfall printf("Please enter your login password followed by your new Kerberos password.\n");
27236343Skfall printf("The Kerberos password you enter now will be used in the future\n");
27337170Skfall printf("as your Kerberos password for all machines in the %s realm.\n", realm);
27436343Skfall printf("You will only be allowed to perform this operation once, although you may run\n");
27538699Skfall printf("the %s program from now on to change your Kerberos password.\n\n", _PATH_KPASSWD);
27636343Skfall }
27736348Skfall
27846666Sbostic void
die()27936348Skfall die()
28036348Skfall {
28138699Skfall fprintf(stderr, "\nServer no longer listening\n");
28236348Skfall fflush(stderr);
28336348Skfall cleanup();
28436348Skfall exit(1);
28536348Skfall }
286