diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/filename.c | 60 | ||||
-rw-r--r-- | source3/smbd/reply.c | 2 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 2 |
3 files changed, 37 insertions, 27 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 44916200da..dd1e0de20f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -57,6 +57,38 @@ static BOOL mangled_equal(const char *name1, const char *name2, } /**************************************************************************** + Cope with the differing wildcard and non-wildcard error cases. +****************************************************************************/ + +static NTSTATUS determine_path_error(const char *name, BOOL allow_wcard_last_component) +{ + const char *p; + + if (!allow_wcard_last_component) { + /* Error code within a pathname. */ + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* We're terminating here so we + * can be a little slower and get + * the error code right. Windows + * treats the last part of the pathname + * separately I think, so if the last + * component is a wildcard then we treat + * this ./ as "end of component" */ + + p = strchr(name, '/'); + + if (!p && (ms_has_wild(name) || ISDOT(name))) { + /* Error code at the end of a pathname. */ + return NT_STATUS_OBJECT_NAME_INVALID; + } else { + /* Error code within a pathname. */ + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } +} + +/**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format changes etc. @@ -150,8 +182,7 @@ NTSTATUS unix_convert(connection_struct *conn, if (name[1] == '\0' || name[2] == '\0') { return NT_STATUS_OBJECT_NAME_INVALID; } else { - /* Longer pathname starts with ./ */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; + return determine_path_error(&name[2], allow_wcard_last_component); } } @@ -264,32 +295,11 @@ NTSTATUS unix_convert(connection_struct *conn, /* The name cannot have a component of "." */ if (ISDOT(start)) { - if (end) { - if (allow_wcard_last_component) { - /* We're terminating here so we - * can be a little slower and get - * the error code right. Windows - * treats the last part of the pathname - * separately I think, so if the last - * component is a wildcard then we treat - * this ./ as "end of component" */ - - const char *p = strchr(end+1, '/'); - - if (!p && ms_has_wild(end+1)) { - /* Error code at the end of a pathname. */ - return NT_STATUS_OBJECT_NAME_INVALID; - } else { - /* Error code within a pathname. */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - } - /* Error code within a pathname. */ - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } else { + if (!end) { /* Error code at the end of a pathname. */ return NT_STATUS_OBJECT_NAME_INVALID; } + return determine_path_error(end+1, allow_wcard_last_component); } /* The name cannot have a wildcard if it's not diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e42c663cec..21c8b13b5c 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -952,7 +952,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size pstrcpy(directory,path); pstrcpy(dir2,path); - nt_status = unix_convert(conn, directory, mask_contains_wcard, NULL, &sbuf); + nt_status = unix_convert(conn, directory, True, NULL, &sbuf); if (!NT_STATUS_IS_OK(nt_status)) { END_PROFILE(SMBsearch); return ERROR_NT(nt_status); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2cfb692b02..7bdecd45ca 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1718,7 +1718,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf); - ntstatus = unix_convert(conn, directory, mask_contains_wcard, NULL, &sbuf); + ntstatus = unix_convert(conn, directory, True, NULL, &sbuf); if (!NT_STATUS_IS_OK(ntstatus)) { return ERROR_NT(ntstatus); } |