xref: /csrg-svn/old/athena/register/register.c (revision 36349)
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