diff --git a/bin/su/su.c b/bin/su/su.c index bdfa9a6..92a6e34 100644 --- a/bin/su/su.c +++ b/bin/su/su.c @@ -52,91 +52,93 @@ static struct pam_conv pamc; static void usage(void) { - fprintf(stderr, "Usage: su [login [args]]\n"); - exit(1); + + fprintf(stderr, "Usage: su [login [args]]\n"); + 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."); + + 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 hostname[MAXHOSTNAMELEN]; + const char *user, *tty; struct passwd *pwd; - int o, status; - pid_t pid; + int o, status; + pid_t pid; - while ((o = getopt(argc, argv, "h")) != -1) - switch (o) { - case 'h': - default: - usage(); - } + while ((o = getopt(argc, argv, "h")) != -1) + switch (o) { + case 'h': + default: + usage(); + } - argc -= optind; - argv += optind; + argc -= optind; + argv += optind; - /* initialize PAM */ - pamc.conv = &openpam_ttyconv; + /* initialize PAM */ + pamc.conv = &openpam_ttyconv; pam_start("su", argc ? *argv : "root", &pamc, &pamh); - /* set some items */ - gethostname(hostname, sizeof hostname); - check("pam_set_item", pam_set_item(pamh, PAM_RHOST, hostname)); - user = getlogin(); - check("pam_set_item", pam_set_item(pamh, PAM_RUSER, user)); - tty = ttyname(STDERR_FILENO); - check("pam_set_item", pam_set_item(pamh, PAM_TTY, tty)); + /* set some items */ + gethostname(hostname, sizeof hostname); + check("pam_set_item", pam_set_item(pamh, PAM_RHOST, hostname)); + user = getlogin(); + check("pam_set_item", pam_set_item(pamh, PAM_RUSER, user)); + tty = ttyname(STDERR_FILENO); + check("pam_set_item", pam_set_item(pamh, PAM_TTY, tty)); - /* 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)); - - /* establish the requested credentials */ - check("pam_setcred", pam_setcred(pamh, PAM_ESTABLISH_CRED)); - - /* authentication succeeded; open a session */ - check("pam_open_session", pam_open_session(pamh, 0)); + /* 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)); + + /* establish the requested credentials */ + check("pam_setcred", pam_setcred(pamh, PAM_ESTABLISH_CRED)); + + /* authentication succeeded; open a session */ + check("pam_open_session", pam_open_session(pamh, 0)); if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) err(1, "initgroups()"); if (setuid(pwd->pw_uid) == -1) err(1, "setuid()"); - + /* XXX export environment variables */ - - switch ((pid = fork())) { - case -1: - err(1, "fork()"); - case 0: - /* child: start a shell */ - *argv = pwd->pw_shell; - execvp(*argv, argv); - err(1, "execvp()"); - 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 */ - check("pam_close_session", pam_close_session(pamh, 0)); - check("pam_end", pam_end(pamh, 0)); + switch ((pid = fork())) { + case -1: + err(1, "fork()"); + case 0: + /* child: start a shell */ + *argv = pwd->pw_shell; + execvp(*argv, argv); + err(1, "execvp()"); + default: + /* parent: wait for child to exit */ + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + status = WEXITSTATUS(status); + else + status = 1; + } - exit(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); } diff --git a/doc/xsso_errata.txt b/doc/xsso_errata.txt index 4c7551f..9e7465d 100644 --- a/doc/xsso_errata.txt +++ b/doc/xsso_errata.txt @@ -2,12 +2,12 @@ $Id$ Errata in XSSO, chapter 5: -p. 25: the first member of struct pam_response is named "resp", not +p. 25: the first member of struct pam_response is named "resp", not "response". Errata in XSSO, chapter 6: -p. 32: "PAM_NEW_AUTHTOKEN_REQD" in the DESCRIPTION and RETURN VALUE +p. 32: "PAM_NEW_AUTHTOKEN_REQD" in the DESCRIPTION and RETURN VALUE sections should be "PAM_NEW_AUTHTOK_REQD". p. 32: pam_acct_mgmt() must be allowed to return PAM_AUTH_ERR. @@ -18,7 +18,7 @@ p. 46: "PAM_AUTHOK" and "PAM_OLDAUTHOK" in the DESCRIPTION section p. 60: "PAM_AUTHOK" and "PAM_OLDAUTHOK" in the DESCRIPTION section should be "PAM_AUTHTOK" and "PAM_OLDAUTHTOK", respectively. -p. 62: the target_authtok_len argument to pam_set_mapped_authtok() is +p. 62: the target_authtok_len argument to pam_set_mapped_authtok() is of type size_t, not a size_t *. p. 52: PAM_CONV_ERR is listed out of order and with the explanatory @@ -52,7 +52,7 @@ p. 85: the names of several arguments to pam_sm_set_mapped_username() p. 89: the user argument to pam_start() is of type const char *. -p. 89: the correct definition for struct pam_conv is as follows: +p. 89: the correct definition for struct pam_conv is as follows: struct pam_conv { int (*conv)(int, struct pam_message **, @@ -60,7 +60,7 @@ p. 89: the correct definition for struct pam_conv is as follows: void *appdata_ptr; }; -p. 90: the correct definition for struct pam_response is as follows: +p. 90: the correct definition for struct pam_response is as follows: struct pam_response { char *resp; diff --git a/include/security/pam_appl.h b/include/security/pam_appl.h index ee872b7..2aed200 100644 --- a/include/security/pam_appl.h +++ b/include/security/pam_appl.h @@ -141,7 +141,7 @@ pam_info(pam_handle_t *_pamh, int pam_prompt(pam_handle_t *pamh, - char **resp, + char **resp, int echo, const char *fmt, ...); diff --git a/lib/openpam_dispatch.c b/lib/openpam_dispatch.c index 93c7298..6b5d0f4 100644 --- a/lib/openpam_dispatch.c +++ b/lib/openpam_dispatch.c @@ -57,7 +57,7 @@ openpam_dispatch(pam_handle_t *pamh, { pam_chain_t *module; int err, fail, r; - + if (pamh == NULL) return (PAM_SYSTEM_ERR); @@ -147,7 +147,7 @@ _openpam_check_error_code(int primitive, int r) r == PAM_CONV_ERR || r == PAM_PERM_DENIED) return; - + /* specific error codes */ switch (primitive) { case PAM_AUTHENTICATE: @@ -186,7 +186,7 @@ _openpam_check_error_code(int primitive, int r) return; break; } - + openpam_log(PAM_LOG_ERROR, "%s(): unexpected return value %d", _pam_sm_func_name[primitive], r); } diff --git a/lib/openpam_findenv.c b/lib/openpam_findenv.c index 2a591d3..c32dd27 100644 --- a/lib/openpam_findenv.c +++ b/lib/openpam_findenv.c @@ -50,7 +50,7 @@ openpam_findenv(pam_handle_t *pamh, size_t len) { int i; - + if (pamh == NULL) return (-1); diff --git a/lib/openpam_impl.h b/lib/openpam_impl.h index dbc83cf..ec358f7 100644 --- a/lib/openpam_impl.h +++ b/lib/openpam_impl.h @@ -43,9 +43,9 @@ * Control flags */ #define PAM_REQUIRED 1 -#define PAM_REQUISITE 2 +#define PAM_REQUISITE 2 #define PAM_SUFFICIENT 3 -#define PAM_OPTIONAL 4 +#define PAM_OPTIONAL 4 #define PAM_NUM_CONTROLFLAGS 5 /* @@ -91,7 +91,7 @@ struct pam_data { struct pam_handle { char *service; - + /* chains */ pam_chain_t *chains[PAM_NUM_CHAINS]; diff --git a/lib/openpam_ttyconv.c b/lib/openpam_ttyconv.c index bdd77b7..ac7eecd 100644 --- a/lib/openpam_ttyconv.c +++ b/lib/openpam_ttyconv.c @@ -51,28 +51,28 @@ int openpam_ttyconv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) + const struct pam_message **msg, + struct pam_response **resp, + void *data) { - char buf[PAM_MAX_RESP_SIZE]; - struct termios tattr; - tcflag_t lflag; - int fd, err, i; - size_t len; + char buf[PAM_MAX_RESP_SIZE]; + struct termios tattr; + tcflag_t lflag; + int fd, err, i; + size_t len; - data = data; - if (n <= 0 || n > PAM_MAX_NUM_MSG) - return (PAM_CONV_ERR); - if ((*resp = calloc(n, sizeof **resp)) == NULL) - return (PAM_BUF_ERR); - fd = fileno(stdin); - for (i = 0; i < n; ++i) { - resp[i]->resp_retcode = 0; - resp[i]->resp = NULL; - switch (msg[i]->msg_style) { - case PAM_PROMPT_ECHO_OFF: - case PAM_PROMPT_ECHO_ON: + data = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + if ((*resp = calloc(n, sizeof **resp)) == NULL) + return (PAM_BUF_ERR); + fd = fileno(stdin); + for (i = 0; i < n; ++i) { + resp[i]->resp_retcode = 0; + resp[i]->resp = NULL; + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + case PAM_PROMPT_ECHO_ON: if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { if (tcgetattr(fd, &tattr) != 0) { openpam_log(PAM_LOG_ERROR, @@ -88,44 +88,44 @@ openpam_ttyconv(int n, err = PAM_CONV_ERR; goto fail; } - } - fputs(msg[i]->msg, stderr); - buf[0] = '\0'; - fgets(buf, sizeof buf, stdin); - if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { - tattr.c_lflag = lflag; - (void)tcsetattr(fd, TCSANOW, &tattr); - fputs("\n", stderr); - } - if (ferror(stdin)) { - err = PAM_CONV_ERR; - goto fail; - } - for (len = strlen(buf); len > 0; --len) - if (!isspace(buf[len - 1])) - break; - buf[len] = '\0'; - if ((resp[i]->resp = strdup(buf)) == NULL) { - err = PAM_BUF_ERR; - goto fail; - } - break; - case PAM_ERROR_MSG: - fputs(msg[i]->msg, stderr); - break; - case PAM_TEXT_INFO: - fputs(msg[i]->msg, stdout); - break; - default: - err = PAM_BUF_ERR; - goto fail; - } - } - return (PAM_SUCCESS); + } + fputs(msg[i]->msg, stderr); + buf[0] = '\0'; + fgets(buf, sizeof buf, stdin); + if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { + tattr.c_lflag = lflag; + (void)tcsetattr(fd, TCSANOW, &tattr); + fputs("\n", stderr); + } + if (ferror(stdin)) { + err = PAM_CONV_ERR; + goto fail; + } + for (len = strlen(buf); len > 0; --len) + if (!isspace(buf[len - 1])) + break; + buf[len] = '\0'; + if ((resp[i]->resp = strdup(buf)) == NULL) { + err = PAM_BUF_ERR; + goto fail; + } + break; + case PAM_ERROR_MSG: + fputs(msg[i]->msg, stderr); + break; + case PAM_TEXT_INFO: + fputs(msg[i]->msg, stdout); + break; + default: + err = PAM_BUF_ERR; + goto fail; + } + } + return (PAM_SUCCESS); fail: while (i) free(resp[--i]); - free(*resp); - *resp = NULL; - return (err); + free(*resp); + *resp = NULL; + return (err); } diff --git a/lib/pam_end.c b/lib/pam_end.c index 09167c0..1452829 100644 --- a/lib/pam_end.c +++ b/lib/pam_end.c @@ -73,8 +73,8 @@ pam_end(pam_handle_t *pamh, /* clear items */ for (i = 0; i < PAM_NUM_ITEMS; ++i) free(pamh->item[i]); - + free(pamh); - + return (PAM_SUCCESS); } diff --git a/lib/pam_get_authtok.c b/lib/pam_get_authtok.c index 0766a17..18a311a 100644 --- a/lib/pam_get_authtok.c +++ b/lib/pam_get_authtok.c @@ -52,7 +52,7 @@ pam_get_authtok(pam_handle_t *pamh, const char *prompt) { int r; - + if (pamh == NULL || authtok == NULL) return (PAM_SYSTEM_ERR); diff --git a/lib/pam_get_data.c b/lib/pam_get_data.c index a0fa640..8b2b090 100644 --- a/lib/pam_get_data.c +++ b/lib/pam_get_data.c @@ -53,7 +53,7 @@ pam_get_data(pam_handle_t *pamh, void **data) { pam_data_t *dp; - + if (pamh == NULL) return (PAM_SYSTEM_ERR); @@ -62,6 +62,6 @@ pam_get_data(pam_handle_t *pamh, *data = dp->data; return (PAM_SUCCESS); } - + return (PAM_NO_MODULE_DATA); } diff --git a/lib/pam_get_item.c b/lib/pam_get_item.c index f40bea6..636aa47 100644 --- a/lib/pam_get_item.c +++ b/lib/pam_get_item.c @@ -54,7 +54,7 @@ pam_get_item(pam_handle_t *pamh, { if (pamh == NULL) return (PAM_SYSTEM_ERR); - + switch (item_type) { case PAM_SERVICE: case PAM_USER: diff --git a/lib/pam_get_user.c b/lib/pam_get_user.c index 149477a..37624af 100644 --- a/lib/pam_get_user.c +++ b/lib/pam_get_user.c @@ -53,7 +53,7 @@ pam_get_user(pam_handle_t *pamh, const char *prompt) { int r; - + if (pamh == NULL || user == NULL) return (PAM_SYSTEM_ERR); diff --git a/lib/pam_getenv.c b/lib/pam_getenv.c index 01a867b..d6bf219 100644 --- a/lib/pam_getenv.c +++ b/lib/pam_getenv.c @@ -53,7 +53,7 @@ pam_getenv(pam_handle_t *pamh, const char *name) { int i; - + if (pamh == NULL) return (NULL); diff --git a/lib/pam_prompt.c b/lib/pam_prompt.c index cdccf0a..2928e18 100644 --- a/lib/pam_prompt.c +++ b/lib/pam_prompt.c @@ -48,7 +48,7 @@ int pam_prompt(pam_handle_t *pamh, - char **resp, + char **resp, int echo, const char *fmt, ...) diff --git a/lib/pam_putenv.c b/lib/pam_putenv.c index 43fa832..c8701f3 100644 --- a/lib/pam_putenv.c +++ b/lib/pam_putenv.c @@ -54,7 +54,7 @@ pam_putenv(pam_handle_t *pamh, { char **env, *p; int i; - + if (pamh == NULL) return (PAM_SYSTEM_ERR); diff --git a/lib/pam_set_data.c b/lib/pam_set_data.c index e96fb39..59d5751 100644 --- a/lib/pam_set_data.c +++ b/lib/pam_set_data.c @@ -57,7 +57,7 @@ pam_set_data(pam_handle_t *pamh, int pam_end_status)) { pam_data_t *dp; - + if (pamh == NULL) return (PAM_SYSTEM_ERR); @@ -70,7 +70,7 @@ pam_set_data(pam_handle_t *pamh, return (PAM_SUCCESS); } } - + if ((dp = malloc(sizeof *dp)) == NULL) return (PAM_BUF_ERR); if ((dp->name = strdup(module_data_name)) == NULL) { diff --git a/lib/pam_set_item.c b/lib/pam_set_item.c index 68e08b5..dd3f2d9 100644 --- a/lib/pam_set_item.c +++ b/lib/pam_set_item.c @@ -59,7 +59,7 @@ pam_set_item(pam_handle_t *pamh, if (pamh == NULL) return (PAM_SYSTEM_ERR); - + switch (item_type) { case PAM_SERVICE: case PAM_USER: diff --git a/lib/pam_start.c b/lib/pam_start.c index a032069..ae3e2d8 100644 --- a/lib/pam_start.c +++ b/lib/pam_start.c @@ -79,11 +79,11 @@ pam_start(const char *service, r = _pam_configure_service(ph, PAM_OTHER); if (r != PAM_SUCCESS) goto fail; - + *pamh = ph; openpam_log(PAM_LOG_DEBUG, "pam_start(\"%s\") succeeded", service); return (PAM_SUCCESS); - + fail: pam_end(ph, r); return (r); @@ -101,10 +101,10 @@ const char *_pam_sm_func_name[PAM_NUM_PRIMITIVES] = { static int _pam_add_module(pam_handle_t *pamh, - int chain, - int flag, - const char *modpath, - const char *options /* XXX */ __unused) + int chain, + int flag, + const char *modpath, + const char *options /* XXX */ __unused) { pam_chain_t *module, *iterator; int i; @@ -145,7 +145,7 @@ _pam_add_module(pam_handle_t *pamh, for (i = 0; i < PAM_NUM_PRIMITIVES; ++i) module->primitive[i] = dlsym(module->dlh, _pam_sm_func_name[i]); - + if ((iterator = pamh->chains[chain]) != NULL) { while (iterator->next != NULL) iterator = iterator->next; @@ -157,7 +157,7 @@ _pam_add_module(pam_handle_t *pamh, } #define PAM_CONF_STYLE 0 -#define PAM_D_STYLE 1 +#define PAM_D_STYLE 1 #define MAX_LINE_LEN 1024 static int @@ -180,7 +180,7 @@ _pam_read_policy_file(pam_handle_t *pamh, } openpam_log(PAM_LOG_DEBUG, "looking for '%s' in %s", service, filename); - + for (line = 1; fgets(buf, MAX_LINE_LEN, f) != NULL; ++line) { if ((len = strlen(buf)) == 0) continue; @@ -206,7 +206,7 @@ _pam_read_policy_file(pam_handle_t *pamh, continue; buf[len] = '\0'; p = q = buf; - + /* check service name */ if (style == PAM_CONF_STYLE) { for (q = p = buf; *q != '\0' && !isspace(*q); ++q) @@ -220,7 +220,7 @@ _pam_read_policy_file(pam_handle_t *pamh, filename, line, service); } - + /* get module type */ for (p = q; isspace(*p); ++p) /* nothing */; @@ -266,7 +266,7 @@ _pam_read_policy_file(pam_handle_t *pamh, filename, line, p); continue; } - + /* get module name */ for (p = q; isspace(*p); ++p) /* nothing */; @@ -274,7 +274,7 @@ _pam_read_policy_file(pam_handle_t *pamh, /* nothing */; if (q == p) goto syntax_error; - + /* get options */ if (*q != '\0') { *q++ = 0; @@ -283,8 +283,8 @@ _pam_read_policy_file(pam_handle_t *pamh, } /* - * Finally, add the module at the end of the - * appropriate chain and bump the counter. + * Finally, add the module at the end of the + * appropriate chain and bump the counter. */ if ((r = _pam_add_module(pamh, chain, flag, p, q)) != PAM_SUCCESS) @@ -302,7 +302,7 @@ _pam_read_policy_file(pam_handle_t *pamh, if (ferror(f)) openpam_log(PAM_LOG_ERROR, "%s: %m", filename); - + fclose(f); return (n); } @@ -313,10 +313,10 @@ static const char *_pam_policy_path[] = { "/usr/local/etc/pam.d/", NULL }; - + static int _pam_configure_service(pam_handle_t *pamh, - const char *service) + const char *service) { const char **path; char *filename; @@ -345,6 +345,6 @@ _pam_configure_service(pam_handle_t *pamh, if (r > 0) return (PAM_SUCCESS); } - + return (PAM_SYSTEM_ERR); } diff --git a/lib/pam_strerror.c b/lib/pam_strerror.c index be88639..516374c 100644 --- a/lib/pam_strerror.c +++ b/lib/pam_strerror.c @@ -54,7 +54,7 @@ pam_strerror(pam_handle_t *pamh, static char unknown[16]; pamh = pamh; - + switch (error_number) { case PAM_SUCCESS: return ("success"); diff --git a/modules/pam_deny/pam_deny.c b/modules/pam_deny/pam_deny.c index 68d6fc9..42c24d0 100644 --- a/modules/pam_deny/pam_deny.c +++ b/modules/pam_deny/pam_deny.c @@ -40,7 +40,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_AUTH_ERR); } @@ -48,7 +48,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_PERM_DENIED); } @@ -56,7 +56,7 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_AUTH_ERR); } diff --git a/modules/pam_permit/pam_permit.c b/modules/pam_permit/pam_permit.c index 4cd42af..ecdbd98 100644 --- a/modules/pam_permit/pam_permit.c +++ b/modules/pam_permit/pam_permit.c @@ -40,7 +40,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_SUCCESS); } @@ -48,7 +48,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_SUCCESS); } @@ -56,7 +56,7 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { - + return (PAM_SUCCESS); }