diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2010-05-12 23:12:23 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2010-05-12 23:12:23 +0200 |
commit | 0fed448ec247e5092c45d226cc28f411816c64a8 (patch) | |
tree | b40a2317e4014714351fefec20d18bbd9c87f8ae /pam | |
parent | c889fdb76089f9c6abff1269d1051c874e275547 (diff) |
make parsing configuration options global, reorganise a bit and make code more consistent and easier to read
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1101 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'pam')
-rw-r--r-- | pam/pam.c | 501 |
1 files changed, 231 insertions, 270 deletions
@@ -30,16 +30,16 @@ #include <sys/types.h> #include <pwd.h> -#include "common.h" -#include "compat/attrs.h" -#include "compat/pam_compat.h" - /* these are defined (before including pam_modules.h) for staticly linking */ #define PAM_SM_AUTH #define PAM_SM_ACCOUNT #define PAM_SM_SESSION #define PAM_SM_PASSWORD +#include "common.h" +#include "compat/attrs.h" +#include "compat/pam_compat.h" + #ifdef HAVE_SECURITY_PAM_APPL_H #include <security/pam_appl.h> #endif /* HAVE_SECURITY_PAM_APPL_H */ @@ -52,13 +52,7 @@ #include <pam/pam_modules.h> #endif /* not HAVE_PAM_PAM_MODULES_H */ -#define IGNORE_UNKNOWN 1 -#define IGNORE_UNAVAIL 2 - -#define USE_FIRST 1 -#define TRY_FIRST 2 -#define USE_TOKEN 4 - +/* the name we store our context under */ #define PLD_CTX "PAM_LDAPD_CTX" /* some systems don't have LOG_AUTHPRIV */ @@ -66,9 +60,10 @@ #define LOG_AUTHPRIV LOG_AUTH #endif /* not LOG_AUTHPRIV */ -/* this struct represents that context that the PAM module keeps + +/* this struct represents the context that the PAM module keeps between calls */ -typedef struct pld_ctx { +struct pld_ctx { char *user; char *dn; char *tmpluser; @@ -78,32 +73,10 @@ typedef struct pld_ctx { int authz; int sessid; char buf[1024]; -} pld_ctx; - -/* map a NSLCD PAM status code to a PAM status code */ -static int nslcd2pam_rc(int rc) -{ -#define map(i) case NSLCD_##i: return i; - switch(rc) { - map(PAM_SUCCESS); - map(PAM_PERM_DENIED); - map(PAM_AUTH_ERR); - map(PAM_CRED_INSUFFICIENT); - map(PAM_AUTHINFO_UNAVAIL); - map(PAM_USER_UNKNOWN); - map(PAM_MAXTRIES); - map(PAM_NEW_AUTHTOK_REQD); - map(PAM_ACCT_EXPIRED); - map(PAM_SESSION_ERR); - map(PAM_AUTHTOK_DISABLE_AGING); - map(PAM_IGNORE); - map(PAM_ABORT); - default: return PAM_ABORT; - } -} +}; /* clear the context to all empty values */ -static void ctx_clear(pld_ctx *ctx) +static void ctx_clear(struct pld_ctx *ctx) { if (ctx->user) { @@ -126,15 +99,15 @@ static void ctx_clear(pld_ctx *ctx) /* free the context (this is installed as handler into PAM) */ static void ctx_free(pam_handle_t *UNUSED(pamh),void *data,int UNUSED(err)) { - pld_ctx *ctx=data; + struct pld_ctx *ctx=data; ctx_clear(ctx); free(ctx); } /* try to get the module's context, returns a PAM status code */ -static int ctx_get(pam_handle_t *pamh,const char *username,pld_ctx **pctx) +static int ctx_get(pam_handle_t *pamh,const char *username,struct pld_ctx **pctx) { - pld_ctx *ctx=NULL; + struct pld_ctx *ctx=NULL; int rc; /* try to get the context from PAM */ rc=pam_get_data(pamh, PLD_CTX,(const void **)&ctx); @@ -147,21 +120,76 @@ static int ctx_get(pam_handle_t *pamh,const char *username,pld_ctx **pctx) else { /* allocate a new context */ - ctx=calloc(1,sizeof(*ctx)); - ctx_clear(ctx); - if (!ctx) + ctx=calloc(1,sizeof(struct pld_ctx)); + if (ctx==NULL) return PAM_BUF_ERR; + ctx_clear(ctx); /* store the new context with the handler to free it */ rc=pam_set_data(pamh,PLD_CTX,ctx,ctx_free); if (rc!=PAM_SUCCESS) + { ctx_free(pamh,ctx,0); + return rc; + } } - if (rc==PAM_SUCCESS) - *pctx=ctx; - return rc; + /* return the context */ + *pctx=ctx; + return PAM_SUCCESS; +} + +/* our PAM module configuration */ +struct pld_cfg { + int use_first_pass; + int try_first_pass; + int use_authtok; + int no_warn; + int ignore_unknown_user; + int ignore_authinfo_unavail; + int debug; + uid_t minimum_uid; +}; + +static void parse_args(struct pld_cfg *cfg,int flags,int argc,const char **argv) +{ + int i; + /* initialise config with defaults */ + cfg->use_first_pass=0; + cfg->try_first_pass=0; + cfg->use_authtok=0; + cfg->no_warn=0; + cfg->ignore_unknown_user=0; + cfg->ignore_authinfo_unavail=0; + cfg->debug=0; + cfg->minimum_uid=0; + /* go over arguments */ + for (i=0;i<argc;i++) + { + if (strcmp(argv[i],"use_first_pass")==0) + cfg->use_first_pass=1; + else if (strcmp(argv[i],"try_first_pass")==0) + cfg->try_first_pass=1; + else if (strcmp(argv[i],"use_authtok")==0) + cfg->use_authtok=1; + else if (strcmp(argv[i], "no_warn")==0) + cfg->no_warn=1; + else if (strcmp(argv[i],"ignore_unknown_user")==0) + cfg->ignore_unknown_user=1; + else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) + cfg->ignore_authinfo_unavail=1; + else if (strcmp(argv[i],"debug")==0) + cfg->debug=1; + else if (strncmp(argv[i], "minimum_uid=", 12) == 0) + cfg->minimum_uid=(uid_t)atoi(argv[i]+12); + else + syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); + } + /* check flags */ + if (flags&PAM_SILENT) + cfg->no_warn=1; } /* ask the user for an authentication token (password) */ +/* FIXME: get rid of this and use proper pam_get_authtok() */ static int my_pam_get_authtok(pam_handle_t *pamh,int flags,char *prompt1,char *prompt2,const char **pwd) { int rc; @@ -228,8 +256,30 @@ static int my_pam_get_authtok(pam_handle_t *pamh,int flags,char *prompt1,char *p return rc; } +/* map a NSLCD PAM status code to a PAM status code */ +static int nslcd2pam_rc(int rc) +{ +#define map(i) case NSLCD_##i: return i; + switch(rc) { + map(PAM_SUCCESS); + map(PAM_PERM_DENIED); + map(PAM_AUTH_ERR); + map(PAM_CRED_INSUFFICIENT); + map(PAM_AUTHINFO_UNAVAIL); + map(PAM_USER_UNKNOWN); + map(PAM_MAXTRIES); + map(PAM_NEW_AUTHTOK_REQD); + map(PAM_ACCT_EXPIRED); + map(PAM_SESSION_ERR); + map(PAM_AUTHTOK_DISABLE_AGING); + map(PAM_IGNORE); + map(PAM_ABORT); + default: return PAM_ABORT; + } +} + /* perform an authentication call over nslcd */ -static int nslcd_request_authc(pld_ctx *ctx,const char *username, +static int nslcd_request_authc(struct pld_ctx *ctx,const char *username, const char *service,const char *passwd) { PAM_REQUEST(NSLCD_ACTION_PAM_AUTHC, @@ -246,36 +296,75 @@ static int nslcd_request_authc(pld_ctx *ctx,const char *username, READ_BUF_STRING(fp,ctx->authzmsg);) } +/* perform an authorisation call over nslcd */ +static int nslcd_request_authz(struct pld_ctx *ctx,const char *username, + const char *service,const char *ruser, + const char *rhost,const char *tty) +{ + PAM_REQUEST(NSLCD_ACTION_PAM_AUTHZ, + /* 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);) +} + +/* do a session nslcd request (open or close) */ +static int nslcd_request_sess(struct pld_ctx *ctx,int action,const char *service, + const char *tty, const char *rhost, + const char *ruser) +{ + PAM_REQUEST(action, + /* write the request parameters */ + WRITE_STRING(fp,ctx->user); + 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), + /* read the result entry */ + READ_INT32(fp,ctx->sessid)) +} + +/* do a password modification nslcd call */ +static int nslcd_request_pwmod(struct pld_ctx *ctx,const char *username, + const char *service,const char *oldpasswd, + const char *newpasswd) +{ + PAM_REQUEST(NSLCD_ACTION_PAM_PWMOD, + /* write the request parameters */ + WRITE_STRING(fp,username); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,service); + 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);) +} + +/* PAM authentication check */ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) { + struct pld_cfg cfg; int rc; const char *username,*svc; char *passwd=NULL; - int first_pass=0,ignore_flags=0; int i; - pld_ctx *ctx; - uid_t minimum_uid=0; + struct pld_ctx *ctx; struct passwd *pwd; - /* go over arguments */ - for (i=0;i<argc;i++) - { - if (strcmp(argv[i],"use_first_pass")==0) - first_pass|=USE_FIRST; - else if (strcmp(argv[i],"try_first_pass")==0) - first_pass|=TRY_FIRST; - else if (strcmp(argv[i],"ignore_unknown_user")==0) - ignore_flags|=IGNORE_UNKNOWN; - else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) - ignore_flags|=IGNORE_UNAVAIL; - else if (strcmp(argv[i], "no_warn")==0) - /* ignore */; - else if (strcmp(argv[i],"debug")==0) - /* ignore */; - else if (strncmp(argv[i], "minimum_uid=", 12) == 0) - minimum_uid=(uid_t)atoi(argv[i]+12); - else - syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); - } + /* parse module options */ + parse_args(&cfg,flags,argc,argv); /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) @@ -283,11 +372,11 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; /* check uid */ - if (minimum_uid>0) + if (cfg.minimum_uid>0) { pwd=pam_modutil_getpwnam(args->pamh,username); - if ((pwd!=NULL)&&(pwd->pw_uid<minimum_uid)) - return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + if ((pwd!=NULL)&&(pwd->pw_uid<cfg.minimum_uid)) + return cfg.ignore_unknown_user?PAM_IGNORE:PAM_USER_UNKNOWN; } /* get our context */ rc=ctx_get(pamh,username,&ctx); @@ -300,7 +389,7 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) /* try twice */ for (i=0;i<2;i++) { - if (!first_pass) + if ((!cfg.try_first_pass)&&(!cfg.use_first_pass)) { rc=my_pam_get_authtok(pamh,flags,i==0?"Password: ":"LDAP Password: ",NULL,(const char **)&passwd); if (rc!=PAM_SUCCESS) @@ -319,14 +408,14 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) rc=nslcd_request_authc(ctx,username,svc,passwd); if (rc==PAM_SUCCESS) rc=ctx->authok; - if ((rc==PAM_AUTHINFO_UNAVAIL)&&(ignore_flags&IGNORE_UNAVAIL)) + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg.ignore_authinfo_unavail) rc=PAM_IGNORE; - else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN)) + else if ((rc==PAM_USER_UNKNOWN)&&cfg.ignore_unknown_user) rc=PAM_IGNORE; } - if ((rc==PAM_SUCCESS)||(first_pass&USE_FIRST)) + if ((rc==PAM_SUCCESS)||(cfg.use_first_pass)) break; - first_pass=0; + cfg.try_first_pass=0; } /* save username */ if (rc==PAM_SUCCESS) { @@ -351,59 +440,16 @@ int pam_sm_setcred(pam_handle_t UNUSED(*pamh),int UNUSED(flags), return PAM_SUCCESS; } -/* perform an authorisation call over nslcd */ -static int nslcd_request_authz(pld_ctx *ctx,const char *username, - const char *service,const char *ruser, - const char *rhost,const char *tty) -{ - PAM_REQUEST(NSLCD_ACTION_PAM_AUTHZ, - /* 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);) -} - +/* PAM authorisation check */ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) { + struct pld_cfg cfg; int rc; const char *username,*svc,*ruser,*rhost,*tty; - int no_warn=0, ignore_flags=0; - int i; - pld_ctx *ctx=NULL, ctx2; - uid_t minimum_uid=0; + struct pld_ctx *ctx=NULL, ctx2; struct passwd *pwent; - /* go over arguments */ - for (i=0;i<argc;i++) - { - if (strcmp(argv[i],"use_first_pass")==0) - ; - else if (strcmp(argv[i],"try_first_pass")==0) - ; - else if (strcmp(argv[i],"no_warn")==0) - no_warn=1; - else if (strcmp(argv[i],"ignore_unknown_user")==0) - ignore_flags|=IGNORE_UNKNOWN; - else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) - ignore_flags|=IGNORE_UNAVAIL; - else if (strcmp(argv[i],"debug")==0) - ; - else if (strncmp(argv[i], "minimum_uid=", 12) == 0) - minimum_uid=(uid_t)atoi(argv[i]+12); - else - syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); - } - - if (flags&PAM_SILENT) - no_warn=1; - + /* parse module options */ + parse_args(&cfg,flags,argc,argv); /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) @@ -411,122 +457,82 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; /* check uid */ - if (minimum_uid>0) + if (cfg.minimum_uid>0) { pwent=pam_modutil_getpwnam(args->pamh,username); - if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) - return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + if ((pwent!=NULL)&&(pwent->pw_uid<cfg.minimum_uid)) + return cfg.ignore_unknown_user?PAM_IGNORE:PAM_USER_UNKNOWN; } - + /* get our context */ rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) return rc; - + /* get service name */ rc=pam_get_item(pamh,PAM_SERVICE,(const void **)&svc); if (rc!=PAM_SUCCESS) return rc; - + /* get remote user name */ rc=pam_get_item (pamh,PAM_RUSER,(const void **)&ruser); if (rc!=PAM_SUCCESS) return rc; - + /* get service host */ rc=pam_get_item (pamh,PAM_RHOST,(const void **)&rhost); if (rc!=PAM_SUCCESS) return rc; - + /* get tty name */ rc=pam_get_item (pamh,PAM_TTY,(const void **)&tty); if (rc!=PAM_SUCCESS) return rc; - + /* 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; rc=nslcd_request_authz(&ctx2,username,svc,ruser,rhost,tty); - if ((rc==PAM_AUTHINFO_UNAVAIL)&&(ignore_flags&IGNORE_UNAVAIL)) + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg.ignore_authinfo_unavail) rc=PAM_IGNORE; - else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN)) + else if ((rc==PAM_USER_UNKNOWN)&&cfg.ignore_unknown_user) rc=PAM_IGNORE; if (rc!=PAM_SUCCESS) { if (rc!=PAM_IGNORE) - if (!no_warn) + if (!cfg.no_warn) pam_error(pamh,"LDAP authorization failed"); + return rc; } - else + /* check the returned authorisation value */ + if (ctx2.authz!=PAM_SUCCESS) { - rc=ctx2.authz; - if (ctx2.authzmsg && ctx2.authzmsg[0]) - if (!no_warn) - pam_info(pamh,"%s",ctx2.authzmsg); - if (ctx2.authz==PAM_SUCCESS) - { - rc=ctx->authz; - if (ctx->authzmsg && ctx->authzmsg[0]) - if (!no_warn) - pam_info(pamh,"%s",ctx->authzmsg); - } + if (!cfg.no_warn) + pam_error(pamh,"%s",ctx2.authzmsg); + return ctx2.authz; } - - /* update caller's idea of the user name */ - if ( (rc==PAM_SUCCESS) && ctx->tmpluser && ctx->tmpluser[0] && - (strcmp(ctx->tmpluser,username)!=0) ) { - rc=pam_set_item(pamh,PAM_USER,ctx->tmpluser); + /* check the original authorisation check from authentication */ + if (ctx->authz!=PAM_SUCCESS) + { + if (!cfg.no_warn) + pam_error(pamh,"%s",ctx->authzmsg); + return ctx->authz; } - return rc; -} - -/* do a session nslcd request (open or close) */ -static int nslcd_request_sess(pld_ctx *ctx,int action,const char *service, - const char *tty, const char *rhost, - const char *ruser) -{ - PAM_REQUEST(action, - /* write the request parameters */ - WRITE_STRING(fp,ctx->user); - 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), - /* read the result entry */ - READ_INT32(fp,ctx->sessid)) + /* 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); + 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) { + struct pld_cfg cfg; int rc; const char *username; - int ignore_flags=0; - int no_warn; - int i; - pld_ctx *ctx=NULL; + struct pld_ctx *ctx=NULL; const char *service=NULL,*tty=NULL,*rhost=NULL,*ruser=NULL; - uid_t minimum_uid=0; struct passwd *pwent; - /* go over arguments */ - for (i=0;i<argc;i++) - { - if (strcmp(argv[i],"use_first_pass")==0) - ; - else if (strcmp(argv[i],"try_first_pass")==0) - ; - else if (strcmp(argv[i],"no_warn")==0) - no_warn=1; - else if (strcmp(argv[i],"ignore_unknown_user")==0) - ignore_flags|=IGNORE_UNKNOWN; - else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) - ignore_flags|=IGNORE_UNAVAIL; - else if (strcmp(argv[i],"debug")==0) - ; - else if (strncmp(argv[i], "minimum_uid=", 12) == 0) - minimum_uid=(uid_t)atoi(argv[i]+12); - else - syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); - } - - if (flags&PAM_SILENT) - no_warn=1; + /* parse module options */ + parse_args(&cfg,flags,argc,argv); /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) @@ -534,13 +540,13 @@ static int pam_sm_session(pam_handle_t *pamh,int flags,int argc, if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; /* check uid */ - if (minimum_uid>0) + if (cfg.minimum_uid>0) { pwent=pam_modutil_getpwnam(args->pamh,username); - if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) - return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + if ((pwent!=NULL)&&(pwent->pw_uid<cfg.minimum_uid)) + return cfg.ignore_unknown_user?PAM_IGNORE:PAM_USER_UNKNOWN; } - + /* get our context */ rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) return rc; @@ -551,52 +557,33 @@ static int pam_sm_session(pam_handle_t *pamh,int flags,int argc, pam_get_item(pamh,PAM_RUSER,(const void **)&ruser); /* do the nslcd request */ rc=nslcd_request_sess(ctx,action,service,tty,rhost,ruser); - if ((rc==PAM_AUTHINFO_UNAVAIL)&&(ignore_flags&IGNORE_UNAVAIL)) + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg.ignore_authinfo_unavail) rc=PAM_IGNORE; - else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN)) + else if ((rc==PAM_USER_UNKNOWN)&&cfg.ignore_unknown_user) rc=PAM_IGNORE; if ((rc!=PAM_SUCCESS)&&(rc!=PAM_IGNORE)) - if (!no_warn) + if (!cfg.no_warn) pam_error(pamh,"LDAP %s session failed", (action==NSLCD_ACTION_PAM_SESS_O)?"open":"clode"); return rc; } +/* 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) { return pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_C); } -/* do a password modification nslcd call */ -static int nslcd_request_pwmod(pld_ctx *ctx,const char *username, - const char *service,const char *oldpasswd, - const char *newpasswd) -{ - PAM_REQUEST(NSLCD_ACTION_PAM_PWMOD, - /* write the request parameters */ - WRITE_STRING(fp,username); - WRITE_STRING(fp,ctx->dn); - WRITE_STRING(fp,service); - 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);) -} - -/* prompt for LDAP administrator password */ - /* ensure that the context includes and oldpassword field */ -static const char *get_old_password(pam_handle_t *pamh, int flags,pld_ctx *ctx) +static const char *get_old_password(pam_handle_t *pamh, int flags,struct pld_ctx *ctx) { int rc; const char *oldpassword; @@ -626,41 +613,15 @@ static const char *get_old_password(pam_handle_t *pamh, int flags,pld_ctx *ctx) password and actually modify the password. */ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) { + struct pld_cfg cfg; int rc; const char *username,*service; const char *oldpassword=NULL; const char *newpassword=NULL; - int first_pass=0, no_warn=0, ignore_flags=0; - int i; - pld_ctx *ctx=NULL; - uid_t minimum_uid=0; + struct pld_ctx *ctx=NULL; struct passwd *pwent; /* parse module options */ - for (i=0;i<argc;i++) - { - if (strcmp(argv[i],"use_first_pass")==0) - first_pass|=USE_FIRST; - else if (strcmp(argv[i],"try_first_pass")==0) - first_pass|=TRY_FIRST; - else if (strcmp(argv[i],"use_authtok")==0) - first_pass|=USE_TOKEN; - else if (strcmp(argv[i],"no_warn")==0) - no_warn=1; - else if (strcmp(argv[i],"ignore_unknown_user")==0) - ignore_flags|=IGNORE_UNKNOWN; - else if (strcmp(argv[i],"ignore_authinfo_unavail")==0) - ignore_flags|=IGNORE_UNAVAIL; - else if (strcmp(argv[i],"debug")==0) - ; - else if (strncmp(argv[i], "minimum_uid=", 12) == 0) - minimum_uid=(uid_t)atoi(argv[i]+12); - else - syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); - } - - if (flags&PAM_SILENT) - no_warn=1; - + parse_args(&cfg,flags,argc,argv); /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) @@ -668,17 +629,17 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; /* check uid */ - if (minimum_uid>0) + if (cfg.minimum_uid>0) { pwent=pam_modutil_getpwnam(args->pamh,username); - if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) - return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + if ((pwent!=NULL)&&(pwent->pw_uid<cfg.minimum_uid)) + return cfg.ignore_unknown_user?PAM_IGNORE:PAM_USER_UNKNOWN; } - + /* get our context */ rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) return rc; - + /* get service name */ rc=pam_get_item(pamh,PAM_SERVICE,(const void **)&service); if (rc!=PAM_SUCCESS) return rc; @@ -711,9 +672,9 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) } if (rc==PAM_SUCCESS) rc=ctx->authok; - if ((rc==PAM_AUTHINFO_UNAVAIL)&&(ignore_flags&IGNORE_UNAVAIL)) + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg.ignore_authinfo_unavail) rc=PAM_IGNORE; - else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN)) + else if ((rc==PAM_USER_UNKNOWN)&&cfg.ignore_unknown_user) rc=PAM_IGNORE; /* TODO: figure out when to return PAM_TRY_AGAIN */ /* TODO: if password is incorrect (NSLCD_PAM_AUTH_ERR) log that */ @@ -733,11 +694,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) rc=ctx->authz; else ctx->authzmsg=(char *)pam_strerror(pamh,rc); - if ((rc==PAM_AUTHINFO_UNAVAIL)&&(ignore_flags&IGNORE_UNAVAIL)) + if ((rc==PAM_AUTHINFO_UNAVAIL)&&cfg.ignore_authinfo_unavail) rc=PAM_IGNORE; - else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN)) + else if ((rc==PAM_USER_UNKNOWN)&&cfg.ignore_unknown_user) rc=PAM_IGNORE; - else if (!no_warn) + else if (!cfg.no_warn) pam_error(pamh,"%s",ctx->authzmsg); return rc; } |