* - -648 Password expired
*
*/
-int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, fr_pair_t *password)
+int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, winbind_auth_call_env_t *env)
{
- int ret = -1;
- struct wbcContext *wb_ctx;
- struct wbcAuthUserParams authparams;
- wbcErr err;
- int len;
- struct wbcAuthUserInfo *info = NULL;
- struct wbcAuthErrorInfo *error = NULL;
- char user_name_buf[500];
- char domain_name_buf[500];
+ int ret = -1;
+ struct wbcContext *wb_ctx;
+ struct wbcAuthUserParams authparams;
+ wbcErr err;
+ struct wbcAuthUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *error = NULL;
/*
* Clear the auth parameters - this is important, as
memset(&authparams, 0, sizeof(authparams));
/*
- * wb_username must be set for this function to be called
+ * username must be set for this function to be called
*/
- fr_assert(inst->wb_username);
+ fr_assert(env->username.type == FR_TYPE_STRING);
- /*
- * Get the username and domain from the configuration
- */
- len = tmpl_expand(&authparams.account_name, user_name_buf, sizeof(user_name_buf),
- request, inst->wb_username, NULL, NULL);
- if (len < 0) {
- REDEBUG2("Unable to expand winbind_username");
- goto done;
- }
+ authparams.account_name = env->username.vb_strvalue;
- if (inst->wb_domain) {
- len = tmpl_expand(&authparams.domain_name, domain_name_buf, sizeof(domain_name_buf),
- request, inst->wb_domain, NULL, NULL);
- if (len < 0) {
- REDEBUG2("Unable to expand winbind_domain");
- goto done;
- }
+ if (env->domain.type == FR_TYPE_STRING) {
+ authparams.domain_name = env->domain.vb_strvalue;
} else {
RWDEBUG2("No domain specified; authentication may fail because of this");
}
* Build the wbcAuthUserParams structure with what we know
*/
authparams.level = WBC_AUTH_USER_LEVEL_PLAIN;
- authparams.password.plaintext = password->data.vb_strvalue;
+ authparams.password.plaintext = env->password.vb_strvalue;
/*
* Parameters documented as part of the MSV1_0_SUBAUTH_LOGON structure
};
static const conf_parser_t module_config[] = {
- { FR_CONF_OFFSET("username", rlm_winbind_t, wb_username) },
{ FR_CONF_OFFSET("domain", rlm_winbind_t, wb_domain) },
{ FR_CONF_POINTER("group", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) group_config },
CONF_PARSER_TERMINATOR
struct wbcInterfaceDetails *wb_info = NULL;
CONF_SECTION *conf = mctx->inst->conf;
- if (!inst->wb_username) {
- cf_log_err(conf, "winbind_username must be defined to use rlm_winbind");
- return -1;
- }
-
inst->wb_pool = module_rlm_connection_pool_init(conf, inst, mod_conn_create, NULL, NULL, NULL, NULL);
if (!inst->wb_pool) {
cf_log_err(conf, "Unable to initialise winbind connection pool");
static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
{
rlm_winbind_t const *inst = talloc_get_type_abort_const(mctx->inst->data, rlm_winbind_t);
- fr_pair_t *username, *password;
-
- username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
- password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
-
- /*
- * We can only authenticate user requests which HAVE
- * a User-Name attribute.
- */
- if (!username) {
- REDEBUG("Attribute \"User-Name\" is required for authentication");
- RETURN_MODULE_INVALID;
- }
-
- if (!password) {
- REDEBUG("Attribute \"User-Password\" is required for authentication");
- RETURN_MODULE_INVALID;
- }
+ winbind_auth_call_env_t *env = talloc_get_type_abort(mctx->env_data, winbind_auth_call_env_t);
/*
* Make sure the supplied password isn't empty
*/
- if (password->vp_length == 0) {
+ if (env->password.vb_length == 0) {
REDEBUG("User-Password must not be empty");
RETURN_MODULE_INVALID;
}
* Log the password
*/
if (RDEBUG_ENABLED3) {
- RDEBUG("Login attempt with password \"%pV\"", &password->data);
+ RDEBUG("Login attempt with password \"%pV\"", &env->password);
} else {
RDEBUG2("Login attempt with password");
}
* many debug outputs or errors as the auth function is
* chatty enough.
*/
- if (do_auth_wbclient_pap(inst, request, password) == 0) {
+ if (do_auth_wbclient_pap(inst, request, env) == 0) {
REDEBUG2("User authenticated successfully using winbind");
RETURN_MODULE_OK;
}
RETURN_MODULE_REJECT;
}
+static const call_env_method_t winbind_auth_method_env = {
+ FR_CALL_ENV_METHOD_OUT(winbind_auth_call_env_t),
+ .env = (call_env_parser_t[]) {
+ { FR_CALL_ENV_OFFSET("username", FR_TYPE_STRING, CALL_ENV_FLAG_REQUIRED, winbind_auth_call_env_t, username) },
+ { FR_CALL_ENV_OFFSET("domain", FR_TYPE_STRING, CALL_ENV_FLAG_NONE, winbind_auth_call_env_t, domain) },
+ { FR_CALL_ENV_OFFSET("password", FR_TYPE_STRING, CALL_ENV_FLAG_SECRET, winbind_auth_call_env_t, password),
+ .pair.dflt = "&User-Password", .pair.dflt_quote = T_BARE_WORD },
+ CALL_ENV_TERMINATOR
+ }
+};
/*
* The module name should be the only globally exported symbol.
},
.method_names = (module_method_name_t[]){
{ .name1 = "recv", .name2 = CF_IDENT_ANY, .method = mod_authorize },
- { .name1 = "authenticate", .name2 = CF_IDENT_ANY, .method = mod_authenticate },
+ { .name1 = "authenticate", .name2 = CF_IDENT_ANY, .method = mod_authenticate,
+ .method_env = &winbind_auth_method_env },
MODULE_NAME_TERMINATOR
}
};