1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
-*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
Sections of this where taken/modified from mod_auth_path for Apache
*/
#include <drizzled/server_includes.h>
#include <drizzled/session.h>
#include <drizzled/plugin_authentication.h>
#include <security/pam_appl.h>
#ifndef __sun
#include <security/pam_misc.h>
#endif
typedef struct {
const char *name;
const char *password;
} auth_pam_userinfo;
static int auth_pam_talker(int num_msg,
#ifdef __sun
struct pam_message **msg,
#else
const struct pam_message **msg,
#endif
struct pam_response **resp,
void *appdata_ptr)
{
auth_pam_userinfo *userinfo = (auth_pam_userinfo*)appdata_ptr;
struct pam_response *response = 0;
int x;
/* parameter sanity checking */
if(!resp || !msg || !userinfo)
return PAM_CONV_ERR;
/* allocate memory to store response */
response= (struct pam_response*)malloc(num_msg * sizeof(struct pam_response));
if(!response)
return PAM_CONV_ERR;
/* copy values */
for(x= 0; x < num_msg; x++)
{
/* initialize to safe values */
response[x].resp_retcode= 0;
response[x].resp= 0;
/* select response based on requested output style */
switch(msg[x]->msg_style)
{
case PAM_PROMPT_ECHO_ON:
/* on memory allocation failure, auth fails */
response[x].resp = strdup(userinfo->name);
break;
case PAM_PROMPT_ECHO_OFF:
response[x].resp = strdup(userinfo->password);
break;
default:
if(response)
free(response);
return PAM_CONV_ERR;
}
}
/* everything okay, set PAM response values */
*resp = response;
return PAM_SUCCESS;
}
static bool authenticate(Session *session, const char *password)
{
int retval;
auth_pam_userinfo userinfo= { NULL, NULL };
struct pam_conv conv_info= { &auth_pam_talker, (void*)&userinfo };
pam_handle_t *pamh= NULL;
userinfo.name= session->security_ctx.user.c_str();
userinfo.password= password;
retval= pam_start("check_user", userinfo.name, &conv_info, &pamh);
if (retval == PAM_SUCCESS)
retval= pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK);
if (retval == PAM_SUCCESS)
retval= pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK);
pam_end(pamh, retval);
return (retval == PAM_SUCCESS) ? true: false;
}
static int initialize(void *p)
{
authentication_st *auth= (authentication_st *)p;
auth->authenticate= authenticate;
return 0;
}
static int finalize(void *p)
{
(void)p;
return 0;
}
mysql_declare_plugin(auth_pam)
{
DRIZZLE_AUTH_PLUGIN,
"pam",
"0.1",
"Brian Aker",
"PAM based authenication.",
PLUGIN_LICENSE_GPL,
initialize, /* Plugin Init */
finalize, /* Plugin Deinit */
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
|