The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_securid.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: 78b44fb2fa657edf64feb42566010d789c03a240 $
19 * @file rlm_securid.c
20 * @brief Supports auth against SecurID servers using OTP h/w tokens.
21 *
22 * Supports "next-token code" and "new-pin" modes.
23 *
24 * @copyright 2012 The FreeRADIUS server project
25 * @copyright 2012 Alan DeKok (aland@networkradius.com)
26 */
27#define "rlm_securid - "
28
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/server/module_rlm.h>
31#include <ctype.h>
32
33#include "rlm_securid.h"
34
35typedef enum {
36 RC_SECURID_AUTH_SUCCESS = 0,
37 RC_SECURID_AUTH_FAILURE = -3,
38 RC_SECURID_AUTH_ACCESS_DENIED_FAILURE = -4,
39 RC_SECURID_AUTH_INVALID_SERVER_FAILURE = -5,
40 RC_SECURID_AUTH_CHALLENGE = -17
41} SECURID_AUTH_RC;
42
43
44static const conf_parser_t module_config[] = {
45 { FR_CONF_OFFSET("timer_expire", rlm_securid_t, timer_limit), .dflt = "600" },
46 { FR_CONF_OFFSET("max_sessions", rlm_securid_t, max_sessions), .dflt = "2048" },
47 { FR_CONF_OFFSET("max_trips_per_session", rlm_securid_t, max_trips_per_session) },
48 { FR_CONF_OFFSET("max_round_trips", rlm_securid_t, max_trips_per_session), .dflt = "6" },
50};
51
52static fr_dict_t const *dict_radius;
53
54extern fr_dict_autoload_t mem_dict[];
55fr_dict_autoload_t mem_dict[] = {
56 { .out = &dict_radius, .proto = "radius" },
58};
59
64
65extern fr_dict_attr_autoload_t mem_dict_attr[];
66fr_dict_attr_autoload_t mem_dict_attr[] = {
67 { .out = &attr_prompt, .name = "Prompt", .type = FR_TYPE_UINT32, .dict = &dict_radius },
68 { .out = &attr_reply_message, .name = "Reply-Message", .type = FR_TYPE_STRING, .dict = &dict_radius },
69 { .out = &attr_user_name, .name = "User-Name", .type = FR_TYPE_STRING, .dict = &dict_radius },
70 { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
72};
73
74static SD_CHAR empty_pin[] = "";
75
76/* comparison function to find session in the tree */
77static int securid_session_cmp(void const *a, void const *b)
78{
79 int ret;
80 SECURID_SESSION const *one = a;
81 SECURID_SESSION const *two = b;
82
83 fr_assert(one != NULL);
84 fr_assert(two != NULL);
85
86 ret = fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr);
87 if (ret != 0) return ret;
88
89 return memcmp(one->state, two->state, sizeof(one->state));
90}
91
92
93static SECURID_AUTH_RC securidAuth(void *instance, request_t *request,
94 char const *username,
95 char const *passcode,
96 char *replyMsgBuffer, size_t replyMsgBufferSize)
97{
98 rlm_securid_t *inst = (rlm_securid_t *) instance;
99 int acm_ret;
100 SD_PIN pin_params;
101 char new_pin[10];
102 char format[30];
103 SECURID_SESSION *securid_session = NULL;
104 int rc = -1;
105
106 SD_CHAR *securid_user, *securid_pass;
107
108 if (!username) {
109 ERROR("SecurID username is NULL");
110 return RC_SECURID_AUTH_FAILURE;
111 }
112
113 if (!passcode) {
114 ERROR("SecurID passcode is NULL for %s user", username);
115 return RC_SECURID_AUTH_FAILURE;
116 }
117
118 memcpy(&securid_user, &username, sizeof(securid_user));
119 memcpy(&securid_pass, &passcode, sizeof(securid_pass));
120
121 *replyMsgBuffer = '\0';
122
123 securid_session = securid_sessionlist_find(inst, request);
124 if (!securid_session) {
125 /* securid session not found */
126 SDI_HANDLE sdiHandle = SDI_HANDLE_NONE;
127
128 acm_ret = SD_Init(&sdiHandle);
129 if (acm_ret != ACM_OK) {
130 RERROR("Cannot communicate with the ACE/Server");
131 return -1;
132 }
133
134 acm_ret = SD_Lock(sdiHandle, securid_user);
135 if (acm_ret != ACM_OK) {
136 REDEBUG("SecurID: Access denied. Name [%s] lock failed", username);
137 return -2;
138 }
139
140 acm_ret = SD_Check(sdiHandle, securid_pass, securid_user);
141 switch (acm_ret) {
142 case ACM_OK:
143 /* we are in now */
144 RDEBUG2("SecurID authentication successful for %s", username);
145 SD_Close(sdiHandle);
146
147 return RC_SECURID_AUTH_SUCCESS;
148
149 case ACM_ACCESS_DENIED:
150 /* not this time */
151 RDEBUG2("SecurID Access denied for %s", username);
152 SD_Close(sdiHandle);
153 return RC_SECURID_AUTH_ACCESS_DENIED_FAILURE;
154
155 case ACM_INVALID_SERVER:
156 RERROR("SecurID: Invalid ACE server");
157 return RC_SECURID_AUTH_INVALID_SERVER_FAILURE;
158
159 case ACM_NEW_PIN_REQUIRED:
160 RDEBUG2("SecurID new pin required for %s", username);
161
162 /* create a new session */
163 securid_session = securid_session_alloc();
164 securid_session->sdiHandle = sdiHandle; /* save ACE handle for future use */
166 securid_session->identity = talloc_typed_strdup(securid_session, username);
167
168 /* Get PIN requirements */
169 acm_ret = AceGetPinParams(sdiHandle, &pin_params);
170
171 /* If a system-generated PIN is required */
172 if (pin_params.Selectable == CANNOT_CHOOSE_PIN) {
173 /* Prompt user to accept a system generated PIN */
174 snprintf(replyMsgBuffer, replyMsgBufferSize,
175 "\r\nAre you prepared to accept a new system-generated PIN [y/n]?");
177
178 } else if (pin_params.Selectable == USER_SELECTABLE) { //may be returned by AM 6.x servers.
179 snprintf(replyMsgBuffer, replyMsgBufferSize,
180 "\r\nPress 'y' to generate a new PIN\r\nOR\r\n'n'to enter a new PIN yourself [y/n]");
182
183 } else {
184 if (pin_params.Alphanumeric) {
185 strcpy(format, "alphanumeric characters");
186 } else {
187 strcpy(format, "digits");
188 }
189 snprintf(replyMsgBuffer, replyMsgBufferSize,
190 " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
191 pin_params.Min, pin_params.Max, format);
192 }
193
194 /* insert new session in the session list */
195 securid_sessionlist_add(inst, request, securid_session);
196
197 return RC_SECURID_AUTH_CHALLENGE;
198
199 case ACM_NEXT_CODE_REQUIRED:
200 RDEBUG2("Next securid token code required for %s",
201 username);
202
203 /* create a new session */
204 securid_session = securid_session_alloc();
205 securid_session->sdiHandle = sdiHandle;
207 securid_session->identity = talloc_typed_strdup(securid_session, username);
208
209 /* insert new session in the session list */
210 securid_sessionlist_add(inst, request, securid_session);
211
212 strlcpy(replyMsgBuffer, "\r\nPlease Enter the Next Code from Your Token:", replyMsgBufferSize);
213 return RC_SECURID_AUTH_CHALLENGE;
214
215 default:
216 ERROR("SecurID: Unexpected error from ACE/Agent API acm_ret=%d", acm_ret);
217 securid_session_free(inst, request, securid_session);
218 return RC_SECURID_AUTH_FAILURE;
219
220
221 }
222 } else {
223 /* existing session found */
224 RDEBUG2("Continuing previous session found for user [%s]", username);
225
226 /* continue previous session */
227 switch (securid_session->securidSessionState) {
229 DEBUG2("Securid NEXT_CODE_REQUIRED_STATE: User [%s]", username);
230 /* next token code mode */
231
232 acm_ret = SD_Next(securid_session->sdiHandle, securid_pass);
233 if (acm_ret == ACM_OK) {
234 INFO("Next SecurID token accepted for [%s].", securid_session->identity);
235 rc = RC_SECURID_AUTH_SUCCESS;
236
237 } else {
238 INFO("SecurID: Next token rejected for [%s].", securid_session->identity);
239 rc = RC_SECURID_AUTH_FAILURE;
240 }
241
242 /* deallocate session */
243 securid_session_free(inst, request, securid_session);
244 return rc;
245
247 RDEBUG2("SecurID NEW_PIN_REQUIRED_STATE for %s",
248 username);
249
250 /* save the previous pin */
251 if (securid_session->pin) TALLOC_FREE(securid_session->pin);
252 securid_session->pin = talloc_typed_strdup(securid_session, passcode);
253
254 strlcpy(replyMsgBuffer, "\r\n Please re-enter new PIN:", replyMsgBufferSize);
255
256 /* set next state */
258
259 /* insert the updated session in the session list */
260 securid_sessionlist_add(inst, request, securid_session);
261 return RC_SECURID_AUTH_CHALLENGE;
262
264 RDEBUG2("SecurID NEW_PIN_USER_CONFIRM_STATE: User [%s]", username);
265 /* compare previous pin and current pin */
266 if (!securid_session->pin || strcmp(securid_session->pin, passcode)) {
267 RDEBUG2("Pin confirmation failed. Pins do not match [%s] and [%s]",
268 SAFE_STR(securid_session->pin), securid_pass);
269 /* pins do not match */
270
271 /* challenge the user again */
272 AceGetPinParams(securid_session->sdiHandle, &pin_params);
273 if (pin_params.Alphanumeric) {
274 strcpy(format, "alphanumeric characters");
275 } else {
276 strcpy(format, "digits");
277 }
278 snprintf(replyMsgBuffer, replyMsgBufferSize,
279 " \r\n Pins do not match--Please try again.\r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
280 pin_params.Min, pin_params.Max, format);
281
283
284 /* insert the updated session in the session list */
285 securid_sessionlist_add(inst, request, securid_session);
286 rc = RC_SECURID_AUTH_CHALLENGE;
287
288 } else {
289 /* pins match */
290 RDEBUG2("Pin confirmation succeeded. Pins match");
291 acm_ret = SD_Pin(securid_session->sdiHandle, securid_pass);
292 if (acm_ret == ACM_NEW_PIN_ACCEPTED) {
293 RDEBUG2("New SecurID pin accepted for %s.", securid_session->identity);
294
296
297 /* insert the updated session in the session list */
298 securid_sessionlist_add(inst, request, securid_session);
299
300 rc = RC_SECURID_AUTH_CHALLENGE;
301 strlcpy(replyMsgBuffer, " \r\n\r\nWait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
302 } else {
303 RDEBUG2("SecurID: New SecurID pin rejected for %s.", securid_session->identity);
304 SD_Pin(securid_session->sdiHandle, &empty_pin[0]); /* cancel PIN */
305
306
307 rc = RC_SECURID_AUTH_FAILURE;
308
309 /* deallocate session */
310 securid_session_free(inst, request, securid_session);
311 }
312 }
313 return rc;
315 acm_ret = SD_Check(securid_session->sdiHandle, securid_pass, securid_user);
316 if (acm_ret == ACM_OK) {
317 RDEBUG2("New SecurID passcode accepted for %s", securid_session->identity);
318 rc = RC_SECURID_AUTH_SUCCESS;
319
320 } else {
321 INFO("SecurID: New passcode rejected for [%s]", securid_session->identity);
322 rc = RC_SECURID_AUTH_FAILURE;
323 }
324
325 /* deallocate session */
326 securid_session_free(inst, request, securid_session);
327
328 return rc;
330 if (!strcmp(passcode, "y")) {
331 AceGetSystemPin(securid_session->sdiHandle, new_pin);
332
333 /* Save the PIN for the next session
334 * continuation */
335 if (securid_session->pin) TALLOC_FREE(securid_session->pin);
336 securid_session->pin = talloc_typed_strdup(securid_session, new_pin);
337
338 snprintf(replyMsgBuffer, replyMsgBufferSize,
339 "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
340 new_pin);
342
343 /* insert the updated session in the
344 * session list */
345 securid_sessionlist_add(inst, request, securid_session);
346
347 rc = RC_SECURID_AUTH_CHALLENGE;
348
349 } else {
350 SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN
351
352 /* deallocate session */
353 securid_session_free(inst, request, securid_session);
354 rc = RC_SECURID_AUTH_FAILURE;
355 }
356
357 return rc;
358
360 acm_ret = SD_Pin(securid_session->sdiHandle, (SD_CHAR*)securid_session->pin);
361 if (acm_ret == ACM_NEW_PIN_ACCEPTED) {
362 strlcpy(replyMsgBuffer, " \r\n\r\nPin Accepted. Wait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
364 /* insert the updated session in the session list */
365 securid_sessionlist_add(inst, request, securid_session);
366 rc = RC_SECURID_AUTH_CHALLENGE;
367
368 } else {
369 SD_Pin(securid_session->sdiHandle, &empty_pin[0]); //Cancel new PIN
370 strlcpy(replyMsgBuffer, " \r\n\r\nPin Rejected. Wait for the code on your card to change, then try again.\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
371 /* deallocate session */
372 securid_session_free(inst, request, securid_session);
373 rc = RC_SECURID_AUTH_FAILURE;
374 }
375
376 return rc;
377
378 /* USER_SELECTABLE state should be implemented to preserve compatibility with AM 6.x servers, which can return this state */
380 if (!strcmp(passcode, "y")) {
381 /* User has opted for a system-generated PIN */
382 AceGetSystemPin(securid_session->sdiHandle, new_pin);
383 snprintf(replyMsgBuffer, replyMsgBufferSize,
384 "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
385 new_pin);
387
388 /* insert the updated session in the session list */
390 securid_session);
391 rc = RC_SECURID_AUTH_CHALLENGE;
392
393 } else {
394 /* User has opted for a user-defined PIN */
395 AceGetPinParams(securid_session->sdiHandle,
396 &pin_params);
397 if (pin_params.Alphanumeric) {
398 strcpy(format, "alphanumeric characters");
399 } else {
400 strcpy(format, "digits");
401 }
402
403 snprintf(replyMsgBuffer, replyMsgBufferSize,
404 " \r\n Enter your new PIN of %d to %d %s, \r\n or\r\n <Ctrl-D> to cancel the New PIN procedure:",
405 pin_params.Min, pin_params.Max, format);
407
408 /* insert the updated session in the session list */
410 securid_session);
411 rc = RC_SECURID_AUTH_CHALLENGE;
412 }
413
414 return rc;
415
416 default:
417 ERROR("Invalid session state %d for user \"%s\"", securid_session->securidSessionState,
419 break;
420 }
421 }
422
423 return 0;
424
425}
426
427/******************************************/
429{
430 rlm_securid_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_securid_t);
431
432 /* delete session tree */
433 if (inst->session_tree) {
434 talloc_free(inst->session_tree);
435 inst->session_tree = NULL;
436 }
437
438 pthread_mutex_destroy(&(inst->session_mutex));
439
440 return 0;
441}
442
443
444static int mod_instantiate(module_inst_ctx_t const *mctx)
445{
446 rlm_securid_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_securid_t);
447
448 /*
449 * Lookup sessions in the tree. We don't free them in
450 * the tree, as that's taken care of elsewhere...
451 */
452 inst->session_tree = fr_rb_inline_talloc_alloc(NULL, SECURID_SESSION, node, securid_session_cmp, NULL);
453 if (!inst->session_tree) {
454 ERROR("Cannot initialize session tree");
455 return -1;
456 }
457
458 pthread_mutex_init(&(inst->session_mutex), NULL);
459 return 0;
460}
461
462
463/*
464 * Authenticate the user via one of any well-known password.
465 */
466static unlang_action_t CC_HINT(nonnull) mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
467{
468 int rcode;
470 char buffer[FR_MAX_STRING_LEN]="";
471 fr_pair_t *username, *password;
472 fr_pair_t *vp;
473
474 username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
475 password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
476
477 /*
478 * We can only authenticate user requests which HAVE
479 * a User-Name attribute.
480 */
481 if (!username) {
482 REDEBUG("Attribute \"User-Name\" is required for authentication");
484 }
485
486 if (!password) {
487 REDEBUG("Attribute \"User-Password\" is required for authentication");
489 }
490
491 /*
492 * The user MUST supply a non-zero-length password.
493 */
494 if (password->vp_length == 0) {
495 REDEBUG("Password should not be empty");
497 }
498
499 if (RDEBUG_ENABLED3) {
500 RDEBUG3("Login attempt with password \"%pV\"", &password->data);
501 } else {
502 RDEBUG2("Login attempt with password");
503 }
504
505 rcode = securidAuth(inst, request, username->vp_strvalue, password->vp_strvalue,
506 buffer, sizeof(buffer));
507
508 switch (rcode) {
509 case RC_SECURID_AUTH_SUCCESS:
510 rcode = RLM_MODULE_OK;
511 break;
512
513 case RC_SECURID_AUTH_CHALLENGE:
514 /* reply with Access-challenge message code (11) */
515
516 /* Generate Prompt attribute */
518 vp->vp_uint32 = 0; /* no echo */
519
520 /* Mark the packet as a Acceess-Challenge Packet */
521 request->reply->code = FR_RADIUS_CODE_ACCESS_CHALLENGE;
522 RDEBUG2("Sending Access-Challenge");
523 rcode = RLM_MODULE_HANDLED;
524 break;
525
526 case RC_SECURID_AUTH_FAILURE:
527 case RC_SECURID_AUTH_ACCESS_DENIED_FAILURE:
528 case RC_SECURID_AUTH_INVALID_SERVER_FAILURE:
529 default:
530 rcode = RLM_MODULE_REJECT;
531 break;
532 }
533
534 if (*buffer) {
537 }
538 RETURN_UNLANG_RCODE(rcode);
539}
540
541
542/*
543 * The module name should be the only globally exported symbol.
544 * That is, everything else should be 'static'.
545 *
546 * If the module needs to temporarily modify it's instantiation
547 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
548 * The server will then take care of ensuring that the module
549 * is single-threaded.
550 */
553 .common = {
554 .magic = MODULE_MAGIC_INIT,
555 .name = "securid",
556 .inst_size = sizeof(rlm_securid_t),
558 .instantiate = mod_instantiate,
559 .detach = mod_detach
560 },
561 .method_group = {
562 .bindings = (module_method_binding_t[]){
563 { .section = SECTION_NAME("authenticate", CF_IDENT_ANY), .method = mod_authenticate },
565 }
566 }
567};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
static int const char char buffer[256]
Definition acutest.h:578
strcpy(log_entry->msg, buffer)
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:660
#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:283
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:597
#define CF_IDENT_ANY
Definition cf_util.h:78
#define MEM(x)
Definition debug.h:36
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition defs.h:43
#define ERROR(fmt,...)
Definition dhcpclient.c:41
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:294
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:307
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:313
Specifies an attribute which must be present for the module to function.
Definition dict.h:293
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:306
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
talloc_free(hp)
int8_t fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
Definition inet.c:1347
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:347
#define RDEBUG3(fmt,...)
Definition log.h:355
#define RERROR(fmt,...)
Definition log.h:310
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
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
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
SECURID_SESSION * securid_sessionlist_find(rlm_securid_t *inst, request_t *request)
Definition mem.c:172
int securid_sessionlist_add(rlm_securid_t *inst, request_t *request, SECURID_SESSION *session)
Definition mem.c:83
SECURID_SESSION * securid_session_alloc(void)
Definition mem.c:32
void securid_session_free(UNUSED rlm_securid_t *inst, request_t *request, SECURID_SESSION *session)
Definition mem.c:42
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2645
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:703
static const conf_parser_t config[]
Definition base.c:172
#define fr_assert(_expr)
Definition rad_assert.h:38
static fr_dict_attr_t const * attr_user_password
static fr_dict_t const * dict_radius
static fr_dict_attr_t const * attr_user_name
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define DEBUG2(fmt,...)
Definition radclient.h:43
#define INFO(fmt,...)
Definition radict.c:64
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition rb.h:246
#define RETURN_UNLANG_INVALID
Definition rcode.h:62
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:57
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:45
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:43
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:46
static const conf_parser_t module_config[]
Definition rlm_always.c:59
static fr_dict_attr_t const * attr_reply_message
username
#define rlm_securid
Definition rlm_securid.c:27
static unlang_action_t mod_authenticate(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int mod_detach(module_detach_ctx_t *mctx)
static int mod_instantiate(module_inst_ctx_t const *mctx)
fr_ipaddr_t src_ipaddr
Definition rlm_securid.h:45
SDI_HANDLE sdiHandle
Definition rlm_securid.h:40
SECURID_SESSION_STATE securidSessionState
Definition rlm_securid.h:41
@ NEW_PIN_SYSTEM_CONFIRM_STATE
Definition rlm_securid.h:17
@ NEW_PIN_REQUIRED_STATE
Definition rlm_securid.h:13
@ NEW_PIN_USER_SELECT_STATE
Definition rlm_securid.h:18
@ NEW_PIN_AUTH_VALIDATE_STATE
Definition rlm_securid.h:15
@ NEW_PIN_SYSTEM_ACCEPT_STATE
Definition rlm_securid.h:16
@ NEXT_CODE_REQUIRED_STATE
Definition rlm_securid.h:12
@ NEW_PIN_USER_CONFIRM_STATE
Definition rlm_securid.h:14
HIDDEN fr_dict_attr_t const * attr_prompt
char state[SECURID_STATE_LEN]
Definition rlm_securid.h:43
#define SAFE_STR(s)
Definition rlm_securid.h:8
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:291
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition pair.h:129
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:467
#define talloc_get_type_abort_const
Definition talloc.h:245
#define FR_MAX_STRING_LEN
Definition value.h:30
int nonnull(2, 5))
int format(printf, 5, 0))