dgaudet 97/08/06 13:32:22
Modified: src CHANGES http_request.c Log: Fix another long-standing bug in sub_req_lookup_file where it would happily skip past access checks on subdirectories looked up with relative paths. (It's used by mod_dir, mod_negotiation, and mod_include.) Revision Changes Path 1.388 +5 -0 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.387 retrieving revision 1.388 diff -u -r1.387 -r1.388 --- CHANGES 1997/08/06 20:21:19 1.387 +++ CHANGES 1997/08/06 20:32:18 1.388 @@ -1,5 +1,10 @@ Changes with Apache 1.3a2 + *) Fix another long-standing bug in sub_req_lookup_file where it would + happily skip past access checks on subdirectories looked up with + relative paths. (It's used by mod_dir, mod_negotiation, + and mod_include.) [Dean Gaudet] + *) directory_walk optimization to reduce an O(N*M) loop to O(N+M) where N is the number of <Directory> sections, and M is the number of components in the filename of an object. 1.71 +23 -14 apache/src/http_request.c Index: http_request.c =================================================================== RCS file: /export/home/cvs/apache/src/http_request.c,v retrieving revision 1.70 retrieving revision 1.71 diff -u -r1.70 -r1.71 --- http_request.c 1997/08/06 20:21:25 1.70 +++ http_request.c 1997/08/06 20:32:19 1.71 @@ -733,22 +733,31 @@ rnew->per_dir_config = r->per_dir_config; - if ((res = check_symlinks (rnew->filename, allow_options (rnew)))) { - log_reason ("Symbolic link not allowed", rnew->filename, rnew); - rnew->status = res; - return rnew; - } - /* do a file_walk, if it doesn't change the per_dir_config then - * we know that we don't have to redo all the access checks */ - if ((res = file_walk (rnew))) { - rnew->status = res; - return rnew; - } - if (rnew->per_dir_config == r->per_dir_config) { - if ((res = find_types (rnew)) || (res = run_fixups (rnew))) { + /* no matter what, if it's a subdirectory, we need to re-run + * directory_walk */ + if (S_ISDIR (rnew->finfo.st_mode)) { + res = directory_walk (rnew); + if (!res) { + res = file_walk (rnew); + } + } else { + if ((res = check_symlinks (rnew->filename, allow_options (rnew)))) { + log_reason ("Symbolic link not allowed", rnew->filename, rnew); + rnew->status = res; + return rnew; + } + /* do a file_walk, if it doesn't change the per_dir_config then + * we know that we don't have to redo all the access checks */ + if ((res = file_walk (rnew))) { rnew->status = res; + return rnew; + } + if (rnew->per_dir_config == r->per_dir_config) { + if ((res = find_types (rnew)) || (res = run_fixups (rnew))) { + rnew->status = res; + } + return rnew; } - return rnew; } } else { /* XXX: this should be set properly like it is in the same-dir case