summaryrefslogtreecommitdiff
path: root/source3/smbd/filename.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-09-07 20:57:01 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:30:32 -0500
commit132ee3990af5d31573978f5a3abf43db2303880b (patch)
tree2ce69566fb9a4ecb0f8ce19261c60e4ad3d8593a /source3/smbd/filename.c
parentc5d8fd3772706a469484df8a16abf10547d1c7a4 (diff)
downloadsamba-132ee3990af5d31573978f5a3abf43db2303880b.tar.gz
samba-132ee3990af5d31573978f5a3abf43db2303880b.tar.bz2
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.c189
1 files changed, 112 insertions, 77 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 5f9563b83c..5871fd143f 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;
}