mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
third_party: Update pam_wrapper to version 1.1.2
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
2a5d994b1a
commit
61a6bf82d4
@ -44,5 +44,5 @@ Build.BuildContext.CHECK_UID_WRAPPER = CHECK_UID_WRAPPER
|
||||
|
||||
@conf
|
||||
def CHECK_PAM_WRAPPER(conf):
|
||||
return conf.CHECK_BUNDLED_SYSTEM_PKG('pam_wrapper', minversion='1.0.7')
|
||||
return conf.CHECK_BUNDLED_SYSTEM_PKG('pam_wrapper', minversion='1.1.2')
|
||||
Build.BuildContext.CHECK_PAM_WRAPPER = CHECK_PAM_WRAPPER
|
||||
|
432
third_party/pam_wrapper/pam_wrapper.c
vendored
432
third_party/pam_wrapper/pam_wrapper.c
vendored
@ -36,6 +36,8 @@
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <ftw.h>
|
||||
|
||||
#ifdef HAVE_SECURITY_PAM_APPL_H
|
||||
@ -97,6 +99,19 @@
|
||||
* LOGGING
|
||||
*****************/
|
||||
|
||||
#ifndef HAVE_GETPROGNAME
|
||||
static const char *getprogname(void)
|
||||
{
|
||||
#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
|
||||
return program_invocation_short_name;
|
||||
#elif defined(HAVE_GETEXECNAME)
|
||||
return getexecname();
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
|
||||
}
|
||||
#endif /* HAVE_GETPROGNAME */
|
||||
|
||||
enum pwrap_dbglvl_e {
|
||||
PWRAP_LOG_ERROR = 0,
|
||||
PWRAP_LOG_WARN,
|
||||
@ -123,6 +138,7 @@ static void pwrap_vlog(enum pwrap_dbglvl_e dbglvl,
|
||||
const char *d;
|
||||
unsigned int lvl = 0;
|
||||
const char *prefix = "PWRAP";
|
||||
const char *progname = getprogname();
|
||||
|
||||
d = getenv("PAM_WRAPPER_DEBUGLEVEL");
|
||||
if (d != NULL) {
|
||||
@ -150,10 +166,15 @@ static void pwrap_vlog(enum pwrap_dbglvl_e dbglvl,
|
||||
break;
|
||||
}
|
||||
|
||||
if (progname == NULL) {
|
||||
progname = "<unknown>";
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s(%d) - %s: %s\n",
|
||||
"%s[%s (%u)] - %s: %s\n",
|
||||
prefix,
|
||||
(int)getpid(),
|
||||
progname,
|
||||
(unsigned int)getpid(),
|
||||
function,
|
||||
buffer);
|
||||
}
|
||||
@ -180,6 +201,12 @@ typedef int (*__libpam_pam_start)(const char *service_name,
|
||||
const struct pam_conv *pam_conversation,
|
||||
pam_handle_t **pamh);
|
||||
|
||||
typedef int (*__libpam_pam_start_confdir)(const char *service_name,
|
||||
const char *user,
|
||||
const struct pam_conv *pam_conversation,
|
||||
const char *confdir,
|
||||
pam_handle_t **pamh);
|
||||
|
||||
typedef int (*__libpam_pam_end)(pam_handle_t *pamh, int pam_status);
|
||||
|
||||
typedef int (*__libpam_pam_authenticate)(pam_handle_t *pamh, int flags);
|
||||
@ -243,6 +270,7 @@ typedef void (*__libpam_pam_vsyslog)(const pam_handle_t *pamh,
|
||||
|
||||
struct pwrap_libpam_symbols {
|
||||
PWRAP_SYMBOL_ENTRY(pam_start);
|
||||
PWRAP_SYMBOL_ENTRY(pam_start_confdir);
|
||||
PWRAP_SYMBOL_ENTRY(pam_end);
|
||||
PWRAP_SYMBOL_ENTRY(pam_authenticate);
|
||||
PWRAP_SYMBOL_ENTRY(pam_chauthtok);
|
||||
@ -300,15 +328,25 @@ static void *pwrap_load_lib_handle(enum pwrap_lib lib)
|
||||
void *handle = NULL;
|
||||
|
||||
#ifdef RTLD_DEEPBIND
|
||||
const char *env = getenv("LD_PRELOAD");
|
||||
const char *env_preload = getenv("LD_PRELOAD");
|
||||
const char *env_deepbind = getenv("UID_WRAPPER_DISABLE_DEEPBIND");
|
||||
bool enable_deepbind = true;
|
||||
|
||||
/* Don't do a deepbind if we run with libasan */
|
||||
if (env != NULL && strlen(env) < PATH_MAX) {
|
||||
const char *p = strstr(env, "libasan.so");
|
||||
if (p == NULL) {
|
||||
flags |= RTLD_DEEPBIND;
|
||||
if (env_preload != NULL && strlen(env_preload) < 1024) {
|
||||
const char *p = strstr(env_preload, "libasan.so");
|
||||
if (p != NULL) {
|
||||
enable_deepbind = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (env_deepbind != NULL && strlen(env_deepbind) >= 1) {
|
||||
enable_deepbind = false;
|
||||
}
|
||||
|
||||
if (enable_deepbind) {
|
||||
flags |= RTLD_DEEPBIND;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (lib) {
|
||||
@ -368,6 +406,22 @@ static void *_pwrap_bind_symbol(enum pwrap_lib lib, const char *fn_name)
|
||||
* valgrind and has probably something todo with with the linker.
|
||||
* So we need load each function at the point it is called the first time.
|
||||
*/
|
||||
#ifdef HAVE_PAM_START_CONFDIR
|
||||
static int libpam_pam_start_confdir(const char *service_name,
|
||||
const char *user,
|
||||
const struct pam_conv *pam_conversation,
|
||||
const char *confdir,
|
||||
pam_handle_t **pamh)
|
||||
{
|
||||
pwrap_bind_symbol_libpam(pam_start_confdir);
|
||||
|
||||
return pwrap.libpam.symbols._libpam_pam_start_confdir.f(service_name,
|
||||
user,
|
||||
pam_conversation,
|
||||
confdir,
|
||||
pamh);
|
||||
}
|
||||
#else
|
||||
static int libpam_pam_start(const char *service_name,
|
||||
const char *user,
|
||||
const struct pam_conv *pam_conversation,
|
||||
@ -381,6 +435,8 @@ static int libpam_pam_start(const char *service_name,
|
||||
pamh);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int libpam_pam_end(pam_handle_t *pamh, int pam_status)
|
||||
{
|
||||
pwrap_bind_symbol_libpam(pam_end);
|
||||
@ -748,14 +804,151 @@ static void pwrap_clean_stale_dirs(const char *dir)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PAM_START_CONFDIR
|
||||
static void pwrap_init(void)
|
||||
{
|
||||
char tmp_config_dir[] = "/tmp/pam.X";
|
||||
size_t len = strlen(tmp_config_dir);
|
||||
const char *env;
|
||||
struct stat sb;
|
||||
int rc;
|
||||
unsigned i;
|
||||
ssize_t ret;
|
||||
FILE *pidfile;
|
||||
char pidfile_path[1024] = { 0 };
|
||||
char letter;
|
||||
|
||||
if (!pam_wrapper_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pwrap.initialised) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The name is selected to match/replace /etc/pam.d
|
||||
* We start from a random alphanum trying letters until
|
||||
* an available directory is found.
|
||||
*/
|
||||
letter = 48 + (getpid() % 70);
|
||||
for (i = 0; i < 127; i++) {
|
||||
if (isalpha(letter) || isdigit(letter)) {
|
||||
tmp_config_dir[len - 1] = letter;
|
||||
|
||||
rc = lstat(tmp_config_dir, &sb);
|
||||
if (rc == 0) {
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE,
|
||||
"Check if pam_wrapper dir %s is a "
|
||||
"stale directory",
|
||||
tmp_config_dir);
|
||||
pwrap_clean_stale_dirs(tmp_config_dir);
|
||||
} else if (rc < 0) {
|
||||
if (errno != ENOENT) {
|
||||
continue;
|
||||
}
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
|
||||
letter++;
|
||||
letter %= 127;
|
||||
}
|
||||
|
||||
if (i == 127) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR,
|
||||
"Failed to find a possible path to create "
|
||||
"pam_wrapper config dir: %s",
|
||||
tmp_config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_DEBUG, "Initialize pam_wrapper");
|
||||
|
||||
pwrap.config_dir = strdup(tmp_config_dir);
|
||||
if (pwrap.config_dir == NULL) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR,
|
||||
"No memory");
|
||||
exit(1);
|
||||
}
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE,
|
||||
"pam_wrapper config dir: %s",
|
||||
tmp_config_dir);
|
||||
|
||||
rc = mkdir(pwrap.config_dir, 0755);
|
||||
if (rc != 0) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR,
|
||||
"Failed to create pam_wrapper config dir: %s - %s",
|
||||
tmp_config_dir, strerror(errno));
|
||||
}
|
||||
|
||||
/* Create file with the PID of the the process */
|
||||
ret = snprintf(pidfile_path, sizeof(pidfile_path),
|
||||
"%s/pid", pwrap.config_dir);
|
||||
if (ret < 0) {
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pidfile = fopen(pidfile_path, "w");
|
||||
if (pidfile == NULL) {
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = fprintf(pidfile, "%d", getpid());
|
||||
fclose(pidfile);
|
||||
if (rc <= 0) {
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pwrap.libpam_so = strdup(PAM_LIBRARY);
|
||||
if (pwrap.libpam_so == NULL) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR, "No memory");
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE, "Using libpam path: %s", pwrap.libpam_so);
|
||||
|
||||
pwrap.initialised = true;
|
||||
|
||||
env = getenv("PAM_WRAPPER_SERVICE_DIR");
|
||||
if (env == NULL) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR, "No config file");
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = copy_confdir(env);
|
||||
if (rc != 0) {
|
||||
PWRAP_LOG(PWRAP_LOG_ERROR, "Failed to copy config files");
|
||||
p_rmdirs(pwrap.config_dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
setenv("PAM_WRAPPER_RUNTIME_DIR", pwrap.config_dir, 1);
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_DEBUG, "Successfully initialized pam_wrapper");
|
||||
}
|
||||
|
||||
#else /* HAVE_PAM_START_CONFDIR */
|
||||
|
||||
#ifdef HAVE_PAM_MODUTIL_SEARCH_KEY
|
||||
/*
|
||||
* This is needed to workaround Tumbleweed which packages a libpam git version.
|
||||
*/
|
||||
static int pso_copy(const char *src, const char *dst, const char *pdir, mode_t mode)
|
||||
{
|
||||
#define PSO_COPY_READ_SIZE 16
|
||||
int srcfd = -1;
|
||||
int dstfd = -1;
|
||||
int rc = -1;
|
||||
ssize_t bread, bwritten;
|
||||
struct stat sb;
|
||||
char buf[10];
|
||||
char buf[PSO_COPY_READ_SIZE + 1];
|
||||
size_t pso_copy_read_size = PSO_COPY_READ_SIZE;
|
||||
int cmp;
|
||||
size_t to_read;
|
||||
bool found_slash;
|
||||
@ -802,14 +995,36 @@ static int pso_copy(const char *src, const char *dst, const char *pdir, mode_t m
|
||||
to_read = 1;
|
||||
if (!found_slash && buf[0] == '/') {
|
||||
found_slash = true;
|
||||
to_read = 9;
|
||||
to_read = pso_copy_read_size;
|
||||
}
|
||||
|
||||
if (found_slash && bread == 9) {
|
||||
if (found_slash && bread == PSO_COPY_READ_SIZE) {
|
||||
cmp = memcmp(buf, "usr/etc/pam.d/%s", 16);
|
||||
if (cmp == 0) {
|
||||
char tmp[16] = {0};
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s/%%s", pdir + 1);
|
||||
|
||||
memcpy(buf, tmp, 12);
|
||||
memset(&buf[12], '\0', 4);
|
||||
|
||||
/*
|
||||
* If we found this string, we need to reduce
|
||||
* the read size to not miss, the next one.
|
||||
*/
|
||||
pso_copy_read_size = 13;
|
||||
} else {
|
||||
cmp = memcmp(buf, "usr/etc/pam.d", 13);
|
||||
if (cmp == 0) {
|
||||
memcpy(buf, pdir + 1, 9);
|
||||
memset(&buf[9], '\0', 4);
|
||||
} else {
|
||||
cmp = memcmp(buf, "etc/pam.d", 9);
|
||||
if (cmp == 0) {
|
||||
memcpy(buf, pdir + 1, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
found_slash = false;
|
||||
}
|
||||
|
||||
@ -840,7 +1055,106 @@ out:
|
||||
}
|
||||
|
||||
return rc;
|
||||
#undef PSO_COPY_READ_SIZE
|
||||
}
|
||||
#else /* HAVE_PAM_MODUTIL_SEARCH_KEY */
|
||||
|
||||
static int pso_copy(const char *src, const char *dst, const char *pdir, mode_t mode)
|
||||
{
|
||||
#define PSO_COPY_READ_SIZE 9
|
||||
int srcfd = -1;
|
||||
int dstfd = -1;
|
||||
int rc = -1;
|
||||
ssize_t bread, bwritten;
|
||||
struct stat sb;
|
||||
char buf[PSO_COPY_READ_SIZE + 1];
|
||||
int cmp;
|
||||
size_t to_read;
|
||||
bool found_slash;
|
||||
|
||||
cmp = strcmp(src, dst);
|
||||
if (cmp == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
srcfd = open(src, O_RDONLY, 0);
|
||||
if (srcfd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == 0) {
|
||||
rc = fstat(srcfd, &sb);
|
||||
if (rc != 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
mode = sb.st_mode;
|
||||
}
|
||||
|
||||
dstfd = open(dst, O_CREAT|O_WRONLY|O_TRUNC, mode);
|
||||
if (dstfd < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
found_slash = false;
|
||||
to_read = 1;
|
||||
|
||||
for (;;) {
|
||||
bread = read(srcfd, buf, to_read);
|
||||
if (bread == 0) {
|
||||
/* done */
|
||||
break;
|
||||
} else if (bread < 0) {
|
||||
errno = EIO;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
to_read = 1;
|
||||
if (!found_slash && buf[0] == '/') {
|
||||
found_slash = true;
|
||||
to_read = PSO_COPY_READ_SIZE;
|
||||
}
|
||||
|
||||
if (found_slash && bread == PSO_COPY_READ_SIZE) {
|
||||
cmp = memcmp(buf, "etc/pam.d", PSO_COPY_READ_SIZE);
|
||||
if (cmp == 0) {
|
||||
memcpy(buf, pdir + 1, PSO_COPY_READ_SIZE);
|
||||
}
|
||||
found_slash = false;
|
||||
}
|
||||
|
||||
bwritten = write(dstfd, buf, bread);
|
||||
if (bwritten < 0) {
|
||||
errno = EIO;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bread != bwritten) {
|
||||
errno = EFAULT;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
if (srcfd != -1) {
|
||||
close(srcfd);
|
||||
}
|
||||
if (dstfd != -1) {
|
||||
close(dstfd);
|
||||
}
|
||||
if (rc < 0) {
|
||||
unlink(dst);
|
||||
}
|
||||
|
||||
return rc;
|
||||
#undef PSO_COPY_READ_SIZE
|
||||
}
|
||||
#endif /* HAVE_PAM_MODUTIL_SEARCH_KEY */
|
||||
|
||||
static void pwrap_init(void)
|
||||
{
|
||||
@ -1027,6 +1341,8 @@ static void pwrap_init(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE, "Using libpam path: %s", pwrap.libpam_so);
|
||||
|
||||
pwrap.initialised = true;
|
||||
|
||||
env = getenv("PAM_WRAPPER_SERVICE_DIR");
|
||||
@ -1047,6 +1363,7 @@ static void pwrap_init(void)
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_DEBUG, "Successfully initialized pam_wrapper");
|
||||
}
|
||||
#endif /* HAVE_PAM_START_CONFDIR */
|
||||
|
||||
bool pam_wrapper_enabled(void)
|
||||
{
|
||||
@ -1071,19 +1388,6 @@ bool pam_wrapper_enabled(void)
|
||||
return pwrap.enabled;
|
||||
}
|
||||
|
||||
/****************************
|
||||
* CONSTRUCTOR
|
||||
***************************/
|
||||
void pwrap_constructor(void)
|
||||
{
|
||||
/*
|
||||
* Here is safe place to call pwrap_init() and initialize data
|
||||
* for main process.
|
||||
*/
|
||||
pwrap_init();
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_OPENPAM
|
||||
static int pwrap_openpam_start(const char *service_name,
|
||||
const char *user,
|
||||
@ -1139,22 +1443,35 @@ static int pwrap_pam_start(const char *service_name,
|
||||
const struct pam_conv *pam_conversation,
|
||||
pam_handle_t **pamh)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pwrap_init();
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE,
|
||||
"pam_start service=%s, user=%s",
|
||||
service_name,
|
||||
user);
|
||||
|
||||
#ifdef HAVE_OPENPAM
|
||||
return pwrap_openpam_start(service_name,
|
||||
#if defined(HAVE_OPENPAM)
|
||||
rc = pwrap_openpam_start(service_name,
|
||||
user,
|
||||
pam_conversation,
|
||||
pamh);
|
||||
#elif defined (HAVE_PAM_START_CONFDIR)
|
||||
rc = libpam_pam_start_confdir(service_name,
|
||||
user,
|
||||
pam_conversation,
|
||||
pwrap.config_dir,
|
||||
pamh);
|
||||
#else
|
||||
return libpam_pam_start(service_name,
|
||||
rc = libpam_pam_start(service_name,
|
||||
user,
|
||||
pam_conversation,
|
||||
pamh);
|
||||
#endif
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE, "pam_start rc=%d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -1678,21 +1995,77 @@ int cannot_audit(int x)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************
|
||||
* CONSTRUCTOR
|
||||
***************************/
|
||||
|
||||
/*
|
||||
* Handler executed before fork(2) processing starts.
|
||||
*/
|
||||
static void pwrap_thread_prepare(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler that is executed in the parent process after fork(2) processing
|
||||
* completes.
|
||||
*/
|
||||
static void pwrap_thread_parent(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler that is executed in the child process after fork(2) processing
|
||||
* completes.
|
||||
*/
|
||||
static void pwrap_thread_child(void)
|
||||
{
|
||||
pwrap.initialised = false;
|
||||
}
|
||||
|
||||
void pwrap_constructor(void)
|
||||
{
|
||||
/*
|
||||
* If we hold a lock and the application forks, then the child
|
||||
* is not able to unlock the mutex and we are in a deadlock.
|
||||
* This should prevent such deadlocks.
|
||||
*/
|
||||
pthread_atfork(&pwrap_thread_prepare,
|
||||
&pwrap_thread_parent,
|
||||
&pwrap_thread_child);
|
||||
|
||||
/*
|
||||
* Here is safe place to call pwrap_init() and initialize data
|
||||
* for main process.
|
||||
*/
|
||||
pwrap_init();
|
||||
}
|
||||
|
||||
/****************************
|
||||
* DESTRUCTOR
|
||||
***************************/
|
||||
|
||||
static int p_rmdirs_at(const char *path, int parent_fd)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *dp;
|
||||
DIR *d = NULL;
|
||||
struct dirent *dp = NULL;
|
||||
struct stat sb;
|
||||
char fd_str[64] = { 0 };
|
||||
int path_fd;
|
||||
int rc;
|
||||
|
||||
switch(parent_fd) {
|
||||
case AT_FDCWD:
|
||||
snprintf(fd_str, sizeof(fd_str), "CWD");
|
||||
break;
|
||||
default:
|
||||
snprintf(fd_str, sizeof(fd_str), "fd=%d", parent_fd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If path is absolute, parent_fd is ignored. */
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE,
|
||||
"p_rmdirs_at removing %s at %d\n", path, parent_fd);
|
||||
"p_rmdirs_at removing %s at %s\n", path, fd_str);
|
||||
|
||||
path_fd = openat(parent_fd,
|
||||
path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
@ -1773,6 +2146,7 @@ void pwrap_destructor(void)
|
||||
if (!pwrap.initialised) {
|
||||
return;
|
||||
}
|
||||
pwrap.initialised = false;
|
||||
|
||||
PWRAP_LOG(PWRAP_LOG_TRACE,
|
||||
"destructor called for pam_wrapper dir %s",
|
||||
|
67
third_party/pam_wrapper/python/pypamtest.c
vendored
67
third_party/pam_wrapper/python/pypamtest.c
vendored
@ -166,11 +166,13 @@ static char **new_conv_list(const size_t list_size)
|
||||
return list;
|
||||
}
|
||||
|
||||
static const char **sequence_as_string_list(PyObject *seq,
|
||||
const char *paramname)
|
||||
static int sequence_as_string_list(PyObject *seq,
|
||||
const char *paramname,
|
||||
const char **str_list[],
|
||||
size_t *num_str_list)
|
||||
{
|
||||
const char *p = paramname ? paramname : "attribute values";
|
||||
const char **ret;
|
||||
const char **result;
|
||||
PyObject *utf_item;
|
||||
int i;
|
||||
Py_ssize_t len;
|
||||
@ -179,18 +181,18 @@ static const char **sequence_as_string_list(PyObject *seq,
|
||||
if (!PySequence_Check(seq)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"The object must be a sequence\n");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = PySequence_Size(seq);
|
||||
if (len == -1) {
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = PyMem_New(const char *, (len + 1));
|
||||
if (!ret) {
|
||||
result = PyMem_New(const char *, (len + 1));
|
||||
if (result == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
@ -202,20 +204,24 @@ static const char **sequence_as_string_list(PyObject *seq,
|
||||
utf_item = get_utf8_string(item, p);
|
||||
if (utf_item == NULL) {
|
||||
Py_DECREF(item);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret[i] = py_strdup(PyBytes_AsString(utf_item));
|
||||
result[i] = py_strdup(PyBytes_AsString(utf_item));
|
||||
Py_DECREF(utf_item);
|
||||
if (!ret[i]) {
|
||||
if (result[i] == NULL) {
|
||||
Py_DECREF(item);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
ret[i] = NULL;
|
||||
return ret;
|
||||
result[i] = NULL;
|
||||
|
||||
*str_list = result;
|
||||
*num_str_list = (size_t)len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *string_list_as_tuple(char **str_list)
|
||||
@ -225,7 +231,7 @@ static PyObject *string_list_as_tuple(char **str_list)
|
||||
PyObject *tup;
|
||||
PyObject *py_str;
|
||||
|
||||
for (len=0; len < PAM_CONV_MSG_MAX; len++) {
|
||||
for (len=0; str_list[len] != NULL; len++) {
|
||||
if (str_list[len][0] == '\0') {
|
||||
/* unused string, stop counting */
|
||||
break;
|
||||
@ -297,7 +303,7 @@ set_pypamtest_exception(PyObject *exc,
|
||||
|
||||
if (test_repr[0] != '\0' && failed != NULL) {
|
||||
PyErr_Format(exc,
|
||||
"Error [%d]: Test case %s retured [%d]",
|
||||
"Error [%d]: Test case %s returned [%d]",
|
||||
perr, test_repr, failed->op_rv);
|
||||
} else {
|
||||
obj = Py_BuildValue(discard_const_p(char, "(i,s)"),
|
||||
@ -808,27 +814,42 @@ static int fill_conv_data(PyObject *py_echo_off,
|
||||
PyObject *py_echo_on,
|
||||
struct pamtest_conv_data *conv_data)
|
||||
{
|
||||
size_t conv_count = 0;
|
||||
size_t count = 0;
|
||||
int rc;
|
||||
|
||||
conv_data->in_echo_on = NULL;
|
||||
conv_data->in_echo_off = NULL;
|
||||
conv_data->out_err = NULL;
|
||||
conv_data->out_info = NULL;
|
||||
|
||||
if (py_echo_off != NULL) {
|
||||
conv_data->in_echo_off = sequence_as_string_list(py_echo_off,
|
||||
"echo_off");
|
||||
if (conv_data->in_echo_off == NULL) {
|
||||
rc = sequence_as_string_list(py_echo_off,
|
||||
"echo_off",
|
||||
&conv_data->in_echo_off,
|
||||
&count);
|
||||
if (rc != 0) {
|
||||
free_conv_data(conv_data);
|
||||
return ENOMEM;
|
||||
}
|
||||
conv_count += count;
|
||||
}
|
||||
|
||||
if (py_echo_on != NULL) {
|
||||
conv_data->in_echo_on = sequence_as_string_list(py_echo_on,
|
||||
"echo_on");
|
||||
if (conv_data->in_echo_on == NULL) {
|
||||
rc = sequence_as_string_list(py_echo_on,
|
||||
"echo_on",
|
||||
&conv_data->in_echo_on,
|
||||
&count);
|
||||
if (rc != 0) {
|
||||
free_conv_data(conv_data);
|
||||
return ENOMEM;
|
||||
}
|
||||
conv_count += count;
|
||||
}
|
||||
|
||||
if (conv_count > PAM_CONV_MSG_MAX) {
|
||||
free_conv_data(conv_data);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
conv_data->out_info = new_conv_list(PAM_CONV_MSG_MAX);
|
||||
@ -885,7 +906,7 @@ static int py_tc_list_to_cstruct_list(PyObject *py_test_list,
|
||||
PyDoc_STRVAR(RunPamTest__doc__,
|
||||
"Run PAM tests\n\n"
|
||||
"This function runs PAM test cases and reports result\n"
|
||||
"Paramaters:\n"
|
||||
"Parameters:\n"
|
||||
"service: The PAM service to use in the conversation (string)\n"
|
||||
"username: The user to run PAM conversation as\n"
|
||||
"test_list: Sequence of pypamtest.TestCase objects\n"
|
||||
|
14
third_party/pam_wrapper/wscript
vendored
14
third_party/pam_wrapper/wscript
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
import os
|
||||
|
||||
VERSION="1.0.7"
|
||||
VERSION="1.1.2"
|
||||
|
||||
def find_library(library_names, lookup_paths):
|
||||
for directory in lookup_paths:
|
||||
@ -51,6 +51,16 @@ def configure(conf):
|
||||
checklibc=False,
|
||||
headers='security/pam_ext.h')
|
||||
|
||||
conf.CHECK_FUNCS_IN('pam_start_confdir',
|
||||
'pam',
|
||||
checklibc=False,
|
||||
headers='security/pam_appl.h')
|
||||
|
||||
conf.CHECK_FUNCS_IN('pam_modutil_search_key',
|
||||
'pam',
|
||||
checklibc=False,
|
||||
headers='security/pam_modutil.h')
|
||||
|
||||
conf.CHECK_C_PROTOTYPE('pam_vprompt',
|
||||
'int pam_vprompt(const pam_handle_t *_pamh, int _style, char **_resp, const char *_fmt, va_list _ap)',
|
||||
define='HAVE_PAM_VPROMPT_CONST', headers='stdio.h sys/types.h security/pam_appl.h security/pam_modules.h')
|
||||
@ -86,7 +96,7 @@ def build(bld):
|
||||
# breaks preloading!
|
||||
bld.SAMBA_LIBRARY('pam_wrapper',
|
||||
source='pam_wrapper.c',
|
||||
deps='dl',
|
||||
deps='dl pthread',
|
||||
install=False,
|
||||
realname='libpam-wrapper.so')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user