From 10324b177ed2c5de07039f035905b8272f51fbf7 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 24 Jul 2009 12:13:07 -0700 Subject: [PATCH] s3: Allow filename_convert() to pass through unix_convert_flags and let the caller know if the path has a wildcard This also eliminates the need for resolve_dfspath(). --- source3/include/proto.h | 2 ++ source3/rpc_server/srv_srvsvc_nt.c | 4 +++ source3/smbd/filename.c | 41 ++++++++++++++++++++++----- source3/smbd/msdfs.c | 45 +++++++----------------------- source3/smbd/nttrans.c | 8 ++++++ source3/smbd/reply.c | 18 ++++++++++++ source3/smbd/smb2_create.c | 2 ++ source3/smbd/trans2.c | 10 +++++++ 8 files changed, 88 insertions(+), 42 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 63a82a8c229..5d0fa18192d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6320,6 +6320,8 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, connection_struct *conn, bool dfs_path, const char *name_in, + uint32_t ucf_flags, + bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname); /* The following definitions come from smbd/filename_utils.c */ diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index b9d1ed6d73e..15b22908054 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2072,6 +2072,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, conn, false, r->in.file, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); @@ -2200,6 +2202,8 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, conn, false, r->in.file, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 09f9a418bd7..a13c66c4e0f 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1027,14 +1027,30 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, return status; } -/**************************************************************************** - Go through all the steps to validate a filename. -****************************************************************************/ - +/** + * Go through all the steps to validate a filename. + * + * @param ctx talloc_ctx to allocate memory with. + * @param conn connection struct for vfs calls. + * @param dfs_path Whether this path requires dfs resolution. + * @param name_in The unconverted name. + * @param ucf_flags flags to pass through to unix_convert(). + * UCF_ALLOW_WCARD_LCOMP will be stripped out if + * p_cont_wcard == NULL or is false. + * @param p_cont_wcard If not NULL, will be set to true if the dfs path + * resolution detects a wildcard. + * @param pp_smb_fname The final converted name will be allocated if the + * return is NT_STATUS_OK. + * + * @return NT_STATUS_OK if all operations completed succesfully, appropriate + * error otherwise. + */ NTSTATUS filename_convert(TALLOC_CTX *ctx, connection_struct *conn, bool dfs_path, const char *name_in, + uint32_t ucf_flags, + bool *ppath_contains_wcard, struct smb_filename **pp_smb_fname) { NTSTATUS status; @@ -1042,10 +1058,11 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, *pp_smb_fname = NULL; - status = resolve_dfspath(ctx, conn, + status = resolve_dfspath_wcard(ctx, conn, dfs_path, name_in, - &fname); + &fname, + ppath_contains_wcard); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("filename_convert: resolve_dfspath failed " "for name %s with %s\n", @@ -1053,7 +1070,17 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, nt_errstr(status) )); return status; } - status = unix_convert(ctx, conn, fname, pp_smb_fname, 0); + + /* + * Strip out the UCF_ALLOW_WCARD_LCOMP if the path doesn't contain a + * wildcard. + */ + if (ppath_contains_wcard != NULL && !*ppath_contains_wcard && + ucf_flags & UCF_ALLOW_WCARD_LCOMP) { + ucf_flags &= ~UCF_ALLOW_WCARD_LCOMP; + } + + status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("filename_convert: unix_convert failed " "for name %s with %s\n", diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 2b63eb17432..3641e8d4cc6 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -1718,40 +1718,9 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn) } /****************************************************************************** - Core function to resolve a dfs pathname. -******************************************************************************/ - -NTSTATUS resolve_dfspath(TALLOC_CTX *ctx, - connection_struct *conn, - bool dfs_pathnames, - const char *name_in, - char **pp_name_out) -{ - NTSTATUS status = NT_STATUS_OK; - bool dummy; - if (dfs_pathnames) { - status = dfs_redirect(ctx, - conn, - name_in, - False, - pp_name_out, - &dummy); - } else { - /* - * Cheat and just return a copy of the in ptr. - * Once srvstr_get_path() uses talloc it'll - * be a talloced ptr anyway. - */ - *pp_name_out = CONST_DISCARD(char *,name_in); - } - return status; -} - -/****************************************************************************** - Core function to resolve a dfs pathname possibly containing a wildcard. - This function is identical to the above except for the bool param to - dfs_redirect but I need this to be separate so it's really clear when - we're allowing wildcards and when we're not. JRA. + Core function to resolve a dfs pathname possibly containing a wildcard. If + ppath_contains_wcard != NULL, it will be set to true if a wildcard is + detected during dfs resolution. ******************************************************************************/ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, @@ -1761,14 +1730,20 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, char **pp_name_out, bool *ppath_contains_wcard) { + bool path_contains_wcard; NTSTATUS status = NT_STATUS_OK; + if (dfs_pathnames) { status = dfs_redirect(ctx, conn, name_in, True, pp_name_out, - ppath_contains_wcard); + &path_contains_wcard); + + if (NT_STATUS_IS_OK(status) && ppath_contains_wcard != NULL) { + *ppath_contains_wcard = path_contains_wcard; + } } else { /* * Cheat and just return a copy of the in ptr. diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 43212dc800f..89fc9dc4a8b 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -478,6 +478,8 @@ void reply_ntcreate_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -967,6 +969,8 @@ static void call_nt_transact_create(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1353,6 +1357,8 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, + 0, + NULL, &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, @@ -1369,6 +1375,8 @@ void reply_ntrename(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, newname, + 0, + NULL, &smb_fname_new); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 76d32a2f98e..b43d3d304cf 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -994,6 +994,8 @@ void reply_checkpath(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { @@ -1090,6 +1092,8 @@ void reply_getatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1191,6 +1195,8 @@ void reply_setatr(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1724,6 +1730,8 @@ void reply_open(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1894,6 +1902,8 @@ void reply_open_and_X(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2103,6 +2113,8 @@ void reply_mknew(struct smb_request *req) conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2235,6 +2247,8 @@ void reply_ctemp(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5240,6 +5254,8 @@ void reply_mkdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, + 0, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5547,6 +5563,8 @@ void reply_rmdir(struct smb_request *req) status = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, + 0, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 511e448ac62..5e744f98f49 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -325,6 +325,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, smbreq->conn, smbreq->flags2 & FLAGS2_DFS_PATHNAMES, in_name, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 856fd9432d0..6a7b1f8b320 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1024,6 +1024,8 @@ static void call_trans2open(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -4891,6 +4893,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5660,6 +5664,8 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, oldname, + 0, + NULL, &smb_fname_old); if (!NT_STATUS_IS_OK(status)) { return status; @@ -7437,6 +7443,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, status = filename_convert(req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname, + 0, + NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -7558,6 +7566,8 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, + 0, + NULL, &smb_dname); if (!NT_STATUS_IS_OK(status)) { -- 2.34.1