The branch, master has been updated via 332338173ec s3: smbd: Convert reply_checkpath() to use filename_convert_dirfsp(). via a70a9c63df3 s3: smbd: Convert call_trans2mkdir() to use filename_convert_dirfsp(). via 12001941a4f s3: smbd: Convert call_trans2open() to use filename_convert_dirfsp(). via 34056ced099 s3: smbd: Convert reply_rmdir() to use filename_convert_dirfsp(). via f599e469066 s3: smbd: Convert reply_ctemp() to use filename_convert_dirfsp(). via 952f92ccb39 s3: smbd: Convert reply_mknew() to use filename_convert_dirfsp(). via 48be22d8cce s3: smbd: Convert reply_open_and_X() to use filename_convert_dirfsp(). via e82a37d42bb s3: smbd: Convert reply_open() to use filename_convert_dirfsp(). via 758ffebb8a8 s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match unix_convert() 100% via be8ac8df178 s3: smbd: In filename_split_lcomp() ensure we never return a streamname if posix is set. via 1a653fdc442 s3: smbd: Ensure we set fsp->file_id in openat_pathref_dirfsp_nosymlink(). from 3469895aca6 s3:winbind: Implement dcerpc_samr_chgpasswd_user4 for PamAuthChangePassword
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 332338173ec9df9628e29eef2eccff2226c01e9d Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 16:21:52 2022 -0700 s3: smbd: Convert reply_checkpath() to use filename_convert_dirfsp(). One less use of filename_convert(). This is the acid test of filename_convert_dirfsp() pathname error handling. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Thu Jul 28 16:34:54 UTC 2022 on sn-devel-184 commit a70a9c63df34467dfef57003cf9f156e9b8d7b03 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:39:11 2022 -0700 s3: smbd: Convert call_trans2mkdir() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 12001941a4f77b1595ff4f64c7377dbc64f2dead Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:36:23 2022 -0700 s3: smbd: Convert call_trans2open() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 34056ced09962c9733e338b9d60559a297acbd9e Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:29:18 2022 -0700 s3: smbd: Convert reply_rmdir() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit f599e469066cd8048498067e083747a611f16342 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:23:42 2022 -0700 s3: smbd: Convert reply_ctemp() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 952f92ccb39edf18e1a2d4e3df4b1781b37c7206 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:09:48 2022 -0700 s3: smbd: Convert reply_mknew() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 48be22d8cce4c3508e145d727a378c4a6d3a4c3a Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:00:32 2022 -0700 s3: smbd: Convert reply_open_and_X() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit e82a37d42bb67fbf351f7d1fd82e8c200414780d Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 12:05:17 2022 -0700 s3: smbd: Convert reply_open() to use filename_convert_dirfsp(). One less use of filename_convert(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 758ffebb8a8ce6b92598137f927a67961690bb69 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 15:28:13 2022 -0700 s3: smbd: Fix the error processing in filename_convert_dirfsp_nosymlink() to match unix_convert() 100% We need this in order to pass: samba3.raw.samba3badpath raw.chkpath samba3.base.chkpath Now we can convert all the SMB1 reply_openXXX functions, and reply_checkpath(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit be8ac8df178556957d3d20d309b0f79cb1df6b34 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 16:52:40 2022 -0700 s3: smbd: In filename_split_lcomp() ensure we never return a streamname if posix is set. POSIX has no streams, even on the root of a directory. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> commit 1a653fdc4422450737ab885d2531db8bed9fcf03 Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 27 14:36:33 2022 -0700 s3: smbd: Ensure we set fsp->file_id in openat_pathref_dirfsp_nosymlink(). This is a subtle one. The dirfsp returned by openat_pathref_dirfsp_nosymlink() can be used inside open.c and passed to check_parent_access_fsp() to check if a delete_on_close flag has been set on an existing "real" open fsp. So the file_id must be correctly set in order for this to work. Without it, samba3.base.delete fails in deltest20 when we convert reply_open_and_X() to use filename_convert_dirfsp(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/smbd/filename.c | 49 +++++++++++++++--- source3/smbd/files.c | 6 +++ source3/smbd/smb1_reply.c | 120 ++++++++++++++++++++++++++++++--------------- source3/smbd/smb1_trans2.c | 41 ++++++++++------ 4 files changed, 154 insertions(+), 62 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 0f9921b62fa..3f0c395fd8f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -2410,7 +2410,7 @@ static bool filename_split_lcomp( return false; } - if (name_in[0] == ':') { + if (!posix && (name_in[0] == ':')) { /* * Special case for stream on root directory */ @@ -2749,6 +2749,19 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( return NT_STATUS_OK; } + /* + * Catch an invalid path of "." before we + * call filename_split_lcomp(). We need to + * do this as filename_split_lcomp() will + * use "." for the missing relative component + * when an empty name_in path is sent by + * the client. + */ + if (ISDOT(name_in)) { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + ok = filename_split_lcomp( talloc_tos(), name_in, @@ -2761,11 +2774,6 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( goto fail; } - if (fname_rel[0] == '\0') { - status = NT_STATUS_OBJECT_NAME_INVALID; - goto fail; - } - if (!posix) { bool name_has_wild = ms_has_wild(dirname); name_has_wild |= ms_has_wild(fname_rel); @@ -2828,13 +2836,39 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( goto fail; } - TALLOC_FREE(dirname); if (!VALID_STAT_OF_DIR(smb_dirname->st)) { status = NT_STATUS_OBJECT_PATH_NOT_FOUND; goto fail; } + /* + * Only look at bad last component values + * once we know we have a valid directory. That + * way we won't confuse error messages from + * opening the directory path with error + * messages from a bad last component. + */ + + /* Relative filename can't be empty */ + if (fname_rel[0] == '\0') { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + + /* Relative filename can't be ".." */ + if (ISDOTDOT(fname_rel)) { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + /* Relative name can only be dot if directory is empty. */ + if (ISDOT(fname_rel) && dirname[0] != '\0') { + status = NT_STATUS_OBJECT_NAME_INVALID; + goto fail; + } + + TALLOC_FREE(dirname); + smb_fname_rel = synthetic_smb_fname( mem_ctx, fname_rel, @@ -2999,6 +3033,7 @@ done: return NT_STATUS_OK; fail: + TALLOC_FREE(dirname); TALLOC_FREE(smb_dirname); TALLOC_FREE(smb_fname_rel); return status; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 9a81a16b3ec..afde81d3070 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -937,6 +937,12 @@ next: nt_errstr(status)); goto fail; } + /* + * We must correctly set fsp->file_id as code inside + * open.c will use this to check if delete_on_close + * has been set on the dirfsp. + */ + fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); result = cp_smb_filename(mem_ctx, fsp->fsp_name); if (result == NULL) { diff --git a/source3/smbd/smb1_reply.c b/source3/smbd/smb1_reply.c index 6dfc636c9d8..de38817ea76 100644 --- a/source3/smbd/smb1_reply.c +++ b/source3/smbd/smb1_reply.c @@ -561,7 +561,9 @@ void reply_checkpath(struct smb_request *req) struct smb_filename *smb_fname = NULL; char *name = NULL; NTSTATUS status; + struct files_struct *dirfsp = NULL; uint32_t ucf_flags = ucf_flags_from_smb_request(req); + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBcheckpath); @@ -578,13 +580,16 @@ void reply_checkpath(struct smb_request *req) DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0))); - status = filename_convert(ctx, - conn, - name, - ucf_flags, - 0, - &smb_fname); - + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(name, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + name, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -1407,6 +1412,7 @@ void reply_open(struct smb_request *req) off_t size = 0; time_t mtime=0; int info; + struct files_struct *dirfsp = NULL; files_struct *fsp; int oplock_request; int deny_mode; @@ -1418,6 +1424,7 @@ void reply_open(struct smb_request *req) uint32_t private_flags = 0; NTSTATUS status; uint32_t ucf_flags; + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBopen); @@ -1448,12 +1455,16 @@ void reply_open(struct smb_request *req) ucf_flags = filename_create_ucf_flags(req, create_disposition); - status = filename_convert(ctx, - conn, - fname, - ucf_flags, - 0, - &smb_fname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(fname, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + fname, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -1468,7 +1479,7 @@ void reply_open(struct smb_request *req) status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ @@ -1580,6 +1591,7 @@ void reply_open_and_X(struct smb_request *req) uint32_t fattr=0; int mtime=0; int smb_action = 0; + struct files_struct *dirfsp = NULL; files_struct *fsp; NTSTATUS status; uint64_t allocation_size; @@ -1590,6 +1602,7 @@ void reply_open_and_X(struct smb_request *req) uint32_t create_options = 0; uint32_t private_flags = 0; uint32_t ucf_flags; + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBopenX); @@ -1638,12 +1651,17 @@ void reply_open_and_X(struct smb_request *req) ucf_flags = filename_create_ucf_flags(req, create_disposition); - status = filename_convert(ctx, - conn, - fname, - ucf_flags, - 0, - &smb_fname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(fname, &twrp); + } + + status = filename_convert_dirfsp(ctx, + conn, + fname, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -1658,7 +1676,7 @@ void reply_open_and_X(struct smb_request *req) status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ @@ -2023,6 +2041,7 @@ void reply_mknew(struct smb_request *req) char *fname = NULL; uint32_t fattr = 0; struct smb_file_time ft; + struct files_struct *dirfsp = NULL; files_struct *fsp; int oplock_request = 0; NTSTATUS status; @@ -2031,6 +2050,7 @@ void reply_mknew(struct smb_request *req) uint32_t create_disposition; uint32_t create_options = 0; uint32_t ucf_flags; + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBcreate); @@ -2063,12 +2083,17 @@ void reply_mknew(struct smb_request *req) } ucf_flags = filename_create_ucf_flags(req, create_disposition); - status = filename_convert(ctx, - conn, - fname, - ucf_flags, - 0, - &smb_fname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(fname, &twrp); + } + + status = filename_convert_dirfsp(ctx, + conn, + fname, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2089,7 +2114,7 @@ void reply_mknew(struct smb_request *req) status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ @@ -2163,12 +2188,14 @@ void reply_ctemp(struct smb_request *req) char *wire_name = NULL; char *fname = NULL; uint32_t fattr; + struct files_struct *dirfsp = NULL; files_struct *fsp; int oplock_request; char *s; NTSTATUS status; int i; uint32_t ucf_flags; + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBctemp); @@ -2206,11 +2233,16 @@ void reply_ctemp(struct smb_request *req) } ucf_flags = filename_create_ucf_flags(req, FILE_CREATE); - status = filename_convert(ctx, conn, - fname, - ucf_flags, - 0, - &smb_fname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(fname, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + fname, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -2225,7 +2257,7 @@ void reply_ctemp(struct smb_request *req) status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_fname, /* fname */ FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */ @@ -2244,6 +2276,7 @@ void reply_ctemp(struct smb_request *req) if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { TALLOC_FREE(fname); + TALLOC_FREE(dirfsp); TALLOC_FREE(smb_fname); continue; } @@ -5834,8 +5867,10 @@ void reply_rmdir(struct smb_request *req) char *directory = NULL; NTSTATUS status; TALLOC_CTX *ctx = talloc_tos(); + struct files_struct *dirfsp = NULL; files_struct *fsp = NULL; int info = 0; + NTTIME twrp = 0; uint32_t ucf_flags = ucf_flags_from_smb_request(req); START_PROFILE(SMBrmdir); @@ -5847,11 +5882,16 @@ void reply_rmdir(struct smb_request *req) goto out; } - status = filename_convert(ctx, conn, - directory, - ucf_flags, - 0, - &smb_dname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(directory, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + directory, + ucf_flags, + twrp, + &dirfsp, + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -5865,7 +5905,7 @@ void reply_rmdir(struct smb_request *req) status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_dname, /* fname */ DELETE_ACCESS, /* access_mask */ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c index 8c3bafa3a00..537b4dc6ff2 100644 --- a/source3/smbd/smb1_trans2.c +++ b/source3/smbd/smb1_trans2.c @@ -512,6 +512,7 @@ static void call_trans2open(connection_struct *conn, int fattr=0,mtime=0; SMB_INO_T inode = 0; int smb_action = 0; + struct files_struct *dirfsp = NULL; files_struct *fsp; struct ea_list *ea_list = NULL; uint16_t flags = 0; @@ -521,6 +522,7 @@ static void call_trans2open(connection_struct *conn, uint32_t create_disposition; uint32_t create_options = 0; uint32_t private_flags = 0; + NTTIME twrp = 0; uint32_t ucf_flags = ucf_flags_from_smb_request(req); TALLOC_CTX *ctx = talloc_tos(); @@ -583,12 +585,16 @@ static void call_trans2open(connection_struct *conn, fname, (unsigned int)deny_mode, (unsigned int)open_attr, (unsigned int)open_ofun, open_size)); - status = filename_convert(ctx, - conn, - fname, - ucf_flags, - 0, - &smb_fname); + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(fname, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + fname, + ucf_flags, + twrp, + &dirfsp, + &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -660,7 +666,7 @@ static void call_trans2open(connection_struct *conn, status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_fname, /* fname */ access_mask, /* access_mask */ share_mode, /* share_access */ @@ -2617,6 +2623,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, char **ppdata, int total_data, unsigned int max_data_bytes) { + struct files_struct *dirfsp = NULL; struct files_struct *fsp = NULL; struct smb_filename *smb_dname = NULL; char *params = *pparams; @@ -2625,6 +2632,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, NTSTATUS status = NT_STATUS_OK; struct ea_list *ea_list = NULL; uint32_t ucf_flags = ucf_flags_from_smb_request(req); + NTTIME twrp = 0; TALLOC_CTX *ctx = talloc_tos(); if (!CAN_WRITE(conn)) { @@ -2663,13 +2671,16 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); - status = filename_convert(ctx, - conn, - directory, - ucf_flags, - 0, - &smb_dname); - + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(directory, &twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + directory, + ucf_flags, + twrp, + &dirfsp, + &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, @@ -2721,7 +2732,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ - NULL, /* dirfsp */ + dirfsp, /* dirfsp */ smb_dname, /* fname */ MAXIMUM_ALLOWED_ACCESS, /* access_mask */ FILE_SHARE_NONE, /* share_access */ -- Samba Shared Repository