[Cvs-nserver-commits] CVS: cvs-nserver/acl dir-acl.c,1.1.2.25,1.1.2.26
Brought to you by:
tyranny
From: Alexey M. <mo...@us...> - 2002-06-19 07:34:56
|
Update of /cvsroot/cvs-nserver/cvs-nserver/acl In directory usw-pr-cvs1:/tmp/cvs-serv1726 Modified Files: Tag: NCLI-1-11-1 dir-acl.c Log Message: BUGFIX: it seems I fixed the 'doubling DIR_ACL bug in add_dir_acl_topdirs BUGFIX: and basic tests are Ok, but more accurate and formal testing required Index: dir-acl.c =================================================================== RCS file: /cvsroot/cvs-nserver/cvs-nserver/acl/Attic/dir-acl.c,v retrieving revision 1.1.2.25 retrieving revision 1.1.2.26 diff -u -d -r1.1.2.25 -r1.1.2.26 --- dir-acl.c 13 Jun 2002 13:44:33 -0000 1.1.2.25 +++ dir-acl.c 19 Jun 2002 07:34:43 -0000 1.1.2.26 @@ -130,14 +130,14 @@ } static struct DIR_ACL *create_and_load_dir_acl (const char *dir); -static struct DIR_ACL *add_dir_acl_topdirs (char *dir, struct DIR_ACL *the_dir_acl); +static struct DIR_ACL *add_dir_acl_topdirs (const char * const dir, + struct DIR_ACL *the_dir_acl); struct DIR_ACL * get_dir_acl (const char *dir, const char *branch) { struct DIR_ACL *dir_acl = NULL; - char *dir_copy = NULL; size_t tldlen = strlen(current_toplevel_directory); size_t dirlen = strlen(dir); @@ -146,37 +146,22 @@ current_toplevel_directory itself, its length is less than length of the current_toplevel_directory because of trailing slash. Handle this case sui generis.... - */ + */ if (!(((tldlen == (dirlen+1)) && (current_toplevel_directory[tldlen-1] == '/') && (strncmp(dir,current_toplevel_directory,dirlen) == 0)) || (strncmp(dir, current_toplevel_directory,tldlen) == 0))) { /* error(0,0,"Trying to access Dir ACL in '%s' outside of '%s'", dir,current_toplevel_directory); */ - goto out; + return NULL; } dir_acl = create_and_load_dir_acl(dir); - if (!dir_acl) - goto err; - - /* add_dir_acl_topdirs() will modify its first argument */ - dir_copy = strdup(dir); - if (dir_copy == NULL) - goto err; - - if (!add_dir_acl_topdirs(dir_copy, dir_acl)) - goto err; - - out: - free(dir_copy); - + if (dir_acl == NULL || add_dir_acl_topdirs(dir,dir_acl)==NULL) { + destroy_dir_acl(dir_acl); + dir_acl = NULL; + } return dir_acl; - - err: - destroy_dir_acl(dir_acl); - dir_acl = NULL; - goto out; } @@ -228,41 +213,64 @@ */ static struct DIR_ACL * -add_dir_acl_topdirs (char *dir, struct DIR_ACL *the_dir_acl) +add_dir_acl_topdirs (const char * const dir, struct DIR_ACL *the_dir_acl) { - int toplevel_len = strlen(current_toplevel_directory); - char *last_component; - - /* FIXME: somehow the parent directory gets added twice. It is - harmless, but needs investigation */ - - last_component = strrchr(dir + toplevel_len, '/'); - if (last_component == NULL) { - /* we are processing the top dir */ - struct DIR_ACL *topdir_acl = create_and_load_dir_acl(dir); - if (!topdir_acl) - return NULL; - - if (!add_dir_to_path(the_dir_acl, topdir_acl)) - return NULL; - - } else { - /* we need to strip the last component and try to get its top dir */ - struct DIR_ACL *this_dir_acl; - *last_component = '\0'; - this_dir_acl = create_and_load_dir_acl(dir); - if (!this_dir_acl) - return NULL; - - if (!add_dir_to_path(the_dir_acl, this_dir_acl)) - return NULL; + size_t tldlen = strlen(current_toplevel_directory); + size_t dirlen = strlen(dir); + char *dircopy; + char *dirp; + char *ptr; + int is_error = 0; + + if ((dirlen + 1 == tldlen || dirlen == tldlen) && + strncmp(dir,current_toplevel_directory,dirlen)==0) { + /* The special case, it's a top level directory itself */ + return the_dir_acl; + } + + if (tldlen > dirlen || + strncmp(dir,current_toplevel_directory, tldlen)!=0) { + /* The bad invocation, the directory asked is not a + subdir inside current_toplevel_directory + */ + /* error(0,0,"Directory '%s' is outside of '%s'", + dir,current_toplevel_directory); */ + return NULL; + } - if (!add_dir_acl_topdirs(dir, the_dir_acl)) - return NULL; + dircopy = strdup(dir); + if (dircopy == NULL) { + /* error(0,0,"Out of memory"); */ + return NULL; + } + + if (dircopy[dirlen-1]=='/') + dircopy[dirlen-1]='\0'; - *last_component = '/'; + dirp = dircopy + tldlen - 1; + + while((ptr = strchr(dirp,'/'))!= NULL) { + DIR_ACL *topdir_acl = NULL; + *ptr = '\0'; + topdir_acl = create_and_load_dir_acl(dircopy); + if (topdir_acl == NULL) { + is_error = 1; + break; + } + if (!add_dir_to_path(the_dir_acl, topdir_acl)) { + destroy_dir_acl(topdir_acl); + is_error = 1; + break; + } + *ptr = '/'; + dirp = ptr + 1; } - return the_dir_acl; + /* We don't to process the last component as its already + * processed */ + + free(dircopy); + + return ((is_error) ? NULL : the_dir_acl); } @@ -560,12 +568,10 @@ USER_ACE* ace; enum DIR_PERM eff_perm = dir_perm_all; int user_was_mentioned_in_acl = 0; - if (dir_acl->top_dirs) { for (top_dirs = dir_acl->top_dirs; *top_dirs; top_dirs++) { struct DIR_ACL* parent_acl = *top_dirs; USER_ACE* ace; - /* restrict current parent permissions */ ace = get_user_ace(parent_acl->user_acls, username); if (ace != NULL) { |