31 RCSID(
"$Id: 9686d20a9d38e616f127d4abdf342911220b08ea $")
33 #include <freeradius-devel/server/base.h>
34 #include <freeradius-devel/server/module_rlm.h>
38 #ifdef HAVE_SECURITY_PAM_APPL_H
39 # include <security/pam_appl.h>
42 #ifdef HAVE_PAM_PAM_APPL_H
43 # include <pam/pam_appl.h>
102 static int pam_conv(
int num_msg,
struct pam_message
const **
msg,
struct pam_response **resp,
void *appdata_ptr)
105 struct pam_response *reply;
111 #define COPY_STRING(s) ((s) ? talloc_strdup(reply, s) : NULL)
112 MEM(reply = talloc_zero_array(NULL,
struct pam_response, num_msg));
115 case PAM_PROMPT_ECHO_ON:
116 reply[
count].resp_retcode = PAM_SUCCESS;
120 case PAM_PROMPT_ECHO_OFF:
121 reply[
count].resp_retcode = PAM_SUCCESS;
131 RERROR(
"PAM conversation failed");
135 if (reply[
count].resp) {
137 memset(reply[
count].resp, 0, strlen(reply[
count].resp));
141 pam_config->
error =
true;
167 pam_handle_t *handle = NULL;
176 conv.appdata_ptr = &pam_config;
180 pam_config.
error =
false;
182 RDEBUG2(
"Using pamauth string \"%s\" for pam.conf lookup", pamauth);
184 ret = pam_start(pamauth,
username, &conv, &handle);
185 if (ret != PAM_SUCCESS) {
186 RERROR(
"pam_start failed: %s", pam_strerror(handle, ret));
190 ret = pam_authenticate(handle, 0);
191 if (ret != PAM_SUCCESS) {
192 RERROR(
"pam_authenticate failed: %s", pam_strerror(handle, ret));
193 pam_end(handle, ret);
201 #if !defined(__FreeBSD_version) || (__FreeBSD_version >= 400000)
202 ret = pam_acct_mgmt(handle, 0);
203 if (ret != PAM_SUCCESS) {
204 RERROR(
"pam_acct_mgmt failed: %s", pam_strerror(handle, ret));
205 pam_end(handle, ret);
209 RDEBUG2(
"Authentication succeeded");
210 pam_end(handle, ret);
220 char const *pam_auth_string =
data->pam_auth_name;
231 REDEBUG(
"Attribute \"User-Name\" is required for authentication");
236 REDEBUG(
"Attribute \"User-Password\" is required for authentication");
243 if (password->vp_length == 0) {
244 REDEBUG(
"User-Password must not be empty");
252 RDEBUG(
"Login attempt with password \"%pV\"", &password->data);
254 RDEBUG2(
"Login attempt with password");
262 if (pair) pam_auth_string = pair->vp_strvalue;
264 ret =
do_pam(request,
username->vp_strvalue, password->vp_strvalue, pam_auth_string);
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define CONF_PARSER_TERMINATOR
#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
Defines a CONF_PAIR to C data type mapping.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
main_config_t const * main_config
Main server configuration.
char const * name
Name of the daemon, usually 'radiusd'.
@ FR_TYPE_STRING
String of printable characters.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
module_t common
Common fields presented by all modules.
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.
static const conf_parser_t config[]
#define RETURN_MODULE_REJECT
#define RETURN_MODULE_INVALID
rlm_rcode_t
Return codes indicating the result of the module call.
static fr_dict_attr_t const * attr_user_password
char const * password
Password to provide to PAM when prompted.
fr_dict_autoload_t rlm_pam_dict[]
fr_dict_attr_autoload_t rlm_pam_dict_attr[]
static fr_dict_attr_t const * attr_pam_auth
static fr_dict_t const * dict_freeradius
static fr_dict_t const * dict_radius
static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int pam_conv(int num_msg, struct pam_message const **msg, struct pam_response **resp, void *appdata_ptr)
Dialogue between RADIUS and PAM modules.
bool error
True if pam_conv failed.
char const * username
Username to provide to PAM when prompted.
request_t * request
The current request.
char const * pam_auth_name
static fr_dict_attr_t const * attr_user_name
static int do_pam(request_t *request, char const *username, char const *passwd, char const *pamauth)
Check the users password against the standard UNIX password table + PAM.
static const conf_parser_t module_config[]
static int mod_instantiate(module_inst_ctx_t const *mctx)
static int instantiate(module_inst_ctx_t const *mctx)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
#define talloc_get_type_abort_const