krb5_passwd.c revision 1.4 1 1.4 mrg /* $NetBSD: krb5_passwd.c,v 1.4 1997/02/11 09:35:56 mrg Exp $ */
2 1.2 thorpej
3 1.1 brezak /*-
4 1.1 brezak * Copyright (c) 1990 The Regents of the University of California.
5 1.1 brezak * All rights reserved.
6 1.1 brezak *
7 1.1 brezak * Redistribution and use in source and binary forms, with or without
8 1.1 brezak * modification, are permitted provided that the following conditions
9 1.1 brezak * are met:
10 1.1 brezak * 1. Redistributions of source code must retain the above copyright
11 1.1 brezak * notice, this list of conditions and the following disclaimer.
12 1.1 brezak * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 brezak * notice, this list of conditions and the following disclaimer in the
14 1.1 brezak * documentation and/or other materials provided with the distribution.
15 1.1 brezak * 3. All advertising materials mentioning features or use of this software
16 1.1 brezak * must display the following acknowledgement:
17 1.1 brezak * This product includes software developed by the University of
18 1.1 brezak * California, Berkeley and its contributors.
19 1.1 brezak * 4. Neither the name of the University nor the names of its contributors
20 1.1 brezak * may be used to endorse or promote products derived from this software
21 1.1 brezak * without specific prior written permission.
22 1.1 brezak *
23 1.1 brezak * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 brezak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 brezak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 brezak * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 brezak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 brezak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 brezak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 brezak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 brezak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 brezak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 brezak * SUCH DAMAGE.
34 1.1 brezak */
35 1.1 brezak
36 1.1 brezak #ifndef lint
37 1.2 thorpej #if 0
38 1.2 thorpej static char sccsid[] = "from: @(#)krb_passwd.c 5.4 (Berkeley) 3/1/91";
39 1.2 thorpej #else
40 1.4 mrg static char rcsid[] = "$NetBSD: krb5_passwd.c,v 1.4 1997/02/11 09:35:56 mrg Exp $";
41 1.2 thorpej #endif
42 1.1 brezak #endif /* not lint */
43 1.1 brezak
44 1.1 brezak #ifdef KERBEROS5
45 1.1 brezak
46 1.1 brezak #include <sys/types.h>
47 1.1 brezak #include <sys/socket.h>
48 1.1 brezak #include <sys/time.h>
49 1.1 brezak #include <sys/resource.h>
50 1.1 brezak #include <netinet/in.h>
51 1.1 brezak #include <netdb.h>
52 1.1 brezak #include <signal.h>
53 1.1 brezak #include <pwd.h>
54 1.1 brezak #include <errno.h>
55 1.1 brezak #include <stdio.h>
56 1.1 brezak #include <string.h>
57 1.1 brezak #include <stdlib.h>
58 1.1 brezak #include <krb5/adm_defs.h>
59 1.1 brezak #include <krb5/krb5.h>
60 1.1 brezak #include <krb5/kdb.h>
61 1.1 brezak #include <krb5/kdb_dbm.h>
62 1.1 brezak #include <krb5/ext-proto.h>
63 1.1 brezak #include <krb5/los-proto.h>
64 1.1 brezak #include <krb5/asn1.h>
65 1.1 brezak #include <krb5/config.h>
66 1.1 brezak #include <krb5/base-defs.h>
67 1.1 brezak #include <krb5/asn.1/encode.h>
68 1.1 brezak
69 1.1 brezak #include <krb5/widen.h>
70 1.1 brezak
71 1.1 brezak #include <krb5/adm_err.h>
72 1.1 brezak #include <krb5/errors.h>
73 1.1 brezak #include <krb5/kdb5_err.h>
74 1.1 brezak #include <krb5/krb5_err.h>
75 1.1 brezak
76 1.1 brezak static krb5_error_code get_first_ticket __P((krb5_ccache, krb5_principal));
77 1.1 brezak static krb5_error_code print_and_choose_password __P((char *, krb5_data *));
78 1.1 brezak static krb5_error_code adm5_init_link __P((krb5_data *, int *));
79 1.1 brezak
80 1.1 brezak struct sockaddr_in local_sin, remote_sin;
81 1.1 brezak
82 1.1 brezak krb5_creds my_creds;
83 1.1 brezak
84 1.1 brezak extern char *krb5_default_pwd_prompt1;
85 1.1 brezak
86 1.1 brezak /*
87 1.1 brezak * Try no preauthentication first; then try the encrypted timestamp
88 1.1 brezak */
89 1.1 brezak int preauth_search_list[] = {
90 1.1 brezak 0,
91 1.1 brezak KRB5_PADATA_ENC_TIMESTAMP,
92 1.1 brezak -1
93 1.1 brezak };
94 1.1 brezak
95 1.3 tls int
96 1.1 brezak krb_passwd()
97 1.1 brezak {
98 1.1 brezak static void finish();
99 1.1 brezak krb5_ccache cache = NULL;
100 1.1 brezak char cache_name[255];
101 1.1 brezak krb5_flags cc_flags;
102 1.1 brezak krb5_address local_addr, foreign_addr;
103 1.1 brezak struct passwd *pw;
104 1.1 brezak krb5_principal client, server;
105 1.1 brezak char default_name[256];
106 1.1 brezak char *client_name; /* Single string representation of client id */
107 1.1 brezak krb5_data requested_realm;
108 1.1 brezak char *local_realm;
109 1.1 brezak char input_string[768];
110 1.1 brezak krb5_error_code retval; /* return code */
111 1.1 brezak int local_socket;
112 1.1 brezak int c, count;
113 1.1 brezak krb5_error *err_ret;
114 1.1 brezak krb5_ap_rep_enc_part *rep_ret;
115 1.1 brezak kadmin_requests rd_priv_resp;
116 1.1 brezak krb5_checksum send_cksum;
117 1.1 brezak int cksum_alloc = 0;
118 1.1 brezak krb5_data msg_data, inbuf;
119 1.1 brezak krb5_int32 seqno;
120 1.1 brezak char *new_password;
121 1.1 brezak int new_pwsize;
122 1.1 brezak krb5_data *decodable_pwd_string;
123 1.1 brezak int i, j;
124 1.1 brezak static struct rlimit rl = { 0, 0 };
125 1.1 brezak
126 1.1 brezak #ifdef KRB_NONETWORK
127 1.1 brezak extern int networked();
128 1.1 brezak int krb_secure;
129 1.1 brezak struct stat statbuf;
130 1.1 brezak #endif
131 1.1 brezak
132 1.1 brezak #ifdef KRB_NONETWORK /* Allow or Disallow Remote Clients to Modify Passwords */
133 1.1 brezak /*
134 1.1 brezak * If a Client Modifies a Password using kpasswd on this host
135 1.1 brezak * from a remote host or network terminal, the Password selected
136 1.1 brezak * is transmitted across the network in Cleartext.
137 1.1 brezak *
138 1.1 brezak * The systems administrator can disallow "remote" kpasswd usage by
139 1.1 brezak * creating the file "/etc/krb.secure"
140 1.1 brezak */
141 1.1 brezak krb_secure = 0;
142 1.1 brezak /*
143 1.1 brezak * First check to see if the file /etc/krb.secure exists.
144 1.1 brezak * If it does then krb_secure to 1.
145 1.1 brezak */
146 1.1 brezak
147 1.1 brezak if (stat("/etc/krb.secure", &statbuf) == 0) krb_secure = 1;
148 1.1 brezak
149 1.1 brezak /*
150 1.1 brezak * Check to see if this process is tied to a physical terminal.
151 1.1 brezak * Network() verifies the terminal device is not a pseudo tty
152 1.1 brezak */
153 1.1 brezak if (networked() && krb_secure) {
154 1.1 brezak fprintf(stderr,"passwd: Sorry but you cannot %s from a\n", argv[0]);
155 1.1 brezak fprintf(stderr," pseudo tty terminal.\n");
156 1.1 brezak retval = 1;
157 1.1 brezak goto finish;
158 1.1 brezak }
159 1.1 brezak #endif
160 1.1 brezak
161 1.1 brezak /* (3 * 255) + 1 (/) + 1 (@) + 1 (NULL) */
162 1.1 brezak if ((client_name = (char *) calloc (1, (3 * 256))) == NULL) {
163 1.1 brezak fprintf(stderr, "passwd: No Memory for Client_name\n");
164 1.1 brezak retval = 1;
165 1.1 brezak goto finish;
166 1.1 brezak }
167 1.1 brezak
168 1.1 brezak if ((requested_realm.data = (char *) calloc (1, 256)) == NULL) {
169 1.1 brezak fprintf(stderr, "passwd: No Memory for realm_name\n");
170 1.1 brezak retval = 1;
171 1.1 brezak free(client_name);
172 1.1 brezak goto finish;
173 1.1 brezak }
174 1.1 brezak
175 1.1 brezak (void)signal(SIGHUP, SIG_IGN);
176 1.1 brezak (void)signal(SIGINT, SIG_IGN);
177 1.1 brezak (void)signal(SIGTSTP, SIG_IGN);
178 1.1 brezak
179 1.1 brezak if (setrlimit(RLIMIT_CORE, &rl) < 0) {
180 1.1 brezak (void)fprintf(stderr,
181 1.1 brezak "passwd: setrlimit: %s\n", strerror(errno));
182 1.1 brezak return(1);
183 1.1 brezak }
184 1.1 brezak
185 1.1 brezak krb5_init_ets();
186 1.1 brezak memset((char *) default_name, 0, sizeof(default_name));
187 1.1 brezak
188 1.1 brezak /* Identify Default Credentials Cache */
189 1.1 brezak if ((retval = krb5_cc_default(&cache))) {
190 1.1 brezak fprintf(stderr, "passwd: Error while getting default ccache.\n");
191 1.1 brezak goto finish;
192 1.1 brezak }
193 1.1 brezak
194 1.1 brezak /*
195 1.1 brezak * Attempt to Modify Credentials Cache
196 1.1 brezak * retval == 0 ==> ccache Exists - Use It
197 1.1 brezak * retval == ENOENT ==> No Entries, but ccache Exists
198 1.1 brezak * retval != 0 ==> Assume ccache does NOT Exist
199 1.1 brezak */
200 1.1 brezak cc_flags = 0;
201 1.1 brezak if ((retval = krb5_cc_set_flags(cache, cc_flags))) {
202 1.1 brezak /* Search passwd file for client */
203 1.1 brezak pw = getpwuid((int) getuid());
204 1.1 brezak if (pw) {
205 1.4 mrg (void)strncpy(default_name, pw->pw_name, sizeof(default_name) - 1);
206 1.1 brezak }
207 1.1 brezak else {
208 1.1 brezak fprintf(stderr,
209 1.1 brezak "passwd: Unable to Identify Customer from Password File\n");
210 1.1 brezak retval = 1;
211 1.1 brezak goto finish;
212 1.1 brezak }
213 1.1 brezak
214 1.1 brezak /* Use this to get default_realm and format client_name */
215 1.1 brezak if ((retval = krb5_parse_name(default_name, &client))) {
216 1.1 brezak fprintf(stderr, "passwd: Unable to Parse Client Name\n");
217 1.1 brezak goto finish;
218 1.1 brezak }
219 1.1 brezak
220 1.1 brezak if ((retval = krb5_unparse_name(client, &client_name))) {
221 1.1 brezak fprintf(stderr, "passwd: Unable to Parse Client Name\n");
222 1.1 brezak goto finish;
223 1.1 brezak }
224 1.1 brezak
225 1.1 brezak requested_realm.length = client->realm.length;
226 1.1 brezak memcpy((char *) requested_realm.data,
227 1.1 brezak (char *) client->realm.data,
228 1.1 brezak requested_realm.length);
229 1.1 brezak }
230 1.1 brezak else {
231 1.1 brezak /* Read Client from Cache */
232 1.1 brezak if ((retval = krb5_cc_get_principal(cache, (krb5_principal *) &client))) {
233 1.1 brezak fprintf(stderr, "passwd: Unable to Read Customer Credentials File\n");
234 1.1 brezak goto finish;
235 1.1 brezak }
236 1.1 brezak
237 1.1 brezak if ((retval = krb5_unparse_name(client, &client_name))) {
238 1.1 brezak fprintf(stderr, "passwd: Unable to Parse Client Name\n");
239 1.1 brezak goto finish;
240 1.1 brezak }
241 1.1 brezak
242 1.1 brezak requested_realm.length = client->realm.length;
243 1.1 brezak memcpy((char *) requested_realm.data,
244 1.1 brezak (char *) client->realm.data,
245 1.1 brezak requested_realm.length);
246 1.1 brezak
247 1.1 brezak (void) krb5_cc_close(cache);
248 1.1 brezak }
249 1.1 brezak
250 1.1 brezak /* Create credential cache for changepw */
251 1.4 mrg (void)snprintf(cache_name, sizeof cache_name, "FILE:/tmp/tkt_cpw_%d",
252 1.4 mrg getpid());
253 1.1 brezak
254 1.1 brezak if ((retval = krb5_cc_resolve(cache_name, &cache))) {
255 1.1 brezak fprintf(stderr, "passwd: Unable to Resolve Cache: %s\n", cache_name);
256 1.1 brezak }
257 1.1 brezak
258 1.1 brezak if ((retval = krb5_cc_initialize(cache, client))) {
259 1.1 brezak fprintf(stderr, "passwd: Error initializing cache: %s\n", cache_name);
260 1.1 brezak goto finish;
261 1.1 brezak }
262 1.1 brezak
263 1.1 brezak /*
264 1.1 brezak * Verify User by Obtaining Initial Credentials prior to Initial Link
265 1.1 brezak */
266 1.1 brezak if ((retval = get_first_ticket(cache, client))) {
267 1.1 brezak goto finish;
268 1.1 brezak }
269 1.1 brezak
270 1.1 brezak /* Initiate Link to Server */
271 1.1 brezak if ((retval = adm5_init_link(&requested_realm, &local_socket))) {
272 1.1 brezak goto finish;
273 1.1 brezak }
274 1.1 brezak
275 1.1 brezak #define SIZEOF_INADDR sizeof(struct in_addr)
276 1.1 brezak
277 1.1 brezak /* V4 kpasswd Protocol Hack */
278 1.1 brezak {
279 1.1 brezak int msg_length = 0;
280 1.1 brezak
281 1.1 brezak retval = krb5_net_write(local_socket, (char *) &msg_length + 2, 2);
282 1.1 brezak if (retval < 0) {
283 1.1 brezak fprintf(stderr, "passwd: krb5_net_write failure\n");
284 1.1 brezak goto finish;
285 1.1 brezak }
286 1.1 brezak }
287 1.1 brezak
288 1.1 brezak local_addr.addrtype = ADDRTYPE_INET;
289 1.1 brezak local_addr.length = SIZEOF_INADDR ;
290 1.1 brezak local_addr.contents = (krb5_octet *)&local_sin.sin_addr;
291 1.1 brezak
292 1.1 brezak foreign_addr.addrtype = ADDRTYPE_INET;
293 1.1 brezak foreign_addr.length = SIZEOF_INADDR ;
294 1.1 brezak foreign_addr.contents = (krb5_octet *)&remote_sin.sin_addr;
295 1.1 brezak
296 1.1 brezak /* compute checksum, using CRC-32 */
297 1.1 brezak if (!(send_cksum.contents = (krb5_octet *)
298 1.1 brezak malloc(krb5_checksum_size(CKSUMTYPE_CRC32)))) {
299 1.1 brezak fprintf(stderr, "passwd: Insufficient Memory while Allocating Checksum\n");
300 1.1 brezak goto finish;
301 1.1 brezak }
302 1.1 brezak cksum_alloc++;
303 1.1 brezak /* choose some random stuff to compute checksum from */
304 1.1 brezak if (retval = krb5_calculate_checksum(CKSUMTYPE_CRC32,
305 1.1 brezak ADM_CPW_VERSION,
306 1.1 brezak strlen(ADM_CPW_VERSION),
307 1.1 brezak 0,
308 1.1 brezak 0, /* if length is 0, crc-32 doesn't
309 1.1 brezak use the seed */
310 1.1 brezak &send_cksum)) {
311 1.1 brezak fprintf(stderr, "Error while Computing Checksum: %s\n",
312 1.1 brezak error_message(retval));
313 1.1 brezak goto finish;
314 1.1 brezak }
315 1.1 brezak
316 1.1 brezak /* call Kerberos library routine to obtain an authenticator,
317 1.1 brezak pass it over the socket to the server, and obtain mutual
318 1.1 brezak authentication. */
319 1.1 brezak
320 1.1 brezak if ((retval = krb5_sendauth((krb5_pointer) &local_socket,
321 1.1 brezak ADM_CPW_VERSION,
322 1.1 brezak my_creds.client,
323 1.1 brezak my_creds.server,
324 1.1 brezak AP_OPTS_MUTUAL_REQUIRED,
325 1.1 brezak &send_cksum,
326 1.1 brezak 0,
327 1.1 brezak cache,
328 1.1 brezak &seqno,
329 1.1 brezak 0, /* don't need a subsession key */
330 1.1 brezak &err_ret,
331 1.1 brezak &rep_ret))) {
332 1.1 brezak fprintf(stderr, "passwd: Error while performing sendauth: %s\n",
333 1.1 brezak error_message(retval));
334 1.1 brezak goto finish;
335 1.1 brezak }
336 1.1 brezak
337 1.1 brezak /* Get credentials : to use for safe and private messages */
338 1.1 brezak if (retval = krb5_get_credentials(0, cache, &my_creds)){
339 1.1 brezak fprintf(stderr, "passwd: Error Obtaining Credentials: %s\n",
340 1.1 brezak error_message(retval));
341 1.1 brezak goto finish;
342 1.1 brezak }
343 1.1 brezak
344 1.1 brezak /* Read back what the server has to say... */
345 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
346 1.1 brezak fprintf(stderr, "passwd: Read Message Error: %s\n",
347 1.1 brezak error_message(retval));
348 1.1 brezak goto finish;
349 1.1 brezak }
350 1.1 brezak if ((inbuf.length != 2) || (inbuf.data[0] != KADMIND) ||
351 1.1 brezak (inbuf.data[1] != KADMSAG)){
352 1.1 brezak fprintf(stderr, "passwd: Invalid ack from admin server.\n");
353 1.1 brezak goto finish;
354 1.1 brezak }
355 1.1 brezak
356 1.1 brezak inbuf.data[0] = KPASSWD;
357 1.1 brezak inbuf.data[1] = CHGOPER;
358 1.1 brezak inbuf.length = 2;
359 1.1 brezak
360 1.1 brezak if ((retval = krb5_mk_priv(&inbuf,
361 1.1 brezak ETYPE_DES_CBC_CRC,
362 1.1 brezak &my_creds.keyblock,
363 1.1 brezak &local_addr,
364 1.1 brezak &foreign_addr,
365 1.1 brezak seqno,
366 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
367 1.1 brezak 0,
368 1.1 brezak 0,
369 1.1 brezak &msg_data))) {
370 1.1 brezak fprintf(stderr, "passwd: Error during First Message Encoding: %s\n",
371 1.1 brezak error_message(retval));
372 1.1 brezak goto finish;
373 1.1 brezak }
374 1.1 brezak free(inbuf.data);
375 1.1 brezak
376 1.1 brezak /* write private message to server */
377 1.1 brezak if (krb5_write_message(&local_socket, &msg_data)){
378 1.1 brezak fprintf(stderr, "passwd: Write Error During First Message Transmission\n");
379 1.1 brezak retval = 1;
380 1.1 brezak goto finish;
381 1.1 brezak }
382 1.1 brezak free(msg_data.data);
383 1.1 brezak
384 1.1 brezak (void)signal(SIGHUP, finish);
385 1.1 brezak (void)signal(SIGINT, finish);
386 1.1 brezak
387 1.1 brezak #ifdef MACH_PASS /* Machine-generated Passwords */
388 1.1 brezak /* Ok Now let's get the private message */
389 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
390 1.1 brezak fprintf(stderr, "passwd: Read Error During First Reply: %s\n",
391 1.1 brezak error_message(retval));
392 1.1 brezak retval = 1;
393 1.1 brezak goto finish;
394 1.1 brezak }
395 1.1 brezak
396 1.1 brezak if ((retval = krb5_rd_priv(&inbuf,
397 1.1 brezak &my_creds.keyblock,
398 1.1 brezak &foreign_addr,
399 1.1 brezak &local_addr,
400 1.1 brezak rep_ret->seq_number,
401 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
402 1.1 brezak 0,
403 1.1 brezak 0,
404 1.1 brezak &msg_data))) {
405 1.1 brezak fprintf(stderr, "passwd: Error during First Read Decoding: %s\n",
406 1.1 brezak error_message(retval));
407 1.1 brezak goto finish;
408 1.1 brezak }
409 1.1 brezak free(inbuf.data);
410 1.1 brezak #endif
411 1.1 brezak
412 1.1 brezak if ((new_password = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == NULL) {
413 1.1 brezak fprintf(stderr, "passwd: Unable to Allocate Space for New Password\n");
414 1.1 brezak goto finish;
415 1.1 brezak }
416 1.1 brezak
417 1.1 brezak #ifdef MACH_PASS /* Machine-generated passwords */
418 1.1 brezak /* Offer Client Password Choices */
419 1.1 brezak if ((retval = print_and_choose_password(new_password,
420 1.1 brezak &msg_data))) {
421 1.1 brezak (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1);
422 1.1 brezak free(new_password);
423 1.1 brezak goto finish;
424 1.1 brezak }
425 1.1 brezak #else
426 1.1 brezak new_pwsize = ADM_MAX_PW_LENGTH+1;
427 1.1 brezak if ((retval = krb5_read_password("New Kerberos password: ",
428 1.1 brezak "Retype new Kerberos password: ",
429 1.1 brezak new_password,
430 1.1 brezak &new_pwsize))) {
431 1.1 brezak fprintf(stderr, "\nError while reading new password for '%s'\n",
432 1.1 brezak client_name);
433 1.1 brezak (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1);
434 1.1 brezak free(new_password);
435 1.1 brezak goto finish;
436 1.1 brezak }
437 1.1 brezak #endif
438 1.1 brezak
439 1.1 brezak inbuf.data = new_password;
440 1.1 brezak inbuf.length = strlen(new_password);
441 1.1 brezak
442 1.1 brezak if ((retval = krb5_mk_priv(&inbuf,
443 1.1 brezak ETYPE_DES_CBC_CRC,
444 1.1 brezak &my_creds.keyblock,
445 1.1 brezak &local_addr,
446 1.1 brezak &foreign_addr,
447 1.1 brezak seqno,
448 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
449 1.1 brezak 0,
450 1.1 brezak 0,
451 1.1 brezak &msg_data))) {
452 1.1 brezak fprintf(stderr, "passwd: Error during Second Message Encoding: %s\n",
453 1.1 brezak error_message(retval));
454 1.1 brezak goto finish;
455 1.1 brezak }
456 1.1 brezak memset(inbuf.data,0,inbuf.length);
457 1.1 brezak free(inbuf.data);
458 1.1 brezak
459 1.1 brezak /* write private message to server */
460 1.1 brezak if (krb5_write_message(&local_socket, &msg_data)){
461 1.1 brezak fprintf(stderr, "passwd: Write Error During Second Message Transmission\n");
462 1.1 brezak retval = 1;
463 1.1 brezak goto finish;
464 1.1 brezak }
465 1.1 brezak free(msg_data.data);
466 1.1 brezak
467 1.1 brezak /* Ok Now let's get the private message */
468 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
469 1.1 brezak fprintf(stderr, "passwd: Read Error During Second Reply: %s\n",
470 1.1 brezak error_message(retval));
471 1.1 brezak retval = 1;
472 1.1 brezak goto finish;
473 1.1 brezak }
474 1.1 brezak
475 1.1 brezak if ((retval = krb5_rd_priv(&inbuf,
476 1.1 brezak &my_creds.keyblock,
477 1.1 brezak &foreign_addr,
478 1.1 brezak &local_addr,
479 1.1 brezak rep_ret->seq_number,
480 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
481 1.1 brezak 0,
482 1.1 brezak 0,
483 1.1 brezak &msg_data))) {
484 1.1 brezak fprintf(stderr, "passwd: Error during Second Read Decoding :%s\n",
485 1.1 brezak error_message(retval));
486 1.1 brezak goto finish;
487 1.1 brezak }
488 1.1 brezak
489 1.1 brezak rd_priv_resp.appl_code = msg_data.data[0];
490 1.1 brezak rd_priv_resp.oper_code = msg_data.data[1];
491 1.1 brezak rd_priv_resp.retn_code = msg_data.data[2];
492 1.1 brezak if (msg_data.length > 3 && msg_data.data[3]) {
493 1.1 brezak rd_priv_resp.message = malloc(msg_data.length - 2);
494 1.1 brezak if (rd_priv_resp.message) {
495 1.1 brezak memcpy(rd_priv_resp.message, msg_data.data + 3,
496 1.1 brezak msg_data.length - 3);
497 1.1 brezak rd_priv_resp.message[msg_data.length - 3] = 0;
498 1.1 brezak }
499 1.1 brezak } else
500 1.1 brezak rd_priv_resp.message = NULL;
501 1.1 brezak
502 1.1 brezak
503 1.1 brezak free(inbuf.data);
504 1.1 brezak free(msg_data.data);
505 1.1 brezak if (rd_priv_resp.appl_code == KPASSWD) {
506 1.1 brezak if (rd_priv_resp.retn_code == KPASSBAD) {
507 1.1 brezak if (rd_priv_resp.message)
508 1.1 brezak fprintf(stderr, "passwd: %s\n", rd_priv_resp.message);
509 1.1 brezak else
510 1.1 brezak fprintf(stderr, "passwd: Server returned KPASSBAD.\n");
511 1.1 brezak } else if (rd_priv_resp.retn_code != KPASSGOOD)
512 1.1 brezak fprintf(stderr, "passwd: Server returned unknown kerberos code.\n");
513 1.1 brezak } else
514 1.1 brezak fprintf(stderr, "passwd: Server returned bad application code %d\n",
515 1.1 brezak rd_priv_resp.appl_code);
516 1.1 brezak
517 1.1 brezak if (rd_priv_resp.message)
518 1.1 brezak free(rd_priv_resp.message);
519 1.1 brezak
520 1.1 brezak finish:
521 1.1 brezak (void) krb5_cc_destroy(cache);
522 1.1 brezak
523 1.1 brezak free(client_name);
524 1.1 brezak free(requested_realm.data);
525 1.1 brezak if (cksum_alloc) free(send_cksum.contents);
526 1.1 brezak if (retval) {
527 1.1 brezak fprintf(stderr, "passwd: Protocol Failure - Password NOT changed\n");
528 1.1 brezak exit(1);
529 1.1 brezak }
530 1.1 brezak
531 1.1 brezak exit(0);
532 1.1 brezak }
533 1.1 brezak
534 1.1 brezak
535 1.1 brezak
536 1.1 brezak krb5_data cpwname = {
537 1.1 brezak sizeof(CPWNAME)-1,
538 1.1 brezak CPWNAME
539 1.1 brezak };
540 1.1 brezak
541 1.1 brezak static krb5_error_code
542 1.1 brezak get_first_ticket(cache, client)
543 1.1 brezak krb5_ccache cache;
544 1.1 brezak krb5_principal client;
545 1.1 brezak {
546 1.1 brezak char prompt[255]; /* for the password prompt */
547 1.1 brezak char verify_prompt[255]; /* Verification Prompt if Desired */
548 1.1 brezak char pword[ADM_MAX_PW_LENGTH+1]; /* storage for the password */
549 1.1 brezak int pword_length = sizeof(pword);
550 1.1 brezak char *old_password;
551 1.1 brezak int old_pwsize;
552 1.1 brezak int i;
553 1.1 brezak
554 1.1 brezak krb5_address **my_addresses;
555 1.1 brezak
556 1.1 brezak char *client_name;
557 1.1 brezak char local_realm[255];
558 1.1 brezak krb5_error_code retval;
559 1.1 brezak
560 1.1 brezak if ((retval = krb5_unparse_name(client, &client_name))) {
561 1.1 brezak fprintf(stderr, "Unable to Unparse Client Name\n");
562 1.1 brezak return(1);
563 1.1 brezak }
564 1.1 brezak
565 1.1 brezak (void) printf("Changing Kerberos password for %s\n", client_name);
566 1.1 brezak
567 1.1 brezak if ((retval = krb5_os_localaddr(&my_addresses))) {
568 1.1 brezak fprintf(stderr, "passwd: Unable to Get Customers Address\n");
569 1.1 brezak return(1);
570 1.1 brezak }
571 1.1 brezak
572 1.1 brezak memset((char *) &my_creds, 0, sizeof(my_creds));
573 1.1 brezak
574 1.1 brezak my_creds.client = client;
575 1.1 brezak
576 1.1 brezak if ((retval = krb5_build_principal_ext(&my_creds.server,
577 1.1 brezak client->realm.length,
578 1.1 brezak client->realm.data,
579 1.1 brezak cpwname.length, /* 6 */
580 1.1 brezak cpwname.data, /* "kadmin" */
581 1.1 brezak client->realm.length,
582 1.1 brezak /* instance is local realm */
583 1.1 brezak client->realm.data,
584 1.1 brezak 0))) {
585 1.1 brezak fprintf(stderr, "Error %s while building server name\n");
586 1.1 brezak return(1);
587 1.1 brezak }
588 1.1 brezak
589 1.1 brezak
590 1.1 brezak if ((old_password = (char *) calloc (1, 255)) == NULL) {
591 1.1 brezak fprintf(stderr, "passwd: No Memory for Retrieving old password\n");
592 1.1 brezak return(1);
593 1.1 brezak }
594 1.1 brezak
595 1.1 brezak old_pwsize = 255;
596 1.1 brezak if ((retval = krb5_read_password("Old kerberos password: ",
597 1.1 brezak 0,
598 1.1 brezak old_password,
599 1.1 brezak &old_pwsize))) {
600 1.1 brezak fprintf(stderr, "\nError while reading password for '%s'\n",
601 1.1 brezak client_name);
602 1.1 brezak return(1);
603 1.1 brezak }
604 1.1 brezak
605 1.1 brezak /* Build Request for Initial Credentials */
606 1.1 brezak for (i=0; preauth_search_list[i] >= 0; i++) {
607 1.1 brezak retval = krb5_get_in_tkt_with_password(
608 1.1 brezak 0, /* options */
609 1.1 brezak my_addresses,
610 1.1 brezak /* do random preauth */
611 1.1 brezak preauth_search_list[i],
612 1.1 brezak ETYPE_DES_CBC_CRC, /* etype */
613 1.1 brezak KEYTYPE_DES,
614 1.1 brezak old_password,
615 1.1 brezak cache,
616 1.1 brezak &my_creds,
617 1.1 brezak 0);
618 1.1 brezak if (retval != KRB5KDC_PREAUTH_FAILED &&
619 1.1 brezak retval != KRB5KRB_ERR_GENERIC)
620 1.1 brezak break;
621 1.1 brezak }
622 1.1 brezak
623 1.1 brezak if (retval) {
624 1.1 brezak fprintf(stderr, "passwd: Unable to Get Initial Credentials : %s\n",
625 1.1 brezak error_message(retval));
626 1.1 brezak }
627 1.1 brezak
628 1.1 brezak /* Do NOT Forget to zap password */
629 1.1 brezak memset((char *) old_password, 0, old_pwsize);
630 1.1 brezak free(old_password);
631 1.1 brezak memset((char *) pword, 0, sizeof(pword));
632 1.1 brezak return(retval);
633 1.1 brezak }
634 1.1 brezak
635 1.1 brezak #ifdef MACH_PASS /* Machine-generated Passwords */
636 1.1 brezak static krb5_error_code
637 1.1 brezak print_and_choose_password(new_password, decodable_pwd_string)
638 1.1 brezak char * new_password;
639 1.1 brezak krb5_data *decodable_pwd_string;
640 1.1 brezak {
641 1.1 brezak krb5_error_code retval;
642 1.1 brezak krb5_pwd_data *pwd_data;
643 1.1 brezak passwd_phrase_element **next_passwd_phrase_element;
644 1.1 brezak char prompt[255];
645 1.1 brezak char *verify_prompt = 0;
646 1.1 brezak int i, j, k;
647 1.1 brezak int legit_pswd = 0; /* Assume No Legitimate Password */
648 1.1 brezak char *password_list[ADM_MAX_PW_CHOICES];
649 1.1 brezak char verification_passwd[ADM_MAX_PW_LENGTH+1];
650 1.1 brezak char phrase_in[ADM_MAX_PHRASE_LENGTH];
651 1.1 brezak int new_passwd_length;
652 1.1 brezak char *ptr;
653 1.1 brezak int verify = 0; /* Do Not Request Password Selection Verification */
654 1.1 brezak int ok = 0;
655 1.1 brezak
656 1.1 brezak #define free_local_password_list() \
657 1.1 brezak { for ( k = 0; k < i && k < ADM_MAX_PW_CHOICES; k++) { \
658 1.1 brezak (void) memset(password_list[k], 0, ADM_MAX_PW_LENGTH); \
659 1.1 brezak free(password_list[k]); } \
660 1.1 brezak }
661 1.1 brezak
662 1.1 brezak /* Decode Password and Phrase Information Obtained from krb5_rd_priv */
663 1.1 brezak if ((retval = decode_krb5_pwd_data(decodable_pwd_string , &pwd_data))) {
664 1.1 brezak fprintf(stderr, "passwd: Unable to Decode Passwords and Phrases\n");
665 1.1 brezak fprintf(stderr, " Notify your System Administrator or the Kerberos Administrator\n");
666 1.1 brezak return(1);
667 1.1 brezak }
668 1.1 brezak
669 1.1 brezak next_passwd_phrase_element = pwd_data->element;
670 1.1 brezak /* Display List in 5 Password/Phrase Increments up to MAX Iterations */
671 1.1 brezak memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH);
672 1.1 brezak for ( j = 0; j <= ADM_MAX_PW_ITERATIONS; j++) {
673 1.1 brezak if (j == ADM_MAX_PW_ITERATIONS) {
674 1.1 brezak fprintf(stderr, "passwd: Sorry - You Have Exceeded the List of Choices (%d) Allowed for Password\n",
675 1.1 brezak ADM_MAX_PW_ITERATIONS * ADM_MAX_PW_CHOICES);
676 1.1 brezak fprintf(stderr, " Modification. You Must Repeat this Operation in order to Successfully\n");
677 1.1 brezak fprintf(stderr, " Change your Password.\n");
678 1.1 brezak break;
679 1.1 brezak }
680 1.1 brezak
681 1.1 brezak display_print:
682 1.1 brezak printf("Choose a password from the following list:\n");
683 1.1 brezak
684 1.1 brezak printf("\nPassword Remembrance Aid\n");
685 1.1 brezak
686 1.1 brezak /* Print Passwords and Assistance Phrases List */
687 1.1 brezak for ( i = 0; i < ADM_MAX_PW_CHOICES; i++){
688 1.1 brezak if ((password_list[i] = (char *) calloc (1,
689 1.1 brezak ADM_MAX_PW_LENGTH + 1)) == NULL) {
690 1.1 brezak fprintf(stderr, "passwd: Unable to Allocate Password List.\n");
691 1.1 brezak return(1);
692 1.1 brezak }
693 1.1 brezak
694 1.1 brezak memcpy(password_list[i],
695 1.1 brezak (*next_passwd_phrase_element)->passwd->data,
696 1.1 brezak (*next_passwd_phrase_element)->passwd->length);
697 1.1 brezak printf("%s ", password_list[i]);
698 1.1 brezak
699 1.1 brezak memcpy((char *) phrase_in,
700 1.1 brezak (*next_passwd_phrase_element)->phrase->data,
701 1.1 brezak (*next_passwd_phrase_element)->phrase->length);
702 1.1 brezak for ( k = 0;
703 1.1 brezak k < 50 && k < (*next_passwd_phrase_element)->phrase->length;
704 1.1 brezak k++) {
705 1.1 brezak printf("%c", phrase_in[k]);
706 1.1 brezak }
707 1.1 brezak for ( k = k;
708 1.1 brezak k < 70 && k < (*next_passwd_phrase_element)->phrase->length;
709 1.1 brezak k++) {
710 1.1 brezak if (phrase_in[k] == ' ') {
711 1.1 brezak printf("\n ");
712 1.1 brezak k++;
713 1.1 brezak break;
714 1.1 brezak } else {
715 1.1 brezak printf("%c", phrase_in[k]);
716 1.1 brezak }
717 1.1 brezak }
718 1.1 brezak for ( k = k;
719 1.1 brezak k < (*next_passwd_phrase_element)->phrase->length;
720 1.1 brezak k++) {
721 1.1 brezak printf("%c", phrase_in[k]);
722 1.1 brezak }
723 1.1 brezak printf("\n");
724 1.1 brezak memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH);
725 1.1 brezak next_passwd_phrase_element++;
726 1.1 brezak }
727 1.1 brezak
728 1.4 mrg (void)snprintf(prompt, sizeof prompt,
729 1.1 brezak "\nEnter Password Selection or a <CR> to get new list: ");
730 1.1 brezak
731 1.1 brezak new_passwd_length = ADM_MAX_PW_LENGTH+1;
732 1.1 brezak /* Read New Password from Terminal (Do Not Print on Screen) */
733 1.1 brezak if ((retval = krb5_read_password(&prompt[0], 0,
734 1.1 brezak new_password, &new_passwd_length))) {
735 1.1 brezak fprintf(stderr,
736 1.1 brezak "passwd: Error Reading Password Input or Input Aborted\n");
737 1.1 brezak free_local_password_list();
738 1.1 brezak break;;
739 1.1 brezak }
740 1.1 brezak
741 1.1 brezak /* Check for <CR> ==> Provide a New List */
742 1.1 brezak if (new_passwd_length == 0) continue;
743 1.1 brezak
744 1.1 brezak /* Check that Selection is from List - Server also does this */
745 1.1 brezak legit_pswd = 0;
746 1.1 brezak for (i = 0; i < ADM_MAX_PW_CHOICES && !legit_pswd; i++)
747 1.1 brezak if ((retval = memcmp(new_password,
748 1.1 brezak password_list[i], 8)) == 0) {
749 1.1 brezak legit_pswd++;
750 1.1 brezak }
751 1.1 brezak free_local_password_list();
752 1.1 brezak
753 1.1 brezak if (!(legit_pswd)) {
754 1.1 brezak printf("\07\07Password must be from the specified list ");
755 1.1 brezak printf("- Try Again\n");
756 1.1 brezak }
757 1.1 brezak
758 1.1 brezak if (legit_pswd) break; /* Exit Loop */
759 1.1 brezak } /* ADM_MAX_PW_CHOICES Loop */
760 1.1 brezak
761 1.1 brezak if (!(legit_pswd)) return (1);
762 1.1 brezak
763 1.1 brezak return(0); /* SUCCESS */
764 1.1 brezak }
765 1.1 brezak #endif
766 1.1 brezak
767 1.1 brezak static krb5_error_code
768 1.1 brezak adm5_init_link(realm_of_server, local_socket)
769 1.1 brezak krb5_data *realm_of_server;
770 1.1 brezak int * local_socket;
771 1.1 brezak {
772 1.1 brezak struct servent *service_process; /* service we will talk to */
773 1.1 brezak struct hostent *local_host; /* us */
774 1.1 brezak struct hostent *remote_host; /* host we will talk to */
775 1.1 brezak struct sockaddr *sockaddr_list;
776 1.1 brezak
777 1.1 brezak char **hostlist;
778 1.1 brezak
779 1.1 brezak int host_count;
780 1.1 brezak int namelen;
781 1.1 brezak int i, count;
782 1.1 brezak
783 1.1 brezak krb5_error_code retval;
784 1.1 brezak
785 1.1 brezak /* clear out the structure first */
786 1.1 brezak (void) memset((char *)&remote_sin, 0, sizeof(remote_sin));
787 1.1 brezak
788 1.1 brezak if ((service_process = getservbyname(CPW_SNAME, "tcp")) == NULL) {
789 1.1 brezak fprintf(stderr, "passwd: Unable to find Service (%s) Check services file\n",
790 1.1 brezak CPW_SNAME);
791 1.1 brezak return(1);
792 1.1 brezak }
793 1.1 brezak
794 1.1 brezak /* Copy the Port Number */
795 1.1 brezak remote_sin.sin_port = service_process->s_port;
796 1.1 brezak
797 1.1 brezak hostlist = 0;
798 1.1 brezak
799 1.1 brezak /* Identify all Hosts Associated with this Realm */
800 1.1 brezak if ((retval = krb5_get_krbhst (realm_of_server, &hostlist))) {
801 1.1 brezak fprintf(stderr, "passwd: Unable to Determine Server Name\n");
802 1.1 brezak return(1);
803 1.1 brezak }
804 1.1 brezak
805 1.1 brezak for (i=0; hostlist[i]; i++);
806 1.1 brezak
807 1.1 brezak count = i;
808 1.1 brezak
809 1.1 brezak if (count == 0) {
810 1.1 brezak host_count = 0;
811 1.1 brezak fprintf(stderr, "passwd: No hosts found\n");
812 1.1 brezak return(1);
813 1.1 brezak }
814 1.1 brezak
815 1.1 brezak for (i=0; hostlist[i]; i++) {
816 1.1 brezak remote_host = gethostbyname(hostlist[i]);
817 1.1 brezak if (remote_host != 0) {
818 1.1 brezak
819 1.1 brezak /* set up the address of the foreign socket for connect() */
820 1.1 brezak remote_sin.sin_family = remote_host->h_addrtype;
821 1.1 brezak (void) memcpy((char *) &remote_sin.sin_addr,
822 1.1 brezak (char *) remote_host->h_addr,
823 1.1 brezak sizeof(remote_host->h_addr));
824 1.1 brezak break; /* Only Need one */
825 1.1 brezak }
826 1.1 brezak }
827 1.1 brezak
828 1.1 brezak free ((char *)hostlist);
829 1.1 brezak
830 1.1 brezak /* open a TCP socket */
831 1.1 brezak *local_socket = socket(PF_INET, SOCK_STREAM, 0);
832 1.1 brezak if (*local_socket < 0) {
833 1.1 brezak fprintf(stderr, "passwd: Cannot Open Socket\n");
834 1.1 brezak return(1);
835 1.1 brezak }
836 1.1 brezak /* connect to the server */
837 1.1 brezak if (connect(*local_socket, (struct sockaddr *)&remote_sin, sizeof(remote_sin)) < 0) {
838 1.1 brezak fprintf(stderr, "passwd: Cannot Connect to Socket\n");
839 1.1 brezak close(*local_socket);
840 1.1 brezak return(1);
841 1.1 brezak }
842 1.1 brezak
843 1.1 brezak /* find out who I am, now that we are connected and therefore bound */
844 1.1 brezak namelen = sizeof(local_sin);
845 1.1 brezak if (getsockname(*local_socket,
846 1.1 brezak (struct sockaddr *) &local_sin, &namelen) < 0) {
847 1.1 brezak fprintf(stderr, "passwd: Cannot Perform getsockname\n");
848 1.1 brezak close(*local_socket);
849 1.1 brezak return(1);
850 1.1 brezak }
851 1.1 brezak return(0);
852 1.1 brezak }
853 1.1 brezak
854 1.1 brezak static void
855 1.1 brezak finish()
856 1.1 brezak {
857 1.1 brezak exit(1);
858 1.1 brezak }
859 1.1 brezak
860 1.1 brezak #ifdef KRB_NONETWORK
861 1.1 brezak #include <utmp.h>
862 1.1 brezak
863 1.1 brezak #ifndef MAXHOSTNAME
864 1.1 brezak #define MAXHOSTNAME 64
865 1.1 brezak #endif
866 1.1 brezak
867 1.1 brezak int utfile; /* Global utfile file descriptor for BSD version
868 1.1 brezak of setutent, getutline, and endutent */
869 1.1 brezak
870 1.1 brezak #if !defined(SYSV) && !defined(UMIPS) /* Setutent, Endutent, and getutline
871 1.1 brezak routines for non System V Unix
872 1.1 brezak systems */
873 1.1 brezak #include <fcntl.h>
874 1.1 brezak
875 1.1 brezak void setutent()
876 1.1 brezak {
877 1.1 brezak utfile = open("/etc/utmp",O_RDONLY);
878 1.1 brezak }
879 1.1 brezak
880 1.1 brezak struct utmp * getutline(utmpent)
881 1.1 brezak struct utmp *utmpent;
882 1.1 brezak {
883 1.1 brezak static struct utmp tmputmpent;
884 1.1 brezak int found = 0;
885 1.1 brezak while ( read(utfile,&tmputmpent,sizeof(struct utmp)) > 0 ){
886 1.1 brezak if ( strcmp(tmputmpent.ut_line,utmpent->ut_line) == 0){
887 1.1 brezak #ifdef NO_UT_HOST
888 1.1 brezak if ( ( 1) &&
889 1.1 brezak #else
890 1.1 brezak if ( (strcmp(tmputmpent.ut_host,"") == 0) &&
891 1.1 brezak #endif
892 1.1 brezak (strcmp(tmputmpent.ut_name,"") == 0)) continue;
893 1.1 brezak found = 1;
894 1.1 brezak break;
895 1.1 brezak }
896 1.1 brezak }
897 1.1 brezak if (found)
898 1.1 brezak return(&tmputmpent);
899 1.1 brezak return((struct utmp *) 0);
900 1.1 brezak }
901 1.1 brezak
902 1.1 brezak void endutent()
903 1.1 brezak {
904 1.1 brezak close(utfile);
905 1.1 brezak }
906 1.1 brezak #endif /* not SYSV */
907 1.1 brezak
908 1.1 brezak
909 1.1 brezak int network_connected()
910 1.1 brezak {
911 1.1 brezak struct utmp utmpent;
912 1.1 brezak struct utmp retutent, *tmpptr;
913 1.1 brezak char *display_indx;
914 1.1 brezak char currenthost[MAXHOSTNAME];
915 1.1 brezak char *username,*tmpname;
916 1.1 brezak
917 1.1 brezak
918 1.1 brezak /* Macro for pseudo_tty */
919 1.1 brezak #define pseudo_tty(ut) \
920 1.1 brezak ((strncmp((ut).ut_line, "tty", 3) == 0 && ((ut).ut_line[3] == 'p' \
921 1.1 brezak || (ut).ut_line[3] == 'q' \
922 1.1 brezak || (ut).ut_line[3] == 'r' \
923 1.1 brezak || (ut).ut_line[3] == 's'))\
924 1.1 brezak || (strncmp((ut).ut_line, "pty", 3) == 0))
925 1.1 brezak
926 1.1 brezak /* Check to see if getlogin returns proper name */
927 1.4 mrg if ( (tmpname = (char *) getlogin()) == (char *) 0)
928 1.4 mrg return(1);
929 1.4 mrg username = strdup(tmpname);
930 1.4 mrg if (username == (char *) 0)
931 1.4 mrg return(1);
932 1.1 brezak
933 1.1 brezak /* Obtain tty device for controlling tty of current process.*/
934 1.1 brezak strncpy(utmpent.ut_line,ttyname(0) + strlen("/dev/"),
935 1.1 brezak sizeof(utmpent.ut_line));
936 1.1 brezak
937 1.1 brezak /* See if this device is currently listed in /etc/utmp under
938 1.1 brezak calling user */
939 1.1 brezak #ifdef SYSV
940 1.1 brezak utmpent.ut_type = USER_PROCESS;
941 1.1 brezak #define ut_name ut_user
942 1.1 brezak #endif
943 1.1 brezak setutent();
944 1.1 brezak while ( (tmpptr = (struct utmp *) getutline(&utmpent))
945 1.1 brezak != ( struct utmp *) 0) {
946 1.1 brezak
947 1.1 brezak /* If logged out name and host will be empty */
948 1.1 brezak if ((strcmp(tmpptr->ut_name,"") == 0) &&
949 1.1 brezak #ifdef NO_UT_HOST
950 1.1 brezak ( 1)) continue;
951 1.1 brezak #else
952 1.1 brezak (strcmp(tmpptr->ut_host,"") == 0)) continue;
953 1.1 brezak #endif
954 1.1 brezak else break;
955 1.1 brezak }
956 1.1 brezak if ( tmpptr == (struct utmp *) 0) {
957 1.1 brezak endutent();
958 1.1 brezak return(1);
959 1.1 brezak }
960 1.1 brezak bcopy((char *)&retutent, (char *)tmpptr, sizeof(struct utmp));
961 1.1 brezak endutent();
962 1.1 brezak #ifdef DEBUG
963 1.1 brezak #ifdef NO_UT_HOST
964 1.1 brezak printf("User %s on line %s :\n",
965 1.1 brezak retutent.ut_name,retutent.ut_line);
966 1.1 brezak #else
967 1.1 brezak printf("User %s on line %s connected from host :%s:\n",
968 1.1 brezak retutent.ut_name,retutent.ut_line,retutent.ut_host);
969 1.1 brezak #endif
970 1.1 brezak #endif
971 1.1 brezak if (strcmp(retutent.ut_name,username) != 0) {
972 1.1 brezak return(1);
973 1.1 brezak }
974 1.1 brezak
975 1.1 brezak
976 1.1 brezak /* If this is not a pseudo tty then everything is OK */
977 1.1 brezak if (! pseudo_tty(retutent)) return(0);
978 1.1 brezak
979 1.1 brezak /* OK now the work begins there is an entry in utmp and
980 1.1 brezak the device is a pseudo tty. */
981 1.1 brezak
982 1.1 brezak /* Check if : is in hostname if so this is xwindow display */
983 1.1 brezak
984 1.1 brezak if (gethostname(currenthost,sizeof(currenthost))) return(1);
985 1.1 brezak #ifdef NO_UT_HOST
986 1.1 brezak display_indx = (char *) 0;
987 1.1 brezak #else
988 1.1 brezak display_indx = (char *) strchr(retutent.ut_host,':');
989 1.1 brezak #endif
990 1.1 brezak if ( display_indx != (char *) 0) {
991 1.1 brezak /*
992 1.1 brezak We have X window application here. The host field should have
993 1.1 brezak the form => local_system_name:0.0 or :0.0
994 1.1 brezak if the window is being displayed on the local system.
995 1.1 brezak */
996 1.1 brezak #ifdef NO_UT_HOST
997 1.1 brezak return(1);
998 1.1 brezak #else
999 1.1 brezak if (strncmp(currenthost,retutent.ut_host,
1000 1.1 brezak (display_indx - retutent.ut_host)) != 0) return(1);
1001 1.1 brezak else return(0);
1002 1.1 brezak #endif
1003 1.1 brezak }
1004 1.1 brezak
1005 1.1 brezak /* Host field is empty or is not X window entry. At this point
1006 1.1 brezak we can't trust that the pseudo tty is not connected to a
1007 1.1 brezak networked process so let's return 1.
1008 1.1 brezak */
1009 1.1 brezak return(1);
1010 1.1 brezak }
1011 1.1 brezak
1012 1.1 brezak int networked()
1013 1.1 brezak {
1014 1.1 brezak return(network_connected());
1015 1.1 brezak }
1016 1.1 brezak #endif
1017 1.3 tls
1018 1.3 tls int
1019 1.3 tls krb_check()
1020 1.3 tls {
1021 1.3 tls return(1): /* XXX! */
1022 1.3 tls }
1023 1.1 brezak
1024 1.1 brezak #endif /* KERBEROS5 */
1025