xref: /original-bsd/old/athena/register/register.c (revision 444dc9d9)
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