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