The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_krb5.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 9ef3cd59f854b0a5ee33d20c0aa65c03a7a0fb2b $
19 * @file rlm_krb5.c
20 * @brief Authenticate users, retrieving their TGT from a Kerberos V5 TDC.
21 *
22 * @copyright 2000,2006,2012-2013 The FreeRADIUS server project
23 * @copyright 2013 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @copyright 2000 Nathan Neulinger (nneul@umr.edu)
25 * @copyright 2000 Alan DeKok (aland@freeradius.org)
26 */
27RCSID("$Id: 9ef3cd59f854b0a5ee33d20c0aa65c03a7a0fb2b $")
28
29#define LOG_PREFIX inst->name
30
31#include <freeradius-devel/server/base.h>
32#include <freeradius-devel/server/module_rlm.h>
33#include "krb5.h"
34
35#ifdef KRB5_IS_THREAD_SAFE
36static const conf_parser_t reuse_krb5_config[] = {
39};
40#endif
41
42static const conf_parser_t module_config[] = {
43 { FR_CONF_OFFSET("keytab", rlm_krb5_t, keytabname) },
44 { FR_CONF_OFFSET("service_principal", rlm_krb5_t, service_princ) },
45#ifdef KRB5_IS_THREAD_SAFE
46 { FR_CONF_OFFSET_SUBSECTION("reuse", 0, rlm_krb5_t, reuse, reuse_krb5_config) },
47#endif
49};
50
55
56#ifdef KRB5_IS_THREAD_SAFE
58{
59 rlm_krb5_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_krb5_t);
60 rlm_krb5_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_krb5_thread_t);
61
62 t->inst = inst;
63 if (!(t->slab = krb5_slab_list_alloc(t, mctx->el, &inst->reuse, krb5_handle_init, NULL, inst, false, true))) {
64 ERROR("Handle pool instantiation failed");
65 return -1;
66 }
67
68 return 0;
69}
70
71static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
72{
73 rlm_krb5_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_krb5_thread_t);
74 talloc_free(t->slab);
75 return 0;
76}
77#endif
78
79static int mod_detach(module_detach_ctx_t const *mctx)
80{
81 rlm_krb5_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_krb5_t);
82
83#ifndef HEIMDAL_KRB5
84 talloc_free(inst->vic_options);
85
86 if (inst->gic_options) krb5_get_init_creds_opt_free(inst->context, inst->gic_options);
87 if (inst->server) krb5_free_principal(inst->context, inst->server);
88#endif
89
90 /* Don't free hostname, it's just a pointer into service_princ */
91 talloc_free(inst->service);
92
93 if (inst->context) krb5_free_context(inst->context);
94
95 return 0;
96}
97
98static int mod_instantiate(module_inst_ctx_t const *mctx)
99{
100 rlm_krb5_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_krb5_t);
101 krb5_error_code ret;
102#ifndef HEIMDAL_KRB5
103 krb5_keytab keytab;
104 char keytab_name[200];
105 char *princ_name;
106#endif
107
108#ifdef HEIMDAL_KRB5
109 DEBUG("Using Heimdal Kerberos library");
110#else
111 DEBUG("Using MIT Kerberos library");
112#endif
113
114
115 if (!krb5_is_thread_safe()) {
116/*
117 * rlm_krb5 was built as threadsafe
118 */
119#ifdef KRB5_IS_THREAD_SAFE
120 ERROR("Build time libkrb5 was threadsafe, but run time library claims not to be");
121 ERROR("Modify runtime linker path (LD_LIBRARY_PATH on most systems), to prefer threadsafe libkrb5");
122 return -1;
123/*
124 * rlm_krb5 was not built as threadsafe
125 */
126#else
127 fr_log(&default_log, L_WARN, __FILE__, __LINE__,
128 "libkrb5 is not threadsafe, recompile it with thread support enabled ("
129# ifdef HEIMDAL_KRB5
130 "--enable-pthread-support"
131# else
132 "--disable-thread-support=no"
133# endif
134 ")");
135 WARN("rlm_krb5 will run in single threaded mode, performance may be degraded");
136 } else {
137 WARN("Build time libkrb5 was not threadsafe, but run time library claims to be");
138 WARN("Reconfigure and recompile rlm_krb5 to enable thread support");
139#endif
140 }
141
142 ret = krb5_init_context(&inst->context);
143 if (ret) {
144 ERROR("Context initialisation failed: %s", rlm_krb5_error(inst, NULL, ret));
145
146 return -1;
147 }
148
149 /*
150 * Split service principal into service and host components
151 * they're needed to build the server principal in MIT,
152 * and to set the validation service in Heimdal.
153 */
154 if (inst->service_princ) {
155 size_t len;
156 /* Service principal appears to contain a host component */
157 inst->hostname = strchr(inst->service_princ, '/');
158 if (inst->hostname) {
159 len = (inst->hostname - inst->service_princ);
160 inst->hostname++;
161 } else {
162 len = strlen(inst->service_princ);
163 }
164
165 if (len) {
166 inst->service = talloc_array(inst, char, (len + 1));
167 strlcpy(inst->service, inst->service_princ, len + 1);
168 }
169 }
170
171#ifdef HEIMDAL_KRB5
172 if (inst->hostname) DEBUG("Ignoring hostname component of service principal \"%s\", not "
173 "needed/supported by Heimdal", inst->hostname);
174#else
175
176 /*
177 * Convert the service principal string to a krb5 principal.
178 */
179 ret = krb5_sname_to_principal(inst->context, inst->hostname, inst->service, KRB5_NT_SRV_HST, &(inst->server));
180 if (ret) {
181 ERROR("Failed parsing service principal: %s", rlm_krb5_error(inst, inst->context, ret));
182
183 return -1;
184 }
185
186 ret = krb5_unparse_name(inst->context, inst->server, &princ_name);
187 if (ret) {
188 /* Uh? */
189 ERROR("Failed constructing service principal string: %s", rlm_krb5_error(inst, inst->context, ret));
190
191 return -1;
192 }
193
194 /*
195 * Not necessarily the same as the config item
196 */
197 DEBUG("Using service principal \"%s\"", princ_name);
198 krb5_free_unparsed_name(inst->context, princ_name);
199
200 /*
201 * Setup options for getting credentials and verifying them
202 */
203 ret = krb5_get_init_creds_opt_alloc(inst->context, &(inst->gic_options)); /* For some reason the 'init' version
204 of this function is deprecated */
205 if (ret) {
206 ERROR("Couldn't allocate initial credential options: %s", rlm_krb5_error(inst, inst->context, ret));
207
208 return -1;
209 }
210
211 /*
212 * Perform basic checks on the keytab
213 */
214 ret = inst->keytabname ?
215 krb5_kt_resolve(inst->context, inst->keytabname, &keytab) :
216 krb5_kt_default(inst->context, &keytab);
217 if (ret) {
218 ERROR("Resolving keytab failed: %s", rlm_krb5_error(inst, inst->context, ret));
219
220 return -1;
221 }
222
223 ret = krb5_kt_get_name(inst->context, keytab, keytab_name, sizeof(keytab_name));
224 krb5_kt_close(inst->context, keytab);
225 if (ret) {
226 ERROR("Can't retrieve keytab name: %s", rlm_krb5_error(inst, inst->context, ret));
227
228 return -1;
229 }
230
231 DEBUG("Using keytab \"%s\"", keytab_name);
232
233 MEM(inst->vic_options = talloc_zero(inst, krb5_verify_init_creds_opt));
234 krb5_verify_init_creds_opt_init(inst->vic_options);
235 krb5_verify_init_creds_opt_set_ap_req_nofail(inst->vic_options, true);
236#endif
237
238#ifndef KRB5_IS_THREAD_SAFE
240 if (!inst->conn) return -1;
241#endif
242 return 0;
243}
244
245/** Common function for transforming a User-Name string into a principal.
246 *
247 * @param[out] client Where to write the client principal.
248 * @param[in] inst of rlm_krb5.
249 * @param[in] request Current request.
250 * @param[in] context Kerberos context.
251 * @param[in] env call env data containing username.
252 */
253static rlm_rcode_t krb5_parse_user(krb5_principal *client, KRB5_UNUSED rlm_krb5_t const *inst, request_t *request,
254 krb5_context context, krb5_auth_call_env_t *env)
255{
256 krb5_error_code ret;
257 char *princ_name;
258
259 ret = krb5_parse_name(context, env->username.vb_strvalue, client);
260 if (ret) {
261 REDEBUG("Failed parsing username as principal: %s", rlm_krb5_error(inst, context, ret));
262
263 return RLM_MODULE_FAIL;
264 }
265
266 krb5_unparse_name(context, *client, &princ_name);
267 RDEBUG2("Using client principal \"%s\"", princ_name);
268#ifdef HEIMDAL_KRB5
269 free(princ_name);
270#else
271 krb5_free_unparsed_name(context, princ_name);
272#endif
273 return RLM_MODULE_OK;
274}
275
276/** Log error message and return appropriate rcode
277 *
278 * Translate kerberos error codes into return codes.
279 * @param inst of rlm_krb5.
280 * @param request Current request.
281 * @param ret code from kerberos.
282 * @param conn used in the last operation.
283 */
285{
286 fr_assert(ret != 0);
287
288 if (!fr_cond_assert(inst)) return RLM_MODULE_FAIL;
289 if (!fr_cond_assert(conn)) return RLM_MODULE_FAIL; /* Silences warnings */
290
291 switch (ret) {
292 case KRB5_LIBOS_BADPWDMATCH:
293 case KRB5KRB_AP_ERR_BAD_INTEGRITY:
294 REDEBUG("Provided password was incorrect (%i): %s", ret, rlm_krb5_error(inst, conn->context, ret));
295 return RLM_MODULE_REJECT;
296
297 case KRB5KDC_ERR_KEY_EXP:
298 case KRB5KDC_ERR_CLIENT_REVOKED:
299 case KRB5KDC_ERR_SERVICE_REVOKED:
300 REDEBUG("Account has been locked out (%i): %s", ret, rlm_krb5_error(inst, conn->context, ret));
301 return RLM_MODULE_DISALLOW;
302
303 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
304 RDEBUG2("User not found (%i): %s", ret, rlm_krb5_error(inst, conn->context, ret));
305 return RLM_MODULE_NOTFOUND;
306
307 default:
308 REDEBUG("Error verifying credentials (%i): %s", ret, rlm_krb5_error(inst, conn->context, ret));
309 return RLM_MODULE_FAIL;
310 }
311}
312
313#ifdef HEIMDAL_KRB5
314
315/*
316 * Validate user/pass (Heimdal)
317 */
318static unlang_action_t CC_HINT(nonnull) mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
319{
320 krb5_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, krb5_auth_call_env_t);
322# ifdef KRB5_IS_THREAD_SAFE
323 rlm_krb5_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_krb5_thread_t);
324# endif
325 rlm_rcode_t rcode;
326 krb5_error_code ret;
327 rlm_krb5_handle_t *conn;
328 krb5_principal client = NULL;
329
330 /*
331 * Make sure the supplied password isn't empty
332 */
333 if (env->password.vb_length == 0) {
334 REDEBUG("User-Password must not be empty");
336 }
337
338 /*
339 * Log the password
340 */
341 if (RDEBUG_ENABLED3) {
342 RDEBUG("Login attempt with password \"%pV\"", &env->password);
343 } else {
344 RDEBUG2("Login attempt with password");
345 }
346
347# ifdef KRB5_IS_THREAD_SAFE
348 conn = krb5_slab_reserve(t->slab);
349 if (!conn) RETURN_UNLANG_FAIL;
350# else
351 conn = inst->conn;
352# endif
353
354 rcode = krb5_parse_user(&client, inst, request, conn->context, env);
355 if (rcode != RLM_MODULE_OK) goto cleanup;
356
357 /*
358 * Verify the user, using the options we set in instantiate
359 */
360 ret = krb5_verify_user_opt(conn->context, client, env->password.vb_strvalue, &conn->options);
361 if (ret) {
362 rcode = krb5_process_error(inst, request, conn, ret);
363 goto cleanup;
364 }
365
366 /*
367 * krb5_verify_user_opt adds the credentials to the ccache
368 * we specified with krb5_verify_opt_set_ccache.
369 *
370 * To make sure we don't accumulate thousands of sets of
371 * credentials, remove them again here.
372 *
373 * @todo This should definitely be optional, which means writing code for the MIT
374 * variant as well.
375 */
376 {
377 krb5_cc_cursor cursor;
378 krb5_creds cred;
379
380 krb5_cc_start_seq_get(conn->context, conn->ccache, &cursor);
381 for (ret = krb5_cc_next_cred(conn->context, conn->ccache, &cursor, &cred);
382 ret == 0;
383 ret = krb5_cc_next_cred(conn->context, conn->ccache, &cursor, &cred)) {
384 krb5_cc_remove_cred(conn->context, conn->ccache, 0, &cred);
385 }
386 krb5_cc_end_seq_get(conn->context, conn->ccache, &cursor);
387 }
388
389cleanup:
390 if (client) {
391 krb5_free_principal(conn->context, client);
392 }
393
394# ifdef KRB5_IS_THREAD_SAFE
395 krb5_slab_release(conn);
396# endif
397 RETURN_UNLANG_RCODE(rcode);
398}
399
400#else /* HEIMDAL_KRB5 */
401
402/*
403 * Validate userid/passwd (MIT)
404 */
405static unlang_action_t CC_HINT(nonnull) mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
406{
407 krb5_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, krb5_auth_call_env_t);
409# ifdef KRB5_IS_THREAD_SAFE
410 rlm_krb5_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_krb5_thread_t);
411# endif
412 rlm_rcode_t rcode;
413 krb5_error_code ret;
414
415 rlm_krb5_handle_t *conn;
416
417 krb5_principal client = NULL; /* actually a pointer value */
418 krb5_creds init_creds;
419
420 /*
421 * Make sure the supplied password isn't empty
422 */
423 if (env->password.vb_length == 0) {
424 REDEBUG("User-Password must not be empty");
426 }
427
428 /*
429 * Log the password
430 */
431 if (RDEBUG_ENABLED3) {
432 RDEBUG("Login attempt with password \"%pV\"", &env->password);
433 } else {
434 RDEBUG2("Login attempt with password");
435 }
436
437# ifdef KRB5_IS_THREAD_SAFE
438 conn = krb5_slab_reserve(t->slab);
439 if (!conn) RETURN_UNLANG_FAIL;
440# else
441 conn = inst->conn;
442# endif
443
444 /*
445 * Zero out local storage
446 */
447 memset(&init_creds, 0, sizeof(init_creds));
448
449 /*
450 * Check we have all the required VPs, and convert the username
451 * into a principal.
452 */
453 rcode = krb5_parse_user(&client, inst, request, conn->context, env);
454 if (rcode != RLM_MODULE_OK) goto cleanup;
455
456 /*
457 * Retrieve the TGT from the TGS/KDC and check we can decrypt it.
458 */
459 RDEBUG2("Retrieving and decrypting TGT");
460 ret = krb5_get_init_creds_password(conn->context, &init_creds, client, UNCONST(char *, env->password.vb_strvalue),
461 NULL, NULL, 0, NULL, inst->gic_options);
462 if (ret) {
463 rcode = krb5_process_error(inst, request, conn, ret);
464 goto cleanup;
465 }
466
467 RDEBUG2("Attempting to authenticate against service principal");
468 ret = krb5_verify_init_creds(conn->context, &init_creds, inst->server, conn->keytab, NULL, inst->vic_options);
469 if (ret) rcode = krb5_process_error(inst, request, conn, ret);
470
471cleanup:
472 if (client) krb5_free_principal(conn->context, client);
473 krb5_free_cred_contents(conn->context, &init_creds);
474
475# ifdef KRB5_IS_THREAD_SAFE
476 krb5_slab_release(conn);
477# endif
478 RETURN_UNLANG_RCODE(rcode);
479}
480
481#endif /* MIT_KRB5 */
482
493
496 .common = {
497 .magic = MODULE_MAGIC_INIT,
498 .name = "krb5",
499 /*
500 * FIXME - Probably want a global mutex created on mod_load
501 */
502#ifndef KRB5_IS_THREAD_SAFE
504#else
505 .thread_inst_size = sizeof(rlm_krb5_thread_t),
508#endif
509 .inst_size = sizeof(rlm_krb5_t),
510 .config = module_config,
511 .instantiate = mod_instantiate,
512 .detach = mod_detach
513 },
514 .method_group = {
515 .bindings = (module_method_binding_t[]){
516 { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate, .method_env = &krb5_auth_call_env },
518 }
519 }
520};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
static int context
Definition radmin.c:69
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:506
#define CALL_ENV_TERMINATOR
Definition call_env.h:236
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
Definition call_env.h:240
call_env_parser_t const * env
Parsing rules for call method env.
Definition call_env.h:247
@ CALL_ENV_FLAG_SECRET
The value is a secret, and should not be logged.
Definition call_env.h:91
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
Definition call_env.h:75
@ CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE
bare words are treated as an attribute, but strings may be xlats.
Definition call_env.h:92
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
Definition call_env.h:340
Per method call config.
Definition call_env.h:180
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:280
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition cf_parse.h:309
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
#define CF_IDENT_ANY
Definition cf_util.h:75
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:141
#define MEM(x)
Definition debug.h:46
#define ERROR(fmt,...)
Definition dhcpclient.c:40
#define DEBUG(fmt,...)
Definition dhcpclient.c:38
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
free(array)
talloc_free(hp)
int krb5_handle_init(rlm_krb5_handle_t *conn, void *uctx)
Definition krb5.c:101
void * krb5_mod_conn_create(TALLOC_CTX *ctx, void *instance, UNUSED fr_time_delta_t timeout)
Create and return a new connection.
Definition krb5.c:145
Context management functions for rlm_krb5.
krb5_keytab keytab
Definition krb5.h:38
#define rlm_krb5_error(_x, _y, _z)
Definition krb5.h:99
#define KRB5_UNUSED
Definition krb5.h:100
krb5_context context
Definition krb5.h:37
Instance configuration for rlm_krb5.
Definition krb5.h:50
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:347
fr_log_t default_log
Definition log.c:288
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
Definition log.c:577
@ L_WARN
Warning.
Definition log.h:54
@ FR_TYPE_STRING
String of printable characters.
void * env_data
Per call environment data.
Definition module_ctx.h:44
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * thread
Thread specific instance data.
Definition module_ctx.h:43
fr_event_list_t * el
Event list to register any IO handlers and timers against.
Definition module_ctx.h:68
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:64
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for detach calls.
Definition module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
#define RDEBUG(fmt,...)
#define WARN(fmt,...)
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
Definition radiusd.c:139
static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
Create module and xlat per-thread instances.
Definition radiusd.c:127
static bool cleanup
Definition radsniff.c:59
#define RETURN_UNLANG_INVALID
Definition rcode.h:66
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:52
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:47
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:53
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
static int mod_detach(module_detach_ctx_t const *mctx)
Definition rlm_krb5.c:79
fr_value_box_t username
Definition rlm_krb5.c:52
fr_value_box_t password
Definition rlm_krb5.c:53
static rlm_rcode_t krb5_process_error(rlm_krb5_t const *inst, request_t *request, rlm_krb5_handle_t *conn, int ret)
Log error message and return appropriate rcode.
Definition rlm_krb5.c:284
static const call_env_method_t krb5_auth_call_env
Definition rlm_krb5.c:483
module_rlm_t rlm_krb5
Definition rlm_krb5.c:495
static rlm_rcode_t krb5_parse_user(krb5_principal *client, KRB5_UNUSED rlm_krb5_t const *inst, request_t *request, krb5_context context, krb5_auth_call_env_t *env)
Common function for transforming a User-Name string into a principal.
Definition rlm_krb5.c:253
static unlang_action_t mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition rlm_krb5.c:405
static const conf_parser_t module_config[]
Definition rlm_krb5.c:42
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_krb5.c:98
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
Definition module.h:49
module_flags_t flags
Flags that control how a module starts up and how a module is called.
Definition module.h:236
void * data
Module's instance data.
Definition module.h:293
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
#define FR_SLAB_CONFIG_CONF_PARSER
conf_parser_t entries to populate user configurable slab values
Definition slab.h:35
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
#define talloc_get_type_abort_const
Definition talloc.h:110
#define fr_time_delta_wrap(_time)
Definition time.h:152
@ T_BARE_WORD
Definition token.h:118
int nonnull(2, 5))