lib/kadm5: find_db_spec do not leak 'info'
[heimdal.git] / kdc / kdc-plugin.c
blob83eabfb3db90cd186bc42b0c214f8b745ada47a4
1 /*
2 * Copyright (c) 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 #include "kdc_locl.h"
36 static int have_plugin = 0;
39 * Pick the first KDC plugin module that we find.
42 static const char *kdc_plugin_deps[] = {
43 "kdc",
44 "krb5",
45 "hdb",
46 NULL
49 static struct heim_plugin_data kdc_plugin_data = {
50 "krb5",
51 "kdc",
52 KRB5_PLUGIN_KDC_VERSION_10,
53 kdc_plugin_deps,
54 kdc_get_instance
57 static krb5_error_code KRB5_LIB_CALL
58 load(krb5_context context, const void *plug, void *plugctx, void *userctx)
60 have_plugin = 1;
61 return KRB5_PLUGIN_NO_HANDLE;
64 KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
65 krb5_kdc_plugin_init(krb5_context context)
67 (void)_krb5_plugin_run_f(context, &kdc_plugin_data, 0, NULL, load);
69 return 0;
72 struct generate_uc {
73 krb5_kdc_configuration *config;
74 hdb_entry *client;
75 hdb_entry *server;
76 const krb5_keyblock *reply_key;
77 uint64_t pac_attributes;
78 krb5_pac *pac;
81 static krb5_error_code KRB5_LIB_CALL
82 generate(krb5_context context, const void *plug, void *plugctx, void *userctx)
84 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
85 struct generate_uc *uc = (struct generate_uc *)userctx;
87 if (ft->pac_generate == NULL)
88 return KRB5_PLUGIN_NO_HANDLE;
90 return ft->pac_generate((void *)plug,
91 context,
92 uc->config,
93 uc->client,
94 uc->server,
95 uc->reply_key,
96 uc->pac_attributes,
97 uc->pac);
101 krb5_error_code
102 _kdc_pac_generate(krb5_context context,
103 krb5_kdc_configuration *config,
104 hdb_entry *client,
105 hdb_entry *server,
106 const krb5_keyblock *reply_key,
107 uint64_t pac_attributes,
108 krb5_pac *pac)
110 krb5_error_code ret = 0;
111 struct generate_uc uc;
113 *pac = NULL;
115 if (krb5_config_get_bool_default(context, NULL, FALSE, "realms",
116 client->principal->realm,
117 "disable_pac", NULL))
118 return 0;
120 if (have_plugin) {
121 uc.config = config;
122 uc.client = client;
123 uc.server = server;
124 uc.reply_key = reply_key;
125 uc.pac = pac;
126 uc.pac_attributes = pac_attributes;
128 ret = _krb5_plugin_run_f(context, &kdc_plugin_data,
129 0, &uc, generate);
130 if (ret != KRB5_PLUGIN_NO_HANDLE)
131 return ret;
132 ret = 0;
135 if (*pac == NULL)
136 ret = krb5_pac_init(context, pac);
138 return ret;
141 struct verify_uc {
142 krb5_kdc_configuration *config;
143 krb5_principal client_principal;
144 krb5_principal delegated_proxy_principal;
145 hdb_entry *client;
146 hdb_entry *server;
147 hdb_entry *krbtgt;
148 krb5_pac *pac;
151 static krb5_error_code KRB5_LIB_CALL
152 verify(krb5_context context, const void *plug, void *plugctx, void *userctx)
154 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
155 struct verify_uc *uc = (struct verify_uc *)userctx;
156 krb5_error_code ret;
158 if (ft->pac_verify == NULL)
159 return KRB5_PLUGIN_NO_HANDLE;
161 ret = ft->pac_verify((void *)plug,
162 context,
163 uc->config,
164 uc->client_principal,
165 uc->delegated_proxy_principal,
166 uc->client, uc->server, uc->krbtgt, uc->pac);
167 return ret;
170 krb5_error_code
171 _kdc_pac_verify(krb5_context context,
172 krb5_kdc_configuration *config,
173 const krb5_principal client_principal,
174 const krb5_principal delegated_proxy_principal,
175 hdb_entry *client,
176 hdb_entry *server,
177 hdb_entry *krbtgt,
178 krb5_pac *pac)
180 struct verify_uc uc;
182 if (!have_plugin)
183 return KRB5_PLUGIN_NO_HANDLE;
185 uc.config = config;
186 uc.client_principal = client_principal;
187 uc.delegated_proxy_principal = delegated_proxy_principal;
188 uc.client = client;
189 uc.server = server;
190 uc.krbtgt = krbtgt;
191 uc.pac = pac;
193 return _krb5_plugin_run_f(context, &kdc_plugin_data,
194 0, &uc, verify);
197 static krb5_error_code KRB5_LIB_CALL
198 check(krb5_context context, const void *plug, void *plugctx, void *userctx)
200 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
202 if (ft->client_access == NULL)
203 return KRB5_PLUGIN_NO_HANDLE;
204 return ft->client_access((void *)plug, userctx);
207 krb5_error_code
208 _kdc_check_access(astgs_request_t r)
210 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
212 if (have_plugin) {
213 ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data,
214 0, r, check);
217 if (ret == KRB5_PLUGIN_NO_HANDLE)
218 return kdc_check_flags(r, r->req.msg_type == krb_as_req,
219 r->client, r->server);
220 return ret;
223 static krb5_error_code KRB5_LIB_CALL
224 referral_policy(krb5_context context, const void *plug, void *plugctx, void *userctx)
226 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
228 if (ft->referral_policy == NULL)
229 return KRB5_PLUGIN_NO_HANDLE;
230 return ft->referral_policy((void *)plug, userctx);
233 krb5_error_code
234 _kdc_referral_policy(astgs_request_t r)
236 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
238 if (have_plugin)
239 ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, referral_policy);
241 return ret;
244 static krb5_error_code KRB5_LIB_CALL
245 finalize_reply(krb5_context context, const void *plug, void *plugctx, void *userctx)
247 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
249 if (ft->finalize_reply == NULL)
250 return KRB5_PLUGIN_NO_HANDLE;
251 return ft->finalize_reply((void *)plug, userctx);
254 krb5_error_code
255 _kdc_finalize_reply(astgs_request_t r)
257 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
259 if (have_plugin)
260 ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, finalize_reply);
262 if (ret == KRB5_PLUGIN_NO_HANDLE)
263 ret = 0;
265 return ret;
268 static krb5_error_code KRB5_LIB_CALL
269 audit(krb5_context context, const void *plug, void *plugctx, void *userctx)
271 const krb5plugin_kdc_ftable *ft = (const krb5plugin_kdc_ftable *)plug;
273 if (ft->audit == NULL)
274 return KRB5_PLUGIN_NO_HANDLE;
275 return ft->audit((void *)plug, userctx);
278 krb5_error_code
279 _kdc_plugin_audit(astgs_request_t r)
281 krb5_error_code ret = KRB5_PLUGIN_NO_HANDLE;
283 if (have_plugin)
284 ret = _krb5_plugin_run_f(r->context, &kdc_plugin_data, 0, r, audit);
286 if (ret == KRB5_PLUGIN_NO_HANDLE)
287 ret = 0;
289 return ret;
292 KDC_LIB_FUNCTION uintptr_t KDC_LIB_CALL
293 kdc_get_instance(const char *libname)
295 static const char *instance = "libkdc";
297 if (strcmp(libname, "kdc") == 0)
298 return (uintptr_t)instance;
299 else if (strcmp(libname, "hdb") == 0)
300 return hdb_get_instance(libname);
301 else if (strcmp(libname, "krb5") == 0)
302 return krb5_get_instance(libname);
303 else if (strcmp(libname, "gssapi") == 0)
304 return gss_get_instance(libname);
306 return 0;