summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/filename.c60
-rw-r--r--source3/smbd/reply.c2
-rw-r--r--source3/smbd/trans2.c2
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);
}