summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <eagle@windlord>2006-11-10 15:37:31 -0800
committerRuss Allbery <eagle@windlord>2006-11-10 15:37:31 -0800
commitd95d495c280b458c211f3337a5db8c6bdbb3c5c8 (patch)
treebc02c946de50498e2cc369ee72f4bdf0529c51bf
parentcb2a38e4686cf6978403059a585d11c186cc61fa (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.in3
-rw-r--r--internal.h9
-rw-r--r--logging.c10
-rw-r--r--options.c9
-rw-r--r--public.c17
-rw-r--r--sys-linux.c13
-rw-r--r--tokens.c44
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)
diff --git a/internal.h b/internal.h
index e7dc15f..ae012a9 100644
--- a/internal.h
+++ b/internal.h
@@ -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) \
diff --git a/logging.c b/logging.c
index 83796fb..9eab9ac 100644
--- a/logging.c
+++ b/logging.c
@@ -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));
-}
diff --git a/options.c b/options.c
index 1fdfc15..4dd2dff 100644
--- a/options.c
+++ b/options.c
@@ -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)
diff --git a/public.c b/public.c
index 451f059..54fa55f 100644
--- a/public.c
+++ b/public.c
@@ -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);
}
diff --git a/tokens.c b/tokens.c
index 2bec3ed..b299b1c 100644
--- a/tokens.c
+++ b/tokens.c
@@ -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;
}