No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / auth / afskauthlib / verify.c
blob1c04e1e5ec8896fb37f8fe7eca668e0cebbef2a1
1 /*
2 * Copyright (c) 1995-2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 __RCSID("$Heimdal: verify.c 14203 2004-09-08 09:02:59Z joda $"
37 "$NetBSD$");
38 #endif
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <pwd.h>
42 #ifdef KRB5
43 #include <krb5.h>
44 #endif
45 #ifdef KRB4
46 #include <krb.h>
47 #include <kafs.h>
48 #endif
49 #include <roken.h>
51 #ifdef KRB5
52 static char krb5ccname[128];
53 #endif
54 #ifdef KRB4
55 static char krbtkfile[128];
56 #endif
58 /*
59 In some cases is afs_gettktstring called twice (once before
60 afs_verify and once after afs_verify).
61 In some cases (rlogin with access allowed via .rhosts)
62 afs_verify is not called!
63 So we can't rely on correct value in krbtkfile in some
64 cases!
67 static int correct_tkfilename=0;
68 static int pag_set=0;
70 #ifdef KRB4
71 static void
72 set_krbtkfile(uid_t uid)
74 snprintf (krbtkfile, sizeof(krbtkfile), "%s%d", TKT_ROOT, (unsigned)uid);
75 krb_set_tkt_string (krbtkfile);
76 correct_tkfilename = 1;
78 #endif
80 /* XXX this has to be the default cache name, since the KRB5CCNAME
81 * environment variable isn't exported by login/xdm
84 #ifdef KRB5
85 static void
86 set_krb5ccname(uid_t uid)
88 snprintf (krb5ccname, sizeof(krb5ccname), "FILE:/tmp/krb5cc_%d", uid);
89 #ifdef KRB4
90 snprintf (krbtkfile, sizeof(krbtkfile), "%s%d", TKT_ROOT, (unsigned)uid);
91 #endif
92 correct_tkfilename = 1;
94 #endif
96 static void
97 set_spec_krbtkfile(void)
99 int fd;
100 #ifdef KRB4
101 snprintf (krbtkfile, sizeof(krbtkfile), "%s_XXXXXX", TKT_ROOT);
102 fd = mkstemp(krbtkfile);
103 close(fd);
104 unlink(krbtkfile);
105 krb_set_tkt_string (krbtkfile);
106 #endif
107 #ifdef KRB5
108 snprintf(krb5ccname, sizeof(krb5ccname),"FILE:/tmp/krb5cc_XXXXXX");
109 fd=mkstemp(krb5ccname+5);
110 close(fd);
111 unlink(krb5ccname+5);
112 #endif
115 #ifdef KRB5
116 static int
117 verify_krb5(struct passwd *pwd,
118 char *password,
119 int32_t *exp,
120 int quiet)
122 krb5_context context;
123 krb5_error_code ret;
124 krb5_ccache ccache;
125 krb5_principal principal;
127 ret = krb5_init_context(&context);
128 if (ret) {
129 syslog(LOG_AUTH|LOG_DEBUG, "krb5_init_context failed: %d", ret);
130 goto out;
133 ret = krb5_parse_name (context, pwd->pw_name, &principal);
134 if (ret) {
135 syslog(LOG_AUTH|LOG_DEBUG, "krb5_parse_name: %s",
136 krb5_get_err_text(context, ret));
137 goto out;
140 set_krb5ccname(pwd->pw_uid);
141 ret = krb5_cc_resolve(context, krb5ccname, &ccache);
142 if(ret) {
143 syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_resolve: %s",
144 krb5_get_err_text(context, ret));
145 goto out;
148 ret = krb5_verify_user_lrealm(context,
149 principal,
150 ccache,
151 password,
152 TRUE,
153 NULL);
154 if(ret) {
155 syslog(LOG_AUTH|LOG_DEBUG, "krb5_verify_user: %s",
156 krb5_get_err_text(context, ret));
157 goto out;
160 if(chown(krb5_cc_get_name(context, ccache), pwd->pw_uid, pwd->pw_gid)) {
161 syslog(LOG_AUTH|LOG_DEBUG, "chown: %s",
162 krb5_get_err_text(context, errno));
163 goto out;
166 #ifdef KRB4
168 krb5_realm realm = NULL;
169 krb5_boolean get_v4_tgt;
171 krb5_get_default_realm(context, &realm);
172 krb5_appdefault_boolean(context, "afskauthlib",
173 realm,
174 "krb4_get_tickets", FALSE, &get_v4_tgt);
175 if (get_v4_tgt) {
176 CREDENTIALS c;
177 krb5_creds mcred, cred;
179 krb5_cc_clear_mcred(&mcred);
181 krb5_make_principal(context, &mcred.server, realm,
182 "krbtgt",
183 realm,
184 NULL);
185 ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
186 if(ret == 0) {
187 ret = krb524_convert_creds_kdc_ccache(context, ccache, &cred, &c);
188 if(ret)
189 krb5_warn(context, ret, "converting creds");
190 else {
191 set_krbtkfile(pwd->pw_uid);
192 tf_setup(&c, c.pname, c.pinst);
194 memset(&c, 0, sizeof(c));
195 krb5_free_cred_contents(context, &cred);
196 } else
197 syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_retrieve_cred: %s",
198 krb5_get_err_text(context, ret));
200 krb5_free_principal(context, mcred.server);
202 free (realm);
203 if (!pag_set && k_hasafs()) {
204 k_setpag();
205 pag_set = 1;
208 if (pag_set)
209 krb5_afslog_uid_home(context, ccache, NULL, NULL,
210 pwd->pw_uid, pwd->pw_dir);
212 #endif
213 out:
214 if(ret && !quiet)
215 printf ("%s\n", krb5_get_err_text (context, ret));
216 return ret;
218 #endif
220 #ifdef KRB4
221 static int
222 verify_krb4(struct passwd *pwd,
223 char *password,
224 int32_t *exp,
225 int quiet)
227 int ret = 1;
228 char lrealm[REALM_SZ];
230 if (krb_get_lrealm (lrealm, 1) != KFAILURE) {
231 set_krbtkfile(pwd->pw_uid);
232 ret = krb_verify_user (pwd->pw_name, "", lrealm, password,
233 KRB_VERIFY_SECURE, NULL);
234 if (ret == KSUCCESS) {
235 if (!pag_set && k_hasafs()) {
236 k_setpag ();
237 pag_set = 1;
239 if (pag_set)
240 krb_afslog_uid_home (0, 0, pwd->pw_uid, pwd->pw_dir);
241 } else if (!quiet)
242 printf ("%s\n", krb_get_err_text (ret));
244 return ret;
246 #endif
249 afs_verify(char *name,
250 char *password,
251 int32_t *exp,
252 int quiet)
254 int ret = 1;
255 struct passwd *pwd = k_getpwnam (name);
257 if(pwd == NULL)
258 return 1;
260 if (!pag_set && k_hasafs()) {
261 k_setpag();
262 pag_set=1;
265 if (ret)
266 ret = unix_verify_user (name, password);
267 #ifdef KRB5
268 if (ret)
269 ret = verify_krb5(pwd, password, exp, quiet);
270 #endif
271 #ifdef KRB4
272 if(ret)
273 ret = verify_krb4(pwd, password, exp, quiet);
274 #endif
275 return ret;
278 char *
279 afs_gettktstring (void)
281 char *ptr;
282 struct passwd *pwd;
284 if (!correct_tkfilename) {
285 ptr = getenv("LOGNAME");
286 if (ptr != NULL && ((pwd = getpwnam(ptr)) != NULL)) {
287 set_krb5ccname(pwd->pw_uid);
288 #ifdef KRB4
289 set_krbtkfile(pwd->pw_uid);
290 if (!pag_set && k_hasafs()) {
291 k_setpag();
292 pag_set=1;
294 #endif
295 } else {
296 set_spec_krbtkfile();
299 #ifdef KRB5
300 esetenv("KRB5CCNAME",krb5ccname,1);
301 #endif
302 #ifdef KRB4
303 esetenv("KRBTKFILE",krbtkfile,1);
304 return krbtkfile;
305 #else
306 return "";
307 #endif