summaryrefslogtreecommitdiff
path: root/libpam
diff options
context:
space:
mode:
Diffstat (limited to 'libpam')
-rw-r--r--libpam/Makefile.am2
-rw-r--r--libpam/include/security/pam_appl.h5
-rw-r--r--libpam/libpam.map5
-rw-r--r--libpam/pam_handlers.c20
-rw-r--r--libpam/pam_private.h1
-rw-r--r--libpam/pam_start.c36
6 files changed, 62 insertions, 7 deletions
diff --git a/libpam/Makefile.am b/libpam/Makefile.am
index 9d5c844d..bd3dc5d3 100644
--- a/libpam/Makefile.am
+++ b/libpam/Makefile.am
@@ -25,7 +25,7 @@ include_HEADERS = include/security/_pam_compat.h \
noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
pam_modutil_private.h include/pam_cc_compat.h
-libpam_la_LDFLAGS = -no-undefined -version-info 84:2:84
+libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85
libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@
if HAVE_VERSIONING
diff --git a/libpam/include/security/pam_appl.h b/libpam/include/security/pam_appl.h
index d4172c69..cf97a493 100644
--- a/libpam/include/security/pam_appl.h
+++ b/libpam/include/security/pam_appl.h
@@ -24,6 +24,11 @@ pam_start(const char *service_name, const char *user,
const struct pam_conv *pam_conversation,
pam_handle_t **pamh);
+extern int PAM_NONNULL((1,3,5))
+pam_start_confdir(const char *service_name, const char *user,
+ const struct pam_conv *pam_conversation,
+ const char *confdir, pam_handle_t **pamh);
+
extern int PAM_NONNULL((1))
pam_end(pam_handle_t *pamh, int pam_status);
diff --git a/libpam/libpam.map b/libpam/libpam.map
index 74fb55b2..c9690a91 100644
--- a/libpam/libpam.map
+++ b/libpam/libpam.map
@@ -77,3 +77,8 @@ LIBPAM_MODUTIL_1.3.2 {
global:
pam_modutil_search_key;
} LIBPAM_MODUTIL_1.1.9;
+
+LIBPAM_1.4 {
+ global:
+ pam_start_confdir;
+} LIBPAM_1.0;
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
index 8e513da3..5dff58c2 100644
--- a/libpam/pam_handlers.c
+++ b/libpam/pam_handlers.c
@@ -285,7 +285,7 @@ _pam_open_config_file(pam_handle_t *pamh
, PAM_CONFIG_DIST2_DF
#endif
};
- char *p;
+ char *p = NULL;
FILE *f;
size_t i;
@@ -296,14 +296,21 @@ _pam_open_config_file(pam_handle_t *pamh
pam_syslog(pamh, LOG_CRIT, "strdup failed");
return PAM_BUF_ERR;
}
+ } else if (pamh->confdir != NULL) {
+ if (asprintf (&p, "%s/%s", pamh->confdir, service) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "asprintf failed");
+ return PAM_BUF_ERR;
+ }
+ }
- f = fopen(service, "r");
+ if (p != NULL) {
+ D(("opening %s", p));
+ f = fopen(p, "r");
if (f != NULL) {
*path = p;
*file = f;
return PAM_SUCCESS;
}
-
_pam_drop(p);
return PAM_ABORT;
}
@@ -313,6 +320,7 @@ _pam_open_config_file(pam_handle_t *pamh
pam_syslog(pamh, LOG_CRIT, "asprintf failed");
return PAM_BUF_ERR;
}
+
D(("opening %s", p));
f = fopen(p, "r");
if (f != NULL) {
@@ -438,7 +446,8 @@ int _pam_init_handlers(pam_handle_t *pamh)
struct stat test_d;
/* Is there a PAM_CONFIG_D directory? */
- if ((stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode)) ||
+ if (pamh->confdir != NULL ||
+ (stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode)) ||
(stat(PAM_CONFIG_DIST_D, &test_d) == 0 && S_ISDIR(test_d.st_mode))
#ifdef PAM_CONFIG_DIST2_D
|| (stat(PAM_CONFIG_DIST2_D, &test_d) == 0
@@ -471,7 +480,8 @@ int _pam_init_handlers(pam_handle_t *pamh)
#ifdef PAM_READ_BOTH_CONFS
D(("checking %s", PAM_CONFIG));
- if ((f = fopen(PAM_CONFIG,"r")) != NULL) {
+ if (pamh->confdir == NULL
+ && (f = fopen(PAM_CONFIG,"r")) != NULL) {
retval = _pam_parse_conf_file(pamh, f, NULL, PAM_T_ANY, 0, 1);
fclose(f);
} else
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
index ed02bb02..69d2ef44 100644
--- a/libpam/pam_private.h
+++ b/libpam/pam_private.h
@@ -178,6 +178,7 @@ struct pam_handle {
int audit_state; /* keep track of reported audit messages */
#endif
int authtok_verified;
+ char *confdir;
};
/* Values for select arg to _pam_dispatch() */
diff --git a/libpam/pam_start.c b/libpam/pam_start.c
index e27c64bb..59d06224 100644
--- a/libpam/pam_start.c
+++ b/libpam/pam_start.c
@@ -15,10 +15,11 @@
#include <string.h>
#include <syslog.h>
-int pam_start (
+static int _pam_start_internal (
const char *service_name,
const char *user,
const struct pam_conv *pam_conversation,
+ const char *confdir,
pam_handle_t **pamh)
{
D(("called pam_start: [%s] [%s] [%p] [%p]"
@@ -80,6 +81,18 @@ int pam_start (
} else
(*pamh)->user = NULL;
+ if (confdir) {
+ if (((*pamh)->confdir = _pam_strdup(confdir)) == NULL) {
+ pam_syslog(*pamh, LOG_CRIT,
+ "pam_start: _pam_strdup failed for confdir");
+ _pam_drop((*pamh)->service_name);
+ _pam_drop((*pamh)->user);
+ _pam_drop(*pamh);
+ return (PAM_BUF_ERR);
+ }
+ } else
+ (*pamh)->confdir = NULL;
+
(*pamh)->tty = NULL;
(*pamh)->prompt = NULL; /* prompt for pam_get_user() */
(*pamh)->ruser = NULL;
@@ -140,3 +153,24 @@ int pam_start (
return PAM_SUCCESS;
}
+
+int pam_start_confdir (
+ const char *service_name,
+ const char *user,
+ const struct pam_conv *pam_conversation,
+ const char *confdir,
+ pam_handle_t **pamh)
+{
+ return _pam_start_internal(service_name, user, pam_conversation,
+ confdir, pamh);
+}
+
+int pam_start (
+ const char *service_name,
+ const char *user,
+ const struct pam_conv *pam_conversation,
+ pam_handle_t **pamh)
+{
+ return _pam_start_internal(service_name, user, pam_conversation,
+ NULL, pamh);
+}