[SCM] Samba Shared Repository - branch v3-5-test updated
Jeremy Allison
jra at samba.org
Wed Nov 25 14:24:38 MST 2009
The branch, v3-5-test has been updated
via 0047845... Make us pass RAW-CHKPATH with a case sensitive share. I know Volker will look at this closely so here's the explaination :-). Originally on a case-sensitive share we simply did a stat (or lstat) call and returned success of fail based on the result. However this failed to take account of incoming paths with a wildcard (which must always fail, and with different error messages depending on whether the wildcard is the last component or in the path). Also it failed to take account of a stat fail with ENOENT due to a missing component of the path as the last component (which is ok as it could be a new file) or if the ENOENT was due to the missing component within the path (not the last component) - which must return the correct error. What this means is that with "case sensitive = yes" we do one more talloc call (to get the parent directory) and one more stat call (on the parent directory) in the case where the stat call fails. I think this is an acceptabl
e overhead to enable case sensitive shares to return the correct error messages for applications. Volker please examine carefully :-). Jeremy. (cherry picked from commit c96d487ae3c65c17b377bb316adac4b5775448f3)
via d99584e... Add RAW-CHKPATH test with case-sensitive share. Jeremy. (cherry picked from commit 108da2adaf77c152fd292bbdf5645923659a7c2c)
from 27522fa... s3-registry: fix REG_MULTI_SZ handling in registry_push_value.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test
- Log -----------------------------------------------------------------
commit 00478458b56a0eea52e08605f9f1746abe22109f
Author: Jeremy Allison <jra at samba.org>
Date: Wed Nov 25 13:17:56 2009 -0800
Make us pass RAW-CHKPATH with a case sensitive share.
I know Volker will look at this closely so here's the explaination :-).
Originally on a case-sensitive share we simply did a stat (or lstat)
call and returned success of fail based on the result. However this
failed to take account of incoming paths with a wildcard (which must
always fail, and with different error messages depending on whether
the wildcard is the last component or in the path). Also it failed
to take account of a stat fail with ENOENT due to a missing component
of the path as the last component (which is ok as it could be a new
file) or if the ENOENT was due to the missing component within
the path (not the last component) - which must return the correct
error. What this means is that with "case sensitive = yes" we do
one more talloc call (to get the parent directory) and one more
stat call (on the parent directory) in the case where the stat
call fails. I think this is an acceptable overhead to enable
case sensitive shares to return the correct error messages for
applications. Volker please examine carefully :-).
Jeremy.
(cherry picked from commit c96d487ae3c65c17b377bb316adac4b5775448f3)
commit d99584e5cd2edd382236f1b083e7274428dfe3ac
Author: Jeremy Allison <jra at samba.org>
Date: Wed Nov 25 13:17:38 2009 -0800
Add RAW-CHKPATH test with case-sensitive share.
Jeremy.
(cherry picked from commit 108da2adaf77c152fd292bbdf5645923659a7c2c)
-----------------------------------------------------------------------
Summary of changes:
source3/script/tests/selftest.sh | 3 +
source3/script/tests/test_posix_s3.sh | 4 +
source3/smbd/filename.c | 147 +++++++++++++++++++++++---------
3 files changed, 112 insertions(+), 42 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh
index 80e5042..c952ef2 100755
--- a/source3/script/tests/selftest.sh
+++ b/source3/script/tests/selftest.sh
@@ -266,6 +266,9 @@ cat >$SERVERCONFFILE<<EOF
[hideunread]
copy = tmp
hide unreadable = yes
+[tmpcase]
+ copy = tmp
+ case sensitive = yes
[hideunwrite]
copy = tmp
hide unwriteable files = yes
diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh
index 11fe247..f2f137b 100755
--- a/source3/script/tests/test_posix_s3.sh
+++ b/source3/script/tests/test_posix_s3.sh
@@ -96,6 +96,10 @@ for t in $tests; do
else
testit "$name" $VALGRIND $SMBTORTURE4 $TORTURE4_OPTIONS $ADDARGS $unc -U"$username"%"$password" $t || failed=`expr $failed + 1`
fi
+ if [ "$t" = "RAW-CHKPATH" ]; then
+ echo "Testing with case sensitive"
+ testit "$name" $VALGRIND $SMBTORTURE4 $TORTURE4_OPTIONS $ADDARGS "$unc"case -U"$username"%"$password" $t || failed=`expr $failed + 1`
+ fi
done
testok $0 $failed
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 16e3631..ab79dfd 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -80,6 +80,24 @@ static NTSTATUS determine_path_error(const char *name,
}
}
+static NTSTATUS check_for_dot_component(const struct smb_filename *smb_fname)
+{
+ /* Ensure we catch all names with in "/."
+ this is disallowed under Windows and
+ in POSIX they've already been removed. */
+ const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
+ if (p) {
+ if (p[2] == '/') {
+ /* Error code within a pathname. */
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ } else if (p[2] == '\0') {
+ /* Error code at the end of a pathname. */
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format changes,
@@ -294,52 +312,103 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
}
/*
- * stat the name - if it exists then we can add the stream back (if
- * there was one) and be done!
+ * If we have a wildcard we must walk the path to
+ * find where the error is, even if case sensitive
+ * is true.
*/
- if (posix_pathnames) {
- ret = SMB_VFS_LSTAT(conn, smb_fname);
- } else {
- ret = SMB_VFS_STAT(conn, smb_fname);
+ name_has_wildcard = ms_has_wild(smb_fname->base_name);
+ if (name_has_wildcard && !allow_wcard_last_component) {
+ /* Wildcard not valid anywhere. */
+ status = NT_STATUS_OBJECT_NAME_INVALID;
+ goto fail;
}
- if (ret == 0) {
- /* Ensure we catch all names with in "/."
- this is disallowed under Windows. */
- const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
- if (p) {
- if (p[2] == '/') {
- /* Error code within a pathname. */
- status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- goto fail;
- } else if (p[2] == '\0') {
- /* Error code at the end of a pathname. */
- status = NT_STATUS_OBJECT_NAME_INVALID;
+ DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
+ smb_fname->base_name, dirpath, start));
+
+ if (!name_has_wildcard) {
+ /*
+ * stat the name - if it exists then we can add the stream back (if
+ * there was one) and be done!
+ */
+
+ if (posix_pathnames) {
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
+ } else {
+ ret = SMB_VFS_STAT(conn, smb_fname);
+ }
+
+ if (ret == 0) {
+ status = check_for_dot_component(smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
+ /* Add the path (not including the stream) to the cache. */
+ stat_cache_add(orig_path, smb_fname->base_name,
+ conn->case_sensitive);
+ DEBUG(5,("conversion of base_name finished %s -> %s\n",
+ orig_path, smb_fname->base_name));
+ goto done;
}
- /* Add the path (not including the stream) to the cache. */
- stat_cache_add(orig_path, smb_fname->base_name,
- conn->case_sensitive);
- DEBUG(5,("conversion of base_name finished %s -> %s\n",
- orig_path, smb_fname->base_name));
- goto done;
- }
- DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
- smb_fname->base_name, dirpath, start));
+ /*
+ * A special case - if we don't have any wildcards or mangling chars and are case
+ * sensitive or the underlying filesystem is case insentive then searching
+ * won't help.
+ */
- /*
- * A special case - if we don't have any mangling chars and are case
- * sensitive or the underlying filesystem is case insentive then searching
- * won't help.
- */
+ if ((conn->case_sensitive || !(conn->fs_capabilities &
+ FILE_CASE_SENSITIVE_SEARCH)) &&
+ !mangle_is_mangled(smb_fname->base_name, conn->params)) {
- if ((conn->case_sensitive || !(conn->fs_capabilities &
- FILE_CASE_SENSITIVE_SEARCH)) &&
- !mangle_is_mangled(smb_fname->base_name, conn->params)) {
- goto done;
+ status = check_for_dot_component(smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ /*
+ * The stat failed. Could be ok as it could be
+ * a new file.
+ */
+
+ if (errno == ENOTDIR || errno == ELOOP) {
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ goto fail;
+ } else if (errno == ENOENT) {
+ /*
+ * Was it a missing last component ?
+ * or a missing intermediate component ?
+ */
+ struct smb_filename parent_fname;
+ ZERO_STRUCT(parent_fname);
+ if (!parent_dirname(ctx, smb_fname->base_name,
+ &parent_fname.base_name,
+ NULL)) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+ if (posix_pathnames) {
+ ret = SMB_VFS_LSTAT(conn, &parent_fname);
+ } else {
+ ret = SMB_VFS_STAT(conn, &parent_fname);
+ }
+ if (ret == -1) {
+ if (errno == ENOTDIR ||
+ errno == ENOENT ||
+ errno == ELOOP) {
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ goto fail;
+ }
+ }
+ /*
+ * Missing last component is ok - new file.
+ * Also deal with permission denied elsewhere.
+ * Just drop out to done.
+ */
+ goto done;
+ }
+ }
}
/*
@@ -404,12 +473,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
name_has_wildcard = ms_has_wild(start);
- /* Wildcard not valid anywhere. */
- if (name_has_wildcard && !allow_wcard_last_component) {
- status = NT_STATUS_OBJECT_NAME_INVALID;
- goto fail;
- }
-
/* Wildcards never valid within a pathname. */
if (name_has_wildcard && end) {
status = NT_STATUS_OBJECT_NAME_INVALID;
--
Samba Shared Repository
More information about the samba-cvs
mailing list