xref: /csrg-svn/old/athena/register/register.c (revision 38046)
1*38046Skfall /*
2*38046Skfall  * Copyright (c) 1989 The Regents of the University of California.
3*38046Skfall  * All rights reserved.
4*38046Skfall  *
5*38046Skfall  * Redistribution and use in source and binary forms are permitted
6*38046Skfall  * provided that the above copyright notice and this paragraph are
7*38046Skfall  * duplicated in all such forms and that any documentation,
8*38046Skfall  * advertising materials, and other materials related to such
9*38046Skfall  * distribution and use acknowledge that the software was developed
10*38046Skfall  * by the University of California, Berkeley.  The name of the
11*38046Skfall  * University may not be used to endorse or promote products derived
12*38046Skfall  * from this software without specific prior written permission.
13*38046Skfall  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38046Skfall  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38046Skfall  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*38046Skfall  */
17*38046Skfall 
18*38046Skfall #ifndef lint
19*38046Skfall static char sccsid[] = "@(#)register.c	1.5 (Berkeley) 05/17/89";
20*38046Skfall #endif /* not lint */
21*38046Skfall 
2236343Skfall #include <sys/types.h>
2336343Skfall #include <sys/time.h>
2436343Skfall #include <sys/resource.h>
2536343Skfall #include <sys/socket.h>
2636343Skfall #include <stdio.h>
2736343Skfall #include <netdb.h>
2836343Skfall #include <netinet/in.h>
2936343Skfall #include <kerberos/krb.h>
3036343Skfall #include <sys/param.h>
3136343Skfall #include <sys/file.h>
3236349Skfall #include <sys/signal.h>
3336343Skfall #include "register_proto.h"
3436343Skfall 
3536343Skfall #define	SERVICE	"krbupdate"
3636343Skfall #define	PROTO	"tcp"
3736343Skfall #define	KFILE	"/.update.key%s"
3837170Skfall #define	KPASSWD	"/usr/athena/kpasswd"
3936343Skfall 
4036343Skfall char	realm[REALM_SZ];
4136343Skfall char	krbhst[MAX_HSTNM];
4236343Skfall 
4336343Skfall static	char	pname[ANAME_SZ];
4436343Skfall static	char	iname[INST_SZ];
4536343Skfall static	char	password[255];
4636343Skfall 
4736343Skfall extern char	*sys_errlist;
4836348Skfall int	die();
4936343Skfall 
main(argc,argv)5036343Skfall main(argc, argv)
5136343Skfall int	argc;
5236343Skfall char	**argv;
5336343Skfall {
5436343Skfall 	struct servent	*se;
5536343Skfall 	struct hostent	*host;
5636343Skfall 	struct sockaddr_in	sin, local;
5736343Skfall 	int		rval;
5836343Skfall 	int		sock, llen;
5936343Skfall 	u_char		code;
6036343Skfall 	static struct rlimit rl = { 0, 0 };
6136343Skfall 
6236348Skfall 	signal(SIGPIPE, die);
6336348Skfall 
64*38046Skfall 	if (setrlimit(RLIMIT_CORE, &rl) < 0) {
6536343Skfall 		perror("rlimit");
6636343Skfall 		exit(1);
6736343Skfall 	}
6836343Skfall 
69*38046Skfall 	if ((se = getservbyname(SERVICE, PROTO)) == NULL) {
7036343Skfall 		fprintf(stderr, "couldn't find entry for service %s\n",
7136343Skfall 			SERVICE);
7236343Skfall 		exit(1);
7336343Skfall 	}
74*38046Skfall 	if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) {
7536343Skfall 		fprintf(stderr, "couldn't get local Kerberos realm: %s\n",
7636343Skfall 			krb_err_txt[rval]);
7736343Skfall 		exit(1);
7836343Skfall 	}
7936343Skfall 
80*38046Skfall 	if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) {
8136343Skfall 		fprintf(stderr, "couldn't get Kerberos host: %s\n",
8236343Skfall 			krb_err_txt[rval]);
8336343Skfall 		exit(1);
8436343Skfall 	}
8536343Skfall 
86*38046Skfall 	if ((host = gethostbyname(krbhst)) == NULL) {
8736343Skfall 		fprintf(stderr, "couldn't get host entry for host %s\n",
8836343Skfall 			krbhst);
8936343Skfall 		exit(1);
9036343Skfall 	}
9136343Skfall 
9236343Skfall 	sin.sin_family = host->h_addrtype;
9336343Skfall 	bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
9436343Skfall 	sin.sin_port = se->s_port;
9536343Skfall 
96*38046Skfall 	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
9736343Skfall 		perror("socket");
9836343Skfall 		exit(1);
9936343Skfall 	}
10036343Skfall 
101*38046Skfall 	if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
10236343Skfall 		perror("connect");
10336343Skfall 		close(sock);
10436343Skfall 		exit(1);
10536343Skfall 	}
10636343Skfall 
10736343Skfall 	llen = sizeof(local);
108*38046Skfall 	if (getsockname(sock, (struct sockaddr *) &local, &llen) < 0) {
10936343Skfall 		perror("getsockname");
11036343Skfall 		close(sock);
11136343Skfall 		exit(1);
11236343Skfall 	}
11336343Skfall 
11436343Skfall 	setup_key(local);
11536343Skfall 
11636343Skfall 	type_info();
11736343Skfall 
118*38046Skfall 	if (!get_user_info()) {
119*38046Skfall 		code = ABORT;
120*38046Skfall 		(void)des_write(sock, &code, 1);
121*38046Skfall 		cleanup();
122*38046Skfall 		exit(1);
123*38046Skfall 	}
124*38046Skfall 
12536343Skfall 	code = APPEND_DB;
12636343Skfall 	if(des_write(sock, &code, 1) != 1) {
12736343Skfall 		perror("write 1");
12836343Skfall 		cleanup();
12936343Skfall 		exit(1);
13036343Skfall 	}
13136343Skfall 
13236343Skfall 	if(des_write(sock, pname, ANAME_SZ) != ANAME_SZ) {
13336343Skfall 		perror("write principal name");
13436343Skfall 		cleanup();
13536343Skfall 		exit(1);
13636343Skfall 	}
13736343Skfall 
13836343Skfall 	if(des_write(sock, iname, INST_SZ) != INST_SZ) {
13936343Skfall 		perror("write instance name");
14036343Skfall 		cleanup();
14136343Skfall 		exit(1);
14236343Skfall 	}
14336343Skfall 
14436343Skfall 	if(des_write(sock, password, 255) != 255) {
14536343Skfall 		perror("write password");
14636343Skfall 		cleanup();
14736343Skfall 		exit(1);
14836343Skfall 	}
14936343Skfall 
15036343Skfall 	/* get return message */
15136343Skfall 
15236343Skfall 	{
15336343Skfall 		int	cc;
15436343Skfall 		char	msgbuf[BUFSIZ];
15536343Skfall 
15637170Skfall 		cc = read(sock, msgbuf, BUFSIZ);
15737170Skfall 		if (cc <= 0) {
15837170Skfall 			fprintf(stderr, "protocol error during key verification\n");
15937170Skfall 			cleanup();
16037170Skfall 			exit(1);
16137170Skfall 		}
162*38046Skfall 		if (strncmp(msgbuf, GOTKEY_MSG, 6) != 0) {
16337170Skfall 			fprintf(stderr, "%s: %s", krbhst, msgbuf);
16437170Skfall 			cleanup();
16537170Skfall 			exit(1);
16637170Skfall 		}
16737170Skfall 
16836343Skfall 		cc = des_read(sock, msgbuf, BUFSIZ);
16936343Skfall 		if(cc <= 0) {
17036343Skfall 			fprintf(stderr, "protocol error during read\n");
17136343Skfall 			cleanup();
17236343Skfall 			exit(1);
17336343Skfall 		} else {
17436343Skfall 			printf("%s: %s", krbhst, msgbuf);
17536343Skfall 		}
17636343Skfall 	}
17736343Skfall 
17836343Skfall 	cleanup();
17936343Skfall 	close(sock);
18036343Skfall }
18136343Skfall 
cleanup()18236343Skfall cleanup()
18336343Skfall {
18436343Skfall 	bzero(password, 255);
18536343Skfall }
18636343Skfall 
18736343Skfall #include <pwd.h>
18836343Skfall 
18936343Skfall extern	char	*crypt();
19036343Skfall extern	char	*getpass();
191*38046Skfall 
192*38046Skfall int
get_user_info()19336343Skfall get_user_info()
19436343Skfall {
19536343Skfall 	int	uid = getuid();
19636343Skfall 	int	valid = 0, i;
19736343Skfall 	struct	passwd	*pw;
19836343Skfall 	char	*pas, *namep;
19936343Skfall 
20036343Skfall 	if((pw = getpwuid(uid)) == NULL) {
20136343Skfall 		fprintf(stderr, "Who are you?\n");
202*38046Skfall 		return(0);
20336343Skfall 	}
20437170Skfall 	seteuid(uid);
20536343Skfall 	strcpy(pname, pw->pw_name);	/* principal name */
20636343Skfall 	for(i = 1; i < 3; i++) {
20736343Skfall 		pas = getpass("login password:");
20836343Skfall 		namep = crypt(pas, pw->pw_passwd);
20936343Skfall 		if(strcmp(namep, pw->pw_passwd)) {
21036343Skfall 			fprintf(stderr, "Password incorrect\n");
21136343Skfall 			continue;
21236343Skfall 		} else {
21336343Skfall 			valid = 1;
21436343Skfall 			break;
21536343Skfall 		}
21636343Skfall 	}
21736343Skfall 	if(!valid)
218*38046Skfall 		return(0);
21936343Skfall 	pas = getpass("Kerberos password (may be the same):");
22037170Skfall 	while(*pas == NULL) {
22137170Skfall 		printf("<NULL> password not allowed\n");
22237170Skfall 		pas = getpass("Kerberos password (may be the same):");
22337170Skfall 	}
22436343Skfall 	strcpy(password, pas);		/* password */
22536343Skfall 	pas = getpass("Retype Kerberos password:");
22636343Skfall 	if(strcmp(password, pas)) {
22736343Skfall 		fprintf(stderr, "Password mismatch -- aborted\n");
228*38046Skfall 		return(0);
22936343Skfall 	}
23036343Skfall 
23136343Skfall 	iname[0] = NULL;	/* null instance name */
232*38046Skfall 	return(1);
23336343Skfall }
23436343Skfall 
23536343Skfall setup_key(local)
23636343Skfall 	struct	sockaddr_in	local;
23736343Skfall {
23836343Skfall 	static	struct	keyfile_data	kdata;
23936343Skfall 	static  Key_schedule		schedule;
24036343Skfall 	int	fd;
24136343Skfall 	char	namebuf[MAXPATHLEN];
24236343Skfall 	extern int errno;
24336343Skfall 
24436343Skfall 	sprintf(namebuf, KFILE, inet_ntoa(local.sin_addr));
24536343Skfall 	fd = open(namebuf, O_RDONLY);
24636343Skfall 	if(fd < 0) {
24736343Skfall 		fprintf(stderr, "couldn't open key file for local host %s\n",
24836343Skfall 			inet_ntoa(local.sin_addr));
24936343Skfall 		perror("open");
25036343Skfall 		exit(1);
25136343Skfall 	}
25236343Skfall 
25336343Skfall 	if(read(fd, (char *)&kdata, sizeof(kdata)) != sizeof(kdata)) {
25436343Skfall 		fprintf(stderr,"size error reading key file for local host %s\n",
25536343Skfall 			inet_ntoa(local.sin_addr));
25636343Skfall 		exit(1);
25736343Skfall 	}
25836343Skfall 	key_sched(kdata.kf_key, schedule);
25936343Skfall 	des_set_key(kdata.kf_key, schedule);
26036343Skfall }
26136343Skfall 
type_info()26236343Skfall type_info()
26336343Skfall {
26436343Skfall 	printf("Kerberos user registration (realm %s)\n\n", realm);
26536343Skfall 	printf("Please enter your login password followed by your new Kerberos password.\n");
26636343Skfall 	printf("The Kerberos password you enter now will be used in the future\n");
26737170Skfall 	printf("as your Kerberos password for all machines in the %s realm.\n", realm);
26836343Skfall 	printf("You will only be allowed to perform this operation once, although you may run\n");
26936348Skfall 	printf("the %s program from now on to change your Kerberos password.\n\n", KPASSWD);
27036343Skfall }
27136348Skfall 
die()27236348Skfall die()
27336348Skfall {
27436348Skfall 	fprintf(stderr, "\nServer no longer listeninga\n");
27536348Skfall 	fflush(stderr);
27636348Skfall 	cleanup();
27736348Skfall 	exit(1);
27836348Skfall }
279