diff --git a/setuidgid.c b/setuidgid.c index e8d1e3f..457995f 100644 --- a/setuidgid.c +++ b/setuidgid.c @@ -1,10 +1,24 @@ #include #include +#include +#include +#include #include "prot.h" #include "strerr.h" #include "pathexec.h" #include "sgetopt.h" +#ifndef PAM_DATA_SILENT +# define PAM_DATA_SILENT 0 +#endif + +#ifndef SETUIDGID_PAM_SERVICE_NAME_ENV +# define SETUIDGID_PAM_SERVICE_NAME_ENV "SETUIDGID_PAM_SERVICE" +#endif +#ifndef SETUIDGID_PAM_SERVICE_NAME_DEFAULT +# define SETUIDGID_PAM_SERVICE_NAME_DEFAULT "other" +#endif + #define FATAL "setuidgid: fatal: " void usage() { @@ -15,6 +29,28 @@ const char *account; struct passwd *pw; int flag2ndgids = 0; +static void pam_prep_user(void) +{ + pam_handle_t *pamh; + const char *pam_service_name = getenv(SETUIDGID_PAM_SERVICE_NAME_ENV); + struct pam_conv pam_conv; + + if (!pam_service_name) + pam_service_name = SETUIDGID_PAM_SERVICE_NAME_DEFAULT; + + /* FIXME: Is this OK? */ + memset(&pam_conv, 0, sizeof(pam_conv)); + + if (pam_start(pam_service_name, pw->pw_name, &pam_conv, &pamh) != PAM_SUCCESS) + strerr_die2x(111,FATAL,"unable to initialize PAM"); + + pam_set_item(pamh, PAM_USER, pw->pw_name); + pam_setcred(pamh, PAM_ESTABLISH_CRED); + + if (pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT) != PAM_SUCCESS) + strerr_die2x(111,FATAL,"unable to finish PAM"); +} + int main(int argc,const char *const *argv,const char *const *envp) { int opt; @@ -34,6 +70,8 @@ int main(int argc,const char *const *argv,const char *const *envp) if (!pw) strerr_die3x(111,FATAL,"unknown account ",account); + pam_prep_user(); + if (prot_gid(pw->pw_gid) == -1) strerr_die2sys(111,FATAL,"unable to setgid"); if (flag2ndgids && prot_gids(pw->pw_name, pw->pw_gid) == -1) diff --git a/setuidgid=x b/setuidgid=x index 09db56a..c319519 100644 --- a/setuidgid=x +++ b/setuidgid=x @@ -1,2 +1,3 @@ unix.a byte.a +-lpam