From 4887de908c06dafe51ce4811114547715969978b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 13:47:49 +1100 Subject: [PATCH 1/3] smbd: Split create_conn_struct into a fn that does not change the working dir The python bindings do not want the current working directory changed during operations, so we provide two functions, one providing the original behaviour, and other providing the python bindings with just the memory allocation and initilisation stuff. Andrew Bartlett Reviewed-by: Jeremy Allison (cherry picked from commit 6c80cf747d75e648a1d88d477bcf476e6874c4b3) --- source3/printing/nt_printing.c | 6 ++-- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 4 +-- source3/smbd/msdfs.c | 58 +++++++++++++++++++++++-------- source3/smbd/proto.h | 11 ++++-- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 5050a5d..4211e84 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -616,7 +616,7 @@ static uint32 get_correct_cversion(struct auth_session_info *session_info, return -1; } - nt_status = create_conn_struct(talloc_tos(), + nt_status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, @@ -1003,7 +1003,7 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info, return WERR_NO_SUCH_SHARE; } - nt_status = create_conn_struct(talloc_tos(), + nt_status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, @@ -1539,7 +1539,7 @@ bool delete_driver_files(const struct auth_session_info *session_info, return false; } - nt_status = create_conn_struct(talloc_tos(), + nt_status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index a6472a6..e14b797 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2037,7 +2037,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } - nt_status = create_conn_struct(talloc_tos(), + nt_status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, @@ -2184,7 +2184,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, goto error_exit; } - nt_status = create_conn_struct(talloc_tos(), + nt_status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index ccbd89c..7cb19c9 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -218,8 +218,9 @@ static NTSTATUS parse_dfs_path(connection_struct *conn, } /******************************************************** - Fake up a connection struct for the VFS layer. - Note: this performs a vfs connect and CHANGES CWD !!!! JRA. + Fake up a connection struct for the VFS layer, for use in + applications (such as the python bindings), that do not want the + global working directory changed under them. *********************************************************/ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, @@ -228,12 +229,10 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, connection_struct **pconn, int snum, const char *path, - const struct auth_session_info *session_info, - char **poldcwd) + const struct auth_session_info *session_info) { connection_struct *conn; char *connpath; - char *oldcwd; const char *vfs_user; conn = talloc_zero(ctx, connection_struct); @@ -247,9 +246,9 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } connpath = talloc_string_sub(conn, - connpath, - "%S", - lp_servicename(talloc_tos(), snum)); + connpath, + "%S", + lp_servicename(talloc_tos(), snum)); if (!connpath) { TALLOC_FREE(conn); return NT_STATUS_NO_MEMORY; @@ -341,6 +340,37 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, } conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res); + *pconn = conn; + + return NT_STATUS_OK; +} + +/******************************************************** + Fake up a connection struct for the VFS layer. + Note: this performs a vfs connect and CHANGES CWD !!!! JRA. + + The old working directory is returned on *poldcwd, allocated on ctx. +*********************************************************/ + +NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx, + struct tevent_context *ev, + struct messaging_context *msg, + connection_struct **pconn, + int snum, + const char *path, + const struct auth_session_info *session_info, + char **poldcwd) +{ + connection_struct *conn; + char *oldcwd; + + NTSTATUS status = create_conn_struct(ctx, ev, + msg, &conn, + snum, path, + session_info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* * Windows seems to insist on doing trans2getdfsreferral() calls on @@ -350,14 +380,14 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, oldcwd = vfs_GetWd(ctx, conn); if (oldcwd == NULL) { - NTSTATUS status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno))); conn_free(conn); return status; } if (vfs_ChDir(conn,conn->connectpath) != 0) { - NTSTATUS status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. " "Error was %s\n", conn->connectpath, strerror(errno) )); @@ -981,7 +1011,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, return NT_STATUS_OK; } - status = create_conn_struct(ctx, + status = create_conn_struct_cwd(ctx, server_event_context(), server_messaging_context(), &conn, snum, @@ -1173,7 +1203,7 @@ static bool junction_to_local_path(const struct junction_map *jucn, if(snum < 0) { return False; } - status = create_conn_struct(talloc_tos(), + status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), conn_out, @@ -1338,7 +1368,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum) * Fake up a connection struct for the VFS layer. */ - status = create_conn_struct(talloc_tos(), + status = create_conn_struct_cwd(talloc_tos(), server_event_context(), server_messaging_context(), &conn, @@ -1414,7 +1444,7 @@ static int form_junctions(TALLOC_CTX *ctx, * Fake up a connection struct for the VFS layer. */ - status = create_conn_struct(ctx, + status = create_conn_struct_cwd(ctx, server_event_context(), server_messaging_context(), &conn, snum, connect_path, NULL, diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index b4f4501..b89015b 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -495,8 +495,15 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, connection_struct **pconn, int snum, const char *path, - const struct auth_session_info *session_info, - char **poldcwd); + const struct auth_session_info *session_info); +NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx, + struct tevent_context *ev, + struct messaging_context *msg, + connection_struct **pconn, + int snum, + const char *path, + const struct auth_session_info *session_info, + char **poldcwd); /* The following definitions come from smbd/negprot.c */ -- 1.8.5.2 From 87e67291fb0990011b36a6f5c878dd1c9fcdc1d7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 8 Jan 2013 09:29:48 +1100 Subject: [PATCH 2/3] smbd: Fix calls to create_conn_struct_cwd to be correctly indented. These are whitespace changes only, left out of the previous commit to preserve clarity. Andrew Bartlett. Reviewed-by: Jeremy Allison (cherry picked from commit 5a3e915d20bb11984c42081bf25ce09baa58e04e) --- source3/printing/nt_printing.c | 36 +++++++++++++++---------------- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 20 ++++++++--------- source3/smbd/msdfs.c | 32 +++++++++++++-------------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 4211e84..766e4c6 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -617,12 +617,12 @@ static uint32 get_correct_cversion(struct auth_session_info *session_info, } nt_status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - printdollar_snum, - lp_pathname(talloc_tos(), printdollar_snum), - session_info, &oldcwd); + server_event_context(), + server_messaging_context(), + &conn, + printdollar_snum, + lp_pathname(talloc_tos(), printdollar_snum), + session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("get_correct_cversion: create_conn_struct " "returned %s\n", nt_errstr(nt_status))); @@ -1004,12 +1004,12 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info, } nt_status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - printdollar_snum, - lp_pathname(talloc_tos(), printdollar_snum), - session_info, &oldcwd); + server_event_context(), + server_messaging_context(), + &conn, + printdollar_snum, + lp_pathname(talloc_tos(), printdollar_snum), + session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("move_driver_to_download_area: create_conn_struct " "returned %s\n", nt_errstr(nt_status))); @@ -1540,12 +1540,12 @@ bool delete_driver_files(const struct auth_session_info *session_info, } nt_status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - printdollar_snum, - lp_pathname(talloc_tos(), printdollar_snum), - session_info, &oldcwd); + server_event_context(), + server_messaging_context(), + &conn, + printdollar_snum, + lp_pathname(talloc_tos(), printdollar_snum), + session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("delete_driver_files: create_conn_struct " "returned %s\n", nt_errstr(nt_status))); diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index e14b797..2d58466 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2038,11 +2038,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, } nt_status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - snum, lp_pathname(talloc_tos(), snum), - p->session_info, &oldcwd); + server_event_context(), + server_messaging_context(), + &conn, + snum, lp_pathname(talloc_tos(), snum), + p->session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("create_conn_struct failed: %s\n", nt_errstr(nt_status))); @@ -2185,11 +2185,11 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, } nt_status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - snum, lp_pathname(talloc_tos(), snum), - p->session_info, &oldcwd); + server_event_context(), + server_messaging_context(), + &conn, + snum, lp_pathname(talloc_tos(), snum), + p->session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("create_conn_struct failed: %s\n", nt_errstr(nt_status))); diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 7cb19c9..e4a5ea4 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -1012,10 +1012,10 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, } status = create_conn_struct_cwd(ctx, - server_event_context(), - server_messaging_context(), - &conn, snum, - lp_pathname(talloc_tos(), snum), NULL, &oldpath); + server_event_context(), + server_messaging_context(), + &conn, snum, + lp_pathname(talloc_tos(), snum), NULL, &oldpath); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(pdp); return status; @@ -1204,10 +1204,10 @@ static bool junction_to_local_path(const struct junction_map *jucn, return False; } status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - conn_out, - snum, lp_pathname(talloc_tos(), snum), NULL, oldpath); + server_event_context(), + server_messaging_context(), + conn_out, + snum, lp_pathname(talloc_tos(), snum), NULL, oldpath); if (!NT_STATUS_IS_OK(status)) { return False; } @@ -1369,10 +1369,10 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum) */ status = create_conn_struct_cwd(talloc_tos(), - server_event_context(), - server_messaging_context(), - &conn, - snum, connect_path, NULL, &cwd); + server_event_context(), + server_messaging_context(), + &conn, + snum, connect_path, NULL, &cwd); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("create_conn_struct failed: %s\n", nt_errstr(status))); @@ -1445,10 +1445,10 @@ static int form_junctions(TALLOC_CTX *ctx, */ status = create_conn_struct_cwd(ctx, - server_event_context(), - server_messaging_context(), - &conn, snum, connect_path, NULL, - &cwd); + server_event_context(), + server_messaging_context(), + &conn, snum, connect_path, NULL, + &cwd); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("create_conn_struct failed: %s\n", nt_errstr(status))); -- 1.8.5.2 From 6cafd7909f12d175159ef41a9bf6ebac6696ec2b Mon Sep 17 00:00:00 2001 From: Garming Sam Date: Thu, 19 Dec 2013 09:55:44 +1300 Subject: [PATCH 3/3] dfs: always call create_conn_struct with root privileges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a bug in dfs_samba4 identified by Daniel Müller. create_conn_struct calls SMB_VFS_CONNECT which requires root privileges. SMB_VFS_CONNECT in turn calls dfs_samba4_connect which connects to samdb. Calls were made to this function without ever becoming root (notably via setup_dfs_referral) which resulted in an error and the VFS connect failing. This happens when you have an active directory domain controller with host msdfs = yes in smb.conf and dfs links in place. Signed-off-by: Garming Sam Reviewed-by: Bjoern Baumbach Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Jan 10 20:11:03 CET 2014 on sn-devel-104 (cherry picked from commit 24a687642de21ce872d25f16b3525003844d05f9) --- source3/smbd/msdfs.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index e4a5ea4..8a88634 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -221,9 +221,11 @@ static NTSTATUS parse_dfs_path(connection_struct *conn, Fake up a connection struct for the VFS layer, for use in applications (such as the python bindings), that do not want the global working directory changed under them. + + SMB_VFS_CONNECT requires root privileges. *********************************************************/ -NTSTATUS create_conn_struct(TALLOC_CTX *ctx, +static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx, struct tevent_context *ev, struct messaging_context *msg, connection_struct **pconn, @@ -346,6 +348,33 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, } /******************************************************** + Fake up a connection struct for the VFS layer, for use in + applications (such as the python bindings), that do not want the + global working directory changed under them. + + SMB_VFS_CONNECT requires root privileges. +*********************************************************/ + +NTSTATUS create_conn_struct(TALLOC_CTX *ctx, + struct tevent_context *ev, + struct messaging_context *msg, + connection_struct **pconn, + int snum, + const char *path, + const struct auth_session_info *session_info) +{ + NTSTATUS status; + become_root(); + status = create_conn_struct_as_root(ctx, ev, + msg, pconn, + snum, path, + session_info); + unbecome_root(); + + return status; +} + +/******************************************************** Fake up a connection struct for the VFS layer. Note: this performs a vfs connect and CHANGES CWD !!!! JRA. -- 1.8.5.2