The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 95d0fc72d8239a9a221c94699b25fb9503152dc2 $
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  */
27 RCSID("$Id: 95d0fc72d8239a9a221c94699b25fb9503152dc2 $")
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 
35 #include "rlm_winbind.h"
36 #include "auth_wbclient_pap.h"
37 #include <grp.h>
38 #include <wbclient.h>
39 
40 static const conf_parser_t group_config[] = {
41  { FR_CONF_OFFSET("add_domain", rlm_winbind_t, group_add_domain), .dflt = "yes" },
43 };
44 
45 static const conf_parser_t module_config[] = {
46  { FR_CONF_POINTER("group", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) group_config },
48 };
49 
50 static fr_dict_t const *dict_freeradius;
51 
54  { .out = &dict_freeradius, .proto = "freeradius" },
55  { NULL }
56 };
57 
60 
63  { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
64  { .out = &attr_expr_bool_enum, .name = "Expr-Bool-Enum", .type = FR_TYPE_BOOL, .dict = &dict_freeradius },
65  { NULL }
66 };
67 
68 typedef struct {
71 
72 typedef struct {
76 
77 /** Group comparison for Winbind-Group
78  *
79  * @param inst Instance of this module
80  * @param request The current request
81  * @param name Group name to be searched
82  * @param env Group check xlat call_env
83  *
84  * @return
85  * - 0 user is in group
86  * - 1 failure or user is not in group
87  */
88 static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, char const *name,
90 {
91  bool rcode = false;
92  struct wbcContext *wb_ctx;
93  wbcErr err;
94  uint32_t num_groups, i;
95  gid_t *wb_groups = NULL;
96 
97  char const *domain = NULL;
98  size_t domain_len = 0;
99  char const *username;
100  char *username_buff = NULL;
101  size_t backslash = 0;
102 
103  RINDENT();
104 
105  /*
106  * Work out what username to check groups for, made up from
107  * either winbind_domain and either group_search_username or
108  * just User-Name.
109  */
110 
111  /*
112  * Include the domain in the username?
113  */
114  if (inst->group_add_domain && env->domain.type == FR_TYPE_STRING){
115  domain = env->domain.vb_strvalue;
116  domain_len = env->domain.vb_length;
117  }
118 
119  if (domain) {
120  username = username_buff = talloc_typed_asprintf(request, "%s\\%s", domain, env->username.vb_strvalue);
121  } else {
122  username = env->username.vb_strvalue;
123  RWDEBUG("Searching group with plain username, this will probably fail");
124  RWDEBUG("Ensure winbind domain is correctly set");
125  }
126 
127  /*
128  * Get a libwbclient connection from the pool
129  */
130  wb_ctx = fr_pool_connection_get(inst->wb_pool, request);
131  if (wb_ctx == NULL) {
132  RERROR("Unable to get winbind connection from the pool");
133  goto error;
134  }
135 
136  RDEBUG2("Trying to find user \"%s\" in group \"%s\"", username, name);
137 
138  err = wbcCtxGetGroups(wb_ctx, username, &num_groups, &wb_groups);
139  switch (err) {
140  case WBC_ERR_SUCCESS:
141  if (!num_groups) {
142  RWDEBUG2("No groups returned");
143  goto finish;
144  }
145 
146  RDEBUG2("Successfully retrieved user's groups");
147  break;
148 
149  case WBC_ERR_WINBIND_NOT_AVAILABLE:
150  RERROR("Failed retrieving groups: Unable to contact winbindd"); /* Global error */
151  goto finish;
152 
153  case WBC_ERR_DOMAIN_NOT_FOUND:
154  /* Yeah, weird. libwbclient returns this if the username is unknown */
155  REDEBUG("Failed retrieving groups: User or Domain not found");
156  goto finish;
157 
158  case WBC_ERR_UNKNOWN_USER:
159  REDEBUG("Failed retrieving groups: User cannot be found");
160  goto finish;
161 
162  default:
163  REDEBUG("Failed retrieving groups: %s", wbcErrorString(err));
164  goto finish;
165  }
166 
167  /*
168  * See if any of the groups match
169  */
170 
171  /*
172  * We try and find where the '\' is in the returned group, which saves
173  * looking for it each time. There seems to be no way to get a list of
174  * groups without the domain in them, but at least the backslash is
175  * always going to be in the same place.
176  *
177  * Maybe there should be an option to include the domain in the compared
178  * group name in case people have multiple domains?
179  */
180  if (domain_len > 0) backslash = domain_len - 1;
181 
182  for (i = 0; i < num_groups; i++) {
183  struct group *group;
184  char *group_name;
185 
186  /* Get the group name from the (fake winbind) gid */
187  err = wbcCtxGetgrgid(wb_ctx, wb_groups[i], &group);
188  if (err != WBC_ERR_SUCCESS) {
189  REDEBUG("Failed resolving GID %i: %s", wb_groups[i], wbcErrorString(err));
190  if (wb_groups[i] == UINT32_MAX) {
191  REDEBUG("GID appears to be winbind placeholder value, idmap likely failed");
192  }
193  continue;
194  }
195 
196  RDEBUG3("Resolved GID %i to name \"%s\"", wb_groups[i], group->gr_name);
197 
198  /* Find the backslash in the returned group name */
199  if ((backslash < strlen(group->gr_name)) && (group->gr_name[backslash] == '\\')) {
200  group_name = group->gr_name + backslash + 1;
201  } else if ((group_name = strchr(group->gr_name, '\\'))) {
202  group_name++;
203  backslash = group_name - (group->gr_name - 1);
204  } else {
205  group_name = group->gr_name;
206  }
207 
208  /* See if the group matches */
209  RDEBUG3("Checking plain group name \"%s\"", group_name);
210  if (!strcasecmp(group_name, name)) {
211  RDEBUG2("Found matching group: %s", group_name);
212  rcode = true;
213  }
214  wbcFreeMemory(group);
215 
216  /* Short-circuit to save unnecessary enumeration */
217  if (rcode) break;
218  }
219 
220  if (!rcode) RWDEBUG2("No groups found that match");
221 
222 finish:
223  wbcFreeMemory(wb_groups);
224  fr_pool_connection_release(inst->wb_pool, request, wb_ctx);
225 
226 error:
227  talloc_free(username_buff);
228  REXDENT();
229 
230  return rcode;
231 }
232 
233 
234 /** Check if the user is a member of a particular winbind group
235  *
236 @verbatim
237 %winbind.group(<name>)
238 @endverbatim
239  *
240  * @ingroup xlat_functions
241  */
243  xlat_ctx_t const *xctx,
244  request_t *request, fr_value_box_list_t *in)
245 {
246  rlm_winbind_t const *inst = talloc_get_type_abort(xctx->mctx->mi->data, rlm_winbind_t);
247  winbind_group_xlat_call_env_t *env = talloc_get_type_abort(xctx->env_data, winbind_group_xlat_call_env_t);
248  fr_value_box_t *arg = fr_value_box_list_head(in);
249  char const *p = arg->vb_strvalue;
250  fr_value_box_t *vb;
251 
253 
255  vb->vb_bool = winbind_check_group(inst, request, p, env);
256  fr_dcursor_append(out, vb);
257 
258  return XLAT_ACTION_DONE;
259 }
260 
261 
262 /** Free connection pool winbind context
263  *
264  * @param[in] wb_ctx libwbclient context
265  * @return 0
266  */
267 static int _mod_conn_free(struct wbcContext **wb_ctx)
268 {
269  wbcCtxFree(*wb_ctx);
270 
271  return 0;
272 }
273 
274 
275 /** Create connection pool winbind context
276  *
277  * @param[in] ctx talloc context
278  * @param[in] instance Module instance (unused)
279  * @param[in] timeout Connection timeout
280  *
281  * @return pointer to libwbclient context
282  */
283 static void *mod_conn_create(TALLOC_CTX *ctx, UNUSED void *instance, UNUSED fr_time_delta_t timeout)
284 {
285  struct wbcContext **wb_ctx;
286 
287  wb_ctx = talloc_zero(ctx, struct wbcContext *);
288  *wb_ctx = wbcCtxCreate();
289 
290  if (*wb_ctx == NULL) {
291  PERROR("failed to create winbind context");
292  talloc_free(wb_ctx);
293  return NULL;
294  }
295 
296  talloc_set_destructor(wb_ctx, _mod_conn_free);
297 
298  return *wb_ctx;
299 }
300 
301 
303  { .required = true, .type = FR_TYPE_STRING, .concat = true },
305 };
306 
307 
308 /** Instantiate this module
309  *
310  * @param[in] mctx data for this module
311  *
312  * @return
313  * - 0 instantiation succeeded
314  * - -1 instantiation failed
315  */
316 static int mod_instantiate(module_inst_ctx_t const *mctx)
317 {
318  rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t);
319  CONF_SECTION *conf = mctx->mi->conf;
320 
321  inst->wb_pool = module_rlm_connection_pool_init(conf, inst, mod_conn_create, NULL, NULL, NULL, NULL);
322  if (!inst->wb_pool) {
323  cf_log_err(conf, "Unable to initialise winbind connection pool");
324  return -1;
325  }
326 
327  inst->auth_type = fr_dict_enum_by_name(attr_auth_type, mctx->mi->name, -1);
328  if (!inst->auth_type) {
329  WARN("Failed to find 'authenticate %s {...}' section. Winbind authentication will likely not work",
330  mctx->mi->name);
331  }
332 
333  return 0;
334 }
335 
336 
337 /** Tidy up module instance
338  *
339  * Frees up the libwbclient connection pool.
340  *
341  * @param[in] mctx data for this module
342  * @return 0
343  */
344 static int mod_detach(module_detach_ctx_t const *mctx)
345 {
346  rlm_winbind_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_winbind_t);
347 
348  fr_pool_free(inst->wb_pool);
349 
350  return 0;
351 }
352 
353 
354 /** Authorize for libwbclient/winbind authentication
355  *
356  * Checks there is a password available so we can authenticate
357  * against winbind and, if so, sets Auth-Type to ourself.
358  *
359  * @param[out] p_result The result of the module call:
360  * - #RLM_MODULE_NOOP unable to use winbind authentication
361  * - #RLM_MODULE_OK Auth-Type has been set to winbind
362  * @param[in] mctx Module instance data.
363  * @param[in] request The current request.
364  */
365 static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
366 {
368  winbind_autz_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_autz_call_env_t);
369  fr_pair_t *vp;
370 
371  vp = fr_pair_find_by_da(&request->request_pairs, NULL, tmpl_attr_tail_da(env->password));
372  if (!vp) {
373  REDEBUG2("No %s found in the request; not doing winbind authentication.",
374  tmpl_attr_tail_da(env->password)->name);
376  }
377 
378  if (!inst->auth_type) {
379  WARN("No 'authenticate %s {...}' section or 'Auth-Type = %s' set. Cannot setup Winbind authentication",
380  mctx->mi->name, mctx->mi->name);
382  }
383 
385 
387 }
388 
389 
390 /** Authenticate the user via libwbclient and winbind
391  *
392  * @param[out] p_result The result of the module call.
393  * @param[in] mctx Module instance data.
394  * @param[in] request The current request
395  */
396 static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
397 {
399  winbind_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_auth_call_env_t);
400 
401  /*
402  * Make sure the supplied password isn't empty
403  */
404  if (env->password.vb_length == 0) {
405  REDEBUG("User-Password must not be empty");
407  }
408 
409  /*
410  * Log the password
411  */
412  if (RDEBUG_ENABLED3) {
413  RDEBUG("Login attempt with password \"%pV\"", &env->password);
414  } else {
415  RDEBUG2("Login attempt with password");
416  }
417 
418  /*
419  * Authenticate and return OK if successful. No need for
420  * many debug outputs or errors as the auth function is
421  * chatty enough.
422  */
423  if (do_auth_wbclient_pap(inst, request, env) == 0) {
424  RDEBUG2("User authenticated successfully using winbind");
426  }
427 
429 }
430 
433  .env = (call_env_parser_t[]) {
435  .pair.dflt = "&User-Password", .pair.dflt_quote = T_BARE_WORD },
437  }
438 };
439 
440 static int domain_call_env_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci,
441  UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule)
442 {
443  CONF_PAIR const *to_parse = cf_item_to_pair(ci);
444  tmpl_t *parsed_tmpl = NULL;
445  struct wbcInterfaceDetails *wb_info = NULL;
446 
447  if (strlen(cf_pair_value(to_parse)) > 0) {
448  if (tmpl_afrom_substr(ctx, &parsed_tmpl,
449  &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_array_length(cf_pair_value(to_parse)) - 1),
450  cf_pair_value_quote(to_parse),
451  NULL, t_rules) < 0) return -1;
452  } else {
453  /*
454  * If the domain has not been specified, try and find
455  * out what it is from winbind.
456  */
457  wbcErr err;
458  struct wbcContext *wb_ctx;
459 
460  cf_log_warn(ci, "winbind domain unspecified; trying to get it from winbind");
461 
462  wb_ctx = wbcCtxCreate();
463  if (!wb_ctx) {
464  /* this should be very unusual */
465  cf_log_err(ci, "Unable to get libwbclient context, cannot get domain");
466  goto no_domain;
467  }
468 
469  err = wbcCtxInterfaceDetails(wb_ctx, &wb_info);
470  wbcCtxFree(wb_ctx);
471 
472  if (err != WBC_ERR_SUCCESS) {
473  cf_log_err(ci, "libwbclient returned wbcErr code %d; unable to get domain name.", err);
474  cf_log_err(ci, "Is winbind running and does the winbind_privileged socket have");
475  cf_log_err(ci, "the correct permissions?");
476  goto no_domain;
477  }
478 
479  if (!wb_info->netbios_domain) {
480  cf_log_err(ci, "winbind returned blank domain name");
481  goto no_domain;
482  }
483 
484  tmpl_afrom_substr(ctx, &parsed_tmpl,
485  &FR_SBUFF_IN(wb_info->netbios_domain, strlen(wb_info->netbios_domain)),
486  T_SINGLE_QUOTED_STRING, NULL, t_rules);
487  if (!parsed_tmpl) {
488  cf_log_perr(ci, "Bad domain");
489  wbcFreeMemory(wb_info);
490  return -1;
491  }
492 
493  cf_log_info(ci, "Using winbind_domain '%s'", parsed_tmpl->name);
494 
495  no_domain:
496  wbcFreeMemory(wb_info);
497  }
498 
499  *(void **)out = parsed_tmpl;
500  return parsed_tmpl ? 0 : -1;
501 }
502 
505  .env = (call_env_parser_t[]) {
508  .pair.dflt = "", .pair.dflt_quote = T_SINGLE_QUOTED_STRING, .pair.func = domain_call_env_parse },
510  .pair.dflt = "&User-Password", .pair.dflt_quote = T_BARE_WORD },
512  }
513 };
514 
517  .env = (call_env_parser_t[]) {
519  .pair.dflt = "", .pair.dflt_quote = T_SINGLE_QUOTED_STRING, .pair.func = domain_call_env_parse },
521  ((call_env_parser_t[]) {
524  }))},
526  }
527 };
528 
529 /** Bootstrap this module
530  *
531  * @param[in] mctx data for this module
532  *
533  * @return
534  * - 0 success
535  * - -1 failure
536  */
537 static int mod_bootstrap(module_inst_ctx_t const *mctx)
538 {
539  CONF_SECTION *conf = mctx->mi->conf;
540  xlat_t *xlat;
541 
542  /*
543  * Define the %winbind.group(name) xlat. The register
544  * function automatically adds the module instance name
545  * as a prefix.
546  */
547  xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "group", winbind_group_xlat, FR_TYPE_BOOL);
548  if (!xlat) {
549  cf_log_err(conf, "Failed registering group expansion");
550  return -1;
551  }
552 
555 
556  return 0;
557 }
558 
559 /*
560  * The module name should be the only globally exported symbol.
561  * That is, everything else should be 'static'.
562  *
563  * If the module needs to temporarily modify it's instantiation
564  * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
565  * The server will then take care of ensuring that the module
566  * is single-threaded.
567  */
570  .common = {
571  .magic = MODULE_MAGIC_INIT,
572  .name = "winbind",
573  .inst_size = sizeof(rlm_winbind_t),
576  .bootstrap = mod_bootstrap,
577  .detach = mod_detach
578  },
579  .method_group = {
580  .bindings = (module_method_binding_t[]){
581  { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate, .method_env = &winbind_auth_method_env },
582  { .section = SECTION_NAME("recv", CF_IDENT_ANY), .method = mod_authorize, .method_env = &winbind_autz_method_env },
584  }
585  }
586 };
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(rlm_winbind_t const *inst, request_t *request, winbind_auth_call_env_t *env)
PAP authentication direct to winbind via Samba's libwbclient library.
#define RCSID(id)
Definition: build.h:481
#define UNUSED
Definition: build.h:313
#define CALL_ENV_TERMINATOR
Definition: call_env.h:231
#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:235
#define FR_CALL_ENV_SUBSECTION(_name, _name2, _flags, _subcs)
Specify a call_env_parser_t which defines a nested subsection.
Definition: call_env.h:397
@ 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
#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:335
#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:384
Per method call config.
Definition: call_env.h:175
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#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:268
#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:310
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:399
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
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
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1594
fr_token_t cf_pair_value_quote(CONF_PAIR const *pair)
Return the value (rhs) quoting of a pair.
Definition: cf_util.c:1638
#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:406
static fr_time_delta_t timeout
Definition: dhcpclient.c:54
static fr_slen_t err
Definition: dict.h:821
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:267
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:280
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition: dict_util.c:3395
static fr_slen_t in
Definition: dict.h:821
Specifies an attribute which must be present for the module to function.
Definition: dict.h:266
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:279
#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.
Definition: rlm_winbind.c:242
#define PERROR(_fmt,...)
Definition: log.h:228
#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.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_BOOL
A truth value.
Definition: merged_model.c:95
unsigned int uint32_t
Definition: merged_model.c:33
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
Definition: misc.h:59
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
module_instance_t * mi
Module instance to detach.
Definition: module_ctx.h:57
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
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:427
fr_pool_t * module_rlm_connection_pool_init(CONF_SECTION *module, void *opaque, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Initialise a module specific connection pool.
Definition: module_rlm.c:308
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:257
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:693
void fr_pool_connection_release(fr_pool_t *pool, request_t *request, void *conn)
Release a connection.
Definition: pool.c:1407
void fr_pool_free(fr_pool_t *pool)
Delete a connection pool.
Definition: pool.c:1329
void * fr_pool_connection_get(fr_pool_t *pool, request_t *request)
Reserve a connection in the connection pool.
Definition: pool.c:1392
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:55
#define RETURN_MODULE_NOOP
Definition: rcode.h:62
#define RETURN_MODULE_INVALID
Definition: rcode.h:59
#define RETURN_MODULE_OK
Definition: rcode.h:57
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:1302
username
Definition: rlm_securid.c:420
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)
Definition: rlm_winbind.c:440
static int mod_detach(module_detach_ctx_t const *mctx)
Tidy up module instance.
Definition: rlm_winbind.c:344
static const call_env_method_t winbind_autz_method_env
Definition: rlm_winbind.c:431
static xlat_arg_parser_t const winbind_group_xlat_arg[]
Definition: rlm_winbind.c:302
static void * mod_conn_create(TALLOC_CTX *ctx, UNUSED void *instance, UNUSED fr_time_delta_t timeout)
Create connection pool winbind context.
Definition: rlm_winbind.c:283
fr_dict_attr_autoload_t rlm_winbind_dict_attr[]
Definition: rlm_winbind.c:62
static const call_env_method_t winbind_auth_method_env
Definition: rlm_winbind.c:503
static const conf_parser_t group_config[]
Definition: rlm_winbind.c:40
static fr_dict_t const * dict_freeradius
Definition: rlm_winbind.c:50
static fr_dict_attr_t const * attr_expr_bool_enum
Definition: rlm_winbind.c:59
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.
Definition: rlm_winbind.c:396
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Bootstrap this module.
Definition: rlm_winbind.c:537
static fr_dict_attr_t const * attr_auth_type
Definition: rlm_winbind.c:58
static bool winbind_check_group(rlm_winbind_t const *inst, request_t *request, char const *name, winbind_group_xlat_call_env_t *env)
Group comparison for Winbind-Group.
Definition: rlm_winbind.c:88
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Authorize for libwbclient/winbind authentication.
Definition: rlm_winbind.c:365
static const call_env_method_t winbind_group_xlat_call_env
Definition: rlm_winbind.c:515
static int _mod_conn_free(struct wbcContext **wb_ctx)
Free connection pool winbind context.
Definition: rlm_winbind.c:267
module_rlm_t rlm_winbind
Definition: rlm_winbind.c:569
static const conf_parser_t module_config[]
Definition: rlm_winbind.c:45
fr_dict_autoload_t rlm_winbind_dict[]
Definition: rlm_winbind.c:53
static int mod_instantiate(module_inst_ctx_t const *mctx)
Instantiate this module.
Definition: rlm_winbind.c:316
fr_value_box_t password
Definition: rlm_winbind.h:22
#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:335
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
void * data
Module's instance data.
Definition: module.h:271
void * boot
Data allocated during the boostrap phase.
Definition: module.h:274
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition: module.h:151
Named methods exported by a module.
Definition: module.h:173
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition: tmpl.h:812
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.
Optional arguments passed to vp_tmpl functions.
Definition: tmpl.h:341
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
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:492
#define talloc_get_type_abort_const
Definition: talloc.h:282
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
@ T_SINGLE_QUOTED_STRING
Definition: token.h:122
@ T_BARE_WORD
Definition: token.h:120
bool required
Argument must be present, and non-empty.
Definition: xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition: xlat.h:166
xlat_action_t
Definition: xlat.h:35
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition: xlat.h:41
Definition for a single argument consumend by an xlat function.
Definition: xlat.h:145
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition: value.h:621
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997
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:365
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:392