diff --git a/lib/krb5/acl.c b/lib/krb5/acl.c index 7550e22ea..803b2189a 100644 --- a/lib/krb5/acl.c +++ b/lib/krb5/acl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 2000 - 2002, 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -46,9 +46,24 @@ struct acl_field { }; static void -acl_free_list(struct acl_field *acl) +free_retv(struct acl_field *acl) +{ + while(acl != NULL) { + if (acl->type == acl_retval) { + if (*acl->u.retv) + free(*acl->u.retv); + *acl->u.retv = NULL; + } + acl = acl->next; + } +} + +static void +acl_free_list(struct acl_field *acl, int retv) { struct acl_field *next; + if (retv) + free_retv(acl); while(acl != NULL) { next = acl->next; free(acl); @@ -69,7 +84,7 @@ acl_parse_format(krb5_context context, tmp = malloc(sizeof(*tmp)); if(tmp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); - acl_free_list(acl); + acl_free_list(acl, 0); return ENOMEM; } if(*p == 's') { @@ -81,6 +96,12 @@ acl_parse_format(krb5_context context, } else if(*p == 'r') { tmp->type = acl_retval; tmp->u.retv = va_arg(ap, char **); + *tmp->u.retv = NULL; + } else { + krb5_set_error_string(context, "acl_parse_format: " + "unknown format specifier %c", *p); + acl_free_list(acl, 0); + return EINVAL; } tmp->next = NULL; if(acl == NULL) @@ -99,9 +120,9 @@ acl_match_field(krb5_context context, struct acl_field *field) { if(field->type == acl_string) { - return !strcmp(string, field->u.cstr); + return !strcmp(field->u.cstr, string); } else if(field->type == acl_fnmatch) { - return !fnmatch(string, field->u.cstr, 0); + return !fnmatch(field->u.cstr, string, 0); } else if(field->type == acl_retval) { *field->u.retv = strdup(string); return TRUE; @@ -115,14 +136,18 @@ acl_match_acl(krb5_context context, const char *string) { char buf[256]; - for(;strsep_copy(&string, " \t", buf, sizeof(buf)) != -1; - acl = acl->next) { + while(strsep_copy(&string, " \t", buf, sizeof(buf)) != -1) { if(buf[0] == '\0') continue; /* skip ws */ + if (acl == NULL) + return FALSE; if(!acl_match_field(context, buf, acl)) { return FALSE; } + acl = acl->next; } + if (acl) + return FALSE; return TRUE; } @@ -145,7 +170,7 @@ krb5_acl_match_string(krb5_context context, return ret; found = acl_match_acl(context, acl, string); - acl_free_list(acl); + acl_free_list(acl, !found); if (found) { return 0; } else { @@ -192,10 +217,11 @@ krb5_acl_match_file(krb5_context context, found = TRUE; break; } + free_retv(acl); } fclose(f); - acl_free_list(acl); + acl_free_list(acl, !found); if (found) { return 0; } else {