31 RCSID(
"$Id: 44bd3ec1ae93180b7510b4ecd5a42745cd01eb37 $")
33 #include <freeradius-devel/radiusd.h>
34 #include <freeradius-devel/modules.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>
80 static int pam_conv(
int num_msg,
struct pam_message
const **msg,
struct pam_response **resp,
void *appdata_ptr)
83 struct pam_response *reply;
90 #define COPY_STRING(s) ((s) ? strdup(s) : NULL)
92 reply =
rad_malloc(num_msg *
sizeof(
struct pam_response));
93 memset(reply, 0, num_msg *
sizeof(
struct pam_response));
94 for (count = 0; count < num_msg; count++) {
95 switch (msg[count]->msg_style) {
96 case PAM_PROMPT_ECHO_ON:
97 reply[count].resp_retcode = PAM_SUCCESS;
101 case PAM_PROMPT_ECHO_OFF:
102 reply[count].resp_retcode = PAM_SUCCESS;
107 RDEBUG2(
"%s", msg[count]->msg);
112 RERROR(
"PAM conversation failed");
114 for (count = 0; count < num_msg; count++) {
115 if (msg[count]->msg_style == PAM_ERROR_MSG)
RERROR(
"%s", msg[count]->msg);
116 if (reply[count].resp) {
118 memset(reply[count].resp, 0, strlen(reply[count].resp));
119 free(reply[count].resp);
123 pam_config->
error =
true;
147 static int do_pam(
REQUEST *request,
char const *username,
char const *passwd,
char const *pamauth)
149 pam_handle_t *handle = NULL;
158 conv.appdata_ptr = &pam_config;
162 pam_config.
error =
false;
164 RDEBUG2(
"Using pamauth string \"%s\" for pam.conf lookup", pamauth);
166 ret = pam_start(pamauth, username, &conv, &handle);
167 if (ret != PAM_SUCCESS) {
168 RERROR(
"pam_start failed: %s", pam_strerror(handle, ret));
172 ret = pam_authenticate(handle, 0);
173 if (ret != PAM_SUCCESS) {
174 RERROR(
"pam_authenticate failed: %s", pam_strerror(handle, ret));
175 pam_end(handle, ret);
183 #if !defined(__FreeBSD_version) || (__FreeBSD_version >= 400000)
184 ret = pam_acct_mgmt(handle, 0);
185 if (ret != PAM_SUCCESS) {
186 RERROR(
"pam_acct_mgmt failed: %s", pam_strerror(handle, ret));
187 pam_end(handle, ret);
191 RDEBUG2(
"Authentication succeeded");
192 pam_end(handle, ret);
208 if (!request->username) {
209 RAUTH(
"Attribute \"User-Name\" is required for authentication");
217 if (!request->password) {
218 RAUTH(
"Attribute \"User-Password\" is required for authentication");
226 if (request->password->da->attr != PW_USER_PASSWORD) {
227 RAUTH(
"Attribute \"User-Password\" is required for authentication. Cannot use \"%s\".", request->password->da->name);
236 if (pair) pam_auth_string = pair->vp_strvalue;
238 ret =
do_pam(request, request->username->vp_strvalue, request->password->vp_strvalue, pam_auth_string);
250 .config = module_config,
static const CONF_PARSER module_config[]
Main server configuration.
The module is OK, continue.
Metadata exported by the module.
static int do_pam(REQUEST *request, char const *username, char const *passwd, char const *pamauth)
Check the users password against the standard UNIX password table + PAM.
#define RLM_TYPE_THREAD_UNSAFE
Module is not threadsafe.
void * rad_malloc(size_t size)
#define CONF_PARSER_TERMINATOR
char const * username
Username to provide to PAM when prompted.
The module considers the request invalid.
char const * name
Name of the daemon, usually 'radiusd'.
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
Defines a CONF_PAIR to C data type mapping.
Immediately reject the request.
struct rlm_pam_t rlm_pam_t
Stores an attribute, a value and various bits of other data.
0 methods index for authenticate section.
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.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
char const * password
Password to provide to PAM when prompted.
uint64_t magic
Used to validate module struct.
#define FR_CONF_OFFSET(_n, _t, _s, _f)
REQUEST * request
The current request.
char const * pam_auth_name
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
static rlm_rcode_t CC_HINT(nonnull)
struct rlm_pam_data_t rlm_pam_data_t
String of printable characters.
bool error
True if pam_conv failed.