krb5_passwd.c revision 1.3 1 1.3 tls /* $NetBSD: krb5_passwd.c,v 1.3 1997/01/07 04:08:15 tls 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.3 tls static char rcsid[] = "$NetBSD: krb5_passwd.c,v 1.3 1997/01/07 04:08:15 tls 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.1 brezak (void) strcpy(default_name, pw->pw_name);
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.1 brezak (void) sprintf(cache_name, "FILE:/tmp/tkt_cpw_%d", getpid());
252 1.1 brezak
253 1.1 brezak if ((retval = krb5_cc_resolve(cache_name, &cache))) {
254 1.1 brezak fprintf(stderr, "passwd: Unable to Resolve Cache: %s\n", cache_name);
255 1.1 brezak }
256 1.1 brezak
257 1.1 brezak if ((retval = krb5_cc_initialize(cache, client))) {
258 1.1 brezak fprintf(stderr, "passwd: Error initializing cache: %s\n", cache_name);
259 1.1 brezak goto finish;
260 1.1 brezak }
261 1.1 brezak
262 1.1 brezak /*
263 1.1 brezak * Verify User by Obtaining Initial Credentials prior to Initial Link
264 1.1 brezak */
265 1.1 brezak if ((retval = get_first_ticket(cache, client))) {
266 1.1 brezak goto finish;
267 1.1 brezak }
268 1.1 brezak
269 1.1 brezak /* Initiate Link to Server */
270 1.1 brezak if ((retval = adm5_init_link(&requested_realm, &local_socket))) {
271 1.1 brezak goto finish;
272 1.1 brezak }
273 1.1 brezak
274 1.1 brezak #define SIZEOF_INADDR sizeof(struct in_addr)
275 1.1 brezak
276 1.1 brezak /* V4 kpasswd Protocol Hack */
277 1.1 brezak {
278 1.1 brezak int msg_length = 0;
279 1.1 brezak
280 1.1 brezak retval = krb5_net_write(local_socket, (char *) &msg_length + 2, 2);
281 1.1 brezak if (retval < 0) {
282 1.1 brezak fprintf(stderr, "passwd: krb5_net_write failure\n");
283 1.1 brezak goto finish;
284 1.1 brezak }
285 1.1 brezak }
286 1.1 brezak
287 1.1 brezak local_addr.addrtype = ADDRTYPE_INET;
288 1.1 brezak local_addr.length = SIZEOF_INADDR ;
289 1.1 brezak local_addr.contents = (krb5_octet *)&local_sin.sin_addr;
290 1.1 brezak
291 1.1 brezak foreign_addr.addrtype = ADDRTYPE_INET;
292 1.1 brezak foreign_addr.length = SIZEOF_INADDR ;
293 1.1 brezak foreign_addr.contents = (krb5_octet *)&remote_sin.sin_addr;
294 1.1 brezak
295 1.1 brezak /* compute checksum, using CRC-32 */
296 1.1 brezak if (!(send_cksum.contents = (krb5_octet *)
297 1.1 brezak malloc(krb5_checksum_size(CKSUMTYPE_CRC32)))) {
298 1.1 brezak fprintf(stderr, "passwd: Insufficient Memory while Allocating Checksum\n");
299 1.1 brezak goto finish;
300 1.1 brezak }
301 1.1 brezak cksum_alloc++;
302 1.1 brezak /* choose some random stuff to compute checksum from */
303 1.1 brezak if (retval = krb5_calculate_checksum(CKSUMTYPE_CRC32,
304 1.1 brezak ADM_CPW_VERSION,
305 1.1 brezak strlen(ADM_CPW_VERSION),
306 1.1 brezak 0,
307 1.1 brezak 0, /* if length is 0, crc-32 doesn't
308 1.1 brezak use the seed */
309 1.1 brezak &send_cksum)) {
310 1.1 brezak fprintf(stderr, "Error while Computing Checksum: %s\n",
311 1.1 brezak error_message(retval));
312 1.1 brezak goto finish;
313 1.1 brezak }
314 1.1 brezak
315 1.1 brezak /* call Kerberos library routine to obtain an authenticator,
316 1.1 brezak pass it over the socket to the server, and obtain mutual
317 1.1 brezak authentication. */
318 1.1 brezak
319 1.1 brezak if ((retval = krb5_sendauth((krb5_pointer) &local_socket,
320 1.1 brezak ADM_CPW_VERSION,
321 1.1 brezak my_creds.client,
322 1.1 brezak my_creds.server,
323 1.1 brezak AP_OPTS_MUTUAL_REQUIRED,
324 1.1 brezak &send_cksum,
325 1.1 brezak 0,
326 1.1 brezak cache,
327 1.1 brezak &seqno,
328 1.1 brezak 0, /* don't need a subsession key */
329 1.1 brezak &err_ret,
330 1.1 brezak &rep_ret))) {
331 1.1 brezak fprintf(stderr, "passwd: Error while performing sendauth: %s\n",
332 1.1 brezak error_message(retval));
333 1.1 brezak goto finish;
334 1.1 brezak }
335 1.1 brezak
336 1.1 brezak /* Get credentials : to use for safe and private messages */
337 1.1 brezak if (retval = krb5_get_credentials(0, cache, &my_creds)){
338 1.1 brezak fprintf(stderr, "passwd: Error Obtaining Credentials: %s\n",
339 1.1 brezak error_message(retval));
340 1.1 brezak goto finish;
341 1.1 brezak }
342 1.1 brezak
343 1.1 brezak /* Read back what the server has to say... */
344 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
345 1.1 brezak fprintf(stderr, "passwd: Read Message Error: %s\n",
346 1.1 brezak error_message(retval));
347 1.1 brezak goto finish;
348 1.1 brezak }
349 1.1 brezak if ((inbuf.length != 2) || (inbuf.data[0] != KADMIND) ||
350 1.1 brezak (inbuf.data[1] != KADMSAG)){
351 1.1 brezak fprintf(stderr, "passwd: Invalid ack from admin server.\n");
352 1.1 brezak goto finish;
353 1.1 brezak }
354 1.1 brezak
355 1.1 brezak inbuf.data[0] = KPASSWD;
356 1.1 brezak inbuf.data[1] = CHGOPER;
357 1.1 brezak inbuf.length = 2;
358 1.1 brezak
359 1.1 brezak if ((retval = krb5_mk_priv(&inbuf,
360 1.1 brezak ETYPE_DES_CBC_CRC,
361 1.1 brezak &my_creds.keyblock,
362 1.1 brezak &local_addr,
363 1.1 brezak &foreign_addr,
364 1.1 brezak seqno,
365 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
366 1.1 brezak 0,
367 1.1 brezak 0,
368 1.1 brezak &msg_data))) {
369 1.1 brezak fprintf(stderr, "passwd: Error during First Message Encoding: %s\n",
370 1.1 brezak error_message(retval));
371 1.1 brezak goto finish;
372 1.1 brezak }
373 1.1 brezak free(inbuf.data);
374 1.1 brezak
375 1.1 brezak /* write private message to server */
376 1.1 brezak if (krb5_write_message(&local_socket, &msg_data)){
377 1.1 brezak fprintf(stderr, "passwd: Write Error During First Message Transmission\n");
378 1.1 brezak retval = 1;
379 1.1 brezak goto finish;
380 1.1 brezak }
381 1.1 brezak free(msg_data.data);
382 1.1 brezak
383 1.1 brezak (void)signal(SIGHUP, finish);
384 1.1 brezak (void)signal(SIGINT, finish);
385 1.1 brezak
386 1.1 brezak #ifdef MACH_PASS /* Machine-generated Passwords */
387 1.1 brezak /* Ok Now let's get the private message */
388 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
389 1.1 brezak fprintf(stderr, "passwd: Read Error During First Reply: %s\n",
390 1.1 brezak error_message(retval));
391 1.1 brezak retval = 1;
392 1.1 brezak goto finish;
393 1.1 brezak }
394 1.1 brezak
395 1.1 brezak if ((retval = krb5_rd_priv(&inbuf,
396 1.1 brezak &my_creds.keyblock,
397 1.1 brezak &foreign_addr,
398 1.1 brezak &local_addr,
399 1.1 brezak rep_ret->seq_number,
400 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
401 1.1 brezak 0,
402 1.1 brezak 0,
403 1.1 brezak &msg_data))) {
404 1.1 brezak fprintf(stderr, "passwd: Error during First Read Decoding: %s\n",
405 1.1 brezak error_message(retval));
406 1.1 brezak goto finish;
407 1.1 brezak }
408 1.1 brezak free(inbuf.data);
409 1.1 brezak #endif
410 1.1 brezak
411 1.1 brezak if ((new_password = (char *) calloc (1, ADM_MAX_PW_LENGTH+1)) == NULL) {
412 1.1 brezak fprintf(stderr, "passwd: Unable to Allocate Space for New Password\n");
413 1.1 brezak goto finish;
414 1.1 brezak }
415 1.1 brezak
416 1.1 brezak #ifdef MACH_PASS /* Machine-generated passwords */
417 1.1 brezak /* Offer Client Password Choices */
418 1.1 brezak if ((retval = print_and_choose_password(new_password,
419 1.1 brezak &msg_data))) {
420 1.1 brezak (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1);
421 1.1 brezak free(new_password);
422 1.1 brezak goto finish;
423 1.1 brezak }
424 1.1 brezak #else
425 1.1 brezak new_pwsize = ADM_MAX_PW_LENGTH+1;
426 1.1 brezak if ((retval = krb5_read_password("New Kerberos password: ",
427 1.1 brezak "Retype new Kerberos password: ",
428 1.1 brezak new_password,
429 1.1 brezak &new_pwsize))) {
430 1.1 brezak fprintf(stderr, "\nError while reading new password for '%s'\n",
431 1.1 brezak client_name);
432 1.1 brezak (void) memset((char *) new_password, 0, ADM_MAX_PW_LENGTH+1);
433 1.1 brezak free(new_password);
434 1.1 brezak goto finish;
435 1.1 brezak }
436 1.1 brezak #endif
437 1.1 brezak
438 1.1 brezak inbuf.data = new_password;
439 1.1 brezak inbuf.length = strlen(new_password);
440 1.1 brezak
441 1.1 brezak if ((retval = krb5_mk_priv(&inbuf,
442 1.1 brezak ETYPE_DES_CBC_CRC,
443 1.1 brezak &my_creds.keyblock,
444 1.1 brezak &local_addr,
445 1.1 brezak &foreign_addr,
446 1.1 brezak seqno,
447 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
448 1.1 brezak 0,
449 1.1 brezak 0,
450 1.1 brezak &msg_data))) {
451 1.1 brezak fprintf(stderr, "passwd: Error during Second Message Encoding: %s\n",
452 1.1 brezak error_message(retval));
453 1.1 brezak goto finish;
454 1.1 brezak }
455 1.1 brezak memset(inbuf.data,0,inbuf.length);
456 1.1 brezak free(inbuf.data);
457 1.1 brezak
458 1.1 brezak /* write private message to server */
459 1.1 brezak if (krb5_write_message(&local_socket, &msg_data)){
460 1.1 brezak fprintf(stderr, "passwd: Write Error During Second Message Transmission\n");
461 1.1 brezak retval = 1;
462 1.1 brezak goto finish;
463 1.1 brezak }
464 1.1 brezak free(msg_data.data);
465 1.1 brezak
466 1.1 brezak /* Ok Now let's get the private message */
467 1.1 brezak if (retval = krb5_read_message(&local_socket, &inbuf)){
468 1.1 brezak fprintf(stderr, "passwd: Read Error During Second Reply: %s\n",
469 1.1 brezak error_message(retval));
470 1.1 brezak retval = 1;
471 1.1 brezak goto finish;
472 1.1 brezak }
473 1.1 brezak
474 1.1 brezak if ((retval = krb5_rd_priv(&inbuf,
475 1.1 brezak &my_creds.keyblock,
476 1.1 brezak &foreign_addr,
477 1.1 brezak &local_addr,
478 1.1 brezak rep_ret->seq_number,
479 1.1 brezak KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
480 1.1 brezak 0,
481 1.1 brezak 0,
482 1.1 brezak &msg_data))) {
483 1.1 brezak fprintf(stderr, "passwd: Error during Second Read Decoding :%s\n",
484 1.1 brezak error_message(retval));
485 1.1 brezak goto finish;
486 1.1 brezak }
487 1.1 brezak
488 1.1 brezak rd_priv_resp.appl_code = msg_data.data[0];
489 1.1 brezak rd_priv_resp.oper_code = msg_data.data[1];
490 1.1 brezak rd_priv_resp.retn_code = msg_data.data[2];
491 1.1 brezak if (msg_data.length > 3 && msg_data.data[3]) {
492 1.1 brezak rd_priv_resp.message = malloc(msg_data.length - 2);
493 1.1 brezak if (rd_priv_resp.message) {
494 1.1 brezak memcpy(rd_priv_resp.message, msg_data.data + 3,
495 1.1 brezak msg_data.length - 3);
496 1.1 brezak rd_priv_resp.message[msg_data.length - 3] = 0;
497 1.1 brezak }
498 1.1 brezak } else
499 1.1 brezak rd_priv_resp.message = NULL;
500 1.1 brezak
501 1.1 brezak
502 1.1 brezak free(inbuf.data);
503 1.1 brezak free(msg_data.data);
504 1.1 brezak if (rd_priv_resp.appl_code == KPASSWD) {
505 1.1 brezak if (rd_priv_resp.retn_code == KPASSBAD) {
506 1.1 brezak if (rd_priv_resp.message)
507 1.1 brezak fprintf(stderr, "passwd: %s\n", rd_priv_resp.message);
508 1.1 brezak else
509 1.1 brezak fprintf(stderr, "passwd: Server returned KPASSBAD.\n");
510 1.1 brezak } else if (rd_priv_resp.retn_code != KPASSGOOD)
511 1.1 brezak fprintf(stderr, "passwd: Server returned unknown kerberos code.\n");
512 1.1 brezak } else
513 1.1 brezak fprintf(stderr, "passwd: Server returned bad application code %d\n",
514 1.1 brezak rd_priv_resp.appl_code);
515 1.1 brezak
516 1.1 brezak if (rd_priv_resp.message)
517 1.1 brezak free(rd_priv_resp.message);
518 1.1 brezak
519 1.1 brezak finish:
520 1.1 brezak (void) krb5_cc_destroy(cache);
521 1.1 brezak
522 1.1 brezak free(client_name);
523 1.1 brezak free(requested_realm.data);
524 1.1 brezak if (cksum_alloc) free(send_cksum.contents);
525 1.1 brezak if (retval) {
526 1.1 brezak fprintf(stderr, "passwd: Protocol Failure - Password NOT changed\n");
527 1.1 brezak exit(1);
528 1.1 brezak }
529 1.1 brezak
530 1.1 brezak exit(0);
531 1.1 brezak }
532 1.1 brezak
533 1.1 brezak
534 1.1 brezak
535 1.1 brezak krb5_data cpwname = {
536 1.1 brezak sizeof(CPWNAME)-1,
537 1.1 brezak CPWNAME
538 1.1 brezak };
539 1.1 brezak
540 1.1 brezak static krb5_error_code
541 1.1 brezak get_first_ticket(cache, client)
542 1.1 brezak krb5_ccache cache;
543 1.1 brezak krb5_principal client;
544 1.1 brezak {
545 1.1 brezak char prompt[255]; /* for the password prompt */
546 1.1 brezak char verify_prompt[255]; /* Verification Prompt if Desired */
547 1.1 brezak char pword[ADM_MAX_PW_LENGTH+1]; /* storage for the password */
548 1.1 brezak int pword_length = sizeof(pword);
549 1.1 brezak char *old_password;
550 1.1 brezak int old_pwsize;
551 1.1 brezak int i;
552 1.1 brezak
553 1.1 brezak krb5_address **my_addresses;
554 1.1 brezak
555 1.1 brezak char *client_name;
556 1.1 brezak char local_realm[255];
557 1.1 brezak krb5_error_code retval;
558 1.1 brezak
559 1.1 brezak if ((retval = krb5_unparse_name(client, &client_name))) {
560 1.1 brezak fprintf(stderr, "Unable to Unparse Client Name\n");
561 1.1 brezak return(1);
562 1.1 brezak }
563 1.1 brezak
564 1.1 brezak (void) printf("Changing Kerberos password for %s\n", client_name);
565 1.1 brezak
566 1.1 brezak if ((retval = krb5_os_localaddr(&my_addresses))) {
567 1.1 brezak fprintf(stderr, "passwd: Unable to Get Customers Address\n");
568 1.1 brezak return(1);
569 1.1 brezak }
570 1.1 brezak
571 1.1 brezak memset((char *) &my_creds, 0, sizeof(my_creds));
572 1.1 brezak
573 1.1 brezak my_creds.client = client;
574 1.1 brezak
575 1.1 brezak if ((retval = krb5_build_principal_ext(&my_creds.server,
576 1.1 brezak client->realm.length,
577 1.1 brezak client->realm.data,
578 1.1 brezak cpwname.length, /* 6 */
579 1.1 brezak cpwname.data, /* "kadmin" */
580 1.1 brezak client->realm.length,
581 1.1 brezak /* instance is local realm */
582 1.1 brezak client->realm.data,
583 1.1 brezak 0))) {
584 1.1 brezak fprintf(stderr, "Error %s while building server name\n");
585 1.1 brezak return(1);
586 1.1 brezak }
587 1.1 brezak
588 1.1 brezak
589 1.1 brezak if ((old_password = (char *) calloc (1, 255)) == NULL) {
590 1.1 brezak fprintf(stderr, "passwd: No Memory for Retrieving old password\n");
591 1.1 brezak return(1);
592 1.1 brezak }
593 1.1 brezak
594 1.1 brezak old_pwsize = 255;
595 1.1 brezak if ((retval = krb5_read_password("Old kerberos password: ",
596 1.1 brezak 0,
597 1.1 brezak old_password,
598 1.1 brezak &old_pwsize))) {
599 1.1 brezak fprintf(stderr, "\nError while reading password for '%s'\n",
600 1.1 brezak client_name);
601 1.1 brezak return(1);
602 1.1 brezak }
603 1.1 brezak
604 1.1 brezak /* Build Request for Initial Credentials */
605 1.1 brezak for (i=0; preauth_search_list[i] >= 0; i++) {
606 1.1 brezak retval = krb5_get_in_tkt_with_password(
607 1.1 brezak 0, /* options */
608 1.1 brezak my_addresses,
609 1.1 brezak /* do random preauth */
610 1.1 brezak preauth_search_list[i],
611 1.1 brezak ETYPE_DES_CBC_CRC, /* etype */
612 1.1 brezak KEYTYPE_DES,
613 1.1 brezak old_password,
614 1.1 brezak cache,
615 1.1 brezak &my_creds,
616 1.1 brezak 0);
617 1.1 brezak if (retval != KRB5KDC_PREAUTH_FAILED &&
618 1.1 brezak retval != KRB5KRB_ERR_GENERIC)
619 1.1 brezak break;
620 1.1 brezak }
621 1.1 brezak
622 1.1 brezak if (retval) {
623 1.1 brezak fprintf(stderr, "passwd: Unable to Get Initial Credentials : %s\n",
624 1.1 brezak error_message(retval));
625 1.1 brezak }
626 1.1 brezak
627 1.1 brezak /* Do NOT Forget to zap password */
628 1.1 brezak memset((char *) old_password, 0, old_pwsize);
629 1.1 brezak free(old_password);
630 1.1 brezak memset((char *) pword, 0, sizeof(pword));
631 1.1 brezak return(retval);
632 1.1 brezak }
633 1.1 brezak
634 1.1 brezak #ifdef MACH_PASS /* Machine-generated Passwords */
635 1.1 brezak static krb5_error_code
636 1.1 brezak print_and_choose_password(new_password, decodable_pwd_string)
637 1.1 brezak char * new_password;
638 1.1 brezak krb5_data *decodable_pwd_string;
639 1.1 brezak {
640 1.1 brezak krb5_error_code retval;
641 1.1 brezak krb5_pwd_data *pwd_data;
642 1.1 brezak passwd_phrase_element **next_passwd_phrase_element;
643 1.1 brezak char prompt[255];
644 1.1 brezak char *verify_prompt = 0;
645 1.1 brezak int i, j, k;
646 1.1 brezak int legit_pswd = 0; /* Assume No Legitimate Password */
647 1.1 brezak char *password_list[ADM_MAX_PW_CHOICES];
648 1.1 brezak char verification_passwd[ADM_MAX_PW_LENGTH+1];
649 1.1 brezak char phrase_in[ADM_MAX_PHRASE_LENGTH];
650 1.1 brezak int new_passwd_length;
651 1.1 brezak char *ptr;
652 1.1 brezak int verify = 0; /* Do Not Request Password Selection Verification */
653 1.1 brezak int ok = 0;
654 1.1 brezak
655 1.1 brezak #define free_local_password_list() \
656 1.1 brezak { for ( k = 0; k < i && k < ADM_MAX_PW_CHOICES; k++) { \
657 1.1 brezak (void) memset(password_list[k], 0, ADM_MAX_PW_LENGTH); \
658 1.1 brezak free(password_list[k]); } \
659 1.1 brezak }
660 1.1 brezak
661 1.1 brezak /* Decode Password and Phrase Information Obtained from krb5_rd_priv */
662 1.1 brezak if ((retval = decode_krb5_pwd_data(decodable_pwd_string , &pwd_data))) {
663 1.1 brezak fprintf(stderr, "passwd: Unable to Decode Passwords and Phrases\n");
664 1.1 brezak fprintf(stderr, " Notify your System Administrator or the Kerberos Administrator\n");
665 1.1 brezak return(1);
666 1.1 brezak }
667 1.1 brezak
668 1.1 brezak next_passwd_phrase_element = pwd_data->element;
669 1.1 brezak /* Display List in 5 Password/Phrase Increments up to MAX Iterations */
670 1.1 brezak memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH);
671 1.1 brezak for ( j = 0; j <= ADM_MAX_PW_ITERATIONS; j++) {
672 1.1 brezak if (j == ADM_MAX_PW_ITERATIONS) {
673 1.1 brezak fprintf(stderr, "passwd: Sorry - You Have Exceeded the List of Choices (%d) Allowed for Password\n",
674 1.1 brezak ADM_MAX_PW_ITERATIONS * ADM_MAX_PW_CHOICES);
675 1.1 brezak fprintf(stderr, " Modification. You Must Repeat this Operation in order to Successfully\n");
676 1.1 brezak fprintf(stderr, " Change your Password.\n");
677 1.1 brezak break;
678 1.1 brezak }
679 1.1 brezak
680 1.1 brezak display_print:
681 1.1 brezak printf("Choose a password from the following list:\n");
682 1.1 brezak
683 1.1 brezak printf("\nPassword Remembrance Aid\n");
684 1.1 brezak
685 1.1 brezak /* Print Passwords and Assistance Phrases List */
686 1.1 brezak for ( i = 0; i < ADM_MAX_PW_CHOICES; i++){
687 1.1 brezak if ((password_list[i] = (char *) calloc (1,
688 1.1 brezak ADM_MAX_PW_LENGTH + 1)) == NULL) {
689 1.1 brezak fprintf(stderr, "passwd: Unable to Allocate Password List.\n");
690 1.1 brezak return(1);
691 1.1 brezak }
692 1.1 brezak
693 1.1 brezak memcpy(password_list[i],
694 1.1 brezak (*next_passwd_phrase_element)->passwd->data,
695 1.1 brezak (*next_passwd_phrase_element)->passwd->length);
696 1.1 brezak printf("%s ", password_list[i]);
697 1.1 brezak
698 1.1 brezak memcpy((char *) phrase_in,
699 1.1 brezak (*next_passwd_phrase_element)->phrase->data,
700 1.1 brezak (*next_passwd_phrase_element)->phrase->length);
701 1.1 brezak for ( k = 0;
702 1.1 brezak k < 50 && k < (*next_passwd_phrase_element)->phrase->length;
703 1.1 brezak k++) {
704 1.1 brezak printf("%c", phrase_in[k]);
705 1.1 brezak }
706 1.1 brezak for ( k = k;
707 1.1 brezak k < 70 && k < (*next_passwd_phrase_element)->phrase->length;
708 1.1 brezak k++) {
709 1.1 brezak if (phrase_in[k] == ' ') {
710 1.1 brezak printf("\n ");
711 1.1 brezak k++;
712 1.1 brezak break;
713 1.1 brezak } else {
714 1.1 brezak printf("%c", phrase_in[k]);
715 1.1 brezak }
716 1.1 brezak }
717 1.1 brezak for ( k = k;
718 1.1 brezak k < (*next_passwd_phrase_element)->phrase->length;
719 1.1 brezak k++) {
720 1.1 brezak printf("%c", phrase_in[k]);
721 1.1 brezak }
722 1.1 brezak printf("\n");
723 1.1 brezak memset((char *) phrase_in, 0, ADM_MAX_PHRASE_LENGTH);
724 1.1 brezak next_passwd_phrase_element++;
725 1.1 brezak }
726 1.1 brezak
727 1.1 brezak sprintf(prompt,
728 1.1 brezak "\nEnter Password Selection or a <CR> to get new list: ");
729 1.1 brezak
730 1.1 brezak new_passwd_length = ADM_MAX_PW_LENGTH+1;
731 1.1 brezak /* Read New Password from Terminal (Do Not Print on Screen) */
732 1.1 brezak if ((retval = krb5_read_password(&prompt[0], 0,
733 1.1 brezak new_password, &new_passwd_length))) {
734 1.1 brezak fprintf(stderr,
735 1.1 brezak "passwd: Error Reading Password Input or Input Aborted\n");
736 1.1 brezak free_local_password_list();
737 1.1 brezak break;;
738 1.1 brezak }
739 1.1 brezak
740 1.1 brezak /* Check for <CR> ==> Provide a New List */
741 1.1 brezak if (new_passwd_length == 0) continue;
742 1.1 brezak
743 1.1 brezak /* Check that Selection is from List - Server also does this */
744 1.1 brezak legit_pswd = 0;
745 1.1 brezak for (i = 0; i < ADM_MAX_PW_CHOICES && !legit_pswd; i++)
746 1.1 brezak if ((retval = memcmp(new_password,
747 1.1 brezak password_list[i], 8)) == 0) {
748 1.1 brezak legit_pswd++;
749 1.1 brezak }
750 1.1 brezak free_local_password_list();
751 1.1 brezak
752 1.1 brezak if (!(legit_pswd)) {
753 1.1 brezak printf("\07\07Password must be from the specified list ");
754 1.1 brezak printf("- Try Again\n");
755 1.1 brezak }
756 1.1 brezak
757 1.1 brezak if (legit_pswd) break; /* Exit Loop */
758 1.1 brezak } /* ADM_MAX_PW_CHOICES Loop */
759 1.1 brezak
760 1.1 brezak if (!(legit_pswd)) return (1);
761 1.1 brezak
762 1.1 brezak return(0); /* SUCCESS */
763 1.1 brezak }
764 1.1 brezak #endif
765 1.1 brezak
766 1.1 brezak static krb5_error_code
767 1.1 brezak adm5_init_link(realm_of_server, local_socket)
768 1.1 brezak krb5_data *realm_of_server;
769 1.1 brezak int * local_socket;
770 1.1 brezak {
771 1.1 brezak struct servent *service_process; /* service we will talk to */
772 1.1 brezak struct hostent *local_host; /* us */
773 1.1 brezak struct hostent *remote_host; /* host we will talk to */
774 1.1 brezak struct sockaddr *sockaddr_list;
775 1.1 brezak
776 1.1 brezak char **hostlist;
777 1.1 brezak
778 1.1 brezak int host_count;
779 1.1 brezak int namelen;
780 1.1 brezak int i, count;
781 1.1 brezak
782 1.1 brezak krb5_error_code retval;
783 1.1 brezak
784 1.1 brezak /* clear out the structure first */
785 1.1 brezak (void) memset((char *)&remote_sin, 0, sizeof(remote_sin));
786 1.1 brezak
787 1.1 brezak if ((service_process = getservbyname(CPW_SNAME, "tcp")) == NULL) {
788 1.1 brezak fprintf(stderr, "passwd: Unable to find Service (%s) Check services file\n",
789 1.1 brezak CPW_SNAME);
790 1.1 brezak return(1);
791 1.1 brezak }
792 1.1 brezak
793 1.1 brezak /* Copy the Port Number */
794 1.1 brezak remote_sin.sin_port = service_process->s_port;
795 1.1 brezak
796 1.1 brezak hostlist = 0;
797 1.1 brezak
798 1.1 brezak /* Identify all Hosts Associated with this Realm */
799 1.1 brezak if ((retval = krb5_get_krbhst (realm_of_server, &hostlist))) {
800 1.1 brezak fprintf(stderr, "passwd: Unable to Determine Server Name\n");
801 1.1 brezak return(1);
802 1.1 brezak }
803 1.1 brezak
804 1.1 brezak for (i=0; hostlist[i]; i++);
805 1.1 brezak
806 1.1 brezak count = i;
807 1.1 brezak
808 1.1 brezak if (count == 0) {
809 1.1 brezak host_count = 0;
810 1.1 brezak fprintf(stderr, "passwd: No hosts found\n");
811 1.1 brezak return(1);
812 1.1 brezak }
813 1.1 brezak
814 1.1 brezak for (i=0; hostlist[i]; i++) {
815 1.1 brezak remote_host = gethostbyname(hostlist[i]);
816 1.1 brezak if (remote_host != 0) {
817 1.1 brezak
818 1.1 brezak /* set up the address of the foreign socket for connect() */
819 1.1 brezak remote_sin.sin_family = remote_host->h_addrtype;
820 1.1 brezak (void) memcpy((char *) &remote_sin.sin_addr,
821 1.1 brezak (char *) remote_host->h_addr,
822 1.1 brezak sizeof(remote_host->h_addr));
823 1.1 brezak break; /* Only Need one */
824 1.1 brezak }
825 1.1 brezak }
826 1.1 brezak
827 1.1 brezak free ((char *)hostlist);
828 1.1 brezak
829 1.1 brezak /* open a TCP socket */
830 1.1 brezak *local_socket = socket(PF_INET, SOCK_STREAM, 0);
831 1.1 brezak if (*local_socket < 0) {
832 1.1 brezak fprintf(stderr, "passwd: Cannot Open Socket\n");
833 1.1 brezak return(1);
834 1.1 brezak }
835 1.1 brezak /* connect to the server */
836 1.1 brezak if (connect(*local_socket, (struct sockaddr *)&remote_sin, sizeof(remote_sin)) < 0) {
837 1.1 brezak fprintf(stderr, "passwd: Cannot Connect to Socket\n");
838 1.1 brezak close(*local_socket);
839 1.1 brezak return(1);
840 1.1 brezak }
841 1.1 brezak
842 1.1 brezak /* find out who I am, now that we are connected and therefore bound */
843 1.1 brezak namelen = sizeof(local_sin);
844 1.1 brezak if (getsockname(*local_socket,
845 1.1 brezak (struct sockaddr *) &local_sin, &namelen) < 0) {
846 1.1 brezak fprintf(stderr, "passwd: Cannot Perform getsockname\n");
847 1.1 brezak close(*local_socket);
848 1.1 brezak return(1);
849 1.1 brezak }
850 1.1 brezak return(0);
851 1.1 brezak }
852 1.1 brezak
853 1.1 brezak static void
854 1.1 brezak finish()
855 1.1 brezak {
856 1.1 brezak exit(1);
857 1.1 brezak }
858 1.1 brezak
859 1.1 brezak #ifdef KRB_NONETWORK
860 1.1 brezak #include <utmp.h>
861 1.1 brezak
862 1.1 brezak #ifndef MAXHOSTNAME
863 1.1 brezak #define MAXHOSTNAME 64
864 1.1 brezak #endif
865 1.1 brezak
866 1.1 brezak int utfile; /* Global utfile file descriptor for BSD version
867 1.1 brezak of setutent, getutline, and endutent */
868 1.1 brezak
869 1.1 brezak #if !defined(SYSV) && !defined(UMIPS) /* Setutent, Endutent, and getutline
870 1.1 brezak routines for non System V Unix
871 1.1 brezak systems */
872 1.1 brezak #include <fcntl.h>
873 1.1 brezak
874 1.1 brezak void setutent()
875 1.1 brezak {
876 1.1 brezak utfile = open("/etc/utmp",O_RDONLY);
877 1.1 brezak }
878 1.1 brezak
879 1.1 brezak struct utmp * getutline(utmpent)
880 1.1 brezak struct utmp *utmpent;
881 1.1 brezak {
882 1.1 brezak static struct utmp tmputmpent;
883 1.1 brezak int found = 0;
884 1.1 brezak while ( read(utfile,&tmputmpent,sizeof(struct utmp)) > 0 ){
885 1.1 brezak if ( strcmp(tmputmpent.ut_line,utmpent->ut_line) == 0){
886 1.1 brezak #ifdef NO_UT_HOST
887 1.1 brezak if ( ( 1) &&
888 1.1 brezak #else
889 1.1 brezak if ( (strcmp(tmputmpent.ut_host,"") == 0) &&
890 1.1 brezak #endif
891 1.1 brezak (strcmp(tmputmpent.ut_name,"") == 0)) continue;
892 1.1 brezak found = 1;
893 1.1 brezak break;
894 1.1 brezak }
895 1.1 brezak }
896 1.1 brezak if (found)
897 1.1 brezak return(&tmputmpent);
898 1.1 brezak return((struct utmp *) 0);
899 1.1 brezak }
900 1.1 brezak
901 1.1 brezak void endutent()
902 1.1 brezak {
903 1.1 brezak close(utfile);
904 1.1 brezak }
905 1.1 brezak #endif /* not SYSV */
906 1.1 brezak
907 1.1 brezak
908 1.1 brezak int network_connected()
909 1.1 brezak {
910 1.1 brezak struct utmp utmpent;
911 1.1 brezak struct utmp retutent, *tmpptr;
912 1.1 brezak char *display_indx;
913 1.1 brezak char currenthost[MAXHOSTNAME];
914 1.1 brezak char *username,*tmpname;
915 1.1 brezak
916 1.1 brezak
917 1.1 brezak /* Macro for pseudo_tty */
918 1.1 brezak #define pseudo_tty(ut) \
919 1.1 brezak ((strncmp((ut).ut_line, "tty", 3) == 0 && ((ut).ut_line[3] == 'p' \
920 1.1 brezak || (ut).ut_line[3] == 'q' \
921 1.1 brezak || (ut).ut_line[3] == 'r' \
922 1.1 brezak || (ut).ut_line[3] == 's'))\
923 1.1 brezak || (strncmp((ut).ut_line, "pty", 3) == 0))
924 1.1 brezak
925 1.1 brezak /* Check to see if getlogin returns proper name */
926 1.1 brezak if ( (tmpname = (char *) getlogin()) == (char *) 0) return(1);
927 1.1 brezak username = (char *) malloc(strlen(tmpname) + 1);
928 1.1 brezak if ( username == (char *) 0) return(1);
929 1.1 brezak strcpy(username,tmpname);
930 1.1 brezak
931 1.1 brezak /* Obtain tty device for controlling tty of current process.*/
932 1.1 brezak strncpy(utmpent.ut_line,ttyname(0) + strlen("/dev/"),
933 1.1 brezak sizeof(utmpent.ut_line));
934 1.1 brezak
935 1.1 brezak /* See if this device is currently listed in /etc/utmp under
936 1.1 brezak calling user */
937 1.1 brezak #ifdef SYSV
938 1.1 brezak utmpent.ut_type = USER_PROCESS;
939 1.1 brezak #define ut_name ut_user
940 1.1 brezak #endif
941 1.1 brezak setutent();
942 1.1 brezak while ( (tmpptr = (struct utmp *) getutline(&utmpent))
943 1.1 brezak != ( struct utmp *) 0) {
944 1.1 brezak
945 1.1 brezak /* If logged out name and host will be empty */
946 1.1 brezak if ((strcmp(tmpptr->ut_name,"") == 0) &&
947 1.1 brezak #ifdef NO_UT_HOST
948 1.1 brezak ( 1)) continue;
949 1.1 brezak #else
950 1.1 brezak (strcmp(tmpptr->ut_host,"") == 0)) continue;
951 1.1 brezak #endif
952 1.1 brezak else break;
953 1.1 brezak }
954 1.1 brezak if ( tmpptr == (struct utmp *) 0) {
955 1.1 brezak endutent();
956 1.1 brezak return(1);
957 1.1 brezak }
958 1.1 brezak bcopy((char *)&retutent, (char *)tmpptr, sizeof(struct utmp));
959 1.1 brezak endutent();
960 1.1 brezak #ifdef DEBUG
961 1.1 brezak #ifdef NO_UT_HOST
962 1.1 brezak printf("User %s on line %s :\n",
963 1.1 brezak retutent.ut_name,retutent.ut_line);
964 1.1 brezak #else
965 1.1 brezak printf("User %s on line %s connected from host :%s:\n",
966 1.1 brezak retutent.ut_name,retutent.ut_line,retutent.ut_host);
967 1.1 brezak #endif
968 1.1 brezak #endif
969 1.1 brezak if (strcmp(retutent.ut_name,username) != 0) {
970 1.1 brezak return(1);
971 1.1 brezak }
972 1.1 brezak
973 1.1 brezak
974 1.1 brezak /* If this is not a pseudo tty then everything is OK */
975 1.1 brezak if (! pseudo_tty(retutent)) return(0);
976 1.1 brezak
977 1.1 brezak /* OK now the work begins there is an entry in utmp and
978 1.1 brezak the device is a pseudo tty. */
979 1.1 brezak
980 1.1 brezak /* Check if : is in hostname if so this is xwindow display */
981 1.1 brezak
982 1.1 brezak if (gethostname(currenthost,sizeof(currenthost))) return(1);
983 1.1 brezak #ifdef NO_UT_HOST
984 1.1 brezak display_indx = (char *) 0;
985 1.1 brezak #else
986 1.1 brezak display_indx = (char *) strchr(retutent.ut_host,':');
987 1.1 brezak #endif
988 1.1 brezak if ( display_indx != (char *) 0) {
989 1.1 brezak /*
990 1.1 brezak We have X window application here. The host field should have
991 1.1 brezak the form => local_system_name:0.0 or :0.0
992 1.1 brezak if the window is being displayed on the local system.
993 1.1 brezak */
994 1.1 brezak #ifdef NO_UT_HOST
995 1.1 brezak return(1);
996 1.1 brezak #else
997 1.1 brezak if (strncmp(currenthost,retutent.ut_host,
998 1.1 brezak (display_indx - retutent.ut_host)) != 0) return(1);
999 1.1 brezak else return(0);
1000 1.1 brezak #endif
1001 1.1 brezak }
1002 1.1 brezak
1003 1.1 brezak /* Host field is empty or is not X window entry. At this point
1004 1.1 brezak we can't trust that the pseudo tty is not connected to a
1005 1.1 brezak networked process so let's return 1.
1006 1.1 brezak */
1007 1.1 brezak return(1);
1008 1.1 brezak }
1009 1.1 brezak
1010 1.1 brezak int networked()
1011 1.1 brezak {
1012 1.1 brezak return(network_connected());
1013 1.1 brezak }
1014 1.1 brezak #endif
1015 1.3 tls
1016 1.3 tls int
1017 1.3 tls krb_check()
1018 1.3 tls {
1019 1.3 tls return(1): /* XXX! */
1020 1.3 tls }
1021 1.1 brezak
1022 1.1 brezak #endif /* KERBEROS5 */
1023