]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /*- | |
25 | * Copyright (c) 1990, 1993, 1994 | |
26 | * The Regents of the University of California. All rights reserved. | |
27 | * | |
28 | * Redistribution and use in source and binary forms, with or without | |
29 | * modification, are permitted provided that the following conditions | |
30 | * are met: | |
31 | * 1. Redistributions of source code must retain the above copyright | |
32 | * notice, this list of conditions and the following disclaimer. | |
33 | * 2. Redistributions in binary form must reproduce the above copyright | |
34 | * notice, this list of conditions and the following disclaimer in the | |
35 | * documentation and/or other materials provided with the distribution. | |
36 | * 3. All advertising materials mentioning features or use of this software | |
37 | * must display the following acknowledgement: | |
38 | * This product includes software developed by the University of | |
39 | * California, Berkeley and its contributors. | |
40 | * 4. Neither the name of the University nor the names of its contributors | |
41 | * may be used to endorse or promote products derived from this software | |
42 | * without specific prior written permission. | |
43 | * | |
44 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
45 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
47 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
48 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
53 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
54 | * SUCH DAMAGE. | |
55 | */ | |
56 | ||
57 | #ifdef KERBEROS | |
58 | #include <sys/param.h> | |
59 | #include <sys/syslog.h> | |
60 | #include <kerberosIV/des.h> | |
61 | #include <kerberosIV/krb.h> | |
62 | ||
63 | #include <err.h> | |
64 | #include <netdb.h> | |
65 | #include <pwd.h> | |
66 | #include <stdio.h> | |
67 | #include <stdlib.h> | |
68 | #include <string.h> | |
69 | #include <unistd.h> | |
70 | ||
71 | #define INITIAL_TICKET "krbtgt" | |
72 | #define VERIFY_SERVICE "rcmd" | |
73 | ||
74 | extern int notickets; | |
75 | extern char *krbtkfile_env; | |
76 | ||
77 | /* | |
78 | * Attempt to log the user in using Kerberos authentication | |
79 | * | |
80 | * return 0 on success (will be logged in) | |
81 | * 1 if Kerberos failed (try local password in login) | |
82 | */ | |
83 | int | |
84 | klogin(pw, instance, localhost, password) | |
85 | struct passwd *pw; | |
86 | char *instance, *localhost, *password; | |
87 | { | |
88 | int kerror; | |
89 | AUTH_DAT authdata; | |
90 | KTEXT_ST ticket; | |
91 | struct hostent *hp; | |
92 | unsigned long faddr; | |
93 | char realm[REALM_SZ], savehost[MAXHOSTNAMELEN]; | |
94 | char tkt_location[MAXPATHLEN]; | |
95 | char *krb_get_phost(); | |
96 | ||
97 | /* | |
98 | * Root logins don't use Kerberos. | |
99 | * If we have a realm, try getting a ticket-granting ticket | |
100 | * and using it to authenticate. Otherwise, return | |
101 | * failure so that we can try the normal passwd file | |
102 | * for a password. If that's ok, log the user in | |
103 | * without issuing any tickets. | |
104 | */ | |
105 | if (strcmp(pw->pw_name, "root") == 0 || | |
106 | krb_get_lrealm(realm, 0) != KSUCCESS) | |
107 | return (1); | |
108 | ||
109 | /* | |
110 | * get TGT for local realm | |
111 | * tickets are stored in a file named TKT_ROOT plus uid | |
112 | * except for user.root tickets. | |
113 | */ | |
114 | ||
115 | if (strcmp(instance, "root") != 0) | |
116 | (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid); | |
117 | else { | |
118 | (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid); | |
119 | krbtkfile_env = tkt_location; | |
120 | } | |
121 | (void)krb_set_tkt_string(tkt_location); | |
122 | ||
123 | /* | |
124 | * Set real as well as effective ID to 0 for the moment, | |
125 | * to make the kerberos library do the right thing. | |
126 | */ | |
127 | if (setuid(0) < 0) { | |
128 | warnx("setuid"); | |
129 | return (1); | |
130 | } | |
131 | kerror = krb_get_pw_in_tkt(pw->pw_name, instance, | |
132 | realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password); | |
133 | /* | |
134 | * If we got a TGT, get a local "rcmd" ticket and check it so as to | |
135 | * ensure that we are not talking to a bogus Kerberos server. | |
136 | * | |
137 | * There are 2 cases where we still allow a login: | |
138 | * 1: the VERIFY_SERVICE doesn't exist in the KDC | |
139 | * 2: local host has no srvtab, as (hopefully) indicated by a | |
140 | * return value of RD_AP_UNDEC from krb_rd_req(). | |
141 | */ | |
142 | if (kerror != INTK_OK) { | |
143 | if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) { | |
144 | syslog(LOG_ERR, "Kerberos intkt error: %s", | |
145 | krb_err_txt[kerror]); | |
146 | dest_tkt(); | |
147 | } | |
148 | return (1); | |
149 | } | |
150 | ||
151 | if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0) | |
152 | syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE); | |
153 | ||
154 | (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost)); | |
155 | savehost[sizeof(savehost)-1] = NULL; | |
156 | ||
157 | /* | |
158 | * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host, | |
159 | * still allow login with tickets, but log the error condition. | |
160 | */ | |
161 | ||
162 | kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33); | |
163 | if (kerror == KDC_PR_UNKNOWN) { | |
164 | syslog(LOG_NOTICE, | |
165 | "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?", | |
166 | krb_err_txt[kerror], VERIFY_SERVICE, savehost); | |
167 | notickets = 0; | |
168 | return (0); | |
169 | } | |
170 | ||
171 | if (kerror != KSUCCESS) { | |
172 | warnx("unable to use TGT: (%s)", krb_err_txt[kerror]); | |
173 | syslog(LOG_NOTICE, "unable to use TGT: (%s)", | |
174 | krb_err_txt[kerror]); | |
175 | dest_tkt(); | |
176 | return (1); | |
177 | } | |
178 | ||
179 | if (!(hp = gethostbyname(localhost))) { | |
180 | syslog(LOG_ERR, "couldn't get local host address"); | |
181 | dest_tkt(); | |
182 | return (1); | |
183 | } | |
184 | ||
185 | memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); | |
186 | ||
187 | kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr, | |
188 | &authdata, ""); | |
189 | ||
190 | if (kerror == KSUCCESS) { | |
191 | notickets = 0; | |
192 | return (0); | |
193 | } | |
194 | ||
195 | /* undecipherable: probably didn't have a srvtab on the local host */ | |
196 | if (kerror = RD_AP_UNDEC) { | |
197 | syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]); | |
198 | dest_tkt(); | |
199 | return (1); | |
200 | } | |
201 | /* failed for some other reason */ | |
202 | warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE, | |
203 | krb_err_txt[kerror]); | |
204 | syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE, | |
205 | krb_err_txt[kerror]); | |
206 | dest_tkt(); | |
207 | return (1); | |
208 | } | |
209 | #endif |