diff options
-rw-r--r-- | lib/base64.c | 20 | ||||
-rw-r--r-- | lib/env.c | 66 | ||||
-rw-r--r-- | lib/graypam.h | 50 | ||||
-rw-r--r-- | lib/ldappass.c | 107 | ||||
-rw-r--r-- | lib/mem.c | 81 | ||||
-rw-r--r-- | lib/slist.c | 127 | ||||
-rw-r--r-- | lib/transform.c | 244 | ||||
-rw-r--r-- | pam_groupmember/pam_groupmember.c | 1 | ||||
-rw-r--r-- | pam_innetgr/pam_innetgr.c | 1 | ||||
-rw-r--r-- | pam_ldaphome/pam_ldaphome.c | 306 | ||||
-rw-r--r-- | pam_log/pam_log.c | 48 | ||||
-rw-r--r-- | pam_regex/pam_regex.c | 26 | ||||
-rw-r--r-- | pam_sql/pam_mysql.c | 14 | ||||
-rw-r--r-- | pam_sql/pam_pgsql.c | 18 | ||||
-rw-r--r-- | pam_sql/pam_sql.c | 81 | ||||
-rw-r--r-- | pam_sql/pam_sql.h | 5 | ||||
-rw-r--r-- | pam_umotd/pam_umotd.c | 49 |
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; @@ -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); @@ -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/ |