00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "wvlog.h"
00013
#include "wvpam.h"
00014
#include "wvautoconf.h"
00015
00016
00017
#ifndef HAVE_SECURITY_PAM_APPL_H
00018
00019
WvPamStream::WvPamStream(
WvStream *cloned,
WvStringParm name,
WvStringParm
00020 success,
WvStringParm fail) :
00021
WvStreamClone(cloned)
00022 {
00023
WvLog log(
"WvPamStream", WvLog::Warning);
00024
log(
"Compiled without PAM support\n");
00025
if (cloned && !!fail)
00026 cloned->
write(fail.
cstr(), fail.
len());
00027 }
00028
00029
WvPamStream::~WvPamStream()
00030 {
00031 }
00032
00033
bool WvPamStream::isok()
const
00034
{
00035
return false;
00036 }
00037
00038
bool WvPamStream::check_pam_status(
WvStringParm step)
00039 {
00040
return false;
00041 }
00042
00043
WvString WvPamStream::getuser()
const
00044
{
00045
return WvString::null;
00046 }
00047
00048
void WvPamStream::getgroups(
WvStringList &l)
const
00049
{
00050 }
00051
00052
#else // HAVE_SECURITY_PAM_APPL_H
00053
00054
#include <security/pam_appl.h>
00055
#include <sys/types.h>
00056
#include <pwd.h>
00057
#include <grp.h>
00058
00059
#include "wvaddr.h"
00060
00061
00062
class WvPamData
00063 {
00064
public:
00065 pam_handle_t *pamh;
00066
int status;
00067
WvStringParm failmsg;
00068
WvString user;
00069
WvStringList groups;
00070
00071 WvPamData(
WvStringParm _failmsg) :
00072 pamh(NULL), status(PAM_SUCCESS), failmsg(_failmsg)
00073 { }
00074 };
00075
00076
00077
00078 int noconv(
int num_msg,
const struct pam_message **msgm,
00079
struct pam_response **response,
void *userdata)
00080 {
00081
00082
return PAM_CONV_ERR;
00083 }
00084
00085
00086
00087
00088
00089 WvPamStream::WvPamStream(
WvStream *cloned,
WvStringParm name,
00090
WvStringParm successmsg,
WvStringParm failmsg) :
00091
WvStreamClone(cloned),
00092 d(new WvPamData(failmsg))
00093 {
00094
00095
struct pam_conv c;
00096 c.conv =
noconv;
00097 c.appdata_ptr = NULL;
00098
00099
00100
struct passwd *pw = getpwuid(getuid());
00101 assert(pw);
00102 d->user = pw->pw_name;
00103
00104
00105
WvString rhost(*
src());
00106
00107
00108 d->status = pam_start(name, d->user, &c, &d->pamh);
00109
if (!check_pam_status(
"startup"))
return;
00110
00111 d->status = pam_set_item(d->pamh, PAM_RHOST, rhost);
00112
if (!check_pam_status(
"environment setup"))
return;
00113
00114 d->status = pam_authenticate(d->pamh, PAM_DISALLOW_NULL_AUTHTOK);
00115
if (!check_pam_status(
"authentication"))
return;
00116
00117 d->status = pam_setcred(d->pamh, PAM_ESTABLISH_CRED);
00118
if (!check_pam_status(
"credentials"))
return;
00119
00120 d->status = pam_open_session(d->pamh, 0);
00121
if (!check_pam_status(
"session open"))
return;
00122
00123
00124
if (cloned && !!successmsg) cloned->
write(successmsg.
cstr(), successmsg.
len());
00125
00126
00127 setgrent();
00128
struct group *gr;
00129
while ((gr = getgrent()))
00130 {
00131
for (
char **i = gr->gr_mem; *i != NULL; i++)
00132 {
00133
if (strcmp(*i, d->user))
00134 {
00135 d->groups.append(
new WvString(gr->gr_name),
true);
00136
break;
00137 }
00138 }
00139 }
00140 endgrent();
00141 }
00142
00143
00144 WvPamStream::~WvPamStream()
00145 {
00146
if (d->status == PAM_SUCCESS)
00147 pam_close_session(d->pamh, 0);
00148 pam_end(d->pamh, d->status);
00149 }
00150
00151
00152 bool WvPamStream::isok()
const
00153
{
00154
return (d->status == PAM_SUCCESS &&
WvStreamClone::isok());
00155 }
00156
00157
00158
bool WvPamStream::check_pam_status(
WvStringParm s)
00159 {
00160
WvLog log(
"WvPamStream", WvLog::Debug2);
00161
if (d->status == PAM_SUCCESS)
00162 {
00163
log(
"PAM %s succeeded\n", s);
00164
return true;
00165 }
00166
else
00167 {
00168
log(
"PAM %s FAILED: %s\n", s, d->status);
00169
if (
cloned && !!d->failmsg)
cloned->
write(d->failmsg.cstr(), d->failmsg.len());
00170 d->user =
WvString::null;
00171 d->groups.zap();
00172
return false;
00173 }
00174 }
00175
00176
00177 WvString WvPamStream::getuser()
const
00178
{
00179
return d->user;
00180 }
00181
00182
00183 void WvPamStream::getgroups(
WvStringList &l)
const
00184
{
00185 assert(l.isempty());
00186 WvStringList::Iter i(d->groups);
00187
for (i.rewind(); i.next(); )
00188 l.append(
new WvString(*i),
true);
00189 }
00190
00191
00192
#endif // HAVE_SECURITY_PAM_APPL_H