diff options
author | Jeremy Allison <jra@samba.org> | 2007-09-07 20:57:01 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:30:32 -0500 |
commit | 132ee3990af5d31573978f5a3abf43db2303880b (patch) | |
tree | 2ce69566fb9a4ecb0f8ce19261c60e4ad3d8593a /source3/smbd/filename.c | |
parent | c5d8fd3772706a469484df8a16abf10547d1c7a4 (diff) | |
download | samba-132ee3990af5d31573978f5a3abf43db2303880b.tar.gz samba-132ee3990af5d31573978f5a3abf43db2303880b.tar.xz samba-132ee3990af5d31573978f5a3abf43db2303880b.zip |
r25009: Large patch discussed with Volker. Move unix_convert to a talloc-based
interface. More development will come on top of this. Remove the
"mangled map" parameter.
Jeremy.
(This used to be commit dee8beba7a92b8a3f68bbcc59fd0a827f68c7736)
Diffstat (limited to 'source3/smbd/filename.c')
-rw-r--r-- | source3/smbd/filename.c | 189 |
1 files changed, 112 insertions, 77 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 5f9563b83c8..5871fd143f7 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. filename handling routines Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1999-2004 + Copyright (C) Jeremy Allison 1999-2007 Copyright (C) Ying Chen 2000 Copyright (C) Volker Lendecke 2007 @@ -37,11 +37,12 @@ static BOOL mangled_equal(const char *name1, const char *name2, const struct share_params *p) { - pstring tmpname; + char mname[13]; - pstrcpy(tmpname, name2); - mangle_map(tmpname, True, False, p); - return strequal(name1, tmpname); + if (!name_to_8_3(name2, mname, False, p)) { + return False; + } + return strequal(name1, mname); } /**************************************************************************** @@ -107,9 +108,10 @@ for nlinks = 0, which can never be true for any file). ****************************************************************************/ NTSTATUS unix_convert(connection_struct *conn, - pstring orig_path, + const char *orig_path, BOOL allow_wcard_last_component, - char *saved_last_component, + char **pp_conv_path, + char **pp_saved_last_component, SMB_STRUCT_STAT *pst) { SMB_STRUCT_STAT st; @@ -119,16 +121,20 @@ NTSTATUS unix_convert(connection_struct *conn, BOOL component_was_mangled = False; BOOL name_has_wildcard = False; NTSTATUS result; + TALLOC_CTX *ctx = talloc_tos(); SET_STAT_INVALID(*pst); - - if(saved_last_component) { - *saved_last_component = 0; + *pp_conv_path = NULL; + if(pp_saved_last_component) { + *pp_saved_last_component = NULL; } if (conn->printer) { /* we don't ever use the filenames on a printer share as a filename - so don't convert them */ + if (!(*pp_conv_path = talloc_strdup(ctx,orig_path))) { + return NT_STATUS_NO_MEMORY; + } return NT_STATUS_OK; } @@ -157,11 +163,13 @@ NTSTATUS unix_convert(connection_struct *conn, */ if (!*orig_path) { - if (!(name = SMB_STRDUP("."))) { + if (!(name = talloc_strdup(ctx,"."))) { return NT_STATUS_NO_MEMORY; } if (SMB_VFS_STAT(conn,name,&st) == 0) { *pst = st; + } else { + return map_nt_error_from_unix(errno); } DEBUG(5,("conversion finished \"\" -> %s\n",name)); goto done; @@ -183,17 +191,18 @@ NTSTATUS unix_convert(connection_struct *conn, * Ensure saved_last_component is valid even if file exists. */ - if(saved_last_component) { + if(pp_saved_last_component) { end = strrchr_m(orig_path, '/'); if (end) { - pstrcpy(saved_last_component, end + 1); + *pp_saved_last_component = talloc_strdup(ctx, end + 1); } else { - pstrcpy(saved_last_component, orig_path); + *pp_saved_last_component = talloc_strdup(ctx, + orig_path); } } - if (!(name = SMB_STRDUP(orig_path))) { - DEBUG(0, ("strdup failed\n")); + if (!(name = talloc_strdup(ctx, orig_path))) { + DEBUG(0, ("talloc_strdup failed\n")); return NT_STATUS_NO_MEMORY; } @@ -224,9 +233,9 @@ NTSTATUS unix_convert(connection_struct *conn, * building the directories with asprintf and free it. */ - if ((dirpath == NULL) && (!(dirpath = SMB_STRDUP("")))) { - DEBUG(0, ("strdup failed\n")); - SAFE_FREE(name); + if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) { + DEBUG(0, ("talloc_strdup failed\n")); + TALLOC_FREE(name); return NT_STATUS_NO_MEMORY; } @@ -264,8 +273,7 @@ NTSTATUS unix_convert(connection_struct *conn, */ if (conn->case_sensitive && - !mangle_is_mangled(name, conn->params) && - !*lp_mangled_map(conn->params)) { + !mangle_is_mangled(name, conn->params)) { goto done; } @@ -302,8 +310,14 @@ NTSTATUS unix_convert(connection_struct *conn, *end = 0; } - if (saved_last_component != 0) { - pstrcpy(saved_last_component, end ? end + 1 : start); + if (pp_saved_last_component) { + TALLOC_FREE(*pp_saved_last_component); + *pp_saved_last_component = talloc_strdup(ctx, + end ? end + 1 : start); + if (!*pp_saved_last_component) { + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; + } } /* The name cannot have a component of "." */ @@ -473,25 +487,27 @@ NTSTATUS unix_convert(connection_struct *conn, */ if (mangle_is_mangled(start, conn->params) - && mangle_check_cache_alloc(start, - &unmangled, - conn->params)) { + && mangle_lookup_name_from_8_3(ctx, + start, + &unmangled, + conn->params)) { char *tmp; size_t start_ofs = start - name; if (*dirpath != '\0') { - asprintf(&tmp, "%s/%s", dirpath, - unmangled); - SAFE_FREE(unmangled); + tmp = talloc_asprintf(ctx, + "%s/%s", dirpath, + unmangled); + TALLOC_FREE(unmangled); } else { tmp = unmangled; } if (tmp == NULL) { - DEBUG(0, ("malloc failed\n")); - result = NT_STATUS_NO_MEMORY; + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; } - SAFE_FREE(name); + TALLOC_FREE(name); name = tmp; start = name + start_ofs; end = start + strlen(start); @@ -511,18 +527,20 @@ NTSTATUS unix_convert(connection_struct *conn, size_t start_ofs = start - name; if (*dirpath != '\0') { - asprintf(&tmp, "%s/%s/%s", dirpath, - found_name, end+1); + tmp = talloc_asprintf(ctx, + "%s/%s/%s", dirpath, + found_name, end+1); } else { - asprintf(&tmp, "%s/%s", found_name, - end+1); + tmp = talloc_asprintf(ctx, + "%s/%s", found_name, + end+1); } if (tmp == NULL) { - DEBUG(0, ("asprintf failed\n")); - result = NT_STATUS_NO_MEMORY; + DEBUG(0, ("talloc_asprintf failed\n")); + return NT_STATUS_NO_MEMORY; } - SAFE_FREE(name); + TALLOC_FREE(name); name = tmp; start = name + start_ofs; end = start + strlen(found_name); @@ -532,18 +550,19 @@ NTSTATUS unix_convert(connection_struct *conn, size_t start_ofs = start - name; if (*dirpath != '\0') { - asprintf(&tmp, "%s/%s", dirpath, - found_name); + tmp = talloc_asprintf(ctx, + "%s/%s", dirpath, + found_name); } else { - tmp = SMB_STRDUP(found_name); + tmp = talloc_strdup(ctx, + found_name); } if (tmp == NULL) { - DEBUG(0, ("malloc failed\n")); - result = NT_STATUS_NO_MEMORY; - goto fail; + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; } - SAFE_FREE(name); + TALLOC_FREE(name); name = tmp; start = name + start_ofs; @@ -560,7 +579,7 @@ NTSTATUS unix_convert(connection_struct *conn, } } - SAFE_FREE(found_name); + TALLOC_FREE(found_name); } /* end else */ #ifdef DEVELOPER @@ -577,19 +596,19 @@ NTSTATUS unix_convert(connection_struct *conn, */ if (*dirpath != '\0') { - char *tmp; - - if (asprintf(&tmp, "%s/%s", dirpath, start) == -1) { - DEBUG(0, ("asprintf failed\n")); + char *tmp = talloc_asprintf(ctx, + "%s/%s", dirpath, start); + if (!tmp) { + DEBUG(0, ("talloc_asprintf failed\n")); return NT_STATUS_NO_MEMORY; } - SAFE_FREE(dirpath); + TALLOC_FREE(dirpath); dirpath = tmp; } else { - SAFE_FREE(dirpath); - if (!(dirpath = SMB_STRDUP(start))) { - DEBUG(0, ("strdup failed\n")); + TALLOC_FREE(dirpath); + if (!(dirpath = talloc_strdup(ctx,start))) { + DEBUG(0, ("talloc_strdup failed\n")); return NT_STATUS_NO_MEMORY; } } @@ -628,17 +647,23 @@ NTSTATUS unix_convert(connection_struct *conn, DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); done: - pstrcpy(orig_path, name); - SAFE_FREE(name); - SAFE_FREE(dirpath); + *pp_conv_path = name; + TALLOC_FREE(dirpath); return NT_STATUS_OK; fail: DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start)); - pstrcpy(orig_path, dirpath); - pstrcat(orig_path, "/"); - pstrcat(orig_path, start); - SAFE_FREE(name); - SAFE_FREE(dirpath); + if (*dirpath != '\0') { + *pp_conv_path = talloc_asprintf(ctx, + "%s/%s", dirpath, start); + } else { + *pp_conv_path = talloc_strdup(ctx, start); + } + if (!*pp_conv_path) { + DEBUG(0, ("talloc_asprintf failed\n")); + return NT_STATUS_NO_MEMORY; + } + TALLOC_FREE(name); + TALLOC_FREE(dirpath); return result; } @@ -649,7 +674,7 @@ NTSTATUS unix_convert(connection_struct *conn, a valid one for the user to access. ****************************************************************************/ -NTSTATUS check_name(connection_struct *conn, const pstring name) +NTSTATUS check_name(connection_struct *conn, const char *name) { if (IS_VETO_PATH(conn, name)) { /* Is it not dot or dot dot. */ @@ -682,8 +707,9 @@ static BOOL fname_equal(const char *name1, const char *name2, BOOL case_sensitive) { /* Normal filename handling */ - if (case_sensitive) + if (case_sensitive) { return(strcmp(name1,name2) == 0); + } return(strequal(name1,name2)); } @@ -701,17 +727,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path, BOOL mangled; char *unmangled_name = NULL; long curpos; + TALLOC_CTX *ctx = talloc_tos(); mangled = mangle_is_mangled(name, conn->params); /* handle null paths */ - if ((path == NULL) || (*path == 0)) + if ((path == NULL) || (*path == 0)) { path = "."; + } /* * The incoming name can be mangled, and if we de-mangle it * here it will not compare correctly against the filename (name2) - * read from the directory and then mangled by the mangle_map() + * read from the directory and then mangled by the name_to_8_3() * call. We need to mangle both names or neither. * (JRA). * @@ -724,15 +752,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path, */ if (mangled && !conn->case_sensitive) { - mangled = !mangle_check_cache_alloc(name, &unmangled_name, - conn->params); - name = unmangled_name; + mangled = !mangle_lookup_name_from_8_3(ctx, + name, + &unmangled_name, + conn->params); + if (mangled) { + name = unmangled_name; + } } /* open the directory */ if (!(cur_dir = OpenDir(conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); - SAFE_FREE(unmangled_name); + TALLOC_FREE(unmangled_name); return(False); } @@ -741,8 +773,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, while ((dname = ReadDirName(cur_dir, &curpos))) { /* Is it dot or dot dot. */ - if ((dname[0] == '.') && (!dname[1] || - (dname[1] == '.' && !dname[2]))) { + if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } @@ -760,15 +791,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path, if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ - *found_name = SMB_STRDUP(dname); - SAFE_FREE(unmangled_name); + *found_name = talloc_strdup(ctx,dname); + TALLOC_FREE(unmangled_name); CloseDir(cur_dir); + if (!*found_name) { + errno = ENOMEM; + return False; + } return(True); } } - SAFE_FREE(unmangled_name); + TALLOC_FREE(unmangled_name); CloseDir(cur_dir); errno = ENOENT; - return(False); + return False; } |