aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/base64.c20
-rw-r--r--lib/env.c66
-rw-r--r--lib/graypam.h50
-rw-r--r--lib/ldappass.c107
-rw-r--r--lib/mem.c81
-rw-r--r--lib/slist.c127
-rw-r--r--lib/transform.c244
-rw-r--r--pam_groupmember/pam_groupmember.c1
-rw-r--r--pam_innetgr/pam_innetgr.c1
-rw-r--r--pam_ldaphome/pam_ldaphome.c306
-rw-r--r--pam_log/pam_log.c48
-rw-r--r--pam_regex/pam_regex.c26
-rw-r--r--pam_sql/pam_mysql.c14
-rw-r--r--pam_sql/pam_pgsql.c18
-rw-r--r--pam_sql/pam_sql.c81
-rw-r--r--pam_sql/pam_sql.h5
-rw-r--r--pam_umotd/pam_umotd.c49
17 files changed, 788 insertions, 456 deletions
diff --git a/lib/base64.c b/lib/base64.c
index 85b974a..9d0191e 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -56,11 +56,17 @@ gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize)
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;
diff --git a/lib/env.c b/lib/env.c
index 83152e4..b1da177 100644
--- a/lib/env.c
+++ b/lib/env.c
@@ -96,3 +96,3 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
- while (p = fgets(buf, sizeof buf, fp)) {
+ while ((p = fgets(buf, sizeof buf, fp))) {
int len;
@@ -107,6 +107,14 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
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);
@@ -116,4 +124,7 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
}
- 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);
@@ -131,6 +142,15 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
/* 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);
@@ -152,6 +172,15 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
} 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)
@@ -162,4 +191,3 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
if (!env) {
- _pam_log(LOG_EMERG, "not enough memory");
- rc = 1;
+ rc = errno;
break;
@@ -169,5 +197,4 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
if (!env->name) {
- _pam_log(LOG_EMERG, "not enough memory");
+ rc = errno;
free(env);
- rc = 1;
break;
@@ -197,3 +224,8 @@ gray_env_read_tr(const char *file_name, struct gray_env **penv, char **trmap)
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;
diff --git a/lib/graypam.h b/lib/graypam.h
index 76dcd68..69c4909 100644
--- a/lib/graypam.h
+++ b/lib/graypam.h
@@ -86,14 +86,3 @@ 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);
@@ -104,3 +93,2 @@ void gray_make_str(pam_handle_t *pamh, const char *str, const char *name,
char **ret);
-
@@ -108,14 +96,16 @@ 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);
@@ -131,6 +121,24 @@ void gray_wait_debug(size_t interval, const char *file, size_t line);
#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);
diff --git a/lib/ldappass.c b/lib/ldappass.c
index 968078c..247cf16 100644
--- a/lib/ldappass.c
+++ b/lib/ldappass.c
@@ -50,3 +50,3 @@ chk_md5 (const char *db_pass, const char *pass)
struct gpam_md5_ctx md5context;
- gray_slist_t slist = gray_slist_create ();
+ gray_slist_t slist;
ssize_t size;
@@ -54,2 +54,6 @@ chk_md5 (const char *db_pass, const char *pass)
int rc;
+
+ slist = gray_slist_create ();
+ if (!slist)
+ return errno_to_pam(errno);
@@ -62,8 +66,17 @@ chk_md5 (const char *db_pass, const char *pass)
{
+ 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);
@@ -79,5 +92,9 @@ chk_smd5 (const char *db_pass, const char *pass)
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));
@@ -85,5 +102,5 @@ chk_smd5 (const char *db_pass, const char *pass)
{
- _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;
}
@@ -91,10 +108,18 @@ chk_smd5 (const char *db_pass, const char *pass)
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);
@@ -110,5 +135,9 @@ chk_sha (const char *db_pass, const char *pass)
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);
@@ -120,4 +149,5 @@ chk_sha (const char *db_pass, const char *pass)
{
+ rc = errno_to_pam(errno);
gray_slist_free(&slist);
- return 1;
+ return rc;
}
@@ -125,4 +155,12 @@ chk_sha (const char *db_pass, const char *pass)
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);
@@ -138,5 +176,9 @@ chk_ssha (const char *db_pass, const char *pass)
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));
@@ -144,15 +186,22 @@ chk_ssha (const char *db_pass, const char *pass)
{
- _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);
diff --git a/lib/mem.c b/lib/mem.c
index fbe5f06..bcb0a89 100644
--- a/lib/mem.c
+++ b/lib/mem.c
@@ -18,48 +18,2 @@
-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 *
@@ -70,25 +24,18 @@ gray_2nrealloc(void *ptr, size_t *pcount, size_t elsiz)
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);
-}
-
-
-char *
-gray_strdup(const char *str)
-{
- char *p;
-
- if (!str)
- return NULL;
- p = gray_malloc(strlen(str) + 1);
- return strcpy(p, str);
+ ptr = realloc(ptr, count * elsiz);
+ if (ptr)
+ *pcount = count;
+ return ptr;
}
-
diff --git a/lib/slist.c b/lib/slist.c
index b110350..46e516e 100644
--- a/lib/slist.c
+++ b/lib/slist.c
@@ -30,2 +30,3 @@ struct gray_slist {
struct gray_slist_bucket *free;
+ int ec; /* error code */
};
@@ -35,7 +36,9 @@ 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;
@@ -43,3 +46,3 @@ alloc_bucket(size_t size)
-static void
+static int
alloc_pool(gray_slist_t slist, size_t size)
@@ -47,2 +50,6 @@ 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)
@@ -52,5 +59,6 @@ alloc_pool(gray_slist_t slist, size_t size)
slist->tail = p;
+ return 0;
}
-static size_t
+static ssize_t
copy_chars(gray_slist_t slist, const char *str, size_t n)
@@ -59,5 +67,6 @@ copy_chars(gray_slist_t slist, const char *str, size_t n)
-
- 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;
@@ -71,6 +80,9 @@ 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;
@@ -78,2 +90,14 @@ gray_slist_create()
+int
+gray_slist_err(gray_slist_t slist)
+{
+ return slist->ec;
+}
+
+void
+gray_slist_clerr(gray_slist_t slist)
+{
+ slist->ec = 0;
+}
+
void
@@ -86,2 +110,3 @@ gray_slist_clear(gray_slist_t slist)
}
+ gray_slist_clerr(slist);
}
@@ -92,4 +117,4 @@ gray_slist_free(gray_slist_t *slist)
{
- struct gray_slist_bucket *p;
if (*slist) {
+ struct gray_slist_bucket *p;
gray_slist_clear(*slist);
@@ -105,17 +130,23 @@ gray_slist_free(gray_slist_t *slist)
-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);
}
@@ -132,3 +163,3 @@ gray_slist_size(gray_slist_t slist)
-size_t
+ssize_t
gray_slist_coalesce(gray_slist_t slist)
@@ -137,3 +168,5 @@ gray_slist_coalesce(gray_slist_t slist)
- if (slist->head && slist->head->next == NULL)
+ if (slist->ec)
+ return -1;
+ else if (slist->head && slist->head->next == NULL)
size = slist->head->level;
@@ -141,4 +174,7 @@ gray_slist_coalesce(gray_slist_t slist)
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;
@@ -167,3 +203,6 @@ 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);
@@ -176,3 +215,3 @@ gray_slist_finish(gray_slist_t slist)
-void
+int
gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
@@ -183,3 +222,5 @@ gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
char *start = text;
-
+
+ if (slist->ec)
+ return -1;
if (text[0] == '\\') {
@@ -198,3 +239,4 @@ 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)
@@ -202,3 +244,4 @@ gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
} else {
- gray_slist_append_char(slist, val);
+ if (gray_slist_append_char(slist, val) != 1)
+ return -1;
if (pend)
@@ -206,2 +249,3 @@ gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
}
+ return 0;
}
@@ -221,3 +265,3 @@ gray_decode_backslash(int c)
-void
+int
gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp)
@@ -225,11 +269,15 @@ 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;
@@ -238,2 +286,3 @@ gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp)
*endp = text;
+ return 0;
}
diff --git a/lib/transform.c b/lib/transform.c
index 36972f0..c8ed54d 100644
--- a/lib/transform.c
+++ b/lib/transform.c
@@ -65,2 +65,3 @@ struct transform
int has_regex;
+ int error;
/* Compiled replacement expression */
@@ -70,14 +71,32 @@ struct transform
+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;
@@ -104,10 +123,15 @@ 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;
@@ -124,3 +148,3 @@ 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)
{
@@ -130,7 +154,15 @@ add_literal_segment (struct transform *tf, char *str, char *end)
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));
+ }
}
@@ -142,7 +174,15 @@ 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));
+ }
}
@@ -153,4 +193,7 @@ 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;
+ }
}
@@ -161,8 +204,11 @@ 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)
{
@@ -170,3 +216,5 @@ parse_transform_expr (const char *expr)
int i, j, rc;
- char *str, *beg, *cur;
+ char *str;
+ const char *beg;
+ const char *cur;
const char *p;
@@ -176,3 +224,7 @@ parse_transform_expr (const char *expr)
if (expr[0] != 's')
- gray_raise ("Invalid transform expression");
+ {
+ _pam_log(LOG_ERR, "invalid transform expression");
+ *endp = expr;
+ return PAM_SERVICE_ERR;
+ }
@@ -186,3 +238,7 @@ parse_transform_expr (const char *expr)
if (expr[i] != delim)
- gray_raise ("Invalid transform expression");
+ {
+ _pam_log(LOG_ERR, "invalid transform expression");
+ *endp = expr + i;
+ return PAM_SERVICE_ERR;
+ }
@@ -194,3 +250,7 @@ parse_transform_expr (const char *expr)
if (expr[j] != delim)
- gray_raise ("Invalid transform expression");
+ {
+ _pam_log(LOG_ERR, "invalid transform expression");
+ *endp = expr + j;
+ return PAM_SERVICE_ERR;
+ }
@@ -220,3 +280,5 @@ parse_transform_expr (const char *expr)
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;
}
@@ -227,3 +289,8 @@ parse_transform_expr (const char *expr)
/* 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);
@@ -237,3 +304,6 @@ parse_transform_expr (const char *expr)
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;
}
@@ -247,3 +317,9 @@ parse_transform_expr (const char *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);
@@ -253,2 +329,9 @@ parse_transform_expr (const char *expr)
{
+ if (transform_err (tf))
+ {
+ *endp = expr + i + (beg - str);
+ free (str);
+ return transform_err (tf);
+ }
+
if (*cur == '\\')
@@ -262,7 +345,12 @@ parse_transform_expr (const char *expr)
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;
@@ -369,7 +457,13 @@ parse_transform_expr (const char *expr)
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)
@@ -377,3 +471,11 @@ 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;
}
@@ -381,3 +483,3 @@ gray_set_transform_expr (const char *expr)
void
-gray_free_transform_expr ()
+gray_free_transform_expr (void)
{
@@ -390,2 +492,5 @@ gray_free_transform_expr ()
transform_tail = NULL;
+ free (case_ctl_buffer);
+ case_ctl_buffer = NULL;
+ case_ctl_bufsize = 0;
}
@@ -397,4 +502,2 @@ 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;
@@ -403,4 +506,7 @@ run_case_conv (enum case_ctl_type case_ctl, char *ptr, size_t 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);
}
@@ -434,3 +540,3 @@ 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,
@@ -452,4 +558,5 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
- 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)
@@ -490,2 +597,4 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
segm->v.literal.size);
+ if (!ptr)
+ return errno;
CASE_CTL_RESET();
@@ -505,2 +614,4 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
ptr = run_case_conv (case_ctl, ptr, size);
+ if (!ptr)
+ return errno;
CASE_CTL_RESET();
@@ -553,2 +664,3 @@ _single_transform_name_to_slist (struct transform *tf, gray_slist_t slist,
free (rmp);
+ return gray_slist_err (slist);
}
@@ -558,11 +670,25 @@ 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)
+ {
+ 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
{
- _single_transform_name_to_slist (tf, slist, input);
+ 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;
}
diff --git a/pam_groupmember/pam_groupmember.c b/pam_groupmember/pam_groupmember.c
index 7045d13..44be0f8 100644
--- a/pam_groupmember/pam_groupmember.c
+++ b/pam_groupmember/pam_groupmember.c
@@ -168,3 +168,2 @@ check_membership0(pam_handle_t *pamh, int argc, const char **argv)
- gray_pam_init(PAM_AUTHINFO_UNAVAIL);
gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV);
diff --git a/pam_innetgr/pam_innetgr.c b/pam_innetgr/pam_innetgr.c
index a926737..96830b8 100644
--- a/pam_innetgr/pam_innetgr.c
+++ b/pam_innetgr/pam_innetgr.c
@@ -197,3 +197,2 @@ check_netgroup0(pam_handle_t *pamh, int argc, const char **argv,
- gray_pam_init(PAM_AUTHINFO_UNAVAIL);
gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV);
diff --git a/pam_ldaphome/pam_ldaphome.c b/pam_ldaphome/pam_ldaphome.c
index dd3f9e3..0b492dd 100644
--- a/pam_ldaphome/pam_ldaphome.c
+++ b/