]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/lib/krb5/verify_user.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / lib / krb5 / verify_user.c
1 /*
2  * Copyright (c) 1997-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. 
12  *
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. 
16  *
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. 
20  *
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. 
32  */
33
34 #include "krb5_locl.h"
35
36 RCSID("$Id: verify_user.c 19078 2006-11-20 18:12:41Z lha $");
37
38 static krb5_error_code
39 verify_common (krb5_context context,
40                krb5_principal principal,
41                krb5_ccache ccache,
42                krb5_keytab keytab,
43                krb5_boolean secure,
44                const char *service,
45                krb5_creds cred)
46 {
47     krb5_error_code ret;
48     krb5_principal server;
49     krb5_verify_init_creds_opt vopt;
50     krb5_ccache id;
51
52     ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
53                                    &server);
54     if(ret)
55         return ret;
56
57     krb5_verify_init_creds_opt_init(&vopt);
58     krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);
59
60     ret = krb5_verify_init_creds(context,
61                                  &cred,
62                                  server,
63                                  keytab,
64                                  NULL,
65                                  &vopt);
66     krb5_free_principal(context, server);
67     if(ret)
68         return ret;
69     if(ccache == NULL)
70         ret = krb5_cc_default (context, &id);
71     else
72         id = ccache;
73     if(ret == 0){
74         ret = krb5_cc_initialize(context, id, principal);
75         if(ret == 0){
76             ret = krb5_cc_store_cred(context, id, &cred);
77         }
78         if(ccache == NULL)
79             krb5_cc_close(context, id);
80     }
81     krb5_free_cred_contents(context, &cred);
82     return ret;
83 }
84
85 /*
86  * Verify user `principal' with `password'.
87  *
88  * If `secure', also verify against local service key for `service'.
89  *
90  * As a side effect, fresh tickets are obtained and stored in `ccache'.
91  */
92
93 void KRB5_LIB_FUNCTION
94 krb5_verify_opt_init(krb5_verify_opt *opt)
95 {
96     memset(opt, 0, sizeof(*opt));
97     opt->secure = TRUE;
98     opt->service = "host";
99 }
100
101 int KRB5_LIB_FUNCTION
102 krb5_verify_opt_alloc(krb5_context context, krb5_verify_opt **opt)
103 {
104     *opt = calloc(1, sizeof(**opt));
105     if ((*opt) == NULL) {
106         krb5_set_error_string(context, "malloc: out of memory");
107         return ENOMEM;
108     }
109     krb5_verify_opt_init(*opt);
110     return 0;
111 }
112
113 void KRB5_LIB_FUNCTION
114 krb5_verify_opt_free(krb5_verify_opt *opt)
115 {
116     free(opt);
117 }
118
119 void KRB5_LIB_FUNCTION
120 krb5_verify_opt_set_ccache(krb5_verify_opt *opt, krb5_ccache ccache)
121 {
122     opt->ccache = ccache;
123 }
124
125 void KRB5_LIB_FUNCTION
126 krb5_verify_opt_set_keytab(krb5_verify_opt *opt, krb5_keytab keytab)
127 {
128     opt->keytab = keytab;
129 }
130
131 void KRB5_LIB_FUNCTION
132 krb5_verify_opt_set_secure(krb5_verify_opt *opt, krb5_boolean secure)
133 {
134     opt->secure = secure;
135 }
136
137 void KRB5_LIB_FUNCTION
138 krb5_verify_opt_set_service(krb5_verify_opt *opt, const char *service)
139 {
140     opt->service = service;
141 }
142
143 void KRB5_LIB_FUNCTION
144 krb5_verify_opt_set_flags(krb5_verify_opt *opt, unsigned int flags)
145 {
146     opt->flags |= flags;
147 }
148
149 static krb5_error_code
150 verify_user_opt_int(krb5_context context,
151                     krb5_principal principal,
152                     const char *password,
153                     krb5_verify_opt *vopt)
154
155 {
156     krb5_error_code ret;
157     krb5_get_init_creds_opt *opt;
158     krb5_creds cred;
159
160     ret = krb5_get_init_creds_opt_alloc (context, &opt);
161     if (ret)
162         return ret;
163     krb5_get_init_creds_opt_set_default_flags(context, NULL, 
164                                               krb5_principal_get_realm(context, principal), 
165                                               opt);
166     ret = krb5_get_init_creds_password (context,
167                                         &cred,
168                                         principal,
169                                         password,
170                                         krb5_prompter_posix,
171                                         NULL,
172                                         0,
173                                         NULL,
174                                         opt);
175     krb5_get_init_creds_opt_free(context, opt);
176     if(ret)
177         return ret;
178 #define OPT(V, D) ((vopt && (vopt->V)) ? (vopt->V) : (D))
179     return verify_common (context, principal, OPT(ccache, NULL), 
180                           OPT(keytab, NULL), vopt ? vopt->secure : TRUE, 
181                           OPT(service, "host"), cred);
182 #undef OPT
183 }
184
185 krb5_error_code KRB5_LIB_FUNCTION
186 krb5_verify_user_opt(krb5_context context,
187                      krb5_principal principal,
188                      const char *password,
189                      krb5_verify_opt *opt)
190 {
191     krb5_error_code ret;
192
193     if(opt && (opt->flags & KRB5_VERIFY_LREALMS)) {
194         krb5_realm *realms, *r;
195         ret = krb5_get_default_realms (context, &realms);
196         if (ret)
197             return ret;
198         ret = KRB5_CONFIG_NODEFREALM;
199         
200         for (r = realms; *r != NULL && ret != 0; ++r) {
201             char *tmp = strdup (*r);
202             
203             if (tmp == NULL) {
204                 krb5_free_host_realm (context, realms);
205                 krb5_set_error_string (context, "malloc: out of memory");
206                 return ENOMEM;
207             }
208             free (*krb5_princ_realm (context, principal));
209             krb5_princ_set_realm (context, principal, &tmp);
210             
211             ret = verify_user_opt_int(context, principal, password, opt);
212         }
213         krb5_free_host_realm (context, realms);
214         if(ret)
215             return ret;
216     } else
217         ret = verify_user_opt_int(context, principal, password, opt);
218     return ret;
219 }
220
221 /* compat function that calls above */
222
223 krb5_error_code KRB5_LIB_FUNCTION
224 krb5_verify_user(krb5_context context, 
225                  krb5_principal principal,
226                  krb5_ccache ccache,
227                  const char *password,
228                  krb5_boolean secure,
229                  const char *service)
230 {
231     krb5_verify_opt opt;
232     
233     krb5_verify_opt_init(&opt);
234     
235     krb5_verify_opt_set_ccache(&opt, ccache);
236     krb5_verify_opt_set_secure(&opt, secure);
237     krb5_verify_opt_set_service(&opt, service);
238     
239     return krb5_verify_user_opt(context, principal, password, &opt);
240 }
241
242 /*
243  * A variant of `krb5_verify_user'.  The realm of `principal' is
244  * ignored and all the local realms are tried.
245  */
246
247 krb5_error_code KRB5_LIB_FUNCTION
248 krb5_verify_user_lrealm(krb5_context context, 
249                         krb5_principal principal,
250                         krb5_ccache ccache,
251                         const char *password,
252                         krb5_boolean secure,
253                         const char *service)
254 {
255     krb5_verify_opt opt;
256     
257     krb5_verify_opt_init(&opt);
258     
259     krb5_verify_opt_set_ccache(&opt, ccache);
260     krb5_verify_opt_set_secure(&opt, secure);
261     krb5_verify_opt_set_service(&opt, service);
262     krb5_verify_opt_set_flags(&opt, KRB5_VERIFY_LREALMS);
263     
264     return krb5_verify_user_opt(context, principal, password, &opt);
265 }