VAX subdirectory has been broken up
[unix-history] / usr / src / usr.bin / login / klogin.c
CommitLineData
7408b3e5
KF
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
fa57fc2a 9static char sccsid[] = "@(#)klogin.c 5.9 (Berkeley) %G%";
7408b3e5
KF
10#endif /* not lint */
11
12#ifdef KERBEROS
13#include <sys/param.h>
14#include <sys/syslog.h>
15#include <kerberosIV/des.h>
16#include <kerberosIV/krb.h>
17#include <pwd.h>
18#include <netdb.h>
19
7408b3e5
KF
20#define INITIAL_TICKET "krbtgt"
21#define VERIFY_SERVICE "rcmd"
22
23extern int notickets;
fa57fc2a 24extern char *krbtkfile_env;
7408b3e5
KF
25
26/*
52b9ec26
KF
27 * Attempt to log the user in using Kerberos authentication
28 *
29 * return 0 on success (will be logged in)
30 * 1 if Kerberos failed (try local password in login)
7408b3e5
KF
31 */
32
4e1d2cf3 33klogin(pw, instance, localhost, password)
7408b3e5 34 struct passwd *pw;
4e1d2cf3 35 char *instance, *localhost, *password;
7408b3e5
KF
36{
37 int kerror;
38 AUTH_DAT authdata;
39 KTEXT_ST ticket;
40 struct hostent *hp;
41 unsigned long faddr;
52b9ec26
KF
42 char realm[REALM_SZ], savehost[MAXHOSTNAMELEN];
43 char tkt_location[MAXPATHLEN];
7408b3e5
KF
44
45 /*
4e1d2cf3
MK
46 * Root logins don't use Kerberos.
47 * If we have a realm, try getting a ticket-granting ticket
48 * and using it to authenticate. Otherwise, return
49 * failure so that we can try the normal passwd file
50 * for a password. If that's ok, log the user in
51 * without issuing any tickets.
7408b3e5 52 */
4e1d2cf3
MK
53 if (strcmp(pw->pw_name, "root") == 0 ||
54 krb_get_lrealm(realm, 0) != KSUCCESS)
55 return (1);
7408b3e5
KF
56
57 /*
52b9ec26 58 * get TGT for local realm
4e1d2cf3 59 * tickets are stored in a file named TKT_ROOT plus uid
fa57fc2a 60 * except for user.root tickets.
7408b3e5 61 */
52b9ec26 62
fa57fc2a
MK
63 if (strcmp(instance, "root") != 0)
64 (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid);
65 else {
66 (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid);
67 krbtkfile_env = tkt_location;
68 }
52b9ec26 69 (void)krb_set_tkt_string(tkt_location);
52b9ec26 70
fa57fc2a
MK
71 /*
72 * Set real as well as effective ID to 0 for the moment,
73 * to make the kerberos library do the right thing.
74 */
75 if (setuid(0) < 0) {
76 perror("login: setuid");
77 return (1);
78 }
4e1d2cf3 79 kerror = krb_get_pw_in_tkt(pw->pw_name, instance,
52b9ec26 80 realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password);
7408b3e5
KF
81 /*
82 * If we got a TGT, get a local "rcmd" ticket and check it so as to
83 * ensure that we are not talking to a bogus Kerberos server.
84 *
85 * There are 2 cases where we still allow a login:
86 * 1: the VERIFY_SERVICE doesn't exist in the KDC
87 * 2: local host has no srvtab, as (hopefully) indicated by a
88 * return value of RD_AP_UNDEC from krb_rd_req().
89 */
90 if (kerror != INTK_OK) {
4e1d2cf3 91 if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) {
7408b3e5
KF
92 syslog(LOG_ERR, "Kerberos intkt error: %s",
93 krb_err_txt[kerror]);
b4cc72c2
KF
94 dest_tkt();
95 }
4e1d2cf3 96 return (1);
7408b3e5
KF
97 }
98
52b9ec26
KF
99 if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0)
100 syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE);
7408b3e5
KF
101
102 (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost));
103 savehost[sizeof(savehost)-1] = NULL;
7408b3e5
KF
104
105 /*
106 * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host,
107 * still allow login with tickets, but log the error condition.
108 */
52b9ec26
KF
109
110 kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33);
7408b3e5 111 if (kerror == KDC_PR_UNKNOWN) {
4e1d2cf3
MK
112 syslog(LOG_NOTICE,
113 "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?",
114 krb_err_txt[kerror], VERIFY_SERVICE, savehost);
7408b3e5
KF
115 notickets = 0;
116 return(0);
117 }
118
119 if (kerror != KSUCCESS) {
120 (void)printf("unable to use TGT: (%s)\n", krb_err_txt[kerror]);
121 syslog(LOG_NOTICE, "unable to use TGT: (%s)",
122 krb_err_txt[kerror]);
123 dest_tkt();
52b9ec26 124 return(1);
7408b3e5
KF
125 }
126
127 if (!(hp = gethostbyname(localhost))) {
128 syslog(LOG_ERR, "couldn't get local host address");
52b9ec26
KF
129 dest_tkt();
130 return(1);
7408b3e5 131 }
52b9ec26 132
7408b3e5
KF
133 bcopy((void *)hp->h_addr, (void *)&faddr, sizeof(faddr));
134
135 kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr,
136 &authdata, "");
52b9ec26 137
7408b3e5
KF
138 if (kerror == KSUCCESS) {
139 notickets = 0;
140 return(0);
141 }
52b9ec26
KF
142
143 /* undecipherable: probably didn't have a srvtab on the local host */
7408b3e5
KF
144 if (kerror = RD_AP_UNDEC) {
145 syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]);
52b9ec26
KF
146 dest_tkt();
147 return(1);
7408b3e5 148 }
52b9ec26 149 /* failed for some other reason */
7408b3e5
KF
150 (void)printf("unable to verify %s ticket: (%s)\n", VERIFY_SERVICE,
151 krb_err_txt[kerror]);
152 syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE,
153 krb_err_txt[kerror]);
52b9ec26
KF
154 dest_tkt();
155 return(1);
7408b3e5
KF
156}
157#endif