mirror of
git://git.gnu.org.ua/pam-modules.git
synced 2025-04-26 00:19:52 +03:00
Major cleanup
* lib/graypam.h (gray_pam_init) (gray_raise,gray_malloc,gray_zalloc,gray_calloc) (gray_realloc,gray_strdup): Remove. (gray_slist_err,gray_slist_clrerr): New functions. (gray_slist_append,gray_slist_append_char): Return ssize_t. (gray_slist_coalesce): Likewise. (gray_slist_grow_backslash_num) (gray_slist_grow_backslash): Return int. (errno_to_pam): New function. (gray_set_transform_expr): Return int. * lib/mem.c (gray_raise,gray_malloc,gray_zalloc,gray_calloc) (gray_realloc,gray_strdup): Remove. (gray_2nrealloc): Rewrite. * lib/base64.c: Check return from gray_slist_append_char * lib/env.c: Check return values from gray_slist functions * lib/ldappass.c: Likewise. * lib/slist.c (gray_slist_bucket) <ec>: New member. (gray_slist_err,gray_slist_clrerr): New functions. (gray_slist_append,gray_slist_append_char): Return ssize_t. (gray_slist_coalesce): Likewise. (gray_slist_grow_backslash_num) (gray_slist_grow_backslash): Return int. * lib/transform.c: Use standard memory allocation functions. * pam_ldaphome/pam_ldaphome.c: Likewise. * pam_innetgr/pam_innetgr.c: Likewise. * pam_log/pam_log.c: Likewise. * pam_regex/pam_regex.c: Likewise. * pam_sql/pam_mysql.c: Likewise. * pam_sql/pam_pgsql.c: Likewise.
This commit is contained in:
parent
988b8e27f5
commit
7a40b7873b
17 changed files with 787 additions and 455 deletions
20
lib/base64.c
20
lib/base64.c
|
@ -54,15 +54,21 @@ gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize)
|
|||
/* I have a entire block of data 32 bits get the output
|
||||
data. */
|
||||
if (i == 4) {
|
||||
gray_slist_append_char(slist,
|
||||
(data[0] << 2) | ((data[1] & 0x30) >> 4));
|
||||
gray_slist_append_char(slist,
|
||||
((data[1] & 0xf) << 4) | ((data[2] & 0x3c) >> 2));
|
||||
gray_slist_append_char(slist,
|
||||
((data[2] & 0x3) << 6) | data[3]);
|
||||
if (gray_slist_append_char(slist,
|
||||
(data[0] << 2) | ((data[1] & 0x30) >> 4)) != 1)
|
||||
return -1;
|
||||
if (gray_slist_append_char(slist,
|
||||
((data[1] & 0xf) << 4) | ((data[2] & 0x3c) >> 2))
|
||||
!= 1)
|
||||
return -1;
|
||||
if (gray_slist_append_char(slist,
|
||||
((data[2] & 0x3) << 6) | data[3]) != 1)
|
||||
return -1;
|
||||
nbytes += 3 - pad;
|
||||
} else
|
||||
} else {
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
return nbytes;
|
||||
|
|
66
lib/env.c
66
lib/env.c
|
@ -94,7 +94,7 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
|
|||
return 1;
|
||||
}
|
||||
|
||||
while (p = fgets(buf, sizeof buf, fp)) {
|
||||
while ((p = fgets(buf, sizeof buf, fp))) {
|
||||
int len;
|
||||
struct gray_env *env;
|
||||
|
||||
|
@ -105,17 +105,28 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
|
|||
if (len == 0)
|
||||
continue;
|
||||
if (p[len-1] != '\n') {
|
||||
if (!slist)
|
||||
if (!slist) {
|
||||
slist = gray_slist_create();
|
||||
gray_slist_append(slist, p, len);
|
||||
while (p = fgets(buf, sizeof buf, fp)) {
|
||||
if (!slist) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gray_slist_append(slist, p, len) != len) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
while ((p = fgets(buf, sizeof buf, fp))) {
|
||||
len = strlen(p);
|
||||
gray_slist_append(slist, p, len);
|
||||
if (p[len - 1] == '\n')
|
||||
break;
|
||||
}
|
||||
gray_slist_append_char(slist, 0);
|
||||
p = gray_slist_finish(slist);
|
||||
if (gray_slist_append_char(slist, 0) != 1
|
||||
|| (p = gray_slist_finish(slist)) == NULL) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
len = strlen(p);
|
||||
}
|
||||
|
||||
|
@ -129,10 +140,19 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
|
|||
int err = 0;
|
||||
|
||||
/* Collect continuation lines */
|
||||
if (!slist)
|
||||
if (!slist) {
|
||||
slist = gray_slist_create();
|
||||
if (!slist) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
do {
|
||||
gray_slist_append(slist, p, len - 1);
|
||||
if (gray_slist_append(slist, p, len - 1)
|
||||
!= len - 1) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
p = fgets (buf, sizeof buf, fp);
|
||||
if (!p)
|
||||
break;
|
||||
|
@ -150,26 +170,33 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
|
|||
p[len-1] = 0;
|
||||
len = gray_trim_ws(p);
|
||||
} while (p[len-1] == '\\');
|
||||
if (len)
|
||||
gray_slist_append(slist, p, len);
|
||||
gray_slist_append_char(slist, 0);
|
||||
p = gray_slist_finish(slist);
|
||||
if (rc)
|
||||
break;
|
||||
if (len) {
|
||||
if (gray_slist_append(slist, p, len) != len) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gray_slist_append_char(slist, 0) != 1
|
||||
|| (p = gray_slist_finish(slist)) == NULL) {
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
continue;
|
||||
}
|
||||
|
||||
env = malloc(sizeof *env);
|
||||
if (!env) {
|
||||
_pam_log(LOG_EMERG, "not enough memory");
|
||||
rc = 1;
|
||||
rc = errno;
|
||||
break;
|
||||
}
|
||||
|
||||
env->name = strdup(p);
|
||||
if (!env->name) {
|
||||
_pam_log(LOG_EMERG, "not enough memory");
|
||||
rc = errno;
|
||||
free(env);
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -195,7 +222,12 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
|
|||
|
||||
gray_slist_free(&slist);
|
||||
fclose(fp);
|
||||
*penv = config_env;
|
||||
if (rc) {
|
||||
_pam_log(LOG_EMERG, "%s", strerror(rc));
|
||||
gray_env_free(config_env);
|
||||
} else {
|
||||
*penv = config_env;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,40 +84,30 @@
|
|||
|
||||
extern jmp_buf gray_pam_jmp;
|
||||
|
||||
#define gray_pam_init(retval) \
|
||||
if (setjmp(gray_pam_jmp)) \
|
||||
return retval; \
|
||||
|
||||
void gray_raise(const char *fmt, ...);
|
||||
|
||||
void *gray_malloc(size_t size);
|
||||
void *gray_zalloc(size_t size);
|
||||
void *gray_calloc(size_t count, size_t size);
|
||||
void *gray_realloc(void *ptr, size_t size);
|
||||
void *gray_2nrealloc(void *ptr, size_t *pcount, size_t elsiz);
|
||||
char *gray_strdup(const char *str);
|
||||
|
||||
void gray_pam_delete(char *x);
|
||||
void gray_cleanup_string(pam_handle_t *pamh, void *x, int error_status);
|
||||
void gray_cleanup_regex(pam_handle_t *pamh, void *x, int error_status);
|
||||
void gray_make_str(pam_handle_t *pamh, const char *str, const char *name,
|
||||
char **ret);
|
||||
|
||||
|
||||
typedef struct gray_slist *gray_slist_t;
|
||||
|
||||
gray_slist_t gray_slist_create();
|
||||
gray_slist_t gray_slist_create(void);
|
||||
int gray_slist_err(gray_slist_t slist);
|
||||
void gray_slist_clrerr(gray_slist_t slist);
|
||||
void gray_slist_clear(gray_slist_t slist);
|
||||
void gray_slist_free(gray_slist_t *slist);
|
||||
void gray_slist_append(gray_slist_t slist, const char *str, size_t n);
|
||||
void gray_slist_append_char(gray_slist_t slist, char c);
|
||||
ssize_t gray_slist_append(gray_slist_t slist, const char *str, size_t n);
|
||||
ssize_t gray_slist_append_char(gray_slist_t slist, char c);
|
||||
size_t gray_slist_size(gray_slist_t slist);
|
||||
size_t gray_slist_coalesce(gray_slist_t slist);
|
||||
ssize_t gray_slist_coalesce(gray_slist_t slist);
|
||||
void *gray_slist_head(gray_slist_t slist, size_t *psize);
|
||||
void *gray_slist_finish(gray_slist_t slist);
|
||||
void gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
|
||||
int len, int base);
|
||||
void gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp);
|
||||
int gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
|
||||
int len, int base);
|
||||
int gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp);
|
||||
|
||||
|
||||
void gray_log_init(int dont_open, const char *tag, int f);
|
||||
|
@ -129,10 +119,28 @@ void gray_wait_debug(size_t interval, const char *file, size_t line);
|
|||
#define _pam_vlog gray_pam_vlog
|
||||
#define _pam_log gray_pam_log
|
||||
#define _pam_debug gray_pam_debug
|
||||
|
||||
static inline int
|
||||
errno_to_pam(int ec)
|
||||
{
|
||||
switch (ec) {
|
||||
case EILSEQ:
|
||||
_pam_log(LOG_ERR, "malformed password hash");
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
case ENOMEM:
|
||||
_pam_log(LOG_ERR, "%s", strerror(errno));
|
||||
return PAM_BUF_ERR;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_pam_log(LOG_ERR, "%s", strerror(errno));
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
int gray_transform_name_to_slist (gray_slist_t slist, char *input, char **output);
|
||||
void gray_set_transform_expr (const char *expr);
|
||||
int gray_set_transform_expr (const char *expr);
|
||||
void gray_free_transform_expr (void);
|
||||
|
||||
|
||||
|
|
107
lib/ldappass.c
107
lib/ldappass.c
|
@ -48,10 +48,14 @@ chk_md5 (const char *db_pass, const char *pass)
|
|||
{
|
||||
unsigned char md5digest[16];
|
||||
struct gpam_md5_ctx md5context;
|
||||
gray_slist_t slist = gray_slist_create ();
|
||||
gray_slist_t slist;
|
||||
ssize_t size;
|
||||
char *p;
|
||||
int rc;
|
||||
|
||||
slist = gray_slist_create ();
|
||||
if (!slist)
|
||||
return errno_to_pam(errno);
|
||||
|
||||
gpam_md5_init_ctx (&md5context);
|
||||
gpam_md5_process_bytes (pass, strlen (pass), &md5context);
|
||||
|
@ -60,12 +64,21 @@ chk_md5 (const char *db_pass, const char *pass)
|
|||
size = gray_base64_decode(slist, db_pass, strlen (db_pass));
|
||||
if (size != 16)
|
||||
{
|
||||
rc = errno_to_pam(errno);
|
||||
gray_slist_free(&slist);
|
||||
return PAM_AUTH_ERR;
|
||||
return rc;
|
||||
}
|
||||
p = gray_slist_finish(slist);
|
||||
rc = memcmp (md5digest, p, sizeof md5digest) == 0 ?
|
||||
PAM_SUCCESS : PAM_AUTH_ERR;
|
||||
if (p)
|
||||
{
|
||||
rc = memcmp (md5digest, p, sizeof md5digest) == 0
|
||||
? PAM_SUCCESS
|
||||
: PAM_AUTH_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = errno_to_pam(errno);
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
return rc;
|
||||
}
|
||||
|
@ -77,26 +90,38 @@ chk_smd5 (const char *db_pass, const char *pass)
|
|||
unsigned char md5digest[16];
|
||||
unsigned char *d1;
|
||||
struct gpam_md5_ctx md5context;
|
||||
gray_slist_t slist = gray_slist_create();
|
||||
gray_slist_t slist;
|
||||
ssize_t size;
|
||||
|
||||
slist = gray_slist_create();
|
||||
if (!slist)
|
||||
return errno_to_pam(errno);
|
||||
|
||||
size = gray_base64_decode(slist, db_pass, strlen (db_pass));
|
||||
if (size <= 16)
|
||||
{
|
||||
_pam_log(LOG_ERR, "malformed SMD5 password: %s", db_pass);
|
||||
rc = errno_to_pam(errno);
|
||||
gray_slist_free(&slist);
|
||||
return PAM_AUTH_ERR;
|
||||
return rc;
|
||||
}
|
||||
|
||||
d1 = gray_slist_finish(slist);
|
||||
|
||||
gpam_md5_init_ctx (&md5context);
|
||||
gpam_md5_process_bytes (pass, strlen (pass), &md5context);
|
||||
gpam_md5_process_bytes (d1 + 16, size - 16, &md5context);
|
||||
gpam_md5_finish_ctx (&md5context, md5digest);
|
||||
if (d1)
|
||||
{
|
||||
gpam_md5_init_ctx (&md5context);
|
||||
gpam_md5_process_bytes (pass, strlen (pass), &md5context);
|
||||
gpam_md5_process_bytes (d1 + 16, size - 16, &md5context);
|
||||
gpam_md5_finish_ctx (&md5context, md5digest);
|
||||
|
||||
rc = memcmp (md5digest, d1, sizeof md5digest) == 0 ?
|
||||
PAM_SUCCESS : PAM_AUTH_ERR;
|
||||
rc = memcmp (md5digest, d1, sizeof md5digest) == 0
|
||||
? PAM_SUCCESS
|
||||
: PAM_AUTH_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = errno_to_pam(gray_slist_err(slist));
|
||||
}
|
||||
|
||||
gray_slist_free(&slist);
|
||||
return rc;
|
||||
}
|
||||
|
@ -108,9 +133,13 @@ chk_sha (const char *db_pass, const char *pass)
|
|||
unsigned char sha1digest[20];
|
||||
unsigned char *d1;
|
||||
struct gpam_sha1_ctx sha1context;
|
||||
gray_slist_t slist = gray_slist_create();
|
||||
gray_slist_t slist;
|
||||
ssize_t size;
|
||||
|
||||
|
||||
slist = gray_slist_create();
|
||||
if (!slist)
|
||||
return errno_to_pam(errno);
|
||||
|
||||
gpam_sha1_init_ctx (&sha1context);
|
||||
gpam_sha1_process_bytes (pass, strlen (pass), &sha1context);
|
||||
gpam_sha1_finish_ctx (&sha1context, sha1digest);
|
||||
|
@ -118,13 +147,22 @@ chk_sha (const char *db_pass, const char *pass)
|
|||
size = gray_base64_decode(slist, db_pass, strlen (db_pass));
|
||||
if (size != 20)
|
||||
{
|
||||
rc = errno_to_pam(errno);
|
||||
gray_slist_free(&slist);
|
||||
return 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
d1 = gray_slist_finish(slist);
|
||||
rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0 ?
|
||||
PAM_SUCCESS : PAM_AUTH_ERR;
|
||||
if (d1)
|
||||
{
|
||||
rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0
|
||||
? PAM_SUCCESS
|
||||
: PAM_AUTH_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = errno_to_pam(errno);
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
return rc;
|
||||
}
|
||||
|
@ -136,25 +174,36 @@ chk_ssha (const char *db_pass, const char *pass)
|
|||
unsigned char sha1digest[20];
|
||||
unsigned char *d1;
|
||||
struct gpam_sha1_ctx sha1context;
|
||||
gray_slist_t slist = gray_slist_create();
|
||||
gray_slist_t slist;
|
||||
ssize_t size;
|
||||
|
||||
slist = gray_slist_create();
|
||||
if (!slist)
|
||||
return errno_to_pam(errno);
|
||||
|
||||
size = gray_base64_decode(slist, db_pass, strlen (db_pass));
|
||||
if (size <= 16)
|
||||
{
|
||||
_pam_log (LOG_ERR, "malformed SSHA1 password: %s", db_pass);
|
||||
rc = errno_to_pam(errno);
|
||||
gray_slist_free(&slist);
|
||||
return 1;
|
||||
return rc;
|
||||
}
|
||||
d1 = gray_slist_finish(slist);
|
||||
|
||||
gpam_sha1_init_ctx (&sha1context);
|
||||
gpam_sha1_process_bytes (pass, strlen (pass), &sha1context);
|
||||
gpam_sha1_process_bytes (d1 + 20, size - 20, &sha1context);
|
||||
gpam_sha1_finish_ctx (&sha1context, sha1digest);
|
||||
if (d1)
|
||||
{
|
||||
gpam_sha1_init_ctx (&sha1context);
|
||||
gpam_sha1_process_bytes (pass, strlen (pass), &sha1context);
|
||||
gpam_sha1_process_bytes (d1 + 20, size - 20, &sha1context);
|
||||
gpam_sha1_finish_ctx (&sha1context, sha1digest);
|
||||
|
||||
rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0 ?
|
||||
PAM_SUCCESS : PAM_AUTH_ERR;
|
||||
rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0
|
||||
? PAM_SUCCESS
|
||||
: PAM_AUTH_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = errno_to_pam(errno);
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
return rc;
|
||||
}
|
||||
|
|
81
lib/mem.c
81
lib/mem.c
|
@ -16,81 +16,28 @@
|
|||
|
||||
#include <graypam.h>
|
||||
|
||||
jmp_buf gray_pam_jmp;
|
||||
|
||||
void
|
||||
gray_raise(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
_pam_vlog(LOG_ERR, fmt, ap);
|
||||
va_end(ap);
|
||||
longjmp(gray_pam_jmp, 1);
|
||||
}
|
||||
|
||||
void *
|
||||
gray_malloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (!p)
|
||||
gray_raise("Not enough memory");
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
gray_zalloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (!p)
|
||||
gray_raise("Not enough memory");
|
||||
memset(p, 0, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
gray_calloc(size_t count, size_t size)
|
||||
{
|
||||
return gray_zalloc(count * size);
|
||||
}
|
||||
|
||||
void *
|
||||
gray_realloc(void *ptr, size_t size)
|
||||
{
|
||||
ptr = realloc(ptr, size);
|
||||
if (!ptr)
|
||||
gray_raise("Not enough memory");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
gray_2nrealloc(void *ptr, size_t *pcount, size_t elsiz)
|
||||
{
|
||||
size_t count = *pcount;
|
||||
|
||||
if (!ptr) {
|
||||
if (!count)
|
||||
count = *pcount = 16;
|
||||
return gray_calloc(count, elsiz);
|
||||
if (!count) {
|
||||
count = 64 / elsiz;
|
||||
count += !count;
|
||||
}
|
||||
} else {
|
||||
if ((size_t)-1 / 2 / elsiz <= count) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
count += (count + 1) / 2;
|
||||
}
|
||||
if ((size_t)-1 / 2 / elsiz <= count)
|
||||
gray_raise("Not enough memory");
|
||||
count *= 2;
|
||||
*pcount = count;
|
||||
return gray_realloc(ptr, count * elsiz);
|
||||
ptr = realloc(ptr, count * elsiz);
|
||||
if (ptr)
|
||||
*pcount = count;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
gray_strdup(const char *str)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
p = gray_malloc(strlen(str) + 1);
|
||||
return strcpy(p, str);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gray_pam_delete(char *x)
|
||||
|
|
127
lib/slist.c
127
lib/slist.c
|
@ -28,38 +28,47 @@ struct gray_slist_bucket {
|
|||
struct gray_slist {
|
||||
struct gray_slist_bucket *head, *tail;
|
||||
struct gray_slist_bucket *free;
|
||||
int ec; /* error code */
|
||||
};
|
||||
|
||||
static struct gray_slist_bucket *
|
||||
alloc_bucket(size_t size)
|
||||
{
|
||||
struct gray_slist_bucket *p = gray_malloc(sizeof(*p) + size);
|
||||
p->buf = (char*)(p + 1);
|
||||
p->level = 0;
|
||||
p->size = size;
|
||||
p->next = NULL;
|
||||
struct gray_slist_bucket *p = malloc(sizeof(*p) + size);
|
||||
if (p) {
|
||||
p->buf = (char*)(p + 1);
|
||||
p->level = 0;
|
||||
p->size = size;
|
||||
p->next = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
alloc_pool(gray_slist_t slist, size_t size)
|
||||
{
|
||||
struct gray_slist_bucket *p = alloc_bucket(GRAY_SLIST_BUCKET_SIZE);
|
||||
if (!p) {
|
||||
slist->ec = errno;
|
||||
return 1;
|
||||
}
|
||||
if (slist->tail)
|
||||
slist->tail->next = p;
|
||||
else
|
||||
slist->head = p;
|
||||
slist->tail = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
static ssize_t
|
||||
copy_chars(gray_slist_t slist, const char *str, size_t n)
|
||||
{
|
||||
size_t rest;
|
||||
|
||||
|
||||
if (!slist->head || slist->tail->level == slist->tail->size)
|
||||
alloc_pool(slist, GRAY_SLIST_BUCKET_SIZE);
|
||||
if (!slist->head || slist->tail->level == slist->tail->size) {
|
||||
if (alloc_pool(slist, GRAY_SLIST_BUCKET_SIZE))
|
||||
return -1;
|
||||
}
|
||||
rest = slist->tail->size - slist->tail->level;
|
||||
if (n > rest)
|
||||
n = rest;
|
||||
|
@ -69,13 +78,28 @@ copy_chars(gray_slist_t slist, const char *str, size_t n)
|
|||
}
|
||||
|
||||
gray_slist_t
|
||||
gray_slist_create()
|
||||
gray_slist_create(void)
|
||||
{
|
||||
gray_slist_t slist = gray_malloc(sizeof(*slist));
|
||||
slist->head = slist->tail = slist->free = 0;
|
||||
gray_slist_t slist = malloc(sizeof(*slist));
|
||||
if (slist) {
|
||||
slist->head = slist->tail = slist->free = 0;
|
||||
slist->ec = 0;
|
||||
}
|
||||
return slist;
|
||||
}
|
||||
|
||||
int
|
||||
gray_slist_err(gray_slist_t slist)
|
||||
{
|
||||
return slist->ec;
|
||||
}
|
||||
|
||||
void
|
||||
gray_slist_clerr(gray_slist_t slist)
|
||||
{
|
||||
slist->ec = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gray_slist_clear(gray_slist_t slist)
|
||||
{
|
||||
|
@ -84,14 +108,15 @@ gray_slist_clear(gray_slist_t slist)
|
|||
slist->free = slist->head;
|
||||
slist->head = slist->tail = NULL;
|
||||
}
|
||||
gray_slist_clerr(slist);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gray_slist_free(gray_slist_t *slist)
|
||||
{
|
||||
struct gray_slist_bucket *p;
|
||||
if (*slist) {
|
||||
struct gray_slist_bucket *p;
|
||||
gray_slist_clear(*slist);
|
||||
for (p = (*slist)->free; p; ) {
|
||||
struct gray_slist_bucket *next = p->next;
|
||||
|
@ -103,21 +128,27 @@ gray_slist_free(gray_slist_t *slist)
|
|||
*slist = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ssize_t
|
||||
gray_slist_append(gray_slist_t slist, const char *str, size_t n)
|
||||
{
|
||||
const char *ptr = str;
|
||||
while (n) {
|
||||
size_t s = copy_chars(slist, ptr, n);
|
||||
ptr += s;
|
||||
n -= s;
|
||||
ssize_t total;
|
||||
|
||||
if (slist->ec)
|
||||
return -1;
|
||||
total = 0;
|
||||
while (total < n) {
|
||||
ssize_t s = copy_chars(slist, str + total, n - total);
|
||||
if (s == -1)
|
||||
return -1;
|
||||
total += s;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void
|
||||
ssize_t
|
||||
gray_slist_append_char(gray_slist_t slist, char c)
|
||||
{
|
||||
gray_slist_append(slist, &c, 1);
|
||||
return gray_slist_append(slist, &c, 1);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -130,17 +161,22 @@ gray_slist_size(gray_slist_t slist)
|
|||
return size;
|
||||
}
|
||||
|
||||
size_t
|
||||
ssize_t
|
||||
gray_slist_coalesce(gray_slist_t slist)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (slist->head && slist->head->next == NULL)
|
||||
if (slist->ec)
|
||||
return -1;
|
||||
else if (slist->head && slist->head->next == NULL)
|
||||
size = slist->head->level;
|
||||
else {
|
||||
size = gray_slist_size(slist);
|
||||
struct gray_slist_bucket *bucket = alloc_bucket(size);
|
||||
struct gray_slist_bucket *p;
|
||||
struct gray_slist_bucket *bucket, *p;
|
||||
|
||||
bucket = alloc_bucket(size);
|
||||
if (!bucket)
|
||||
return -1;
|
||||
|
||||
for (p = slist->head; p; ) {
|
||||
struct gray_slist_bucket *next = p->next;
|
||||
|
@ -165,7 +201,10 @@ gray_slist_head(gray_slist_t slist, size_t *psize)
|
|||
void *
|
||||
gray_slist_finish(gray_slist_t slist)
|
||||
{
|
||||
gray_slist_coalesce(slist);
|
||||
if (slist->ec)
|
||||
return NULL;
|
||||
if (gray_slist_coalesce(slist) == -1)
|
||||
return NULL;
|
||||
gray_slist_clear(slist);
|
||||
return slist->free->buf;
|
||||
}
|
||||
|
@ -174,14 +213,16 @@ gray_slist_finish(gray_slist_t slist)
|
|||
#define to_num(c) \
|
||||
(isdigit(c) ? c - '0' : (isxdigit(c) ? toupper(c) - 'A' + 10 : 255 ))
|
||||
|
||||
void
|
||||
int
|
||||
gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
|
||||
int len, int base)
|
||||
{
|
||||
int i;
|
||||
int val = 0;
|
||||
char *start = text;
|
||||
|
||||
|
||||
if (slist->ec)
|
||||
return -1;
|
||||
if (text[0] == '\\') {
|
||||
text++;
|
||||
if (base == 16)
|
||||
|
@ -196,14 +237,17 @@ gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
|
|||
}
|
||||
|
||||
if (i == 0) {
|
||||
gray_slist_append(slist, start, 1);
|
||||
if (gray_slist_append(slist, start, 1) != 1)
|
||||
return -1;
|
||||
if (pend)
|
||||
*pend = start + 1;
|
||||
} else {
|
||||
gray_slist_append_char(slist, val);
|
||||
if (gray_slist_append_char(slist, val) != 1)
|
||||
return -1;
|
||||
if (pend)
|
||||
*pend = text + i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -219,22 +263,27 @@ gray_decode_backslash(int c)
|
|||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp)
|
||||
{
|
||||
if (text[1] == '\\' || (unsigned char)text[1] > 127) {
|
||||
gray_slist_append_char(slist, text[1]);
|
||||
if (gray_slist_append_char(slist, text[1]) != 1)
|
||||
return -1;
|
||||
text += 2;
|
||||
} else if (isdigit(text[1]))
|
||||
gray_slist_grow_backslash_num(slist, text, &text, 3, 8);
|
||||
else if (text[1] == 'x' || text[1] == 'X')
|
||||
gray_slist_grow_backslash_num(slist, text, &text, 2, 16);
|
||||
else {
|
||||
} else if (isdigit(text[1])) {
|
||||
if (gray_slist_grow_backslash_num(slist, text, &text, 3, 8))
|
||||
return -1;
|
||||
} else if (text[1] == 'x' || text[1] == 'X') {
|
||||
if (gray_slist_grow_backslash_num(slist, text, &text, 2, 16))
|
||||
return -1;
|
||||
} else {
|
||||
int c = gray_decode_backslash(text[1]);
|
||||
gray_slist_append_char(slist, c);
|
||||
if (gray_slist_append_char(slist, c) != 1)
|
||||
return -1;
|
||||
text += 2;
|
||||
}
|
||||
|
||||
*endp = text;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
244
lib/transform.c
244
lib/transform.c
|
@ -63,23 +63,42 @@ struct transform
|
|||
unsigned match_number;
|
||||
regex_t regex;
|
||||
int has_regex;
|
||||
int error;
|
||||
/* Compiled replacement expression */
|
||||
struct replace_segm *repl_head, *repl_tail;
|
||||
size_t segm_count; /* Number of elements in the above list */
|
||||
};
|
||||
|
||||
static inline int
|
||||
transform_err(struct transform *tf)
|
||||
{
|
||||
return tf->error;
|
||||
}
|
||||
|
||||
static void
|
||||
transform_seterr (struct transform *tf, int ec)
|
||||
{
|
||||
errno_to_pam (errno);
|
||||
tf->error = ec;
|
||||
}
|
||||
|
||||
|
||||
static struct transform *transform_head, *transform_tail;
|
||||
static char *case_ctl_buffer;
|
||||
static size_t case_ctl_bufsize;
|
||||
|
||||
static struct transform *
|
||||
new_transform ()
|
||||
new_transform (void)
|
||||
{
|
||||
struct transform *p = gray_zalloc (sizeof *p);
|
||||
if (transform_tail)
|
||||
transform_tail->next = p;
|
||||
else
|
||||
transform_head = p;
|
||||
transform_tail = p;
|
||||
struct transform *p = calloc (1, sizeof *p);
|
||||
if (p)
|
||||
{
|
||||
if (transform_tail)
|
||||
transform_tail->next = p;
|
||||
else
|
||||
transform_head = p;
|
||||
transform_tail = p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -102,14 +121,19 @@ free_transform (struct transform *tr)
|
|||
static struct replace_segm *
|
||||
add_segment (struct transform *tf)
|
||||
{
|
||||
struct replace_segm *segm = gray_malloc (sizeof *segm);
|
||||
segm->next = NULL;
|
||||
if (tf->repl_tail)
|
||||
tf->repl_tail->next = segm;
|
||||
struct replace_segm *segm = malloc (sizeof *segm);
|
||||
if (segm)
|
||||
{
|
||||
segm->next = NULL;
|
||||
if (tf->repl_tail)
|
||||
tf->repl_tail->next = segm;
|
||||
else
|
||||
tf->repl_head = segm;
|
||||
tf->repl_tail = segm;
|
||||
tf->segm_count++;
|
||||
}
|
||||
else
|
||||
tf->repl_head = segm;
|
||||
tf->repl_tail = segm;
|
||||
tf->segm_count++;
|
||||
transform_seterr (tf, errno_to_pam (errno));
|
||||
return segm;
|
||||
}
|
||||
|
||||
|
@ -122,17 +146,25 @@ free_segment (struct replace_segm *segm)
|
|||
}
|
||||
|
||||
static void
|
||||
add_literal_segment (struct transform *tf, char *str, char *end)
|
||||
add_literal_segment (struct transform *tf, char const *str, char const *end)
|
||||
{
|
||||
size_t len = end - str;
|
||||
if (len)
|
||||
{
|
||||
struct replace_segm *segm = add_segment (tf);
|
||||
segm->type = segm_literal;
|
||||
segm->v.literal.ptr = gray_malloc (len + 1);
|
||||
memcpy (segm->v.literal.ptr, str, len);
|
||||
segm->v.literal.ptr[len] = 0;
|
||||
segm->v.literal.size = len;
|
||||
if (segm)
|
||||
{
|
||||
segm->type = segm_literal;
|
||||
segm->v.literal.ptr = malloc (len + 1);
|
||||
if (segm->v.literal.ptr)
|
||||
{
|
||||
memcpy (segm->v.literal.ptr, str, len);
|
||||
segm->v.literal.ptr[len] = 0;
|
||||
segm->v.literal.size = len;
|
||||
}
|
||||
else
|
||||
transform_seterr (tf, errno_to_pam (errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,41 +172,61 @@ static void
|
|||
add_char_segment (struct transform *tf, int chr)
|
||||
{
|
||||
struct replace_segm *segm = add_segment (tf);
|
||||
segm->type = segm_literal;
|
||||
segm->v.literal.ptr = gray_malloc (2);
|
||||
segm->v.literal.ptr[0] = chr;
|
||||
segm->v.literal.ptr[1] = 0;
|
||||
segm->v.literal.size = 1;
|
||||
if (segm)
|
||||
{
|
||||
segm->type = segm_literal;
|
||||
segm->v.literal.ptr = malloc (2);
|
||||
if (segm->v.literal.ptr)
|
||||
{
|
||||
segm->v.literal.ptr[0] = chr;
|
||||
segm->v.literal.ptr[1] = 0;
|
||||
segm->v.literal.size = 1;
|
||||
}
|
||||
else
|
||||
transform_seterr (tf, errno_to_pam (errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_backref_segment (struct transform *tf, size_t ref)
|
||||
{
|
||||
struct replace_segm *segm = add_segment (tf);
|
||||
segm->type = segm_backref;
|
||||
segm->v.ref = ref;
|
||||
if (segm)
|
||||
{
|
||||
segm->type = segm_backref;
|
||||
segm->v.ref = ref;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_case_ctl_segment (struct transform *tf, enum case_ctl_type ctl)
|
||||
{
|
||||
struct replace_segm *segm = add_segment (tf);
|
||||
segm->type = segm_case_ctl;
|
||||
segm->v.ctl = ctl;
|
||||
if (segm)
|
||||
{
|
||||
segm->type = segm_case_ctl;
|
||||
segm->v.ctl = ctl;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_transform_expr (const char *expr)
|
||||
static int
|
||||
parse_transform_expr (const char *expr, const char **endp)
|
||||
{
|
||||
int delim;
|
||||
int i, j, rc;
|
||||
char *str, *beg, *cur;
|
||||
char *str;
|
||||
const char *beg;
|
||||
const char *cur;
|
||||
const char *p;
|
||||
int cflags = 0;
|
||||
struct transform *tf = new_transform ();
|
||||
|
||||
if (expr[0] != 's')
|
||||
gray_raise ("Invalid transform expression");
|
||||
{
|
||||
_pam_log(LOG_ERR, "invalid transform expression");
|
||||
*endp = expr;
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
delim = expr[1];
|
||||
|
||||
|
@ -184,7 +236,11 @@ parse_transform_expr (const char *expr)
|
|||
i++;
|
||||
|
||||
if (expr[i] != delim)
|
||||
gray_raise ("Invalid transform expression");
|
||||
{
|
||||
_pam_log(LOG_ERR, "invalid transform expression");
|
||||
*endp = expr + i;
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Scan replacement expression */
|
||||
for (j = i + 1; expr[j] && expr[j] != delim; j++)
|
||||
|
@ -192,7 +248,11 @@ parse_transform_expr (const char *expr)
|
|||
j++;
|
||||
|
||||
if (expr[j] != delim)
|
||||
gray_raise ("Invalid transform expression");
|
||||
{
|
||||
_pam_log(LOG_ERR, "invalid transform expression");
|
||||
*endp = expr + j;
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Check flags */
|
||||
tf->transform_type = transform_first;
|
||||
|
@ -218,14 +278,21 @@ parse_transform_expr (const char *expr)
|
|||
break;
|
||||
|
||||
default:
|
||||
gray_raise("Unknown flag in transform expression: %c", *p);
|
||||
_pam_log(LOG_ERR, "unknown flag in transform expression: %c", *p);
|
||||
*endp = p;
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
if (*p == ';')
|
||||
p++;
|
||||
|
||||
/* Extract and compile regex */
|
||||
str = gray_malloc (i - 1);
|
||||
str = malloc (i - 1);
|
||||
if (!str)
|
||||
{
|
||||
*endp = p;
|
||||
return errno_to_pam (errno);
|
||||
}
|
||||
memcpy (str, expr + 2, i - 2);
|
||||
str[i - 2] = 0;
|
||||
|
||||
|
@ -235,7 +302,10 @@ parse_transform_expr (const char *expr)
|
|||
{
|
||||
char errbuf[512];
|
||||
regerror (rc, &tf->regex, errbuf, sizeof (errbuf));
|
||||
gray_raise("Invalid transform expression: %s", errbuf);
|
||||
_pam_log(LOG_ERR, "invalid transform expression: %s", errbuf);
|
||||
free (str);
|
||||
*endp = p;
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
tf->has_regex = 1;
|
||||
if (str[0] == '^' || str[strlen (str) - 1] == '$')
|
||||
|
@ -245,12 +315,25 @@ parse_transform_expr (const char *expr)
|
|||
|
||||
/* Extract and compile replacement expr */
|
||||
i++;
|
||||
str = gray_malloc (j - i + 1);
|
||||
str = malloc (j - i + 1);
|
||||
if (!str)
|
||||
{
|
||||
*endp = p;
|
||||
return errno_to_pam (errno);
|
||||
}
|
||||
|
||||
memcpy (str, expr + i, j - i);
|
||||
str[j - i] = 0;
|
||||
|
||||
for (cur = beg = str; *cur;)
|
||||
{
|
||||
if (transform_err (tf))
|
||||
{
|
||||
*endp = expr + i + (beg - str);
|
||||
free (str);
|
||||
return transform_err (tf);
|
||||
}
|
||||
|
||||
if (*cur == '\\')
|
||||
{
|
||||
size_t n;
|
||||
|
@ -260,11 +343,16 @@ parse_transform_expr (const char *expr)
|
|||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
n = strtoul (cur, &cur, 10);
|
||||
n = strtoul (cur, (char**)&cur, 10);
|
||||
if (n > tf->regex.re_nsub)
|
||||
gray_raise ("Invalid transform replacement: "
|
||||
"back reference out of range");
|
||||
add_backref_segment (tf, n);
|
||||
{
|
||||
_pam_log(LOG_ERR,
|
||||
"invalid transform replacement: "
|
||||
"back reference out of range");
|
||||
transform_seterr (tf, PAM_SERVICE_ERR);
|
||||
}
|
||||
else
|
||||
add_backref_segment (tf, n);
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
|
@ -367,19 +455,33 @@ parse_transform_expr (const char *expr)
|
|||
cur++;
|
||||
}
|
||||
add_literal_segment (tf, beg, cur);
|
||||
|
||||
return p;
|
||||
if (transform_err (tf))
|
||||
{
|
||||
*endp = expr + i + (beg - str);
|
||||
free (str);
|
||||
return transform_err (tf);
|
||||
}
|
||||
*endp = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
gray_set_transform_expr (const char *expr)
|
||||
{
|
||||
while (*expr)
|
||||
expr = parse_transform_expr (expr);
|
||||
{
|
||||
int rc = parse_transform_expr (expr, &expr);
|
||||
if (rc != PAM_SUCCESS)
|
||||
{
|
||||
gray_free_transform_expr ();
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
gray_free_transform_expr ()
|
||||
gray_free_transform_expr (void)
|
||||
{
|
||||
while (transform_head)
|
||||
{
|
||||
|
@ -388,6 +490,9 @@ gray_free_transform_expr ()
|
|||
transform_head = next;
|
||||
}
|
||||
transform_tail = NULL;
|
||||
free (case_ctl_buffer);
|
||||
case_ctl_buffer = NULL;
|
||||
case_ctl_bufsize = 0;
|
||||
}
|
||||
|
||||
/* Run case conversion specified by CASE_CTL on array PTR of SIZE
|
||||
|
@ -395,14 +500,15 @@ gray_free_transform_expr ()
|
|||
static char *
|
||||
run_case_conv (enum case_ctl_type case_ctl, char *ptr, size_t size)
|
||||
{
|
||||
static char *case_ctl_buffer;
|
||||
static size_t case_ctl_bufsize;
|
||||
char *p;
|
||||
|
||||
if (case_ctl_bufsize < size)
|
||||
{
|
||||
p = realloc (case_ctl_buffer, size);
|
||||
if (!p)
|
||||
return NULL;
|
||||
case_ctl_buffer = p;
|
||||
case_ctl_bufsize = size;
|
||||
case_ctl_buffer = gray_realloc (case_ctl_buffer, case_ctl_bufsize);
|
||||
}
|
||||
memcpy (case_ctl_buffer, ptr, size);
|
||||
switch (case_ctl)
|
||||
|
@ -432,7 +538,7 @@ run_case_conv (enum case_ctl_type case_ctl, char *ptr, size_t size)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
static int
|
||||
_single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
|
||||
char *input)
|
||||
{
|
||||
|
@ -450,8 +556,9 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
|
|||
save_ctl = ctl_stop; \
|
||||
}
|
||||
|
||||
rmp = gray_malloc ((tf->regex.re_nsub + 1) * sizeof (*rmp));
|
||||
|
||||
rmp = malloc ((tf->regex.re_nsub + 1) * sizeof (*rmp));
|
||||
if (!rmp)
|
||||
return errno;
|
||||
while (*input)
|
||||
{
|
||||
size_t disp;
|
||||
|
@ -488,6 +595,8 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
|
|||
ptr = run_case_conv (case_ctl,
|
||||
segm->v.literal.ptr,
|
||||
segm->v.literal.size);
|
||||
if (!ptr)
|
||||
return errno;
|
||||
CASE_CTL_RESET();
|
||||
}
|
||||
gray_slist_append (slist, ptr, segm->v.literal.size);
|
||||
|
@ -503,6 +612,8 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
|
|||
if (case_ctl != ctl_stop)
|
||||
{
|
||||
ptr = run_case_conv (case_ctl, ptr, size);
|
||||
if (!ptr)
|
||||
return errno;
|
||||
CASE_CTL_RESET();
|
||||
}
|
||||
|
||||
|
@ -551,20 +662,35 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
|
|||
|
||||
gray_slist_append_char (slist, 0);
|
||||
free (rmp);
|
||||
return gray_slist_err (slist);
|
||||
}
|
||||
|
||||
int
|
||||
gray_transform_name_to_slist (gray_slist_t slist, char *input, char **output)
|
||||
{
|
||||
struct transform *tf;
|
||||
|
||||
for (tf = transform_head; tf; tf = tf->next)
|
||||
if (transform_head)
|
||||
{
|
||||
_single_transform_name_to_slist (tf, slist, input);
|
||||
struct transform *tf;
|
||||
for (tf = transform_head; tf; tf = tf->next)
|
||||
{
|
||||
int rc = _single_transform_name_to_slist (tf, slist, input);
|
||||
if (rc)
|
||||
return errno_to_pam(rc);
|
||||
input = gray_slist_finish (slist);
|
||||
if (!input)
|
||||
return errno_to_pam(errno);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gray_slist_append(slist, input, strlen(input) + 1);
|
||||
input = gray_slist_finish (slist);
|
||||
if (!input)
|
||||
return errno_to_pam(errno);
|
||||
}
|
||||
*output = input;
|
||||
return transform_head != NULL;
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -166,7 +166,6 @@ check_membership0(pam_handle_t *pamh, int argc, const char **argv)
|
|||
struct passwd *pw;
|
||||
static int retval[] = { PAM_SUCCESS, PAM_AUTH_ERR };
|
||||
|
||||
gray_pam_init(PAM_AUTHINFO_UNAVAIL);
|
||||
gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV);
|
||||
gray_parseopt(pam_opt, argc, argv);
|
||||
if (!groups) {
|
||||
|
|
|
@ -195,7 +195,6 @@ check_netgroup0(pam_handle_t *pamh, int argc, const char **argv,
|
|||
use_resolve = 1;
|
||||
sense = SENSE_ALLOW;
|
||||
|
||||
gray_pam_init(PAM_AUTHINFO_UNAVAIL);
|
||||
gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV);
|
||||
gray_parseopt(pam_opt, argc, argv);
|
||||
if (!netgroup_name) {
|
||||
|
|
|
@ -177,7 +177,7 @@ get_intval(struct gray_env *env, const char *name, int base, unsigned long *pv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
static char *
|
||||
parse_ldap_uri(const char *uri)
|
||||
{
|
||||
int wc;
|
||||
|
@ -722,25 +722,35 @@ check_groups(int gc, char **gv, const char *username, gid_t gid)
|
|||
int i;
|
||||
struct group *gp;
|
||||
char *pgname;
|
||||
|
||||
int rc = 1;
|
||||
|
||||
gp = getgrgid(gid);
|
||||
pgname = gp ? gray_strdup(gp->gr_name) : NULL;
|
||||
for (i = 0; i < gc; i++) {
|
||||
if (gp) {
|
||||
pgname = strdup(gp->gr_name);
|
||||
if (!pgname) {
|
||||
errno_to_pam(errno);
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
gp = NULL;
|
||||
for (i = 0; rc && i < gc; i++) {
|
||||
if (strcmp(gv[i], pgname) == 0) {
|
||||
free(pgname);
|
||||
return 0;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
gp = getgrnam(gv[i]);
|
||||
if (gp) {
|
||||
char **p;
|
||||
for (p = gp->gr_mem; *p; p++)
|
||||
for (p = gp->gr_mem; *p; p++) {
|
||||
if (strcmp(username, *p) == 0) {
|
||||
free(pgname);
|
||||
return 0;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
free(pgname);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -856,36 +866,24 @@ copy_file(pam_handle_t *pamh, const char *src, const char *dst,
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define INITIAL_READLINK_SIZE 128
|
||||
|
||||
int
|
||||
read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
|
||||
static int
|
||||
read_link_name(const char *name, char **pbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
char *buf = *pbuf;
|
||||
size_t size = *psize;
|
||||
ssize_t linklen;
|
||||
char *buf = NULL;
|
||||
size_t size = 0;
|
||||
ssize_t linklen = 0;
|
||||
|
||||
while (1) {
|
||||
if (!buf) {
|
||||
size = INITIAL_READLINK_SIZE;
|
||||
buf = malloc(size);
|
||||
} else {
|
||||
char *p;
|
||||
size_t newsize = size << 1;
|
||||
if (newsize < size) {
|
||||
rc = ENAMETOOLONG;
|
||||
if (linklen == size) {
|
||||
char *p = gray_2nrealloc(&buf, &size, 1);
|
||||
if (!p) {
|
||||
errno_to_pam(errno);
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
size = newsize;
|
||||
p = realloc(buf, size);
|
||||
if (!p)
|
||||
free(buf);
|
||||
buf = p;
|
||||
}
|
||||
if (!buf) {
|
||||
rc = 1;
|
||||
break;
|
||||
linklen = size;
|
||||
}
|
||||
|
||||
linklen = readlink(name, buf, size);
|
||||
|
@ -894,7 +892,7 @@ read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((size_t) linklen < size) {
|
||||
if (linklen < size) {
|
||||
buf[linklen++] = '\0';
|
||||
rc = 0;
|
||||
break;
|
||||
|
@ -906,12 +904,8 @@ read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
|
|||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
*pbuf = buf;
|
||||
*psize = size;
|
||||
if (plen)
|
||||
*plen = linklen;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -920,11 +914,10 @@ static int
|
|||
copy_link(pam_handle_t *pamh, const char *src, const char *dst,
|
||||
char *buffer, size_t bufsize, struct stat *st)
|
||||
{
|
||||
char *lnkname = NULL;
|
||||
size_t lnklen = 0;
|
||||
char *lnkname;
|
||||
int rc;
|
||||
|
||||
if (read_link_name(src, &lnkname, &lnklen, NULL)) {
|
||||
if (read_link_name(src, &lnkname)) {
|
||||
_pam_log(LOG_ERR, "error reading link %s: %s",
|
||||
src, strerror(errno));
|
||||
return 1;
|
||||
|
@ -999,7 +992,11 @@ create_interdir(const char *path, struct passwd *pw)
|
|||
if (!p)
|
||||
return 1;
|
||||
len = p - path;
|
||||
dir = gray_malloc(len + 1);
|
||||
dir = malloc(len + 1);
|
||||
if (!dir) {
|
||||
errno_to_pam(errno);
|
||||
return -1;
|
||||
}
|
||||
memcpy(dir, path, len);
|
||||
dir[len] = 0;
|
||||
rc = create_hierarchy(dir, strlen(pw->pw_dir));
|
||||
|
@ -1268,6 +1265,21 @@ struct pubkeyfile {
|
|||
size_t lnm; /* Max. capacity of lnv */
|
||||
};
|
||||
|
||||
/* Close the public key file */
|
||||
static void
|
||||
pubkeyfile_close(struct pubkeyfile *pkb)
|
||||
{
|
||||
close(pkb->fd);
|
||||
free(pkb->file_name);
|
||||
free(pkb->base);
|
||||
free(pkb->lnv);
|
||||
|
||||
pkb->fd = -1;
|
||||
pkb->file_name = NULL;
|
||||
pkb->base = NULL;
|
||||
pkb->lnv = NULL;
|
||||
}
|
||||
|
||||
/* Open public key file NAME. Return 0 on success. On error, issue a
|
||||
diagnostic message and return -1. */
|
||||
static int
|
||||
|
@ -1280,7 +1292,13 @@ pubkeyfile_open(struct pubkeyfile *pkb, char *name)
|
|||
name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pkb->file_name = gray_strdup(name);
|
||||
pkb->file_name = strdup(name);
|
||||
if (!pkb->file_name) {
|
||||
int rc = errno_to_pam(errno);
|
||||
close(pkb->fd);
|
||||
pkb->fd = -1;
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1298,7 +1316,11 @@ pubkeyfile_read(struct pubkeyfile *pkb)
|
|||
return -1;
|
||||
}
|
||||
pkb->size = st.st_size;
|
||||
pkb->base = gray_malloc(st.st_size + 1);
|
||||
pkb->base = malloc(st.st_size + 1);
|
||||
if (!pkb->base) {
|
||||
errno_to_pam(errno);
|
||||
return -1;
|
||||
}
|
||||
if (full_read(pkb->fd, pkb->file_name, pkb->base, pkb->size)) {
|
||||
_pam_log(LOG_ERR, "fread %s: %s",
|
||||
pkb->file_name, strerror(errno));
|
||||
|
@ -1310,8 +1332,11 @@ pubkeyfile_read(struct pubkeyfile *pkb)
|
|||
if (*p == '\n')
|
||||
++pkb->lnc;
|
||||
pkb->lnm = pkb->lnc + 1;
|
||||
pkb->lnv = gray_calloc(pkb->lnm, sizeof(pkb->lnv[0]));
|
||||
|
||||
pkb->lnv = calloc(pkb->lnm, sizeof(pkb->lnv[0]));
|
||||
if (pkb->lnv) {
|
||||
errno_to_pam(errno);
|
||||
return -1;
|
||||
}
|
||||
i = 0;
|
||||
for (p = pkb->base; *p; p++) {
|
||||
if (p == pkb->base || p[-1] == 0)
|
||||
|
@ -1329,7 +1354,10 @@ pubkeyfile_init(struct pubkeyfile *pkb, char *name)
|
|||
{
|
||||
if (pubkeyfile_open(pkb, name))
|
||||
return -1;
|
||||
return pubkeyfile_read(pkb);
|
||||
if (pubkeyfile_read(pkb) == 0)
|
||||
return 0;
|
||||
pubkeyfile_close(pkb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write data from lnv into the public key file, overwriting its current
|
||||
|
@ -1388,51 +1416,48 @@ pubkeyfile_remove_lines(struct pubkeyfile *pkb, int pos, int count)
|
|||
|
||||
/* Allocate COUNT lines starting from position POS in PKB, preserving
|
||||
the existing data. */
|
||||
static void
|
||||
static int
|
||||
pubkeyfile_alloc_lines(struct pubkeyfile *pkb, size_t pos, size_t count)
|
||||
{
|
||||
if (pos > pkb->lnc) {
|
||||
_pam_log(LOG_ERR, "%s:%d: INTERNAL ERROR: pos out of range",
|
||||
__FILE__, __LINE__);
|
||||
abort();
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
if (pkb->lnc + count + 1 > pkb->lnm) {
|
||||
pkb->lnm += count;
|
||||
pkb->lnv = gray_realloc(pkb->lnv,
|
||||
pkb->lnm * sizeof(pkb->lnv[0]));
|
||||
char **p;
|
||||
size_t lnm = pkb->lnm + count;
|
||||
p = realloc(pkb->lnv, lnm * sizeof(pkb->lnv[0]));
|
||||
if (!p)
|
||||
return errno_to_pam(errno);
|
||||
pkb->lnv = p;
|
||||
pkb->lnm = lnm;
|
||||
}
|
||||
memmove(pkb->lnv + pos + count, pkb->lnv + pos,
|
||||
(pkb->lnc - pos + 1) * sizeof(pkb->lnv[0]));
|
||||
pkb->lnc += count;
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Insert lines from LV in position POS in the file PKB, shifting down
|
||||
existing lines as necessary. */
|
||||
void
|
||||
static int
|
||||
pubkeyfile_insert_lines(struct pubkeyfile *pkb, size_t pos, char **lv)
|
||||
{
|
||||
size_t i;
|
||||
size_t lc;
|
||||
int rc;
|
||||
|
||||
for (lc = 0; lv[lc]; lc++)
|
||||
;
|
||||
|
||||
pubkeyfile_alloc_lines(pkb, pos, lc);
|
||||
|
||||
for (i = 0; i < lc; i++)
|
||||
pkb->lnv[pos + i] = lv[i];
|
||||
rc = pubkeyfile_alloc_lines(pkb, pos, lc);
|
||||
if (rc == 0) {
|
||||
for (i = 0; i < lc; i++)
|
||||
pkb->lnv[pos + i] = lv[i];
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Close the public key file */
|
||||
void
|
||||
pubkeyfile_close(struct pubkeyfile *pkb)
|
||||
{
|
||||
close(pkb->fd);
|
||||
free(pkb->file_name);
|
||||
free(pkb->base);
|
||||
free(pkb->lnv);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
store_pubkeys(char **keys, struct passwd *pw, struct gray_env *env)
|
||||
|
@ -1451,7 +1476,9 @@ store_pubkeys(char **keys, struct passwd *pw, struct gray_env *env)
|
|||
len = homelen + pathlen;
|
||||
if (pw->pw_dir[homelen - 1] != '/')
|
||||
len++;
|
||||
file_name = gray_malloc(len + 1);
|
||||
file_name = malloc(len + 1);
|
||||
if (!file_name)
|
||||
return errno_to_pam(errno);
|
||||
memcpy(file_name, pw->pw_dir, homelen);
|
||||
if (pw->pw_dir[homelen - 1] != '/')
|
||||
file_name[homelen++] = '/';
|
||||
|
@ -1520,9 +1547,11 @@ store_pubkeys(char **keys, struct passwd *pw, struct gray_env *env)
|
|||
|
||||
if (update) {
|
||||
pubkeyfile_remove_lines(&pkf, 0, i);
|
||||
pubkeyfile_insert_lines(&pkf, 0, keys);
|
||||
pubkeyfile_write(&pkf);
|
||||
retval = PAM_TRY_AGAIN;
|
||||
retval = pubkeyfile_insert_lines(&pkf, 0, keys);
|
||||
if (retval == PAM_SUCCESS) {
|
||||
pubkeyfile_write(&pkf);
|
||||
retval = PAM_TRY_AGAIN;
|
||||
}
|
||||
} else
|
||||
retval = PAM_SUCCESS;
|
||||
pubkeyfile_close(&pkf);
|
||||
|
@ -1560,20 +1589,27 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
|
|||
else {
|
||||
char *filter;
|
||||
gray_slist_t slist;
|
||||
char **keys;
|
||||
|
||||
slist = gray_slist_create();
|
||||
gray_expand_string(pamh, filter_pat, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
filter = gray_slist_finish(slist);
|
||||
|
||||
keys = get_pubkeys(ld, base, filter, attr);
|
||||
gray_slist_free(&slist);
|
||||
if (keys) {
|
||||
retval = store_pubkeys(keys, pw, env);
|
||||
argcvz_free(keys);
|
||||
} else
|
||||
retval = PAM_SUCCESS;
|
||||
if (!slist)
|
||||
retval = errno_to_pam(errno);
|
||||
else {
|
||||
gray_expand_string(pamh, filter_pat, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
filter = gray_slist_finish(slist);
|
||||
if (filter) {
|
||||
char **keys = get_pubkeys(ld, base, filter,
|
||||
attr);
|
||||
if (keys) {
|
||||
retval = store_pubkeys(keys, pw, env);
|
||||
argcvz_free(keys);
|
||||
} else
|
||||
retval = PAM_SUCCESS;
|
||||
} else {
|
||||
retval = errno_to_pam(gray_slist_err(slist));
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
}
|
||||
ldap_unbind(ld);
|
||||
return retval;
|
||||
|
@ -1694,6 +1730,12 @@ locate_unset(char **env, const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Concatenate NAMELEN bytes from NAME, "=", A, and B. Allocate the
|
||||
result using malloc.
|
||||
|
||||
On ENOMEM, log a diagnostic message and exit with code 127. This function
|
||||
should be used from child process only.
|
||||
*/
|
||||
static char *
|
||||
env_concat(char *name, size_t namelen, char *a, char *b)
|
||||
{
|
||||
|
@ -1701,25 +1743,35 @@ env_concat(char *name, size_t namelen, char *a, char *b)
|
|||
size_t len;
|
||||
|
||||
if (a && b) {
|
||||
res = gray_malloc(namelen + 1 + strlen(a) + strlen(b) + 1);
|
||||
strcpy(res + namelen + 1, a);
|
||||
strcat(res, b);
|
||||
res = malloc(namelen + 1 + strlen(a) + strlen(b) + 1);
|
||||
if (res) {
|
||||
strcpy(res + namelen + 1, a);
|
||||
strcat(res, b);
|
||||
}
|
||||
} else if (a) {
|
||||
len = strlen(a);
|
||||
if (ispunct(a[len-1]))
|
||||
len--;
|
||||
res = gray_malloc(namelen + 1 + len + 1);
|
||||
memcpy(res + namelen + 1, a, len);
|
||||
res[namelen + 1 + len] = 0;
|
||||
res = malloc(namelen + 1 + len + 1);
|
||||
if (res) {
|
||||
memcpy(res + namelen + 1, a, len);
|
||||
res[namelen + 1 + len] = 0;
|
||||
}
|
||||
} else /* if (a == NULL) */ {
|
||||
if (ispunct(b[0]))
|
||||
b++;
|
||||
len = strlen(b);
|
||||
res = gray_malloc(namelen + 1 + len + 1);
|
||||
strcpy(res + namelen + 1, b);
|
||||
res = malloc(namelen + 1 + len + 1);
|
||||
if (res)
|
||||
strcpy(res + namelen + 1, b);
|
||||
}
|
||||
memcpy(res, name, namelen);
|
||||
res[namelen] = '=';
|
||||
if (res) {
|
||||
memcpy(res, name, namelen);
|
||||
res[namelen] = '=';
|
||||
} else {
|
||||
errno_to_pam(errno);
|
||||
_exit(127);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1739,6 +1791,14 @@ parsenv(char *str)
|
|||
char *p, *kw;
|
||||
char **wv = NULL;
|
||||
size_t wi = 0, wc = 0;
|
||||
|
||||
# define ASSERT_NOTNULL(p) do { \
|
||||
if (!(p)) { \
|
||||
errno_to_pam(errno); \
|
||||
_exit(127); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
@ -1791,17 +1851,15 @@ parsenv(char *str)
|
|||
char *q;
|
||||
|
||||
if (wi == wc) {
|
||||
if (wc == 0)
|
||||
wc = 4;
|
||||
else
|
||||
wc *= 2;
|
||||
wv = gray_realloc(wv, wc * sizeof(wv[0]));
|
||||
wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
|
||||
ASSERT_NOTNULL(wv);
|
||||
}
|
||||
|
||||
switch (prev_state) {
|
||||
case st_squote:
|
||||
len -= 2;
|
||||
wv[wi] = gray_malloc(len + 1);
|
||||
wv[wi] = malloc(len + 1);
|
||||
ASSERT_NOTNULL(wv[wi]);
|
||||
for (q = wv[wi]; *kw; ) {
|
||||
if (*kw == '\'')
|
||||
++kw;
|
||||
|
@ -1812,7 +1870,8 @@ parsenv(char *str)
|
|||
break;
|
||||
case st_dquote:
|
||||
len -= 2;
|
||||
wv[wi] = gray_malloc(len + 1);
|
||||
wv[wi] = malloc(len + 1);
|
||||
ASSERT_NOTNULL(wv[wi]);
|
||||
q = wv[wi];
|
||||
while ((*q++ = *kw++) != '=')
|
||||
;
|
||||
|
@ -1827,7 +1886,8 @@ parsenv(char *str)
|
|||
*q = 0;
|
||||
break;
|
||||
default:
|
||||
wv[wi] = gray_malloc(len + 1);
|
||||
wv[wi] = malloc(len + 1);
|
||||
ASSERT_NOTNULL(wv[wi]);
|
||||
memcpy(wv[wi], kw, len);
|
||||
wv[wi][len] = 0;
|
||||
}
|
||||
|
@ -1838,19 +1898,26 @@ parsenv(char *str)
|
|||
|
||||
if (state != st_init) {
|
||||
if (wc == wi) {
|
||||
++wc;
|
||||
wv = gray_realloc(wv, (wc + 1) * sizeof(wv[0]));
|
||||
wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
|
||||
ASSERT_NOTNULL(wv);
|
||||
}
|
||||
wv[wi++] = gray_strdup(kw);
|
||||
wv[wi] = strdup(kw);
|
||||
ASSERT_NOTNULL(wv[wi]);
|
||||
++wi;
|
||||
}
|
||||
|
||||
if (wc == wi)
|
||||
wv = gray_realloc(wv, (wc + 1) * sizeof(wv[0]));
|
||||
if (wc == wi) {
|
||||
wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
|
||||
ASSERT_NOTNULL(wv);
|
||||
}
|
||||
wv[wi] = NULL;
|
||||
|
||||
return wv;
|
||||
}
|
||||
|
||||
/* Setup environment for exec* family call. On ENOMEM, exit with code 127.
|
||||
This function should be called from a child process.
|
||||
*/
|
||||
static char **
|
||||
env_setup(char *envstr)
|
||||
{
|
||||
|
@ -1879,8 +1946,11 @@ env_setup(char *envstr)
|
|||
count++;
|
||||
|
||||
/* Allocate the new environment. */
|
||||
new_env = gray_calloc(count + 1, sizeof new_env[0]);
|
||||
|
||||
new_env = calloc(count + 1, sizeof new_env[0]);
|
||||
if (!new_env) {
|
||||
errno_to_pam(errno);
|
||||
_exit(127);
|
||||
}
|
||||
/* Populate the environment. */
|
||||
n = 0;
|
||||
|
||||
|
@ -1938,9 +2008,16 @@ runas(struct passwd *pw)
|
|||
continue;
|
||||
for (p = gr->gr_mem; *p; p++) {
|
||||
if (strcmp (*p, pw->pw_name) == 0) {
|
||||
if (sgc == sgm)
|
||||
sgv = gray_2nrealloc(sgv, &sgm,
|
||||
sizeof(sgv[0]));
|
||||
if (sgc == sgm) {
|
||||
gid_t *p;
|
||||
p = gray_2nrealloc(sgv, &sgm,
|
||||
sizeof(sgv[0]));
|
||||
if (!p) {
|
||||
errno_to_pam(errno);
|
||||
return 1; //FIXME: proper error code
|
||||
}
|
||||
sgv = p;
|
||||
}
|
||||
sgv[sgc++] = gr->gr_gid;
|
||||
}
|
||||
}
|
||||
|
@ -2143,12 +2220,11 @@ ldaphome_main(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
|||
_pam_parse(pamh, argc, argv);
|
||||
|
||||
DEBUG(90,("enter %s", func));
|
||||
gray_pam_init(PAM_AUTHINFO_UNAVAIL);
|
||||
if (gray_env_read(config_file_name, &env) == 0) {
|
||||
char *val;
|
||||
struct passwd *pw;
|
||||
|
||||
if (val = gray_env_get(env, "ldap-config")) {
|
||||
if ((val = gray_env_get(env, "ldap-config"))) {
|
||||
if (strcmp(val, "none") == 0)
|
||||
ldap_config_name = NULL;
|
||||
else
|
||||
|
@ -2162,7 +2238,7 @@ ldaphome_main(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
|||
gray_env_merge(&env, &tmp);
|
||||
}
|
||||
|
||||
if (val = gray_env_get(env, "authorized_keys"))
|
||||
if ((val = gray_env_get(env, "authorized_keys")))
|
||||
authorized_keys_file = val;
|
||||
|
||||
if (check_user_groups(pamh, env, &pw, &retval) == 0) {
|
||||
|
|
|
@ -102,7 +102,7 @@ struct pam_opt pam_opt[] = {
|
|||
};
|
||||
|
||||
|
||||
static void
|
||||
static int
|
||||
_pam_parse(pam_handle_t *pamh, int argc, const char **argv)
|
||||
{
|
||||
int i;
|
||||
|
@ -110,7 +110,9 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
|
|||
|
||||
gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV);
|
||||
|
||||
targv = gray_malloc(argc * sizeof (targv[0]));
|
||||
targv = calloc(argc, sizeof (targv[0]));
|
||||
if (!targv)
|
||||
return errno_to_pam(errno);
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (argv[i][1] == '-' && argv[i][2] == 0)
|
||||
|
@ -128,25 +130,35 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
|
|||
|
||||
closelog();
|
||||
gray_log_init(!do_open, syslog_tag, facility);
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
echo(pam_handle_t *pamh, const char *prefix, int argc, const char **argv)
|
||||
{
|
||||
char *str;
|
||||
gray_slist_t slist;
|
||||
|
||||
_pam_parse(pamh, argc, argv);
|
||||
slist = gray_slist_create();
|
||||
if (prefix) {
|
||||
gray_slist_append(slist, prefix, strlen(prefix));
|
||||
gray_slist_append(slist, ": ", 2);
|
||||
if (_pam_parse(pamh, argc, argv) == PAM_SUCCESS) {
|
||||
gray_slist_t slist;
|
||||
|
||||
slist = gray_slist_create();
|
||||
if (!slist) {
|
||||
errno_to_pam(errno);
|
||||
} else {
|
||||
char *str;
|
||||
if (prefix) {
|
||||
gray_slist_append(slist, prefix,
|
||||
strlen(prefix));
|
||||
gray_slist_append(slist, ": ", 2);
|
||||
}
|
||||
gray_expand_argv(pamh, xargc, xargv, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
str = gray_slist_finish(slist);
|
||||
if (str)
|
||||
_pam_log(priority, "%s", str);
|
||||
else
|
||||
errno_to_pam(gray_slist_err(slist));
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
gray_expand_argv(pamh, xargc, xargv, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
str = gray_slist_finish(slist);
|
||||
_pam_log(priority, "%s", str);
|
||||
gray_slist_free(&slist);
|
||||
return PAM_IGNORE;
|
||||
}
|
||||
|
||||
|
@ -155,28 +167,24 @@ echo(pam_handle_t *pamh, const char *prefix, int argc, const char **argv)
|
|||
PAM_EXTERN int
|
||||
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
|
@ -184,7 +192,6 @@ PAM_EXTERN int
|
|||
pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
|
||||
const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
|
@ -192,7 +199,6 @@ PAM_EXTERN int
|
|||
pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
|
||||
const char **argv)
|
||||
{
|
||||
gray_pam_init(PAM_IGNORE);
|
||||
return echo(pamh, __FUNCTION__, argc, argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ pam_sm_authenticate(pam_handle_t *pamh,
|
|||
|
||||
DEBUG(90,("enter pam_sm_authenticate"));
|
||||
|
||||
gray_pam_init(PAM_AUTHINFO_UNAVAIL);
|
||||
|
||||
/*
|
||||
* get username
|
||||
|
@ -129,14 +128,23 @@ pam_sm_authenticate(pam_handle_t *pamh,
|
|||
char *newname;
|
||||
gray_slist_t slist;
|
||||
|
||||
gray_set_transform_expr(transform);
|
||||
retval = gray_set_transform_expr(transform);
|
||||
if (retval != PAM_SUCCESS)
|
||||
return retval;
|
||||
slist = gray_slist_create();
|
||||
gray_transform_name_to_slist(slist, name, &newname);
|
||||
DEBUG(90,("new name: %s", newname));
|
||||
MAKE_STR(pamh, newname, name);
|
||||
retval = pam_set_item(pamh, PAM_USER, name);
|
||||
gray_slist_free(&slist);
|
||||
gray_free_transform_expr();
|
||||
if (!slist)
|
||||
retval = errno_to_pam(errno);
|
||||
else {
|
||||
retval = gray_transform_name_to_slist(slist, name,
|
||||
&newname);
|
||||
if (retval == PAM_SUCCESS) {
|
||||
DEBUG(90,("new name: %s", newname));
|
||||
MAKE_STR(pamh, newname, name);
|
||||
retval = pam_set_item(pamh, PAM_USER, name);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
gray_free_transform_expr();
|
||||
}
|
||||
if (retval != PAM_SUCCESS) {
|
||||
_pam_log(LOG_ERR, "retval %d", retval);
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
|
@ -145,7 +153,7 @@ pam_sm_authenticate(pam_handle_t *pamh,
|
|||
|
||||
if (regex) {
|
||||
for (;;) {
|
||||
if (rc = regcomp(&rx, regex, regex_flags)) {
|
||||
if ((rc = regcomp(&rx, regex, regex_flags)) != 0) {
|
||||
char errbuf[512];
|
||||
regerror (rc, &rx, errbuf, sizeof (errbuf));
|
||||
_pam_log(LOG_ERR, "can't compile regex: %s",
|
||||
|
|
|
@ -365,11 +365,15 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
|
|||
/* FIXME: This comment is needed to pacify
|
||||
`make check-sql-config' in doc:
|
||||
gpam_sql_find_config("setenv-query") */
|
||||
if (rc == PAM_SUCCESS
|
||||
&& (q = gpam_sql_get_query(pamh, "setenv-query",
|
||||
&slist, 0))) {
|
||||
mysql_setenv(pamh, &mysql, q);
|
||||
gray_slist_free(&slist);
|
||||
if (rc == PAM_SUCCESS) {
|
||||
rc = gpam_sql_get_query(pamh, "setenv-query", 0,
|
||||
&slist, &q);
|
||||
if (rc == PAM_SUCCESS) {
|
||||
if (q) {
|
||||
mysql_setenv(pamh, &mysql, q);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
}
|
||||
}
|
||||
mysql_close(&mysql);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,8 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
|
|||
char *p;
|
||||
int n;
|
||||
gray_slist_t slist;
|
||||
|
||||
char const *query;
|
||||
|
||||
n = PQntuples(res);
|
||||
DEBUG(20,("Returned %d tuples", n));
|
||||
if (n != 1) {
|
||||
|
@ -153,12 +154,15 @@ gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *password,
|
|||
/* FIXME: This comment is needed to pacify
|
||||
`make check-sql-config' in doc:
|
||||
gpam_sql_find_config("setenv-query") */
|
||||
if (rc == PAM_SUCCESS
|
||||
&& (query = gpam_sql_get_query(pamh,
|
||||
"setenv-query",
|
||||
&slist, 0))) {
|
||||
pgsql_setenv(pamh, pgconn, query);
|
||||
gray_slist_free(&slist);
|
||||
if (rc == PAM_SUCCESS) {
|
||||
rc = gpam_sql_get_query(pamh, "setenv-query", 0,
|
||||
&slist, &query);
|
||||
if (rc == PAM_SUCCESS) {
|
||||
if (query) {
|
||||
pgsql_setenv(pamh, pgconn, query);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -159,48 +159,39 @@ gpam_sql_check_boolean_config(const char *name, int defval)
|
|||
}
|
||||
|
||||
|
||||
const char *
|
||||
gpam_sql_get_query(pam_handle_t *pamh, const char *name, gray_slist_t *pslist,
|
||||
int required)
|
||||
int
|
||||
gpam_sql_get_query(pam_handle_t *pamh, const char *name, int required,
|
||||
gray_slist_t *pslist, const char **retptr)
|
||||
{
|
||||
gray_slist_t slist;
|
||||
const char *query = gpam_sql_find_config(name);
|
||||
|
||||
char *retval;
|
||||
|
||||
if (!query) {
|
||||
if (required)
|
||||
gray_raise("%s: %s not defined", gpam_sql_config_file, name);
|
||||
return NULL;
|
||||
if (required) {
|
||||
_pam_log(LOG_ERR, "%s: %s not defined",
|
||||
gpam_sql_config_file, name);
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
}
|
||||
*pslist = NULL;
|
||||
*retptr = NULL;
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
slist = gray_slist_create();
|
||||
if (!slist)
|
||||
return errno_to_pam(errno);
|
||||
gray_expand_string(pamh, query, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
*pslist = slist;
|
||||
return gray_slist_finish(slist);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_query2(pam_handle_t *pamh, const char *name1, const char *name2,
|
||||
gray_slist_t *pslist, int required)
|
||||
{
|
||||
gray_slist_t slist;
|
||||
const char *query = gpam_sql_find_config(name1);
|
||||
|
||||
if (!query)
|
||||
query = gpam_sql_find_config(name2);
|
||||
|
||||
if (!query) {
|
||||
if (required)
|
||||
gray_raise("%s: %s not defined",
|
||||
gpam_sql_config_file, name1);
|
||||
return NULL;
|
||||
retval = gray_slist_finish(slist);
|
||||
if (gray_slist_err(slist)) {
|
||||
int rc = errno_to_pam(gray_slist_err(slist));
|
||||
gray_slist_free(&slist);
|
||||
return rc;
|
||||
}
|
||||
|
||||
slist = gray_slist_create();
|
||||
gray_expand_string(pamh, query, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
*pslist = slist;
|
||||
return gray_slist_finish(slist);
|
||||
*retptr = retval;
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +203,6 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
|||
const char *username;
|
||||
char *password;
|
||||
int retval = PAM_AUTH_ERR;
|
||||
gray_pam_init(PAM_SERVICE_ERR);
|
||||
|
||||
/* parse arguments */
|
||||
_pam_parse(argc, argv);
|
||||
|
@ -237,13 +227,18 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
|||
retval = PAM_SERVICE_ERR;
|
||||
else {
|
||||
gray_slist_t slist;
|
||||
char const *query;
|
||||
|
||||
/* FIXME: This comment is needed to pacify
|
||||
`make check-sql-config' in doc:
|
||||
gpam_sql_find_config("passwd-query") */
|
||||
retval = gpam_sql_verify_user_pass(pamh, password,
|
||||
get_query2(pamh, "passwd-query",
|
||||
"query", &slist, 1));
|
||||
gray_slist_free(&slist);
|
||||
retval = gpam_sql_get_query(pamh, "passwd-query", 1,
|
||||
&slist, &query);
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = gpam_sql_verify_user_pass(pamh, password,
|
||||
query);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
}
|
||||
|
||||
gray_env_free(config_env);
|
||||
|
@ -276,7 +271,6 @@ sql_session_mgmt(pam_handle_t *pamh, int flags,
|
|||
{
|
||||
int retval;
|
||||
|
||||
gray_pam_init(PAM_SERVICE_ERR);
|
||||
|
||||
/* parse arguments */
|
||||
_pam_parse(argc, argv);
|
||||
|
@ -285,10 +279,15 @@ sql_session_mgmt(pam_handle_t *pamh, int flags,
|
|||
retval = PAM_SERVICE_ERR;
|
||||
else {
|
||||
gray_slist_t slist;
|
||||
retval = gpam_sql_acct(pamh,
|
||||
gpam_sql_get_query(pamh, query_name,
|
||||
&slist, 0));
|
||||
gray_slist_free(&slist);
|
||||
char const *query;
|
||||
|
||||
retval = gpam_sql_get_query(pamh, query_name, 0, &slist, &query);
|
||||
if (retval == PAM_SUCCESS) {
|
||||
if (query) {
|
||||
retval = gpam_sql_acct(pamh, query);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gray_env_free(config_env);
|
||||
|
|
|
@ -47,7 +47,8 @@ int gpam_sql_verify_user_pass(pam_handle_t *pamh, const char *passwd,
|
|||
int gpam_sql_acct(pam_handle_t *pamh, const char *query);
|
||||
|
||||
char *gpam_sql_find_config(const char *name);
|
||||
const char *gpam_sql_get_query(pam_handle_t *pamh, const char *name,
|
||||
gray_slist_t *pslist, int required);
|
||||
int gpam_sql_get_query(pam_handle_t *pamh, char const *var,
|
||||
int required,
|
||||
gray_slist_t *pslist, const char **query);
|
||||
int gpam_sql_check_boolean_config(const char *name, int defval);
|
||||
|
||||
|
|
|
@ -340,32 +340,51 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
|||
char *file;
|
||||
|
||||
slist = gray_slist_create();
|
||||
gray_expand_string(pamh, motd_file_name, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
file = gray_slist_finish(slist);
|
||||
retval = read_file(pamh, file);
|
||||
if (!slist)
|
||||
retval = errno_to_pam(errno);
|
||||
else {
|
||||
gray_expand_string(pamh, motd_file_name, slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
file = gray_slist_finish(slist);
|
||||
if (file)
|
||||
retval = read_file(pamh, file);
|
||||
else
|
||||
retval = errno_to_pam(errno);
|
||||
}
|
||||
gray_slist_free(&slist);
|
||||
} else if (optindex >= 0) {
|
||||
int i;
|
||||
char **xargv;
|
||||
|
||||
|
||||
argc -= optindex;
|
||||
argv += optindex;
|
||||
if (!argc) {
|
||||
_pam_log(LOG_INFO, "empty command line");
|
||||
return retval;
|
||||
}
|
||||
xargv = gray_malloc((argc + 1) * sizeof (xargv[0]));
|
||||
xargv = calloc((argc + 1), sizeof (xargv[0]));
|
||||
if (!xargv)
|
||||
return errno_to_pam(errno);
|
||||
slist = gray_slist_create();
|
||||
for (i = 0; i < argc; i++) {
|
||||
gray_expand_string(pamh, argv[i], slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
xargv[i] = gray_slist_finish(slist);
|
||||
if (!slist)
|
||||
retval = errno_to_pam(errno);
|
||||
else {
|
||||
int i;
|
||||
int ec;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
gray_expand_string(pamh, argv[i], slist);
|
||||
gray_slist_append_char(slist, 0);
|
||||
xargv[i] = gray_slist_finish(slist);
|
||||
}
|
||||
xargv[i] = NULL;
|
||||
ec = gray_slist_err(slist);
|
||||
if (ec)
|
||||
retval = errno_to_pam(ec);
|
||||
else
|
||||
retval = exec_file(pamh, xargv, logfile_name);
|
||||
free(xargv);
|
||||
gray_slist_free(&slist);
|
||||
}
|
||||
xargv[i] = NULL;
|
||||
retval = exec_file(pamh, xargv, logfile_name);
|
||||
free(xargv);
|
||||
gray_slist_free(&slist);
|
||||
} else
|
||||
_pam_log(LOG_ERR,
|
||||
"invalid usage: either file or exec must be specified");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue