The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_winbind.c
Go to the documentation of this file.
1/*
2 * This program is 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 (at
5 * 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: 1a2041472da920f135e3a2f36ce8b655d1e2d768 $
19 * @file rlm_winbind.c
20 * @brief Authenticates against Active Directory or Samba using winbind
21 *
22 * @author Matthew Newton (matthew@newtoncomputing.co.uk)
23 *
24 * @copyright 2016 The FreeRADIUS server project
25 * @copyright 2016 Matthew Newton (matthew@newtoncomputing.co.uk)
26 */
27RCSID("$Id: 1a2041472da920f135e3a2f36ce8b655d1e2d768 $")
28
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/server/module_rlm.h>
31#include <freeradius-devel/unlang/call_env.h>
32#include <freeradius-devel/unlang/xlat_func.h>
33#include <freeradius-devel/util/debug.h>
34#include <freeradius-devel/unlang/xlat.h>
35#include <freeradius-devel/util/dcursor.h>
36#include <freeradius-devel/util/skip.h>
37#include <freeradius-devel/util/value.h>
38
39#include "rlm_winbind.h"
40#include "auth_wbclient_pap.h"
41#include <grp.h>
42#include <wbclient.h>
43
44static const conf_parser_t group_config[] = {
45 { FR_CONF_OFFSET("add_domain", rlm_winbind_t, group_add_domain), .dflt = "yes" },
47};
48
53
54static const conf_parser_t module_config[] = {
55 { FR_CONF_POINTER("group", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) group_config },
58};
59
61
64 { .out = &dict_freeradius, .proto = "freeradius" },
65 { NULL }
66};
67
70
73 { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
74 { .out = &attr_expr_bool_enum, .name = "Expr-Bool-Enum", .type = FR_TYPE_BOOL, .dict = &dict_freeradius },
75 { NULL }
76};
77
81
86
87/** Group comparison for Winbind-Group
88 *
89 * @param inst Instance of this module
90 * @param request The current request
91 * @param name Group name to be searched
92 * @param env Group check xlat call_env
93 *
94 * @return
95 * - 0 user is in group
96 * - 1 failure or user is not in group
97 */
98static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, char const *name,
100{
101 bool rcode = false;
102 winbind_ctx_t *wbctx;
103 struct wbcContext *wb_ctx;
104 wbcErr err;
105 uint32_t num_groups, i;
106 gid_t *wb_groups = NULL;
107
108 char const *domain = NULL;
109 size_t domain_len = 0;
110 char const *username;
111 char *username_buff = NULL;
112 size_t backslash = 0;
113
114 RINDENT();
115
116 /*
117 * Work out what username to check groups for, made up from
118 * either winbind_domain and either group_search_username or
119 * just User-Name.
120 */
121
122 /*
123 * Include the domain in the username?
124 */
125 if (inst->group_add_domain && env->domain.type == FR_TYPE_STRING){
126 domain = env->domain.vb_strvalue;
127 domain_len = env->domain.vb_length;
128 }
129
130 if (domain) {
131 username = username_buff = talloc_typed_asprintf(request, "%s\\%s", domain, env->username.vb_strvalue);
132 } else {
133 username = env->username.vb_strvalue;
134 RWDEBUG("Searching group with plain username, this will probably fail");
135 RWDEBUG("Ensure winbind domain is correctly set");
136 }
137
138 /*
139 * Get a libwbclient context
140 */
141 wbctx = winbind_slab_reserve(t->slab);
142 if (!wbctx) {
143 RERROR("Unable to get winbind context");
144 goto error;
145 }
146 wb_ctx = wbctx->ctx;
147
148 RDEBUG2("Trying to find user \"%s\" in group \"%s\"", username, name);
149
150 err = wbcCtxGetGroups(wb_ctx, username, &num_groups, &wb_groups);
151 switch (err) {
152 case WBC_ERR_SUCCESS:
153 if (!num_groups) {
154 RWDEBUG2("No groups returned");
155 goto finish;
156 }
157
158 RDEBUG2("Successfully retrieved user's groups");
159 break;
160
161 case WBC_ERR_WINBIND_NOT_AVAILABLE:
162 RERROR("Failed retrieving groups: Unable to contact winbindd"); /* Global error */
163 goto finish;
164
165 case WBC_ERR_DOMAIN_NOT_FOUND:
166 /* Yeah, weird. libwbclient returns this if the username is unknown */
167 REDEBUG("Failed retrieving groups: User or Domain not found");
168 goto finish;
169
170 case WBC_ERR_UNKNOWN_USER:
171 REDEBUG("Failed retrieving groups: User cannot be found");
172 goto finish;
173
174 default:
175 REDEBUG("Failed retrieving groups: %s", wbcErrorString(err));
176 goto finish;
177 }
178
179 /*
180 * See if any of the groups match
181 */
182
183 /*
184 * We try and find where the '\' is in the returned group, which saves
185 * looking for it each time. There seems to be no way to get a list of
186 * groups without the domain in them, but at least the backslash is
187 * always going to be in the same place.
188 *
189 * Maybe there should be an option to include the domain in the compared
190 * group name in case people have multiple domains?
191 */
192 if (domain_len > 0) backslash = domain_len - 1;
193
194 for (i = 0; i < num_groups; i++) {
195 struct group *group;
196 char *group_name;
197
198 /* Get the group name from the (fake winbind) gid */
199 err = wbcCtxGetgrgid(wb_ctx, wb_groups[i], &group);
200 if (err != WBC_ERR_SUCCESS) {
201 REDEBUG("Failed resolving GID %i: %s", wb_groups[i], wbcErrorString(err));
202 if (wb_groups[i] == UINT32_MAX) {
203 REDEBUG("GID appears to be winbind placeholder value, idmap likely failed");
204 }
205 continue;
206 }
207
208 RDEBUG3("Resolved GID %i to name \"%s\"", wb_groups[i], group->gr_name);
209
210 /* Find the backslash in the returned group name */
211 if ((backslash < strlen(group->gr_name)) && (group->gr_name[backslash] == '\\')) {
212 group_name = group->gr_name + backslash + 1;
213 } else if ((group_name = strchr(group->gr_name, '\\'))) {
214 group_name++;
215 backslash = group_name - (group->gr_name - 1);
216 } else {
217 group_name = group->gr_name;
218 }
219
220 /* See if the group matches */
221 RDEBUG3("Checking plain group name \"%s\"", group_name);
222 if (!strcasecmp(group_name, name)) {
223 RDEBUG2("Found matching group: %s", group_name);
224 rcode = true;
225 }
226 wbcFreeMemory(group);
227
228 /* Short-circuit to save unnecessary enumeration */
229 if (rcode) break;
230 }
231
232 if (!rcode) RWDEBUG2("No groups found that match");
233
234finish:
235 wbcFreeMemory(wb_groups);
236 winbind_slab_release(wbctx);
237
238error:
239 talloc_free(username_buff);
240 REXDENT();
241
242 return rcode;
243}
244
246 { .required = true, .type = FR_TYPE_STRING, .concat = true },
248};
249
250/** Check if the user is a member of a particular winbind group
251 *
252@verbatim
253%winbind.group(<name>)
254@endverbatim
255 *
256 * @ingroup xlat_functions
257 */
259 xlat_ctx_t const *xctx,
260 request_t *request, fr_value_box_list_t *in)
261{
262 rlm_winbind_t const *inst = talloc_get_type_abort(xctx->mctx->mi->data, rlm_winbind_t);
263 winbind_group_xlat_call_env_t *env = talloc_get_type_abort(xctx->env_data, winbind_group_xlat_call_env_t);
264 rlm_winbind_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_winbind_thread_t);
265 fr_value_box_t *arg = fr_value_box_list_head(in);
266 char const *p = arg->vb_strvalue;
267 fr_value_box_t *vb;
268
270
272 vb->vb_bool = winbind_check_group(inst, request, p, env, t);
274
275 return XLAT_ACTION_DONE;
276}
277
279 { .required = false, .type = FR_TYPE_STRING },
281};
282
283
284/** Ping a specific domain
285 *
286 * Sends a noop style message to AD to check if winbind and AD are responsive.
287@verbatim
288%winbind.ping([<domain>])
289@endverbatim
290 */
292 xlat_ctx_t const *xctx,
293 request_t *request, fr_value_box_list_t *in)
294{
295 rlm_winbind_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_winbind_thread_t);
296 fr_value_box_t const *domain = fr_value_box_list_head(in);
297 winbind_ctx_t *wbctx;
298 char *dc = NULL;
299 struct wbcAuthErrorInfo *err_info = NULL;
300 wbcErr err;
301 fr_value_box_t *out_vb;
302 fr_time_t then, now;
303
304 wbctx = winbind_slab_reserve(t->slab);
305 if (!wbctx) {
306 RERROR("Ping failed - Unable to get winbind context");
307 return XLAT_ACTION_FAIL;
308 }
309
310 then = fr_time();
311 /*
312 * Yes, this is a synchronous call, no, we can't set an explicit timeout
313 */
314 err = wbcCtxPingDc2(wbctx->ctx, domain ? domain->vb_strvalue : NULL, &err_info, &dc);
315 now = fr_time();
316
317 MEM(out_vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
318 if (WBC_ERROR_IS_OK(err)) {
319 RDEBUG2("Ping succeeded to DC %s after %pVms", dc,
321
322 MEM(out_vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL));
323 MEM(fr_value_box_strdup(out_vb, out_vb, NULL, "ok", false) == 0);
324 } else {
325 char const *err_str = wbcErrorString(err);
326
327 RERROR("Ping failed (%s) to DC %s after %pVms%s%s", err_str, dc,
329 err_info->display_string ? " - " : "",
330 err_info->display_string ? err_info->display_string : "");
331
332 MEM(fr_value_box_strdup(out_vb, out_vb, NULL, err_str, false) == 0);
333 }
334
335 if (dc) wbcFreeMemory(dc);
336 if (err_info) wbcFreeMemory(err_info);
337 winbind_slab_release(wbctx);
338
339 fr_dcursor_append(out, out_vb);
340
341 return XLAT_ACTION_DONE;
342}
343
344/*
345 * Free winbind context
346 */
347static int _mod_ctx_free(winbind_ctx_t *wbctx)
348{
349 wbcCtxFree(wbctx->ctx);
350 return 0;
351}
352
353/*
354 * Create winbind context
355 */
356static int winbind_ctx_alloc(winbind_ctx_t *wbctx, UNUSED void *uctx)
357{
358 wbctx->ctx = wbcCtxCreate();
359 if (!wbctx->ctx) {
360 fr_strerror_printf("Unable to create winbind context");
361 return -1;
362 }
363 talloc_set_destructor(wbctx, _mod_ctx_free);
364 return 0;
365}
366
367/** Instantiate this module
368 *
369 * @param[in] mctx data for this module
370 *
371 * @return
372 * - 0 instantiation succeeded
373 * - -1 instantiation failed
374 */
375static int mod_instantiate(module_inst_ctx_t const *mctx)
376{
377 rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t);
378
379 inst->auth_type = fr_dict_enum_by_name(attr_auth_type, mctx->mi->name, -1);
380 if (!inst->auth_type) {
381 WARN("Failed to find 'authenticate %s {...}' section. Winbind authentication will likely not work",
382 mctx->mi->name);
383 }
384
385 return 0;
386}
387
388
389/** Authorize for libwbclient/winbind authentication
390 *
391 * Checks there is a password available so we can authenticate
392 * against winbind and, if so, sets Auth-Type to ourself.
393 *
394 * @param[out] p_result The result of the module call:
395 * - #RLM_MODULE_NOOP unable to use winbind authentication
396 * - #RLM_MODULE_OK Auth-Type has been set to winbind
397 * @param[in] mctx Module instance data.
398 * @param[in] request The current request.
399 */
400static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
401{
403 winbind_autz_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_autz_call_env_t);
404 fr_pair_t *vp;
405
406 vp = fr_pair_find_by_da(&request->request_pairs, NULL, tmpl_attr_tail_da(env->password));
407 if (!vp) {
408 REDEBUG2("No %s found in the request; not doing winbind authentication.",
409 tmpl_attr_tail_da(env->password)->name);
411 }
412
413 if (!inst->auth_type) {
414 WARN("No 'authenticate %s {...}' section or 'Auth-Type = %s' set. Cannot setup Winbind authentication",
415 mctx->mi->name, mctx->mi->name);
417 }
418
420
422}
423
424
425/** Authenticate the user via libwbclient and winbind
426 *
427 * @param[out] p_result The result of the module call.
428 * @param[in] mctx Module instance data.
429 * @param[in] request The current request
430 */
431static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
432{
433 winbind_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_auth_call_env_t);
434 rlm_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t);
435
436 /*
437 * Make sure the supplied password isn't empty
438 */
439 if (env->password.vb_length == 0) {
440 REDEBUG("User-Password must not be empty");
442 }
443
444 /*
445 * Log the password
446 */
447 if (RDEBUG_ENABLED3) {
448 RDEBUG("Login attempt with password \"%pV\"", &env->password);
449 } else {
450 RDEBUG2("Login attempt with password");
451 }
452
453 /*
454 * Authenticate and return OK if successful. No need for
455 * many debug outputs or errors as the auth function is
456 * chatty enough.
457 */
458 if (do_auth_wbclient_pap(request, env, t) == 0) {
459 RDEBUG2("User authenticated successfully using winbind");
461 }
462
464}
465
474
475static int domain_call_env_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci,
476 UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
477{
478 CONF_PAIR const *to_parse = cf_item_to_pair(ci);
479 tmpl_t *parsed_tmpl = NULL;
480 struct wbcInterfaceDetails *wb_info = NULL;
481
482 if (strlen(cf_pair_value(to_parse)) > 0) {
483 if (tmpl_afrom_substr(ctx, &parsed_tmpl,
484 &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_array_length(cf_pair_value(to_parse)) - 1),
485 cf_pair_value_quote(to_parse),
486 NULL, t_rules) < 0) return -1;
487 } else {
488 /*
489 * If the domain has not been specified, try and find
490 * out what it is from winbind.
491 */
492 wbcErr err;
493 struct wbcContext *wb_ctx;
494
495 cf_log_warn(ci, "winbind domain unspecified; trying to get it from winbind");
496
497 wb_ctx = wbcCtxCreate();
498 if (!wb_ctx) {
499 /* this should be very unusual */
500 cf_log_err(ci, "Unable to get libwbclient context, cannot get domain");
501 goto no_domain;
502 }
503
504 err = wbcCtxInterfaceDetails(wb_ctx, &wb_info);
505 wbcCtxFree(wb_ctx);
506
507 if (err != WBC_ERR_SUCCESS) {
508 cf_log_err(ci, "libwbclient returned wbcErr code %d; unable to get domain name.", err);
509 cf_log_err(ci, "Is winbind running and does the winbind_privileged socket have");
510 cf_log_err(ci, "the correct permissions?");
511 goto no_domain;
512 }
513
514 if (!wb_info->netbios_domain) {
515 cf_log_err(ci, "winbind returned blank domain name");
516 goto no_domain;
517 }
518
519 tmpl_afrom_substr(ctx, &parsed_tmpl,
520 &FR_SBUFF_IN(wb_info->netbios_domain, strlen(wb_info->netbios_domain)),
521 T_SINGLE_QUOTED_STRING, NULL, t_rules);
522 if (!parsed_tmpl) {
523 cf_log_perr(ci, "Bad domain");
524 wbcFreeMemory(wb_info);
525 return -1;
526 }
527
528 cf_log_info(ci, "Using winbind_domain '%s'", parsed_tmpl->name);
529
530 no_domain:
531 wbcFreeMemory(wb_info);
532 }
533
534 *(void **)out = parsed_tmpl;
535 return parsed_tmpl ? 0 : -1;
536}
537
549
563
564/** Bootstrap this module
565 *
566 * @param[in] mctx data for this module
567 *
568 * @return
569 * - 0 success
570 * - -1 failure
571 */
572static int mod_bootstrap(module_inst_ctx_t const *mctx)
573{
574 CONF_SECTION *conf = mctx->mi->conf;
575 xlat_t *xlat;
576
577 /*
578 * Define the %winbind.group(name) xlat. The register
579 * function automatically adds the module instance name
580 * as a prefix.
581 */
582 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "group", winbind_group_xlat, FR_TYPE_BOOL);
583 if (!xlat) {
584 cf_log_err(conf, "Failed registering group expansion");
585 return -1;
586 }
587
590
591 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "ping", winbind_ping_xlat, FR_TYPE_STRING);
592 if (!xlat) {
593 cf_log_err(conf, "Failed registering ping expansion");
594 return -1;
595 }
597
598 return 0;
599}
600
602{
603 rlm_winbind_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t);
604 rlm_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t);
605
606 t->inst = inst;
607 if (!(t->slab = winbind_slab_list_alloc(t, mctx->el, &inst->reuse, winbind_ctx_alloc, NULL, NULL, false, false))) {
608 ERROR("Connection handle pool instantiation failed");
609 return -1;
610 }
611
612 return 0;
613}
614
616{
617 rlm_winbind_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_winbind_thread_t);
618 talloc_free(t->slab);
619 return 0;
620}
621
622/*
623 * The module name should be the only globally exported symbol.
624 * That is, everything else should be 'static'.
625 *
626 * If the module needs to temporarily modify it's instantiation
627 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
628 * The server will then take care of ensuring that the module
629 * is single-threaded.
630 */
633 .common = {
634 .magic = MODULE_MAGIC_INIT,
635 .name = "winbind",
636 .inst_size = sizeof(rlm_winbind_t),
639 .bootstrap = mod_bootstrap,
640 .thread_inst_size = sizeof(rlm_winbind_thread_t),
641 .thread_instantiate = mod_thread_instantiate,
642 .thread_detach = mod_thread_detach,
643 },
644 .method_group = {
645 .bindings = (module_method_binding_t[]){
646 { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate, .method_env = &winbind_auth_method_env },
647 { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize, .method_env = &winbind_autz_method_env },
649 }
650 }
651};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
int do_auth_wbclient_pap(request_t *request, winbind_auth_call_env_t *env, rlm_winbind_thread_t *t)
PAP authentication direct to winbind via Samba's libwbclient library.
#define RCSID(id)
Definition build.h:485
#define UNUSED
Definition build.h:317
#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
#define FR_CALL_ENV_SUBSECTION(_name, _name2, _flags, _subcs)
Specify a call_env_parser_t which defines a nested subsection.
Definition call_env.h:402
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl MUST contain an attribute reference.
Definition call_env.h:86
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
Definition call_env.h:85
@ CALL_ENV_FLAG_SECRET
The value is a secret, and should not be logged.
Definition call_env.h:91
@ CALL_ENV_FLAG_NONE
Definition call_env.h:74
@ 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
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
Definition call_env.h:389
Per method call config.
Definition call_env.h:180
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:658
#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:284
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition cf_parse.h:339
#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:313
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:428
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
Common header for all CONF_* types.
Definition cf_priv.h:49
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:70
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
Definition cf_util.c:1637
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:663
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1593
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define cf_log_info(_cf, _fmt,...)
Definition cf_util.h:291
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:296
#define cf_log_warn(_cf, _fmt,...)
Definition cf_util.h:290
#define CF_IDENT_ANY
Definition cf_util.h:78
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:408
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
static fr_slen_t err
Definition dict.h:840
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:273
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:286
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition dict_util.c:3439
static fr_slen_t in
Definition dict.h:840
Specifies an attribute which must be present for the module to function.
Definition dict.h:272
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:285
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
static xlat_action_t winbind_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Check if the user is a member of a particular winbind group.
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:443
#define RWDEBUG(fmt,...)
Definition log.h:361
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:335
#define RDEBUG3(fmt,...)
Definition log.h:343
#define RWDEBUG2(fmt,...)
Definition log.h:362
#define RERROR(fmt,...)
Definition log.h:298
#define REDEBUG2(fmt,...)
Definition log.h:372
#define RINDENT()
Indent R* messages by one level.
Definition log.h:430
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
unsigned int uint32_t
int strcasecmp(char *s1, char *s2)
Definition missing.c:66
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
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 instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition module_rlm.c:243
bool module_rlm_section_type_set(request_t *request, fr_dict_attr_t const *type_da, fr_dict_enum_value_t const *enumv)
Set the next section type if it's not already set.
Definition module_rlm.c:413
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:697
static const conf_parser_t config[]
Definition base.c:183
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define RDEBUG(fmt,...)
Definition radclient.h:53
#define WARN(fmt,...)
Definition radclient.h:47
static rs_t * conf
Definition radsniff.c:53
#define RETURN_MODULE_REJECT
Definition rcode.h:56
#define RETURN_MODULE_NOOP
Definition rcode.h:63
#define RETURN_MODULE_INVALID
Definition rcode.h:60
#define RETURN_MODULE_OK
Definition rcode.h:58
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1313
username
static int domain_call_env_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
static const call_env_method_t winbind_autz_method_env
static xlat_arg_parser_t const winbind_group_xlat_arg[]
static int winbind_ctx_alloc(winbind_ctx_t *wbctx, UNUSED void *uctx)
fr_dict_attr_autoload_t rlm_winbind_dict_attr[]
Definition rlm_winbind.c:72
static const call_env_method_t winbind_auth_method_env
static const conf_parser_t group_config[]
Definition rlm_winbind.c:44
static fr_dict_t const * dict_freeradius
Definition rlm_winbind.c:60
static fr_dict_attr_t const * attr_expr_bool_enum
Definition rlm_winbind.c:69
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Authenticate the user via libwbclient and winbind.
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Bootstrap this module.
static xlat_action_t winbind_ping_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Ping a specific domain.
static fr_dict_attr_t const * attr_auth_type
Definition rlm_winbind.c:68
static conf_parser_t reuse_winbind_config[]
Definition rlm_winbind.c:49
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Authorize for libwbclient/winbind authentication.
static int _mod_ctx_free(winbind_ctx_t *wbctx)
static const call_env_method_t winbind_group_xlat_call_env
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
module_rlm_t rlm_winbind
static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, char const *name, winbind_group_xlat_call_env_t *env, rlm_winbind_thread_t *t)
Group comparison for Winbind-Group.
Definition rlm_winbind.c:98
static const conf_parser_t module_config[]
Definition rlm_winbind.c:54
fr_dict_autoload_t rlm_winbind_dict[]
Definition rlm_winbind.c:63
static xlat_arg_parser_t const winbind_ping_xlat_arg[]
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
static int mod_instantiate(module_inst_ctx_t const *mctx)
Instantiate this module.
fr_value_box_t password
Definition rlm_winbind.h:35
rlm_winbind_t const * inst
Instance of rlm_winbind.
Definition rlm_winbind.h:28
winbind_slab_list_t * slab
Slab list for winbind handles.
Definition rlm_winbind.h:29
struct wbcContext * ctx
Definition rlm_winbind.h:21
#define FR_SBUFF_IN(_start, _len_or_end)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
char const * name
Instance name e.g. user_database.
Definition module.h:336
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:330
size_t inst_size
Size of the module's instance data.
Definition module.h:204
void * data
Module's instance data.
Definition module.h:272
void * boot
Data allocated during the boostrap phase.
Definition module.h:275
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition tmpl.h:801
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:332
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
Definition skip.h:37
#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
fr_pair_t * vp
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition state_test.c:8
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:514
#define talloc_get_type_abort_const
Definition talloc.h:287
#define fr_time_sub(_a, _b)
Subtract one time from another.
Definition time.h:229
"server local" time.
Definition time.h:69
@ T_SINGLE_QUOTED_STRING
Definition token.h:122
@ T_BARE_WORD
Definition token.h:120
uint8_t required
Argument must be present, and non-empty.
Definition xlat.h:145
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:169
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumend by an xlat function.
Definition xlat.h:144
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
Definition value.c:4158
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition value.h:640
#define fr_box_time_delta_msec(_val)
Definition value.h:366
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1020
void * env_data
Expanded call env data.
Definition xlat_ctx.h:53
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition xlat_ctx.h:52
An xlat calling ctx.
Definition xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:363
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.
Definition xlat_func.c:389