Date: Fri, 7 Jun 2002 04:37:58 -0700 (PDT) From: Dag-Erling Smorgrav <des@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 12486 for review Message-ID: <200206071137.g57Bbwa79143@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=12486 Change 12486 by des@des.at.aes.thinksec.com on 2002/06/07 04:37:44 Make this actually work... Sponsored by: DARPA, NAI Labs Affected files ... ... //depot/projects/openpam/bin/su/su.c#7 edit Differences ... ==== //depot/projects/openpam/bin/su/su.c#7 (text+ko) ==== @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/openpam/bin/su/su.c#6 $ + * $P4: //depot/projects/openpam/bin/su/su.c#7 $ */ #include <sys/param.h> @@ -41,11 +41,14 @@ #include <pwd.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <syslog.h> #include <unistd.h> #include <security/pam_appl.h> -#include <security/openpam.h> +#include <security/openpam.h> /* for openpam_ttyconv() */ + +extern char **environ; static pam_handle_t *pamh; static struct pam_conv pamc; @@ -58,24 +61,14 @@ exit(1); } -static int -check(const char *func, int pam_err) -{ - - if (pam_err == PAM_SUCCESS || pam_err == PAM_NEW_AUTHTOK_REQD) - return pam_err; - openlog("su", LOG_CONS, LOG_AUTH); - syslog(LOG_ERR, "%s(): %s", func, pam_strerror(pamh, pam_err)); - errx(1, "Sorry."); -} - int main(int argc, char *argv[]) { char hostname[MAXHOSTNAMELEN]; const char *user, *tty; + char **args, **pam_envlist, **pam_env; struct passwd *pwd; - int o, status; + int o, pam_err, status; pid_t pid; while ((o = getopt(argc, argv, "h")) != -1) @@ -94,52 +87,93 @@ /* set some items */ gethostname(hostname, sizeof(hostname)); - check("pam_set_item", pam_set_item(pamh, PAM_RHOST, hostname)); + if ((pam_err = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS) + goto pamerr; user = getlogin(); - check("pam_set_item", pam_set_item(pamh, PAM_RUSER, user)); + if ((pam_err = pam_set_item(pamh, PAM_RUSER, user)) != PAM_SUCCESS) + goto pamerr; tty = ttyname(STDERR_FILENO); - check("pam_set_item", pam_set_item(pamh, PAM_TTY, tty)); + if ((pam_err = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS) + goto pamerr; /* authenticate the applicant */ - check("pam_authenticate", pam_authenticate(pamh, 0)); - if (check("pam_acct_mgmt", pam_acct_mgmt(pamh, 0)) == - PAM_NEW_AUTHTOK_REQD) - check("pam_chauthtok", - pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK)); + if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS) + goto pamerr; + if ((pam_err = pam_acct_mgmt(pamh, 0)) == PAM_NEW_AUTHTOK_REQD) + pam_err = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + if (pam_err != PAM_SUCCESS) + goto pamerr; /* establish the requested credentials */ - check("pam_setcred", pam_setcred(pamh, PAM_ESTABLISH_CRED)); + if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) + goto pamerr; /* authentication succeeded; open a session */ - check("pam_open_session", pam_open_session(pamh, 0)); + if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS) + goto pamerr; + + /* get mapped user name; PAM may have changed it */ + pam_err = pam_get_item(pamh, PAM_USER, (const void **)&user); + if (pam_err != PAM_SUCCESS || (pwd = getpwnam(user)) == NULL) + goto pamerr; + + /* set uid and groups */ + if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { + warn("initgroups()"); + goto err; + } + if (setgid(pwd->pw_gid) == -1) { + warn("setgid()"); + goto err; + } + if (setuid(pwd->pw_uid) == -1) { + warn("setuid()"); + goto err; + } - if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) - err(1, "initgroups()"); - if (setuid(pwd->pw_uid) == -1) - err(1, "setuid()"); + /* export PAM environment */ + if ((pam_envlist = pam_getenvlist(pamh)) != NULL) { + for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) { + putenv(*pam_env); + free(*pam_env); + } + free(pam_envlist); + } - /* XXX export environment variables */ + /* build argument list */ + if ((args = calloc(argc + 2, sizeof *args)) == NULL) { + warn("calloc()"); + goto err; + } + *args = pwd->pw_shell; + memcpy(args + 1, argv, argc * sizeof *args); + /* fork and exec */ switch ((pid = fork())) { case -1: - err(1, "fork()"); + warn("fork()"); + goto err; case 0: /* child: start a shell */ - *argv = pwd->pw_shell; - execvp(*argv, argv); - err(1, "execvp()"); + execve(*args, args, environ); + warn("execve()"); + _exit(1); default: /* parent: wait for child to exit */ waitpid(pid, &status, 0); - if (WIFEXITED(status)) - status = WEXITSTATUS(status); - else - status = 1; + + /* close the session and release PAM resources */ + pam_err = pam_close_session(pamh, 0); + pam_end(pamh, pam_err); + + exit(WEXITSTATUS(status)); } - /* close the session and release PAM resources */ - check("pam_close_session", pam_close_session(pamh, 0)); - check("pam_end", pam_end(pamh, 0)); - - exit(status); +pamerr: + pam_end(pamh, pam_err); + fprintf(stderr, "Sorry\n"); + exit(1); +err: + pam_end(pamh, pam_err); + exit(1); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206071137.g57Bbwa79143>