nss-pam-ldapd commit: r1865 - in nss-pam-ldapd: . nslcd pam
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
nss-pam-ldapd commit: r1865 - in nss-pam-ldapd: . nslcd pam
- From: Commits of the nss-pam-ldapd project <nss-pam-ldapd-commits [at] lists.arthurdejong.org>
- To: nss-pam-ldapd-commits [at] lists.arthurdejong.org
- Reply-to: nss-pam-ldapd-users [at] lists.arthurdejong.org
- Subject: nss-pam-ldapd commit: r1865 - in nss-pam-ldapd: . nslcd pam
- Date: Sun, 16 Dec 2012 16:17:42 +0100 (CET)
Author: arthur
Date: Sun Dec 16 16:17:42 2012
New Revision: 1865
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?revision=1865&view=revision
Log:
change PAM protocol to be more consistent and simpler
Modified:
nss-pam-ldapd/nslcd.h
nss-pam-ldapd/nslcd/pam.c
nss-pam-ldapd/pam/common.h
nss-pam-ldapd/pam/pam.c
Modified: nss-pam-ldapd/nslcd.h
==============================================================================
--- nss-pam-ldapd/nslcd.h Sun Dec 16 16:11:59 2012 (r1864)
+++ nss-pam-ldapd/nslcd.h Sun Dec 16 16:17:42 2012 (r1865)
@@ -191,58 +191,58 @@
/* PAM-related requests. The request parameters for all these requests
begin with:
STRING user name
- STRING DN (if value is known already, otherwise empty)
STRING service name
- all requests, except the SESSION requests start the result value with:
- STRING user name (cannonical name)
- STRING DN (can be used to speed up requests)
- Some functions may return an authorisation message. This message, if
- supplied will be used by the PAM module instead of a message that is
- generated by the PAM module itself. */
+ STRING ruser
+ STRING rhost
+ STRING tty
+ If the user is not known in LDAP no result may be returned (immediately
+ return NSLCD_RESULT_END instead of a PAM error code). */
/* PAM authentication check request. The extra request values are:
STRING password
- and the result value ends with:
+ and the result value consists of:
INT32 authc NSLCD_PAM_* result code
+ STRING user name (the cannonical user name)
INT32 authz NSLCD_PAM_* result code
STRING authorisation error message
If the username is empty in this request an attempt is made to
- authenticate as the administrator (set using rootpwmoddn). The returned DN
- is that of the administrator. */
-#define NSLCD_ACTION_PAM_AUTHC 20001
-
-/* PAM authorisation check request. The extra request values are:
- STRING ruser
- STRING rhost
- STRING tty
- and the result value ends with:
+ authenticate as the administrator (set using rootpwmoddn).
+ Some authorisation checks are already done during authentication so the
+ response also includes authorisation information. */
+#define NSLCD_ACTION_PAM_AUTHC 21001
+
+/* PAM authorisation check request. The result value consists of:
INT32 authz NSLCD_PAM_* result code
- STRING authorisation error message */
-#define NSLCD_ACTION_PAM_AUTHZ 20002
+ STRING authorisation error message
+ The authentication check may have already returned some authorisation
+ information. The authorisation error message, if supplied, will be used
+ by the PAM module instead of a message that is generated by the PAM
+ module itself. */
+#define NSLCD_ACTION_PAM_AUTHZ 21002
+
+/* PAM session open request. The result value consists of:
+ STRING session id
+ This session id may be used to close this session with. */
+#define NSLCD_ACTION_PAM_SESS_O 21003
-/* PAM session open and close requests. These requests have the following
- extra request values:
- STRING tty
- STRING rhost
- STRING ruser
- INT32 session id (ignored for SESS_O)
- and these calls only return the session ID:
- INT32 session id
- The SESS_C must contain the ID that is retured by SESS_O to close the
- correct session. */
-#define NSLCD_ACTION_PAM_SESS_O 20003
-#define NSLCD_ACTION_PAM_SESS_C 20004
+/* PAM session close request. This request has the following
+ extra request value:
+ STRING session id
+ and this calls only returns an empty response value. */
+#define NSLCD_ACTION_PAM_SESS_C 21004
+
+/*
+Note: I'm not sure whether PAM result codes are required here.
+*/
/* PAM password modification request. This requests has the following extra
request values:
- STRING old password
- STRING new password
+ INT32 asroot: 0=oldpasswd is user passwd, 1=oldpasswd is root passwd
+ STRING old password
+ STRING new password
and returns there extra result values:
- INT32 authz NSLCD_PAM_* result code
- STRING authorisation error message
- In this request the DN may be set to the administrator's DN. In this
- case old password should be the administrator's password. This allows
- the administrator to change any user's password. */
+ INT32 NSLCD_PAM_* result code
+ STRING error message */
#define NSLCD_ACTION_PAM_PWMOD 20005
/* Request result codes. */
Modified: nss-pam-ldapd/nslcd/pam.c
==============================================================================
--- nss-pam-ldapd/nslcd/pam.c Sun Dec 16 16:11:59 2012 (r1864)
+++ nss-pam-ldapd/nslcd/pam.c Sun Dec 16 16:17:42 2012 (r1865)
@@ -244,8 +244,7 @@
{
int32_t tmpint32;
int rc;
- char username[256];
- char servicename[64];
+ char username[256],service[64],ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
char password[64];
const char *userdn;
MYLDAP_ENTRY *entry;
@@ -254,13 +253,15 @@
authzmsg[0]='\0';
/* read request parameters */
READ_STRING(fp,username);
- SKIP_STRING(fp); /* DN */
- READ_STRING(fp,servicename);
+ READ_STRING(fp,service);
+ READ_STRING(fp,ruser);
+ READ_STRING(fp,rhost);
+ READ_STRING(fp,tty);
READ_STRING(fp,password);
/* log call */
log_setrequest("authc=\"%s\"",username);
log_log(LOG_DEBUG,"nslcd_pam_authc(\"%s\",\"%s\",\"%s\")",
- username,servicename,*password?"***":"");
+ username,service,*password?"***":"");
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHC);
@@ -312,9 +313,8 @@
authzrc=check_shadow(session,username,authzmsg,sizeof(authzmsg),1,0);
/* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,userdn);
WRITE_INT32(fp,rc);
+ WRITE_STRING(fp,username);
WRITE_INT32(fp,authzrc);
WRITE_STRING(fp,authzmsg);
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -460,23 +460,20 @@
{
int32_t tmpint32;
int rc;
- char username[256];
- char servicename[64];
- char ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
+ char username[256],service[64],ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
MYLDAP_ENTRY *entry;
char authzmsg[1024];
authzmsg[0]='\0';
/* read request parameters */
READ_STRING(fp,username);
- SKIP_STRING(fp); /* DN */
- READ_STRING(fp,servicename);
+ READ_STRING(fp,service);
READ_STRING(fp,ruser);
READ_STRING(fp,rhost);
READ_STRING(fp,tty);
/* log call */
log_setrequest("authz=\"%s\"",username);
log_log(LOG_DEBUG,"nslcd_pam_authz(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")",
- username,servicename,ruser,rhost,tty);
+ username,service,ruser,rhost,tty);
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHZ);
@@ -492,12 +489,10 @@
return -1;
}
/* check authorisation search */
-
rc=try_autzsearch(session,myldap_get_dn(entry),username,servicename,ruser,rhost,tty);
+
rc=try_autzsearch(session,myldap_get_dn(entry),username,service,ruser,rhost,tty);
if (rc!=LDAP_SUCCESS)
{
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,"");
WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED);
WRITE_STRING(fp,"LDAP authorisation check failed");
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -507,8 +502,6 @@
rc=check_shadow(session,username,authzmsg,sizeof(authzmsg),0,0);
/* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,myldap_get_dn(entry));
WRITE_INT32(fp,rc);
WRITE_STRING(fp,authzmsg);
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -518,28 +511,32 @@
int nslcd_pam_sess_o(TFILE *fp,MYLDAP_SESSION *session)
{
int32_t tmpint32;
- char username[256];
- char servicename[64];
- char tty[64],rhost[HOST_NAME_MAX+1],ruser[256];
- int32_t sessionid;
+ char username[256],service[64],ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
+ char sessionid[25];
+ static const char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "01234567890";
+ int i;
/* read request parameters */
READ_STRING(fp,username);
- SKIP_STRING(fp); /* DN */
- READ_STRING(fp,servicename);
- READ_STRING(fp,tty);
- READ_STRING(fp,rhost);
+ READ_STRING(fp,service);
READ_STRING(fp,ruser);
- READ_INT32(fp,sessionid);
+ READ_STRING(fp,rhost);
+ READ_STRING(fp,tty);
+ /* generate pseudo-random session id */
+ for (i=0;i<(sizeof(sessionid)-1);i++)
+ sessionid[i]=alphabet[rand()%(sizeof(alphabet)-1)];
+ sessionid[i]='\0';
/* log call */
log_setrequest("sess_o=\"%s\"",username);
- log_log(LOG_DEBUG,"nslcd_pam_sess_o(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")",
- username,servicename,tty,rhost,ruser);
+ log_log(LOG_DEBUG,"nslcd_pam_sess_o(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"): %s",
+ username,service,tty,rhost,ruser,sessionid);
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_SESS_O);
/* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp,12345); /* session id */
+ WRITE_STRING(fp,sessionid);
WRITE_INT32(fp,NSLCD_RESULT_END);
return 0;
}
@@ -547,28 +544,24 @@
int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session)
{
int32_t tmpint32;
- char username[256];
- char servicename[64];
- char tty[64],rhost[HOST_NAME_MAX+1],ruser[256];
- int32_t sessionid;
+ char username[256],service[64],ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
+ char sessionid[64];
/* read request parameters */
READ_STRING(fp,username);
- SKIP_STRING(fp); /* DN */
- READ_STRING(fp,servicename);
- READ_STRING(fp,tty);
- READ_STRING(fp,rhost);
+ READ_STRING(fp,service);
READ_STRING(fp,ruser);
- READ_INT32(fp,sessionid);
+ READ_STRING(fp,rhost);
+ READ_STRING(fp,tty);
+ READ_STRING(fp,sessionid);
/* log call */
log_setrequest("sess_c=\"%s\"",username);
- log_log(LOG_DEBUG,"nslcd_pam_sess_c(\"%s\",\"%s\",%d)",
- username,servicename,(int)sessionid);
+ log_log(LOG_DEBUG,"nslcd_pam_sess_c(\"%s\",\"%s\",%s)",
+ username,service,sessionid);
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_SESS_C);
/* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp,0); /* session id */
WRITE_INT32(fp,NSLCD_RESULT_END);
return 0;
}
@@ -610,10 +603,8 @@
{
int32_t tmpint32;
int rc;
- char username[256];
- char userdn[256];
+ char username[256],service[64],ruser[256],rhost[HOST_NAME_MAX+1],tty[64];
int asroot;
- char servicename[64];
char oldpassword[64];
char newpassword[64];
const char *binddn=NULL; /* the user performing the modification */
@@ -622,16 +613,17 @@
authzmsg[0]='\0';
/* read request parameters */
READ_STRING(fp,username);
- READ_STRING(fp,userdn); /* we can't ignore userdn for now here because we
- need it to determine the modify-as-root case */
-
asroot=(nslcd_cfg->ldc_rootpwmoddn!=NULL)&&(strcmp(userdn,nslcd_cfg->ldc_rootpwmoddn)==0);
- READ_STRING(fp,servicename);
+ READ_STRING(fp,service);
+ READ_STRING(fp,ruser);
+ READ_STRING(fp,rhost);
+ READ_STRING(fp,tty);
+ READ_INT32(fp,asroot);
READ_STRING(fp,oldpassword);
READ_STRING(fp,newpassword);
/* log call */
log_setrequest("pwmod=\"%s\"",username);
log_log(LOG_DEBUG,"nslcd_pam_pwmod(\"%s\",%s,\"%s\",\"%s\",\"%s\")",
-
username,asroot?"asroot":"asuser",servicename,*oldpassword?"***":"",
+
username,asroot?"asroot":"asuser",service,*oldpassword?"***":"",
*newpassword?"***":"");
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
@@ -652,8 +644,6 @@
{
log_log(LOG_NOTICE,"password change prohibited");
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,"");
WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED);
WRITE_STRING(fp,nslcd_cfg->pam_password_prohibit_message);
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -682,8 +672,6 @@
if (rc!=NSLCD_PAM_SUCCESS)
{
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,"");
WRITE_INT32(fp,rc);
WRITE_STRING(fp,authzmsg);
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -696,8 +684,6 @@
{
mysnprintf(authzmsg,sizeof(authzmsg)-1,"password change failed:
%s",ldap_err2string(rc));
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,"");
WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED);
WRITE_STRING(fp,authzmsg);
WRITE_INT32(fp,NSLCD_RESULT_END);
@@ -706,8 +692,6 @@
/* write response */
log_log(LOG_NOTICE,"password changed for %s",myldap_get_dn(entry));
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_STRING(fp,username);
- WRITE_STRING(fp,myldap_get_dn(entry));
WRITE_INT32(fp,NSLCD_PAM_SUCCESS);
WRITE_STRING(fp,"");
WRITE_INT32(fp,NSLCD_RESULT_END);
Modified: nss-pam-ldapd/pam/common.h
==============================================================================
--- nss-pam-ldapd/pam/common.h Sun Dec 16 16:11:59 2012 (r1864)
+++ nss-pam-ldapd/pam/common.h Sun Dec 16 16:17:42 2012 (r1865)
@@ -76,9 +76,6 @@
#define PAM_REQUEST(action,debuglog,writefn,readfn) \
TFILE *fp; \
int32_t tmpint32; \
- char *buffer=ctx->buf; \
- size_t buflen=sizeof(ctx->buf); \
- size_t bufptr=0; \
if (cfg->debug) \
debuglog; \
/* open socket and write request */ \
Modified: nss-pam-ldapd/pam/pam.c
==============================================================================
--- nss-pam-ldapd/pam/pam.c Sun Dec 16 16:11:59 2012 (r1864)
+++ nss-pam-ldapd/pam/pam.c Sun Dec 16 16:17:42 2012 (r1865)
@@ -55,40 +55,41 @@
/* the name we store our context under */
#define PLD_CTX "PAM_LDAPD_CTX"
+/* structure that stores the results for an nslcd call */
+struct nslcd_resp {
+ int res;
+ char msg[1024];
+};
/* this struct represents the context that the PAM module keeps
between calls */
struct pld_ctx {
- char *user;
- char *dn;
- char *tmpluser;
- char *authzmsg;
+ char *username;
+ struct nslcd_resp saved_authz;
+ struct nslcd_resp saved_session;
+ int asroot;
char *oldpassword;
- int authok;
- int authz;
- int sessid;
- char buf[1024];
};
/* clear the context to all empty values */
static void ctx_clear(struct pld_ctx *ctx)
{
- if (ctx->user)
+ if (ctx->username)
{
- free(ctx->user);
- ctx->user=NULL;
+ free(ctx->username);
+ ctx->username=NULL;
}
+ ctx->saved_authz.res=PAM_SUCCESS;
+ memset(ctx->saved_authz.msg,0,sizeof(ctx->saved_authz.msg));
+ ctx->saved_session.res=PAM_SUCCESS;
+ memset(ctx->saved_session.msg,0,sizeof(ctx->saved_session.msg));
+ ctx->asroot=0;
if (ctx->oldpassword)
{
memset(ctx->oldpassword,0,strlen(ctx->oldpassword));
free(ctx->oldpassword);
ctx->oldpassword=NULL;
}
- ctx->dn=NULL;
- ctx->tmpluser=NULL;
- ctx->authzmsg=NULL;
- ctx->authok=0;
- ctx->authz=0;
}
/* free the context (this is installed as handler into PAM) */
@@ -109,7 +110,7 @@
if ((rc==PAM_SUCCESS)&&(ctx!=NULL))
{
/* if the user is different clear the context */
- if ((ctx->user!=NULL)&&(strcmp(ctx->user,username)!=0))
+ if ((ctx->username!=NULL)&&(strcmp(ctx->username,username)!=0))
ctx_clear(ctx);
}
else
@@ -131,6 +132,9 @@
return rc;
}
}
+ /* save the username in the context */
+ if (ctx->username==NULL)
+ ctx->username=strdup(username);
/* return the context */
*pctx=ctx;
return PAM_SUCCESS;
@@ -187,7 +191,8 @@
}
static int init(pam_handle_t *pamh,struct pld_cfg *cfg,struct pld_ctx **ctx,
- const char **username,const char **service)
+ const char **username,const char **service,const char **ruser,
+ const char **rhost,const char **tty)
{
int rc;
struct passwd *pwent;
@@ -225,6 +230,10 @@
pam_syslog(pamh,LOG_ERR,"failed to get service name:
%s",pam_strerror(pamh,rc));
return rc;
}
+ /* get more PAM information (ignore errors) */
+ pam_get_item(pamh,PAM_RUSER,(const void **)ruser);
+ pam_get_item(pamh,PAM_RHOST,(const void **)rhost);
+ pam_get_item(pamh,PAM_TTY,(const void **)tty);
return PAM_SUCCESS;
}
@@ -263,7 +272,7 @@
pam_syslog(pamh,LOG_DEBUG,"nslcd account check; user=%s",username),
/* write the request parameters */
WRITE_STRING(fp,username),
- /* read the result entry */
+ /* read the result entry (skip it completely) */
SKIP_STRING(fp); /* user name */
SKIP_STRING(fp); /* passwd entry */
SKIP(fp,sizeof(int32_t)); /* uid */
@@ -275,94 +284,125 @@
}
/* perform an authentication call over nslcd */
-static int nslcd_request_authc(pam_handle_t *pamh,struct pld_ctx *ctx,struct
pld_cfg *cfg,
+static int nslcd_request_authc(pam_handle_t *pamh,struct pld_cfg *cfg,
const char *username,const char *service,
- const char *passwd)
+ const char *ruser,const char *rhost,
+ const char *tty,const char *passwd,
+ struct nslcd_resp *authc_resp,
+ struct nslcd_resp *authz_resp)
{
PAM_REQUEST(NSLCD_ACTION_PAM_AUTHC,
/* log debug message */
pam_syslog(pamh,LOG_DEBUG,"nslcd authentication; user=%s",username),
/* write the request parameters */
WRITE_STRING(fp,username);
- WRITE_STRING(fp,ctx->dn);
WRITE_STRING(fp,service);
+ WRITE_STRING(fp,ruser);
+ WRITE_STRING(fp,rhost);
+ WRITE_STRING(fp,tty);
WRITE_STRING(fp,passwd),
/* read the result entry */
- READ_BUF_STRING(fp,ctx->tmpluser);
- READ_BUF_STRING(fp,ctx->dn);
- READ_PAM_CODE(fp,ctx->authok)
- READ_PAM_CODE(fp,ctx->authz)
- READ_BUF_STRING(fp,ctx->authzmsg);)
+ READ_PAM_CODE(fp,authc_resp->res);
+ READ_STRING(fp,authc_resp->msg); /* user name */
+ /* if we want the authorisation response, save it, otherwise skip it */
+ if (authz_resp!=NULL)
+ {
+ READ_PAM_CODE(fp,authz_resp->res);
+ READ_STRING(fp,authz_resp->msg);
+ }
+ else
+ {
+ SKIP(fp,sizeof(int32_t));
+ SKIP_STRING(fp);
+ })
}
/* perform an authorisation call over nslcd */
-static int nslcd_request_authz(pam_handle_t *pamh,struct pld_ctx *ctx,struct
pld_cfg *cfg,
+static int nslcd_request_authz(pam_handle_t *pamh,struct pld_cfg *cfg,
const char *username,const char *service,
const char *ruser,const char *rhost,
- const char *tty)
+ const char *tty,struct nslcd_resp *resp)
{
PAM_REQUEST(NSLCD_ACTION_PAM_AUTHZ,
/* log debug message */
pam_syslog(pamh,LOG_DEBUG,"nslcd authorisation; user=%s",username),
/* write the request parameters */
WRITE_STRING(fp,username);
- WRITE_STRING(fp,ctx->dn);
WRITE_STRING(fp,service);
WRITE_STRING(fp,ruser);
WRITE_STRING(fp,rhost);
WRITE_STRING(fp,tty),
/* read the result entry */
- READ_BUF_STRING(fp,ctx->tmpluser);
- READ_BUF_STRING(fp,ctx->dn);
- READ_PAM_CODE(fp,ctx->authz);
- READ_BUF_STRING(fp,ctx->authzmsg);)
+ READ_PAM_CODE(fp,resp->res);
+ READ_STRING(fp,resp->msg);)
}
-/* do a session nslcd request (open or close) */
-static int nslcd_request_sess(pam_handle_t *pamh,struct pld_ctx *ctx,struct
pld_cfg *cfg,int action,
- const char *username,const char *service,
- const char *tty,const char *rhost,
- const char *ruser)
+/* do a session open nslcd request */
+static int nslcd_request_sess_o(pam_handle_t *pamh,struct pld_cfg *cfg,
+ const char *username,const char *service,
+ const char *ruser,const char *rhost,
+ const char *tty,struct nslcd_resp *resp)
{
- PAM_REQUEST(action,
+ PAM_REQUEST(NSLCD_ACTION_PAM_SESS_O,
/* log debug message */
- pam_syslog(pamh,LOG_DEBUG,"nslcd session %s; user=%s",
- (action==NSLCD_ACTION_PAM_SESS_O)?"open":"close",username),
+ pam_syslog(pamh,LOG_DEBUG,"nslcd session open; user=%s",username),
/* write the request parameters */
WRITE_STRING(fp,username);
- WRITE_STRING(fp,ctx->dn);
WRITE_STRING(fp,service);
- WRITE_STRING(fp,tty);
- WRITE_STRING(fp,rhost);
WRITE_STRING(fp,ruser);
- WRITE_INT32(fp,ctx->sessid),
+ WRITE_STRING(fp,rhost);
+ WRITE_STRING(fp,tty),
/* read the result entry */
- READ_INT32(fp,ctx->sessid))
+ READ_STRING(fp,resp->msg))
+}
+
+/* do a session close nslcd request */
+static int nslcd_request_sess_c(pam_handle_t *pamh,struct pld_cfg *cfg,
+ const char *username,const char *service,
+ const char *ruser,const char *rhost,
+ const char *tty,const char *sessid)
+{
+ PAM_REQUEST(NSLCD_ACTION_PAM_SESS_C,
+ /* log debug message */
+ pam_syslog(pamh,LOG_DEBUG,"nslcd session close; user=%s",username),
+ /* write the request parameters */
+ WRITE_STRING(fp,username);
+ WRITE_STRING(fp,service);
+ WRITE_STRING(fp,ruser);
+ WRITE_STRING(fp,rhost);
+ WRITE_STRING(fp,tty);
+ WRITE_STRING(fp,sessid),
+ /* no result entry to read */;)
}
/* do a password modification nslcd call */
-static int nslcd_request_pwmod(pam_handle_t *pamh,struct pld_ctx *ctx,struct
pld_cfg *cfg,
+static int nslcd_request_pwmod(pam_handle_t *pamh,struct pld_cfg *cfg,
const char *username,const char *service,
- const char *oldpasswd,const char *newpasswd)
+ const char *ruser,const char *rhost,
+ const char *tty,
+ int asroot,
+ const char *oldpasswd,const char *newpasswd,
+ struct nslcd_resp *resp)
{
PAM_REQUEST(NSLCD_ACTION_PAM_PWMOD,
/* log debug message */
pam_syslog(pamh,LOG_DEBUG,"nslcd password modify; user=%s",username),
/* write the request parameters */
WRITE_STRING(fp,username);
- WRITE_STRING(fp,ctx->dn);
WRITE_STRING(fp,service);
+ WRITE_STRING(fp,ruser);
+ WRITE_STRING(fp,rhost);
+ WRITE_STRING(fp,tty);
+ WRITE_INT32(fp,asroot);
WRITE_STRING(fp,oldpasswd);
WRITE_STRING(fp,newpasswd),
/* read the result entry */
- READ_BUF_STRING(fp,ctx->tmpluser);
- READ_BUF_STRING(fp,ctx->dn);
- READ_PAM_CODE(fp,ctx->authz);
- READ_BUF_STRING(fp,ctx->authzmsg);)
+ READ_PAM_CODE(fp,resp->res);
+ READ_STRING(fp,resp->msg);)
}
-static int nslcd_request_config_get(pam_handle_t *pamh,struct pld_ctx
*ctx,struct pld_cfg *cfg,
- int cfgopt,char **value)
+static int nslcd_request_config_get(pam_handle_t *pamh,struct pld_cfg *cfg,
+ int cfgopt,struct nslcd_resp *resp)
{
PAM_REQUEST(NSLCD_ACTION_CONFIG_GET,
/* log debug message */
@@ -370,7 +410,7 @@
/* write the request parameter */
WRITE_INT32(fp,cfgopt),
/* read the result entry */
- READ_BUF_STRING(fp,*value);)
+ READ_STRING(fp,resp->msg);)
}
/* remap the return code based on the configuration */
@@ -390,27 +430,28 @@
struct pld_cfg cfg;
struct pld_ctx *ctx;
const char *username,*service;
- char *prohibit_message;
+ const char *ruser=NULL,*rhost=NULL,*tty=NULL;
char *passwd=NULL;
+ struct nslcd_resp resp;
/* set up configuration */
cfg_init(pamh,flags,argc,argv,&cfg);
- rc=init(pamh,&cfg,&ctx,&username,&service);
+ rc=init(pamh,&cfg,&ctx,&username,&service,&ruser,&rhost,&tty);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
/* if service is "passwd" and pwdmod is not allowed alert user */
if (!strcmp(service,"passwd"))
{
-
rc=nslcd_request_config_get(pamh,ctx,&cfg,NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE,&prohibit_message);
- if
((rc==PAM_SUCCESS)&&(prohibit_message!=NULL)&&(prohibit_message[0]!='\0'))
+
rc=nslcd_request_config_get(pamh,&cfg,NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE,&resp);
+ if ((rc==PAM_SUCCESS)&&(resp.msg!=NULL)&&(resp.msg[0]!='\0'))
{
/* we silently ignore errors to get the configuration option */
- pam_syslog(pamh,LOG_NOTICE,"password change prohibited: %s;
user=%s",prohibit_message,username);
+ pam_syslog(pamh,LOG_NOTICE,"password change prohibited: %s;
user=%s",resp.msg,username);
if (!cfg.no_warn)
- pam_error(pamh,"%s",prohibit_message);
+ pam_error(pamh,"%s",resp.msg);
return remap_pam_rc(PAM_PERM_DENIED,&cfg);
}
}
- /* get the password */
+ /* prompt the user for a password */
rc=pam_get_authtok(pamh,PAM_AUTHTOK,(const char **)&passwd,NULL);
if (rc!=PAM_SUCCESS)
{
@@ -425,30 +466,32 @@
return PAM_AUTH_ERR;
}
/* do the nslcd request */
- rc=nslcd_request_authc(pamh,ctx,&cfg,username,service,passwd);
+
rc=nslcd_request_authc(pamh,&cfg,username,service,ruser,rhost,tty,passwd,&resp,&(ctx->saved_authz));
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
/* check the authentication result */
- rc=ctx->authok;
- if (rc!=PAM_SUCCESS)
+ if (resp.res!=PAM_SUCCESS)
{
- pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",pam_strerror(pamh,rc),username);
- return remap_pam_rc(rc,&cfg);
+ pam_syslog(pamh,LOG_NOTICE,"%s;
user=%s",pam_strerror(pamh,resp.res),username);
+ return remap_pam_rc(resp.res,&cfg);
}
/* debug log */
if (cfg.debug)
pam_syslog(pamh,LOG_DEBUG,"authentication succeeded");
- /* save username */
- ctx->user=strdup(username);
/* if password change is required, save old password in context */
- if (ctx->authz==PAM_NEW_AUTHTOK_REQD)
+ if (resp.res==PAM_NEW_AUTHTOK_REQD)
ctx->oldpassword=strdup(passwd);
/* update caller's idea of the user name */
- if ( ctx->tmpluser && ctx->tmpluser[0] &&
(strcmp(ctx->tmpluser,username)!=0) )
+ if ((resp.msg[0]!='\0') && (strcmp(resp.msg,username)!=0))
{
- pam_syslog(pamh,LOG_INFO,"username changed from %s to %s",username,
- ctx->tmpluser);
- rc=pam_set_item(pamh,PAM_USER,ctx->tmpluser);
+ pam_syslog(pamh,LOG_INFO,"username changed from %s to
%s",username,resp.msg);
+ rc=pam_set_item(pamh,PAM_USER,resp.msg);
+ /* empty the username in the context to not loose our context */
+ if (ctx->username==NULL)
+ {
+ free(ctx->username);
+ ctx->username=NULL;
+ }
}
return rc;
}
@@ -466,104 +509,100 @@
{
int rc;
struct pld_cfg cfg;
- struct pld_ctx *ctx=NULL,ctx2;
+ struct pld_ctx *ctx;
const char *username,*service;
const char *ruser=NULL,*rhost=NULL,*tty=NULL;
+ struct nslcd_resp authz_resp;
+ const char *msg;
/* set up configuration */
cfg_init(pamh,flags,argc,argv,&cfg);
- rc=init(pamh,&cfg,&ctx,&username,&service);
+ rc=init(pamh,&cfg,&ctx,&username,&service,&ruser,&rhost,&tty);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
- /* get more PAM information */
- pam_get_item(pamh,PAM_RUSER,(const void **)&ruser);
- pam_get_item(pamh,PAM_RHOST,(const void **)&rhost);
- pam_get_item(pamh,PAM_TTY,(const void **)&tty);
- /* call the function with a copy of the context to be able to keep the
- original context */
- ctx2.dn=ctx->dn;
- ctx2.user=ctx->user;
/* do the nslcd request */
- rc=nslcd_request_authz(pamh,&ctx2,&cfg,username,service,ruser,rhost,tty);
+
rc=nslcd_request_authz(pamh,&cfg,username,service,ruser,rhost,tty,&authz_resp);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
- /* check the returned authorisation value */
- if (ctx2.authz!=PAM_SUCCESS)
+ /* check the returned authorisation value and the value from authentication
*/
+ if (authz_resp.res!=PAM_SUCCESS)
+ {
+ rc=authz_resp.res;
+ msg=authz_resp.msg;
+ }
+ else if (ctx->saved_authz.res!=PAM_SUCCESS)
+ {
+ rc=ctx->saved_authz.res;
+ msg=ctx->saved_authz.msg;
+ }
+ if (rc!=PAM_SUCCESS)
{
/* turn in to generic PAM error message if message is empty */
- if ((ctx2.authzmsg==NULL)||(ctx2.authzmsg[0]=='\0'))
+ if ((msg==NULL)||(msg[0]=='\0'))
{
- ctx2.authzmsg=(char *)pam_strerror(pamh,ctx2.authz);
- pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",ctx2.authzmsg,username);
+ msg=pam_strerror(pamh,rc);
+ pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",msg,username);
}
else
- pam_syslog(pamh,LOG_NOTICE,"%s; user=%s;
err=%s",ctx2.authzmsg,username,pam_strerror(pamh,rc));
- rc=remap_pam_rc(ctx2.authz,&cfg);
- if ((rc!=PAM_IGNORE)&&(!cfg.no_warn))
- pam_error(pamh,"%s",ctx2.authzmsg);
- return rc;
- }
- /* check the original authorisation check from authentication */
- if (ctx->authz!=PAM_SUCCESS)
- {
- if ((ctx->authzmsg==NULL)||(ctx->authzmsg[0]=='\0'))
- ctx->authzmsg=(char *)pam_strerror(pamh,ctx->authz);
- pam_syslog(pamh,LOG_NOTICE,"%s; user=%s",ctx->authzmsg,username);
- rc=remap_pam_rc(ctx->authz,&cfg);
+ pam_syslog(pamh,LOG_NOTICE,"%s; user=%s;
err=%s",msg,username,pam_strerror(pamh,rc));
+ rc=remap_pam_rc(rc,&cfg);
if ((rc!=PAM_IGNORE)&&(!cfg.no_warn))
- pam_error(pamh,"%s",ctx->authzmsg);
+ pam_error(pamh,"%s",msg);
return rc;
}
if (cfg.debug)
pam_syslog(pamh,LOG_DEBUG,"authorization succeeded");
/* present any informational messages to the user */
- if ((ctx2.authzmsg!=NULL)&&(ctx2.authzmsg[0]!='\0')&&(!cfg.no_warn))
- pam_info(pamh,"%s",ctx2.authzmsg);
- if ((ctx->authzmsg!=NULL)&&(ctx->authzmsg[0]!='\0')&&(!cfg.no_warn))
- pam_info(pamh,"%s",ctx->authzmsg);
+ if ((authz_resp.msg[0]!='\0')&&(!cfg.no_warn))
+ pam_info(pamh,"%s",authz_resp.msg);
+ if ((ctx->saved_authz.msg[0]!='\0')&&(!cfg.no_warn))
+ pam_info(pamh,"%s",ctx->saved_authz.msg);
return PAM_SUCCESS;
}
-/* PAM session open/close calls */
-static int pam_sm_session(pam_handle_t *pamh,int flags,int argc,
- const char **argv,int action)
+/* PAM session open call */
+int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc,const char
**argv)
{
int rc;
struct pld_cfg cfg;
struct pld_ctx *ctx;
const char *username,*service;
- const char *tty=NULL,*rhost=NULL,*ruser=NULL;
+ const char *ruser=NULL,*rhost=NULL,*tty=NULL;
/* set up configuration */
cfg_init(pamh,flags,argc,argv,&cfg);
- rc=init(pamh,&cfg,&ctx,&username,&service);
+ rc=init(pamh,&cfg,&ctx,&username,&service,&ruser,&rhost,&tty);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
- /* get more PAM information */
- pam_get_item(pamh,PAM_TTY,(const void **)&tty);
- pam_get_item(pamh,PAM_RHOST,(const void **)&rhost);
- pam_get_item(pamh,PAM_RUSER,(const void **)&ruser);
/* do the nslcd request */
- rc=nslcd_request_sess(pamh,ctx,&cfg,action,username,service,tty,rhost,ruser);
+
rc=nslcd_request_sess_o(pamh,&cfg,username,service,ruser,rhost,tty,&(ctx->saved_session));
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
/* debug log */
if (cfg.debug)
- pam_syslog(pamh,LOG_DEBUG,"session %s succeeded; session_id=%d",
- (action==NSLCD_ACTION_PAM_SESS_O)?"open":"close",ctx->sessid);
+ pam_syslog(pamh,LOG_DEBUG,"session open succeeded;
session_id=%s",ctx->saved_session.msg);
return PAM_SUCCESS;
}
-/* PAM session open call */
-int pam_sm_open_session(
- pam_handle_t *pamh,int flags,int argc,const char **argv)
-{
- return pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_O);
-}
-
/* PAM session close call */
-int pam_sm_close_session(
- pam_handle_t *pamh,int flags,int argc,const char **argv)
+int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc,const char
**argv)
{
- return pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_C);
+ int rc;
+ struct pld_cfg cfg;
+ struct pld_ctx *ctx;
+ const char *username,*service;
+ const char *ruser=NULL,*rhost=NULL,*tty=NULL;
+ /* set up configuration */
+ cfg_init(pamh,flags,argc,argv,&cfg);
+ rc=init(pamh,&cfg,&ctx,&username,&service,&ruser,&rhost,&tty);
+ if (rc!=PAM_SUCCESS)
+ return remap_pam_rc(rc,&cfg);
+ /* do the nslcd request */
+
rc=nslcd_request_sess_c(pamh,&cfg,username,service,ruser,rhost,tty,ctx->saved_session.msg);
+ if (rc!=PAM_SUCCESS)
+ return remap_pam_rc(rc,&cfg);
+ /* debug log */
+ if (cfg.debug)
+ pam_syslog(pamh,LOG_DEBUG,"session close succeeded;
session_id=%s",ctx->saved_session.msg);
+ return PAM_SUCCESS;
}
/* Change the password of the user. This function is first called with
@@ -577,37 +616,37 @@
struct pld_cfg cfg;
struct pld_ctx *ctx;
const char *username,*service;
+ const char *ruser=NULL,*rhost=NULL,*tty=NULL;
const char *oldpassword=NULL,*newpassword=NULL;
- char *prohibit_message;
struct passwd *pwent;
uid_t myuid;
+ struct nslcd_resp resp;
+ const char *msg;
/* set up configuration */
cfg_init(pamh,flags,argc,argv,&cfg);
- rc=init(pamh,&cfg,&ctx,&username,&service);
+ rc=init(pamh,&cfg,&ctx,&username,&service,&ruser,&rhost,&tty);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
/* check if password modification is allowed */
-
rc=nslcd_request_config_get(pamh,ctx,&cfg,NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE,&prohibit_message);
- if ((rc==PAM_SUCCESS)&&(prohibit_message!=NULL)&&(prohibit_message[0]!='\0'))
+
rc=nslcd_request_config_get(pamh,&cfg,NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE,&resp);
+ if ((rc==PAM_SUCCESS)&&(resp.msg!=NULL)&&(resp.msg[0]!='\0'))
{
/* we silently ignore errors to get the configuration option */
- pam_syslog(pamh,LOG_NOTICE,"password change prohibited: %s;
user=%s",prohibit_message,username);
+ pam_syslog(pamh,LOG_NOTICE,"password change prohibited: %s;
user=%s",resp.msg,username);
if (!cfg.no_warn)
- pam_error(pamh,"%s",prohibit_message);
+ pam_error(pamh,"%s",resp.msg);
return remap_pam_rc(PAM_PERM_DENIED,&cfg);
}
/* see if we are dealing with an LDAP user first */
- if (ctx->dn==NULL)
- {
- rc=nslcd_request_exists(pamh,ctx,&cfg,username);
- if (rc!=PAM_SUCCESS)
- return remap_pam_rc(rc,&cfg);
- }
- /* prelimenary check, just see if we can connect to the LDAP server
- and authenticate with the current password */
+ rc=nslcd_request_exists(pamh,ctx,&cfg,username);
+ if (rc!=PAM_SUCCESS)
+ return remap_pam_rc(rc,&cfg);
+ /* preliminary check, just see if we can authenticate with the current
password */
if (flags&PAM_PRELIM_CHECK)
{
+ ctx->asroot=0;
/* see if the user is trying to modify another user's password */
+ /* TODO: perhaps this can be combined with the nslcd_request_exists() call
above */
pwent=pam_modutil_getpwnam(args->pamh,username);
myuid=getuid();
if
((pwent!=NULL)&&(pwent->pw_uid!=myuid)&&(!(flags&PAM_CHANGE_EXPIRED_AUTHTOK)))
@@ -616,15 +655,19 @@
user's password without the admin password */
if (myuid==0)
{
- rc=nslcd_request_authc(pamh,ctx,&cfg,"",service,"");
- if ((rc==PAM_SUCCESS)&&(ctx->authok==PAM_SUCCESS))
+
rc=nslcd_request_authc(pamh,&cfg,"",service,ruser,rhost,tty,"",&resp,NULL);
+ if ((rc==PAM_SUCCESS)&&(resp.res==PAM_SUCCESS))
+ {
+ ctx->asroot=1;
return pam_set_item(pamh,PAM_OLDAUTHTOK,"");
+ }
}
/* try to authenticate with the LDAP administrator password by passing
an empty username to the authc request */
rc=pam_get_authtok(pamh,PAM_OLDAUTHTOK,&oldpassword,"LDAP administrator
password: ");
if (rc!=PAM_SUCCESS)
return rc;
+ ctx->asroot=1;
username="";
}
else if ((ctx->oldpassword!=NULL)&&(*ctx->oldpassword!='\0'))
@@ -633,6 +676,7 @@
oldpassword=ctx->oldpassword;
else
{
+ /* prompt the user for a password if needed */
rc=pam_get_authtok(pamh,PAM_OLDAUTHTOK,(const char
**)&oldpassword,"(current) LDAP Password: ");
if (rc!=PAM_SUCCESS)
return rc;
@@ -645,46 +689,49 @@
return PAM_AUTH_ERR;
}
/* try authenticating */
- rc=nslcd_request_authc(pamh,ctx,&cfg,username,service,oldpassword);
+
rc=nslcd_request_authc(pamh,&cfg,username,service,ruser,rhost,tty,oldpassword,&resp,NULL);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
/* handle authentication result */
- if (ctx->authok!=PAM_SUCCESS)
- pam_syslog(pamh,LOG_NOTICE,"%s;
user=%s",pam_strerror(pamh,ctx->authok),username);
+ if (resp.res!=PAM_SUCCESS)
+ pam_syslog(pamh,LOG_NOTICE,"%s;
user=%s",pam_strerror(pamh,resp.res),username);
else if (cfg.debug)
pam_syslog(pamh,LOG_DEBUG,"authentication succeeded");
/* store password (needed if oldpassword was retreived from context) */
- if (ctx->authok==PAM_SUCCESS)
+ if (resp.res==PAM_SUCCESS)
{
rc=pam_set_item(pamh,PAM_OLDAUTHTOK,oldpassword);
if (rc!=PAM_SUCCESS)
return remap_pam_rc(rc,&cfg);
}
/* remap error code */
- return remap_pam_rc(ctx->authok,&cfg);
+ return remap_pam_rc(resp.res,&cfg);
}
/* get the old password (from the previous call) */
rc=pam_get_item(pamh,PAM_OLDAUTHTOK,(const void **)&oldpassword);
if (rc!=PAM_SUCCESS)
return rc;
- /* get the new password */
+ /* prompt for new password */
rc=pam_get_authtok(pamh,PAM_AUTHTOK,&newpassword,NULL);
if (rc!=PAM_SUCCESS)
return rc;
/* perform the password modification */
-
rc=nslcd_request_pwmod(pamh,ctx,&cfg,username,service,oldpassword,newpassword);
- if (rc==PAM_SUCCESS)
- rc=ctx->authz;
+
rc=nslcd_request_pwmod(pamh,&cfg,username,service,ruser,rhost,tty,ctx->asroot,oldpassword,newpassword,&resp);
+ if (rc!=PAM_SUCCESS)
+ msg=pam_strerror(pamh,rc);
else
- ctx->authzmsg=(char *)pam_strerror(pamh,rc);
+ {
+ rc=resp.res;
+ msg=resp.msg;
+ }
/* remap error code */
rc=remap_pam_rc(rc,&cfg);
/* check the returned value */
if (rc!=PAM_SUCCESS)
{
- pam_syslog(pamh,LOG_NOTICE,"password change failed: %s;
user=%s",ctx->authzmsg,username);
+ pam_syslog(pamh,LOG_NOTICE,"password change failed: %s;
user=%s",msg,username);
if ((rc!=PAM_IGNORE)&&(!cfg.no_warn))
- pam_error(pamh,"%s",ctx->authzmsg);
+ pam_error(pamh,"%s",msg);
return rc;
}
pam_syslog(pamh,LOG_NOTICE,"password changed for %s",username);
--
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits/
- nss-pam-ldapd commit: r1865 - in nss-pam-ldapd: . nslcd pam,
Commits of the nss-pam-ldapd project