]>
Commit | Line | Data |
---|---|---|
1815bff5 | 1 | /* |
cf37c299 | 2 | * Copyright (c) 1999-2016 Apple Inc. All rights reserved. |
1815bff5 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
cf37c299 | 5 | * |
2fc1e207 A |
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. | |
cf37c299 | 13 | * |
1815bff5 A |
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, | |
2fc1e207 A |
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." | |
cf37c299 | 21 | * |
1815bff5 A |
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 | |
cf37c299 | 84 | klogin(struct passwd *pw, char *instance, char *localhost, char *password) |
1815bff5 A |
85 | { |
86 | int kerror; | |
87 | AUTH_DAT authdata; | |
88 | KTEXT_ST ticket; | |
89 | struct hostent *hp; | |
90 | unsigned long faddr; | |
91 | char realm[REALM_SZ], savehost[MAXHOSTNAMELEN]; | |
92 | char tkt_location[MAXPATHLEN]; | |
93 | char *krb_get_phost(); | |
94 | ||
95 | /* | |
96 | * Root logins don't use Kerberos. | |
97 | * If we have a realm, try getting a ticket-granting ticket | |
98 | * and using it to authenticate. Otherwise, return | |
99 | * failure so that we can try the normal passwd file | |
100 | * for a password. If that's ok, log the user in | |
101 | * without issuing any tickets. | |
102 | */ | |
103 | if (strcmp(pw->pw_name, "root") == 0 || | |
104 | krb_get_lrealm(realm, 0) != KSUCCESS) | |
105 | return (1); | |
106 | ||
107 | /* | |
108 | * get TGT for local realm | |
109 | * tickets are stored in a file named TKT_ROOT plus uid | |
110 | * except for user.root tickets. | |
111 | */ | |
112 | ||
113 | if (strcmp(instance, "root") != 0) | |
114 | (void)sprintf(tkt_location, "%s%d", TKT_ROOT, pw->pw_uid); | |
115 | else { | |
116 | (void)sprintf(tkt_location, "%s_root_%d", TKT_ROOT, pw->pw_uid); | |
117 | krbtkfile_env = tkt_location; | |
118 | } | |
119 | (void)krb_set_tkt_string(tkt_location); | |
120 | ||
121 | /* | |
122 | * Set real as well as effective ID to 0 for the moment, | |
123 | * to make the kerberos library do the right thing. | |
124 | */ | |
125 | if (setuid(0) < 0) { | |
126 | warnx("setuid"); | |
127 | return (1); | |
128 | } | |
129 | kerror = krb_get_pw_in_tkt(pw->pw_name, instance, | |
130 | realm, INITIAL_TICKET, realm, DEFAULT_TKT_LIFE, password); | |
131 | /* | |
132 | * If we got a TGT, get a local "rcmd" ticket and check it so as to | |
133 | * ensure that we are not talking to a bogus Kerberos server. | |
134 | * | |
135 | * There are 2 cases where we still allow a login: | |
136 | * 1: the VERIFY_SERVICE doesn't exist in the KDC | |
137 | * 2: local host has no srvtab, as (hopefully) indicated by a | |
138 | * return value of RD_AP_UNDEC from krb_rd_req(). | |
139 | */ | |
140 | if (kerror != INTK_OK) { | |
141 | if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) { | |
142 | syslog(LOG_ERR, "Kerberos intkt error: %s", | |
143 | krb_err_txt[kerror]); | |
144 | dest_tkt(); | |
145 | } | |
146 | return (1); | |
147 | } | |
148 | ||
149 | if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0) | |
150 | syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE); | |
151 | ||
152 | (void)strncpy(savehost, krb_get_phost(localhost), sizeof(savehost)); | |
153 | savehost[sizeof(savehost)-1] = NULL; | |
154 | ||
155 | /* | |
156 | * if the "VERIFY_SERVICE" doesn't exist in the KDC for this host, | |
157 | * still allow login with tickets, but log the error condition. | |
158 | */ | |
159 | ||
160 | kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33); | |
161 | if (kerror == KDC_PR_UNKNOWN) { | |
162 | syslog(LOG_NOTICE, | |
cf37c299 | 163 | "warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?", |
1815bff5 A |
164 | krb_err_txt[kerror], VERIFY_SERVICE, savehost); |
165 | notickets = 0; | |
166 | return (0); | |
167 | } | |
168 | ||
169 | if (kerror != KSUCCESS) { | |
170 | warnx("unable to use TGT: (%s)", krb_err_txt[kerror]); | |
171 | syslog(LOG_NOTICE, "unable to use TGT: (%s)", | |
172 | krb_err_txt[kerror]); | |
173 | dest_tkt(); | |
174 | return (1); | |
175 | } | |
176 | ||
177 | if (!(hp = gethostbyname(localhost))) { | |
178 | syslog(LOG_ERR, "couldn't get local host address"); | |
179 | dest_tkt(); | |
180 | return (1); | |
181 | } | |
182 | ||
183 | memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); | |
184 | ||
185 | kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr, | |
186 | &authdata, ""); | |
187 | ||
188 | if (kerror == KSUCCESS) { | |
189 | notickets = 0; | |
190 | return (0); | |
191 | } | |
192 | ||
193 | /* undecipherable: probably didn't have a srvtab on the local host */ | |
194 | if (kerror = RD_AP_UNDEC) { | |
195 | syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]); | |
196 | dest_tkt(); | |
197 | return (1); | |
198 | } | |
199 | /* failed for some other reason */ | |
200 | warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE, | |
201 | krb_err_txt[kerror]); | |
202 | syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE, | |
203 | krb_err_txt[kerror]); | |
204 | dest_tkt(); | |
205 | return (1); | |
206 | } | |
207 | #endif |