diff options
Diffstat (limited to 'lib/transform.c')
-rw-r--r-- | lib/transform.c | 190 |
1 files changed, 158 insertions, 32 deletions
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,9 +71,26 @@ 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 = calloc (1, sizeof *p); + if (p) { - struct transform *p = gray_zalloc (sizeof *p); if (transform_tail) @@ -82,2 +100,3 @@ new_transform () transform_tail = p; + } return p; @@ -104,3 +123,5 @@ add_segment (struct transform *tf) { - struct replace_segm *segm = gray_malloc (sizeof *segm); + struct replace_segm *segm = malloc (sizeof *segm); + if (segm) + { segm->next = NULL; @@ -112,2 +133,5 @@ add_segment (struct transform *tf) tf->segm_count++; + } + else + 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,4 +154,8 @@ add_literal_segment (struct transform *tf, char *str, char *end) struct replace_segm *segm = add_segment (tf); + if (segm) + { segm->type = segm_literal; - segm->v.literal.ptr = gray_malloc (len + 1); + segm->v.literal.ptr = malloc (len + 1); + if (segm->v.literal.ptr) + { memcpy (segm->v.literal.ptr, str, len); @@ -136,2 +164,6 @@ add_literal_segment (struct transform *tf, char *str, char *end) } + else + transform_seterr (tf, errno_to_pam (errno)); + } + } } @@ -142,4 +174,8 @@ add_char_segment (struct transform *tf, int chr) struct replace_segm *segm = add_segment (tf); + if (segm) + { segm->type = segm_literal; - segm->v.literal.ptr = gray_malloc (2); + segm->v.literal.ptr = malloc (2); + if (segm->v.literal.ptr) + { segm->v.literal.ptr[0] = chr; @@ -148,2 +184,6 @@ add_char_segment (struct transform *tf, int chr) } + else + transform_seterr (tf, errno_to_pam (errno)); + } +} @@ -153,2 +193,4 @@ add_backref_segment (struct transform *tf, size_t ref) struct replace_segm *segm = add_segment (tf); + if (segm) + { segm->type = segm_backref; @@ -156,2 +198,3 @@ add_backref_segment (struct transform *tf, size_t ref) } +} @@ -161,2 +204,4 @@ add_case_ctl_segment (struct transform *tf, enum case_ctl_type ctl) struct replace_segm *segm = add_segment (tf); + if (segm) + { segm->type = segm_case_ctl; @@ -164,5 +209,6 @@ add_case_ctl_segment (struct transform *tf, enum case_ctl_type 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,6 +345,11 @@ 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: " + { + _pam_log(LOG_ERR, + "invalid transform replacement: " "back reference out of range"); + transform_seterr (tf, PAM_SERVICE_ERR); + } + else add_backref_segment (tf, n); @@ -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) { + if (transform_head) + { struct transform *tf; - for (tf = transform_head; tf; tf = tf->next) { - _single_transform_name_to_slist (tf, slist, input); + 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; } |