Changeset 154 in openpam for trunk


Ignore:
Timestamp:
Jun 7, 2002, 1:37:44 PM (17 years ago)
Author:
Dag-Erling Smørgrav
Message:

Make this actually work...

Sponsored by: DARPA, NAI Labs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/su/su.c

    r147 r154  
    3232 * SUCH DAMAGE.
    3333 *
    34  * $P4: //depot/projects/openpam/bin/su/su.c#6 $
     34 * $P4: //depot/projects/openpam/bin/su/su.c#7 $
    3535 */
    3636
     
    4242#include <stdio.h>
    4343#include <stdlib.h>
     44#include <string.h>
    4445#include <syslog.h>
    4546#include <unistd.h>
    4647
    4748#include <security/pam_appl.h>
    48 #include <security/openpam.h>
     49#include <security/openpam.h>   /* for openpam_ttyconv() */
     50
     51extern char **environ;
    4952
    5053static pam_handle_t *pamh;
     
    5962}
    6063
    61 static int
    62 check(const char *func, int pam_err)
    63 {
    64 
    65         if (pam_err == PAM_SUCCESS || pam_err == PAM_NEW_AUTHTOK_REQD)
    66                 return pam_err;
    67         openlog("su", LOG_CONS, LOG_AUTH);
    68         syslog(LOG_ERR, "%s(): %s", func, pam_strerror(pamh, pam_err));
    69         errx(1, "Sorry.");
    70 }
    71 
    7264int
    7365main(int argc, char *argv[])
     
    7567        char hostname[MAXHOSTNAMELEN];
    7668        const char *user, *tty;
     69        char **args, **pam_envlist, **pam_env;
    7770        struct passwd *pwd;
    78         int o, status;
     71        int o, pam_err, status;
    7972        pid_t pid;
    8073
     
    9588        /* set some items */
    9689        gethostname(hostname, sizeof(hostname));
    97         check("pam_set_item", pam_set_item(pamh, PAM_RHOST, hostname));
     90        if ((pam_err = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS)
     91                goto pamerr;
    9892        user = getlogin();
    99         check("pam_set_item", pam_set_item(pamh, PAM_RUSER, user));
     93        if ((pam_err = pam_set_item(pamh, PAM_RUSER, user)) != PAM_SUCCESS)
     94                goto pamerr;
    10095        tty = ttyname(STDERR_FILENO);
    101         check("pam_set_item", pam_set_item(pamh, PAM_TTY, tty));
     96        if ((pam_err = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS)
     97                goto pamerr;
    10298
    10399        /* authenticate the applicant */
    104         check("pam_authenticate", pam_authenticate(pamh, 0));
    105         if (check("pam_acct_mgmt", pam_acct_mgmt(pamh, 0)) ==
    106             PAM_NEW_AUTHTOK_REQD)
    107                 check("pam_chauthtok",
    108                     pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK));
     100        if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
     101                goto pamerr;
     102        if ((pam_err = pam_acct_mgmt(pamh, 0)) == PAM_NEW_AUTHTOK_REQD)
     103                pam_err = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
     104        if (pam_err != PAM_SUCCESS)
     105                goto pamerr;
    109106
    110107        /* establish the requested credentials */
    111         check("pam_setcred", pam_setcred(pamh, PAM_ESTABLISH_CRED));
     108        if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS)
     109                goto pamerr;
    112110
    113111        /* authentication succeeded; open a session */
    114         check("pam_open_session", pam_open_session(pamh, 0));
     112        if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS)
     113                goto pamerr;
    115114
    116         if (initgroups(pwd->pw_name, pwd->pw_gid) == -1)
    117                 err(1, "initgroups()");
    118         if (setuid(pwd->pw_uid) == -1)
    119                 err(1, "setuid()");
     115        /* get mapped user name; PAM may have changed it */
     116        pam_err = pam_get_item(pamh, PAM_USER, (const void **)&user);
     117        if (pam_err != PAM_SUCCESS || (pwd = getpwnam(user)) == NULL)
     118                goto pamerr;
    120119
    121         /* XXX export environment variables */
     120        /* set uid and groups */
     121        if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) {
     122                warn("initgroups()");
     123                goto err;
     124        }
     125        if (setgid(pwd->pw_gid) == -1) {
     126                warn("setgid()");
     127                goto err;
     128        }
     129        if (setuid(pwd->pw_uid) == -1) {
     130                warn("setuid()");
     131                goto err;
     132        }
    122133
     134        /* export PAM environment */
     135        if ((pam_envlist = pam_getenvlist(pamh)) != NULL) {
     136                for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) {
     137                        putenv(*pam_env);
     138                        free(*pam_env);
     139                }
     140                free(pam_envlist);
     141        }
     142
     143        /* build argument list */
     144        if ((args = calloc(argc + 2, sizeof *args)) == NULL) {
     145                warn("calloc()");
     146                goto err;
     147        }
     148        *args = pwd->pw_shell;
     149        memcpy(args + 1, argv, argc * sizeof *args);
     150
     151        /* fork and exec */
    123152        switch ((pid = fork())) {
    124153        case -1:
    125                 err(1, "fork()");
     154                warn("fork()");
     155                goto err;
    126156        case 0:
    127157                /* child: start a shell */
    128                 *argv = pwd->pw_shell;
    129                 execvp(*argv, argv);
    130                 err(1, "execvp()");
     158                execve(*args, args, environ);
     159                warn("execve()");
     160                _exit(1);
    131161        default:
    132162                /* parent: wait for child to exit */
    133163                waitpid(pid, &status, 0);
    134                 if (WIFEXITED(status))
    135                         status = WEXITSTATUS(status);
    136                 else
    137                         status = 1;
     164
     165                /* close the session and release PAM resources */
     166                pam_err = pam_close_session(pamh, 0);
     167                pam_end(pamh, pam_err);
     168
     169                exit(WEXITSTATUS(status));
    138170        }
    139171
    140         /* close the session and release PAM resources */
    141         check("pam_close_session", pam_close_session(pamh, 0));
    142         check("pam_end", pam_end(pamh, 0));
    143 
    144         exit(status);
     172pamerr:
     173        pam_end(pamh, pam_err);
     174        fprintf(stderr, "Sorry\n");
     175        exit(1);
     176err:
     177        pam_end(pamh, pam_err);
     178        exit(1);
    145179}
Note: See TracChangeset for help on using the changeset viewer.