diff options
author | Russ Allbery <eagle@windlord> | 2006-11-10 15:37:31 -0800 |
---|---|---|
committer | Russ Allbery <eagle@windlord> | 2006-11-10 15:37:31 -0800 |
commit | d95d495c280b458c211f3337a5db8c6bdbb3c5c8 (patch) | |
tree | bc02c946de50498e2cc369ee72f4bdf0529c51bf | |
parent | cb2a38e4686cf6978403059a585d11c186cc61fa (diff) |
Now actually compiles and appears to work properly. Added the
program PAM argument to set which program to run and fixed lots of
syntax errors and extra and missing variables.
-rw-r--r-- | Makefile.in | 3 | ||||
-rw-r--r-- | internal.h | 9 | ||||
-rw-r--r-- | logging.c | 10 | ||||
-rw-r--r-- | options.c | 9 | ||||
-rw-r--r-- | public.c | 17 | ||||
-rw-r--r-- | sys-linux.c | 13 | ||||
-rw-r--r-- | tokens.c | 44 |
7 files changed, 53 insertions, 52 deletions
diff --git a/Makefile.in b/Makefile.in index 82e7145..6be389a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -25,12 +25,13 @@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ SOURCES = logging.c options.c public.c tokens.c -OBJECTS = $(SOURCES:.c=.o) +OBJECTS = $(SOURCES:.c=.o) @LIBOBJS@ all: pam_afs_session.so pam_afs_session.so: $(OBJECTS) $(CC) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS) + chmod 644 $@ install: pam_afs_session.so $(INSTALL) -d $(pamdir) @@ -23,6 +23,7 @@ struct pam_args { int ignore_root; /* Skip authentication for root. */ int minimum_uid; /* Ignore users below this UID. */ int nopag; /* Don't create a new PAG. */ + char *program; /* Program to run for tokens. */ int retain; /* Don't destroy the cache on session end. */ /* @@ -39,17 +40,13 @@ struct pam_args *pamafs_args_parse(int flags, int argc, const char **argv); /* Free the pam_args struct when we're done. */ void pamafs_args_free(struct pam_args *); -/* Returns true if we should ignore this user (root or low UID). */ -int pamafs_should_ignore(struct pam_args *, const struct passwd *pwd); - /* Token manipulation functions. */ int pamafs_token_get(pam_handle_t *pamh, struct pam_args *args); int pamafs_token_delete(pam_handle_t *pamh, struct pam_args *args); /* Error reporting and debugging functions. */ -void pamafs_error(struct context *, const char *, ...); -void pamafs_debug(struct context *, struct pam_args *, const char *, ...); -void pamafs_debug_pam(struct context *, struct pam_args *, const char *, int); +void pamafs_error(const char *, ...); +void pamafs_debug(struct pam_args *, const char *, ...); /* Macros to record entry and exit from the main PAM functions. */ #define ENTRY(args, flags) \ @@ -50,13 +50,3 @@ pamafs_debug(struct pam_args *pargs, const char *fmt, ...) va_end(args); syslog(LOG_DEBUG, "(pam_afs_session): %s", msg); } - - -/* - * Log a PAM failure if debugging is enabled. - */ -void -pamafs_debug_pam(struct pam_args *args, const char *msg, int status) -{ - pamafs_debug(ctx, args, "%s: %s", msg, pam_strerror(ctx->pamh, status)); -} @@ -48,11 +48,12 @@ pamafs_args_free(struct pam_args *args) * from krb5.conf, but that requires linking with Kerberos libraries. */ struct pam_args * -pamk5_args_parse(int flags, int argc, const char **argv) +pamafs_args_parse(int flags, int argc, const char **argv) { struct pam_args *args; + int i; - args = pamk5_args_new(); + args = pamafs_args_new(); if (args == NULL) return NULL; @@ -65,10 +66,12 @@ pamk5_args_parse(int flags, int argc, const char **argv) args->minimum_uid = atoi(&argv[i][strlen("minimum_uid=")]); else if (strcmp(argv[i], "nopag") == 0) args->nopag = 1; + else if (strncmp(argv[i], "program=", 8) == 0) + args->program = strdup(&argv[i][strlen("program=")]); else if (strcmp(argv[i], "retain_after_close") == 0) args->retain = 1; else - pamk5_error(NULL, "unknown option %s", argv[i]); + pamafs_error(NULL, "unknown option %s", argv[i]); } if (flags & PAM_SILENT) @@ -11,18 +11,16 @@ #include "config.h" #include <errno.h> -#include <pwd.h> #include <security/pam_appl.h> #include <security/pam_modules.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/types.h> #include <unistd.h> -#ifdef HAVE_KAFS_H +#if HAVE_KAFS_H # include <kafs.h> -#elif +#elif HAVE_KOPENAFS_H # include <kopenafs.h> #else int k_hasafs(void); @@ -43,10 +41,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, { struct pam_args *args; int pamret, status; - uid_t uid; - const char *user, *cache; const void *dummy; - struct passwd *pwd; args = pamafs_args_parse(flags, argc, argv); if (args == NULL) { @@ -69,7 +64,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, */ status = pam_get_data(pamh, "pam_afs_session", &dummy); if (status == PAM_SUCCESS) { - pamafs_debug("skipping, apparently already ran"); + pamafs_debug(args, "skipping, apparently already ran"); pamret = PAM_SUCCESS; goto done; } @@ -111,6 +106,7 @@ pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, { struct pam_args *args; int pamret, status; + const void *dummy; args = pamafs_args_parse(flags, argc, argv); if (args == NULL) { @@ -142,7 +138,7 @@ pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, if (!(flags & (PAM_REINITIALIZE_CRED | PAM_REFRESH_CRED))) { status = pam_get_data(pamh, "pam_afs_session", &dummy); if (status == PAM_SUCCESS) { - pamafs_debug("skipping, apparently already ran"); + pamafs_debug(args, "skipping, apparently already ran"); pamret = PAM_SUCCESS; goto done; } @@ -171,7 +167,6 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, { struct pam_args *args; int pamret; - const void *dummy; args = pamafs_args_parse(flags, argc, argv); if (args == NULL) { @@ -183,7 +178,7 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, /* Do nothing if so configured. */ if (args->retain) { - pamafs_debug("skipping as configured"); + pamafs_debug(args, "skipping as configured"); pamret = PAM_SUCCESS; goto done; } diff --git a/sys-linux.c b/sys-linux.c index 6b06112..27baa6a 100644 --- a/sys-linux.c +++ b/sys-linux.c @@ -19,7 +19,9 @@ #include "config.h" +#include <errno.h> #include <fcntl.h> +#include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -44,7 +46,7 @@ struct ViceIoctl { void *in, *out; short in_size; short out_size; -} +}; /* * The workhorse function that does the actual system call. All the values @@ -59,7 +61,7 @@ afs_syscall(long syscall, long param1, long param2, long param3, long param4, int *rval) { struct afsprocdata syscall_data; - int fd; + int fd, oerrno; fd = open("/proc/fs/openafs/afs_ioctl", O_RDWR); if (fd < 0) @@ -74,7 +76,9 @@ afs_syscall(long syscall, long param1, long param2, long param3, long param4, syscall_data.param4 = param4; *rval = ioctl(fd, _IOW('C', 1, void *), &syscall_data); + oerrno = errno; close(fd); + errno = oerrno; return 0; } @@ -104,13 +108,14 @@ int k_hasafs(void) { struct ViceIoctl iob; - int result; + int id, result, err; iob.in = NULL; iob.in_size = 0; iob.out = NULL; iob.out_size = 0; - result = k_pioctl(NULL, _IOW('V', 3, struct ViceIoctl), &iob, 0); + id = _IOW('V', 3, struct ViceIoctl); + result = afs_syscall(20, 0, id, (long) &iob, 0, &err); return (result == 0); } @@ -15,13 +15,14 @@ #include <pwd.h> #include <security/pam_modules.h> #include <stdio.h> +#include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> -#ifdef HAVE_KAFS_H +#if HAVE_KAFS_H # include <kafs.h> -#elif +#elif HAVE_KOPENAFS_H # include <kopenafs.h> #else int k_unlog(void); @@ -43,10 +44,9 @@ pamafs_should_ignore(struct pam_args *args, const struct passwd *pwd) return 1; } if (args->minimum_uid > 0 && pwd->pw_uid < args->minimum_uid) { - pamk5_debug(ctx, args, "ignoring low-UID user (%lu < %d)", + pamafs_debug(args, "ignoring low-UID user (%lu < %d)", (unsigned long) pwd->pw_uid, args->minimum_uid); - return 1; - } + return 1; } return 0; } @@ -58,12 +58,23 @@ pamafs_should_ignore(struct pam_args *args, const struct passwd *pwd) * PAM_SESSION_ERR. */ static int -pamafs_run_aklog(struct pam_args *args, uid_t uid) +pamafs_run_aklog(pam_handle_t *pamh, struct pam_args *args, uid_t uid) { - int status, result; + int result; char **env; pid_t child; + /* Sanity check that we have some program to run. */ + if (args->program == NULL) { + pamafs_error("no token program set in PAM arguments"); + return PAM_SESSION_ERR; + } + + /* + * Run the program. Be sure to use _exit instead of exit in the + * subprocess so that we won't run exit handlers or double-flush stdio + * buffers in the child process. + */ pamafs_debug(args, "running %s as UID %lu", args->program, (unsigned long) uid); env = pam_getenvlist(pamh); @@ -71,7 +82,7 @@ pamafs_run_aklog(struct pam_args *args, uid_t uid) if (child < 0) return PAM_SESSION_ERR; else if (child == 0) { - if (setuid(pwd->pw_uid) < 0) { + if (setuid(uid) < 0) { pamafs_error("cannot setuid to UID %lu: %s", (unsigned long) uid, strerror(errno)); _exit(1); @@ -98,20 +109,19 @@ pamafs_token_get(pam_handle_t *pamh, struct pam_args *args) { int status; const char *user, *cache; - const void *dummy; struct passwd *pwd; /* Don't try to get a token unless we have a K5 ticket cache. */ cache = pam_getenv(pamh, "KRB5CCNAME"); if (cache == NULL) { - pamafs_debug("skipping, no Kerberos ticket cache"); + pamafs_debug(args, "skipping, no Kerberos ticket cache"); return PAM_SUCCESS; } /* Get the user, look them up, and see if we should skip this user. */ status = pam_get_user(pamh, &user, NULL); if (status != PAM_SUCCESS || user == NULL) { - pamafs_error("no user set: %s", pam_strerror(status)); + pamafs_error("no user set: %s", pam_strerror(pamh, status)); return PAM_SESSION_ERR; } pwd = getpwnam(user); @@ -121,11 +131,12 @@ pamafs_token_get(pam_handle_t *pamh, struct pam_args *args) } if (pamafs_should_ignore(args, pwd)) return PAM_SUCCESS; - status = pamafs_run_aklog(args, pwd->pw_uid); + status = pamafs_run_aklog(pamh, args, pwd->pw_uid); if (status == PAM_SUCCESS) { status = pam_set_data(pamh, "pam_afs_session", "yes", NULL); if (status != PAM_SUCCESS) { - pamafs_error("cannot set success data: %s", pam_strerror(status)); + pamafs_error("cannot set success data: %s", + pam_strerror(pamh, status)); status = PAM_SESSION_ERR; } } else @@ -141,15 +152,14 @@ pamafs_token_get(pam_handle_t *pamh, struct pam_args *args) int pamafs_token_delete(pam_handle_t *pamh, struct pam_args *args) { - int pamret; + const void *dummy; /* * Do nothing if open_session (or setcred) didn't run. Otherwise, we may * be wiping out some other token that we aren't responsible for. */ - status = pam_get_data(pamh, "pam_afs_session", &dummy); - if (status != PAM_SUCCESS) { - pamafs_debug("skipping, no open session"); + if (pam_get_data(pamh, "pam_afs_session", &dummy) != PAM_SUCCESS) { + pamafs_debug(args, "skipping, no open session"); return PAM_SUCCESS; } |