The branch, master has been updated via 4e585186f2b smbd: Get the symlink mode for posix through fdos_mode() via aaa73cce1da smbd: Centralize fdos_mode() in smbd_dirptr_get_entry() via 80c98acbf05 smbd: Centralize wiping the ".." stat info via c96010a2a9f smbd: Simplify smbd_dirptr_get_entry() via 6b0cfcdbc37 smbd: Remove a pointless NULL check via 5991f4e66b5 smbd: Slightly simplify smbd_dirptr_get_entry() via 901c7cc6aaf smbd: Move mask_match_search() to smb1_reply.c via b1e5ed4490f smbd: Simplify smbd_dirptr_get_entry() via 47f36e0b1df smbd: Simplify smbd_dirptr_8_3_mode_fn() via f905384f5df smbd: Rename "fsp" to "dirfsp" in smbd_smb2_query_directory_state via f195df4e652 smbd: Directly print errno in openat_pathref_fsp_lcomp() via 46372997a09 smbd: Remove a NULL check that became obsolete via 15648b5da5d smbd: Modernize a DEBUG statement from b6661e77de2 netcmd: docs: update docs for silo member grant + revoke
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4e585186f2b4905ab4504a464766b3fda1875cb3 Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 14 12:12:22 2023 +0100 smbd: Get the symlink mode for posix through fdos_mode() fdos_mode() has special code to deal with symlinks, so we don't have to replicate that logic here. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Wed Nov 15 06:10:38 UTC 2023 on atb-devel-224 commit aaa73cce1da0c9058615a9b3d91e926d445277de Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 14 12:11:17 2023 +0100 smbd: Centralize fdos_mode() in smbd_dirptr_get_entry() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 80c98acbf0550c760dbc9de2cc7a3328c3c53bd6 Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 14 12:09:54 2023 +0100 smbd: Centralize wiping the ".." stat info Make sure this also happens for symlinks etc. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c96010a2a9ff59b3cc086fc3df15ce9408fe5986 Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 13 13:46:51 2023 +0100 smbd: Simplify smbd_dirptr_get_entry() This uses the much simpler openat_pathef_fsp_lcomp, avoiding non_widelink_open where we don't need it. The only case where we still have to call openat_pathref_fsp() in its full capacity is to find out whether a symlink we found is dangling or not. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6b0cfcdbc3755709f928ac4bc010d130deb042fe Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 13 13:48:42 2023 +0100 smbd: Remove a pointless NULL check We've dereferenced smb_fname before, and talloc_move() never fails. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 5991f4e66b59cda65142a68f9db4e0fa1b7b147d Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 13 10:25:58 2023 +0100 smbd: Slightly simplify smbd_dirptr_get_entry() Check for dirptr being toplevel just once. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 901c7cc6aafc98a91888e6ca7c9f7cb2ccdf8627 Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 12 11:48:30 2023 +0100 smbd: Move mask_match_search() to smb1_reply.c Only called there. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b1e5ed4490ff92f001d9f0d282059c4cc17e19a7 Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 12 11:30:11 2023 +0100 smbd: Simplify smbd_dirptr_get_entry() Both mode_fn's are now the same. Fold them into smbd_dirptr_get_entry() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 47f36e0b1df028cf9abf1a88efaf0296c527e18b Author: Volker Lendecke <v...@samba.org> Date: Sat Nov 11 19:12:16 2023 +0100 smbd: Simplify smbd_dirptr_8_3_mode_fn() Do the smb1-specific code directly in smb1-code. Don't tunnel it through generic smb1/smb2 code. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f905384f5dfe8e297a54e3e3ad1d2ecd13e96713 Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 9 12:50:07 2023 +0100 smbd: Rename "fsp" to "dirfsp" in smbd_smb2_query_directory_state Makes it clearer to me what we have there. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f195df4e65257b8fe1175135fd1217dd9541cbff Author: Volker Lendecke <v...@samba.org> Date: Tue Nov 14 10:53:30 2023 +0100 smbd: Directly print errno in openat_pathref_fsp_lcomp() This is where the error came from. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 46372997a09c6c4cc213941d3d510cfebf500855 Author: Volker Lendecke <v...@samba.org> Date: Thu Nov 9 12:25:32 2023 +0100 smbd: Remove a NULL check that became obsolete Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 15648b5da5d69f4c6ab614cf9288180d55ebc15d Author: Volker Lendecke <v...@samba.org> Date: Mon Nov 13 17:30:22 2023 +0100 smbd: Modernize a DEBUG statement Avoid casts Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 1 - source3/lib/util.c | 16 --- source3/smbd/dir.c | 271 ++++++++++++++---------------------- source3/smbd/dosmode.c | 10 -- source3/smbd/durable.c | 16 +-- source3/smbd/files.c | 2 +- source3/smbd/globals.h | 6 - source3/smbd/smb1_reply.c | 51 +++---- source3/smbd/smb2_query_directory.c | 18 +-- source3/smbd/smb2_trans2.c | 18 --- 10 files changed, 147 insertions(+), 262 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index 06ad7fb508a..13152f7a10a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -347,7 +347,6 @@ bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent, bool ms_has_wild(const char *s); bool ms_has_wild_w(const smb_ucs2_t *s); bool mask_match(const char *string, const char *pattern, bool is_case_sensitive); -bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive); bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive); #include "lib/util/unix_match.h" bool name_to_fqdn(fstring fqdn, const char *name); diff --git a/source3/lib/util.c b/source3/lib/util.c index f891842a6b7..fa01f419d65 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1481,22 +1481,6 @@ bool mask_match(const char *string, const char *pattern, bool is_case_sensitive) return ms_fnmatch_protocol(pattern, string, Protocol, is_case_sensitive) == 0; } -/******************************************************************* - A wrapper that handles case sensitivity and the special handling - of the ".." name. Variant that is only called by old search code which requires - pattern translation. -*******************************************************************/ - -bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive) -{ - if (ISDOTDOT(string)) - string = "."; - if (ISDOT(pattern)) - return False; - - return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0; -} - /******************************************************************* A wrapper that handles a list of patterns and calls mask_match() on each. Returns True if any of the patterns match. diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2fc364a42fd..d9e10b919d3 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -517,12 +517,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, const char *dname, const char *mask, char **_fname), - bool (*mode_fn)(TALLOC_CTX *ctx, - void *private_data, - struct files_struct *dirfsp, - struct smb_filename *smb_fname, - bool get_dosmode, - uint32_t *_mode), void *private_data, char **_fname, struct smb_filename **_smb_fname, @@ -532,7 +526,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, struct smb_Dir *dir_hnd = dirptr->dir_hnd; struct smb_filename *dir_fname = dir_hnd->dir_smb_fname; bool posix = (dir_fname->flags & SMB_FILENAME_POSIX_PATH); - const char *dpath = dir_fname->base_name; + const bool toplevel = ISDOT(dir_fname->base_name); NTSTATUS status; *_smb_fname = NULL; @@ -557,9 +551,10 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, char *dname = NULL; char *fname = NULL; struct smb_filename *smb_fname = NULL; - struct open_symlink_err *symlink_err = NULL; uint32_t mode = 0; bool get_dosmode = get_dosmode_in; + bool toplevel_dotdot; + bool visible; bool ok; dname = dptr_ReadDirName(ctx, dirptr); @@ -592,183 +587,116 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, continue; } - if (ISDOT(dname) || ISDOTDOT(dname)) { + toplevel_dotdot = toplevel && ISDOTDOT(dname); - const char *dotname = dname; - - if (ISDOTDOT(dname) && ISDOT(dpath)) { - /* - * Handle ".." in toplevel like "." to not - * leak info from outside the share. - */ - dotname = "."; - } - - smb_fname = synthetic_smb_fname(talloc_tos(), - dotname, - NULL, - NULL, - dir_fname->twrp, - dir_fname->flags); - if (smb_fname == NULL) { - TALLOC_FREE(dname); - return false; - } - - status = openat_pathref_fsp(dir_hnd->fsp, smb_fname); - if (!NT_STATUS_IS_OK(status)) { - DBG_INFO("Could not open \"..\": %s\n", - nt_errstr(status)); - TALLOC_FREE(smb_fname); - TALLOC_FREE(dname); - continue; - } + smb_fname = synthetic_smb_fname(talloc_tos(), + toplevel_dotdot ? "." : dname, + NULL, + NULL, + dir_fname->twrp, + dir_fname->flags); + if (smb_fname == NULL) { + TALLOC_FREE(dname); + return false; + } - mode = fdos_mode(smb_fname->fsp); + /* + * UCF_POSIX_PATHNAMES to avoid the readdir fallback + * if we get raced between readdir and unlink. + */ + status = openat_pathref_fsp_lcomp(dir_hnd->fsp, + smb_fname, + UCF_POSIX_PATHNAMES); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("Could not open %s: %s\n", + dname, + nt_errstr(status)); + TALLOC_FREE(smb_fname); + TALLOC_FREE(fname); + TALLOC_FREE(dname); + continue; + } - /* - * Don't leak INO/DEV/User SID/Group SID about - * the containing directory of the share. - */ - if (ISDOT(dpath) && ISDOTDOT(dname)) { - /* - * Ensure posix fileid and sids are hidden - */ - smb_fname->st.st_ex_ino = 0; - smb_fname->st.st_ex_dev = 0; - smb_fname->st.st_ex_uid = -1; - smb_fname->st.st_ex_gid = -1; - } + visible = is_visible_fsp(smb_fname->fsp); + if (!visible) { + TALLOC_FREE(smb_fname); + TALLOC_FREE(fname); + TALLOC_FREE(dname); + continue; + } + if (!S_ISLNK(smb_fname->st.st_ex_mode)) { goto done; } - status = openat_pathref_fsp_nosymlink(talloc_tos(), - conn, - dir_hnd->fsp, - dname, - dir_fname->twrp, - posix, - &smb_fname, - &symlink_err); - - if (NT_STATUS_IS_OK(status)) { - bool visible = is_visible_fsp(smb_fname->fsp); - if (!visible) { - TALLOC_FREE(smb_fname); - TALLOC_FREE(dname); - TALLOC_FREE(fname); - continue; - } - } else if (NT_STATUS_EQUAL(status, - NT_STATUS_STOPPED_ON_SYMLINK)) { - struct symlink_reparse_struct *reparse = - symlink_err->reparse; - const char *target = reparse->substitute_name; - bool is_msdfs_link; - - is_msdfs_link = lp_host_msdfs(); - is_msdfs_link &= lp_msdfs_root(SNUM(conn)); - is_msdfs_link &= (strncmp(target, "msdfs:", 6) == 0); - - if (is_msdfs_link) { - char *path = NULL; - - path = full_path_from_dirfsp_at_basename( - talloc_tos(), - dir_hnd->fsp, - dname); - if (path == NULL) { - return false; - } - - smb_fname = - synthetic_smb_fname(talloc_tos(), - path, - NULL, - &symlink_err->st, - dir_fname->twrp, - dir_fname->flags); - TALLOC_FREE(path); - if (smb_fname == NULL) { - return false; - } - - DBG_INFO("Masquerading msdfs link %s as a" - "directory\n", - smb_fname->base_name); - - smb_fname->st.st_ex_mode = - (smb_fname->st.st_ex_mode & ~S_IFMT) | - S_IFDIR; - - mode = dos_mode_msdfs(conn, - dname, - &smb_fname->st); - get_dosmode = false; - ask_sharemode = false; - goto done; - } + if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && + is_msdfs_link(dir_hnd->fsp, smb_fname)) + { + DBG_INFO("Masquerading msdfs link %s as a directory\n", + smb_fname->base_name); - smb_fname = synthetic_smb_fname(talloc_tos(), - dname, - NULL, - &symlink_err->st, - dir_fname->twrp, - dir_fname->flags); - if (smb_fname == NULL) { - return false; - } + smb_fname->st.st_ex_mode = (smb_fname->st.st_ex_mode & + ~S_IFMT) | + S_IFDIR; - status = openat_pathref_fsp(dir_hnd->fsp, smb_fname); + mode = dos_mode_msdfs(conn, dname, &smb_fname->st); + get_dosmode = false; + ask_sharemode = false; + goto done; + } - if (posix) { - /* - * Posix always wants to see symlinks, - * dangling or not. We've done the - * openat_pathref_fsp() to fill in - * smb_fname->fsp just in case it's - * not dangling. - */ - mode = FILE_ATTRIBUTE_NORMAL; - get_dosmode = false; - ask_sharemode = false; - goto done; - } + if (posix) { + /* + * Posix always wants to see symlinks, + * dangling or not. We've done the + * openat_pathref_fsp() to fill in + * smb_fname->fsp just in case it's not + * dangling. + */ + ask_sharemode = false; + goto done; + } - if (!NT_STATUS_IS_OK(status)) { - /* - * Dangling symlink. Hide. - */ - TALLOC_FREE(smb_fname); - TALLOC_FREE(fname); - TALLOC_FREE(dname); - continue; - } - } else { - DBG_NOTICE("Could not open %s: %s\n", - dname, - nt_errstr(status)); - TALLOC_FREE(dname); - TALLOC_FREE(fname); + if (!lp_follow_symlinks(SNUM(conn))) { + /* + * Hide symlinks not followed + */ TALLOC_FREE(smb_fname); + TALLOC_FREE(fname); + TALLOC_FREE(dname); continue; } - ok = mode_fn(ctx, - private_data, - dir_hnd->fsp, - smb_fname, - get_dosmode, - &mode); - if (!ok) { + /* + * We have to find out if it's a dangling + * symlink. Use the fat logic behind + * openat_pathref_fsp(). + */ + + { + struct files_struct *fsp = smb_fname->fsp; + smb_fname_fsp_unlink(smb_fname); + fd_close(fsp); + file_free(NULL, fsp); + } + + status = openat_pathref_fsp(dir_hnd->fsp, smb_fname); + + if (!NT_STATUS_IS_OK(status)) { + /* + * Dangling symlink. Hide. + */ TALLOC_FREE(smb_fname); - TALLOC_FREE(dname); TALLOC_FREE(fname); + TALLOC_FREE(dname); continue; } - done: +done: + if (get_dosmode) { + mode = fdos_mode(smb_fname->fsp); + smb_fname->st = smb_fname->fsp->fsp_name->st; + } if (!dir_check_ftype(mode, dirtype)) { DBG_INFO("[%s] attribs 0x%" PRIx32 " didn't match " @@ -795,6 +723,16 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, } } + if (toplevel_dotdot) { + /* + * Ensure posix fileid and sids are hidden + */ + smb_fname->st.st_ex_ino = 0; + smb_fname->st.st_ex_dev = 0; + smb_fname->st.st_ex_uid = -1; + smb_fname->st.st_ex_gid = -1; + } + DBG_NOTICE("mask=[%s] found %s fname=%s (%s)\n", mask, smb_fname_str_dbg(smb_fname), @@ -804,9 +742,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, TALLOC_FREE(dname); *_smb_fname = talloc_move(ctx, &smb_fname); - if (*_smb_fname == NULL) { - return false; - } *_fname = fname; *_mode = mode; diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 229a85a9171..41241fd2bfc 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -686,16 +686,6 @@ uint32_t fdos_mode(struct files_struct *fsp) uint32_t result = 0; NTSTATUS status = NT_STATUS_OK; - if (fsp == NULL) { - /* - * The pathological case where a caller does - * fdos_mode(smb_fname->fsp) passing a pathref fsp. But as - * smb_fname points at a symlink in POSIX context smb_fname->fsp - * is NULL. - */ - return FILE_ATTRIBUTE_NORMAL; - } - DBG_DEBUG("%s\n", fsp_str_dbg(fsp)); if (fsp->fake_file_handle != NULL) { diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c index b21c223b2e4..5f55ff658bb 100644 --- a/source3/smbd/durable.c +++ b/source3/smbd/durable.c @@ -486,14 +486,14 @@ static bool vfs_default_durable_reconnect_check_stat( } if (cookie_st->st_ex_flags != fsp_st->st_ex_flags) { - DEBUG(1, ("vfs_default_durable_reconnect (%s): " - "stat_ex.%s differs: " - "cookie:%llu != stat:%llu, " - "denying durable reconnect\n", - name, - "st_ex_flags", - (unsigned long long)cookie_st->st_ex_flags, - (unsigned long long)fsp_st->st_ex_flags)); + DBG_WARNING(" (%s): " + "stat_ex.%s differs: " + "cookie:%"PRIu32" != stat:%"PRIu32", " + "denying durable reconnect\n", + name, + "st_ex_flags", + cookie_st->st_ex_flags, + fsp_st->st_ex_flags); return false; } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 28a741c8b54..5da90480a67 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -1576,7 +1576,7 @@ NTSTATUS openat_pathref_fsp_lcomp(struct files_struct *dirfsp, (fd >= 0) ? "F" : "", dirfsp->fsp_name->base_name, smb_fname_rel->base_name, - nt_errstr(status)); + strerror(errno)); fd_close(fsp); file_free(NULL, fsp); return status; diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index f58e3176f31..0c7e791711f 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -171,12 +171,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, const char *dname, const char *mask, char **_fname), - bool (*mode_fn)(TALLOC_CTX *ctx, - void *private_data, - struct files_struct *dirfsp, - struct smb_filename *smb_fname, - bool get_dosmode, - uint32_t *_mode), void *private_data, char **_fname, struct smb_filename **_smb_fname, diff --git a/source3/smbd/smb1_reply.c b/source3/smbd/smb1_reply.c index addca927c74..ed6a1737485 100644 --- a/source3/smbd/smb1_reply.c +++ b/source3/smbd/smb1_reply.c @@ -1125,6 +1125,25 @@ static void make_dir_struct(TALLOC_CTX *ctx, DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname)); } +/******************************************************************* + A wrapper that handles case sensitivity and the special handling + of the ".." name. +*******************************************************************/ + +static bool mask_match_search(const char *string, + const char *pattern, + bool is_case_sensitive) +{ + if (ISDOTDOT(string)) { + string = "."; + } + if (ISDOT(pattern)) { + return False; + } + + return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0; +} + static bool mangle_mask_match(connection_struct *conn, const char *filename, const char *mask) @@ -1199,30 +1218,6 @@ static bool smbd_dirptr_8_3_match_fn(TALLOC_CTX *ctx, return false; } -static bool smbd_dirptr_8_3_mode_fn(TALLOC_CTX *ctx, - void *private_data, - struct files_struct *dirfsp, - struct smb_filename *smb_fname, - bool get_dosmode, - uint32_t *_mode) -{ - if (*_mode & FILE_ATTRIBUTE_REPARSE_POINT) { - /* - * Don't show symlinks/special files to old clients -- Samba Shared Repository