The branch, master has been updated via a95b2ba s3:smbd/msdfs: pass allow_broken_path to resolve_dfspath_wcard() via 758d612 s3:smbd/msdfs: pass 'allow_broken_path' to get_referred_path() via a92f717 s3:smbd/msdfs: let create_conn_struct() also fake the 'smbd_server_connection' via 0733183 s3:smbd/files: work without sconn->file_bmap and assign fsp->fnum = -1 via 768004b s3:smbd/files: fix error path and correctly cleanup from e33bf32 selftest: Run only the samba3 tests on builds without the AD DC
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit a95b2ba043ce843149fef4821cc25823c53cf994 Author: Stefan Metzmacher <me...@samba.org> Date: Wed May 23 13:22:47 2012 +0200 s3:smbd/msdfs: pass allow_broken_path to resolve_dfspath_wcard() metze Autobuild-User: Stefan Metzmacher <me...@samba.org> Autobuild-Date: Thu May 24 16:14:01 CEST 2012 on sn-devel-104 commit 758d61201f7b51da6ce74aee2d18c5125d72522e Author: Stefan Metzmacher <me...@samba.org> Date: Wed May 23 13:09:40 2012 +0200 s3:smbd/msdfs: pass 'allow_broken_path' to get_referred_path() Note the DCERPC code should not be smb2 specific! I wonder why this is at all smb2 specific... metze commit a92f7176bd7f198a547952142b7d361a9b4e9146 Author: Stefan Metzmacher <me...@samba.org> Date: Wed May 23 13:06:55 2012 +0200 s3:smbd/msdfs: let create_conn_struct() also fake the 'smbd_server_connection' metze commit 0733183594dbd3ce07ddaf9e1fcf8102b80fc605 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 24 10:43:56 2012 +0200 s3:smbd/files: work without sconn->file_bmap and assign fsp->fnum = -1 For faked connection_structs we do not need valid fnum values, e.g. in the dfs and printing code. metze commit 768004b11d396edfafaee90c7c710722376ff2e6 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 24 11:22:11 2012 +0200 s3:smbd/files: fix error path and correctly cleanup metze ----------------------------------------------------------------------- Summary of changes: source3/modules/vfs_default.c | 4 +- source3/printing/nt_printing.c | 15 +++++- source3/rpc_server/dfs/srv_dfs_nt.c | 11 +++-- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 10 +++- source3/smbd/filename.c | 2 + source3/smbd/files.c | 76 +++++++++++++++++----------- source3/smbd/msdfs.c | 55 +++++++++++++++------ source3/smbd/proto.h | 16 +++--- source3/smbd/trans2.c | 1 + 9 files changed, 128 insertions(+), 62 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 887dbcb..8908508 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -22,6 +22,7 @@ #include "system/time.h" #include "system/filesys.h" #include "smbd/smbd.h" +#include "smbd/globals.h" #include "ntioctl.h" #include "smbprofile.h" #include "../libcli/security/security.h" @@ -209,7 +210,8 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle, } /* The following call can change cwd. */ - status = get_referred_path(r, pathnamep, handle->conn->sconn, + status = get_referred_path(r, pathnamep, + !handle->conn->sconn->using_smb2, junction, &consumedcnt, &self_referral); if (!NT_STATUS_IS_OK(status)) { vfs_ChDir(handle->conn, handle->conn->connectpath); diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 96947f1..f52b6ae 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -616,7 +616,10 @@ static uint32 get_correct_cversion(struct auth_session_info *session_info, return -1; } - nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn, + nt_status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + &conn, printdollar_snum, lp_pathname(printdollar_snum), session_info, &oldcwd); @@ -1000,7 +1003,10 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info, return WERR_NO_SUCH_SHARE; } - nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn, + nt_status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + &conn, printdollar_snum, lp_pathname(printdollar_snum), session_info, &oldcwd); @@ -1533,7 +1539,10 @@ bool delete_driver_files(const struct auth_session_info *session_info, return false; } - nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn, + nt_status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + &conn, printdollar_snum, lp_pathname(printdollar_snum), session_info, &oldcwd); diff --git a/source3/rpc_server/dfs/srv_dfs_nt.c b/source3/rpc_server/dfs/srv_dfs_nt.c index e765f15..2c840e2 100644 --- a/source3/rpc_server/dfs/srv_dfs_nt.c +++ b/source3/rpc_server/dfs/srv_dfs_nt.c @@ -75,8 +75,9 @@ WERROR _dfs_Add(struct pipes_struct *p, struct dfs_Add *r) } /* The following call can change the cwd. */ - status = get_referred_path(ctx, r->in.path, smbd_server_conn, jn, - &consumedcnt, &self_ref); + status = get_referred_path(ctx, r->in.path, + true, /*allow_broken_path */ + jn, &consumedcnt, &self_ref); if(!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); } @@ -142,7 +143,8 @@ WERROR _dfs_Remove(struct pipes_struct *p, struct dfs_Remove *r) r->in.dfs_entry_path, r->in.servername, r->in.sharename)); } - status = get_referred_path(ctx, r->in.dfs_entry_path, smbd_server_conn, + status = get_referred_path(ctx, r->in.dfs_entry_path, + true, /*allow_broken_path */ jn, &consumedcnt, &self_ref); if(!NT_STATUS_IS_OK(status)) { return WERR_DFS_NO_SUCH_VOL; @@ -369,7 +371,8 @@ WERROR _dfs_GetInfo(struct pipes_struct *p, struct dfs_GetInfo *r) } /* The following call can change the cwd. */ - status = get_referred_path(ctx, r->in.dfs_entry_path, smbd_server_conn, + status = get_referred_path(ctx, r->in.dfs_entry_path, + true, /*allow_broken_path */ jn, &consumedcnt, &self_ref); if(!NT_STATUS_IS_OK(status) || consumedcnt < strlen(r->in.dfs_entry_path)) { diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index c9f8ceb..38f272c 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2133,7 +2133,10 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } - nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn, + nt_status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + &conn, snum, lp_pathname(snum), p->session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { @@ -2274,7 +2277,10 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, goto error_exit; } - nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn, + nt_status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + &conn, snum, lp_pathname(snum), p->session_info, &oldcwd); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index ac218a1..a4f9cd1 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -28,6 +28,7 @@ #include "system/filesys.h" #include "fake_file.h" #include "smbd/smbd.h" +#include "smbd/globals.h" static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, connection_struct *conn, @@ -1309,6 +1310,7 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, dfs_path, name_in, allow_wcards, + !conn->sconn->using_smb2, &fname, ppath_contains_wcard); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 203d0ad..ae34006 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -48,29 +48,36 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, files_struct **result) { struct smbd_server_connection *sconn = conn->sconn; - int i; + int i = -1; files_struct *fsp; NTSTATUS status; - /* we want to give out file handles differently on each new - connection because of a common bug in MS clients where they try to - reuse a file descriptor from an earlier smb connection. This code - increases the chance that the errant client will get an error rather - than causing corruption */ - if (sconn->first_file == 0) { - sconn->first_file = (getpid() ^ (int)time(NULL)); - sconn->first_file %= sconn->real_max_open_files; - } + if (sconn->file_bmap != NULL) { - /* TODO: Port the id-tree implementation from Samba4 */ + /* + * we want to give out file handles differently on each new + * connection because of a common bug in MS clients where they + * try to reuse a file descriptor from an earlier smb + * connection. This code increases the chance that the errant + * client will get an error rather than causing corruption + */ + if (sconn->first_file == 0) { + sconn->first_file = (getpid() ^ (int)time(NULL)); + sconn->first_file %= sconn->real_max_open_files; + } - i = bitmap_find(sconn->file_bmap, sconn->first_file); - if (i == -1) { - DEBUG(0,("ERROR! Out of file structures\n")); - /* TODO: We have to unconditionally return a DOS error here, - * W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with - * NTSTATUS negotiated */ - return NT_STATUS_TOO_MANY_OPENED_FILES; + /* TODO: Port the id-tree implementation from Samba4 */ + + i = bitmap_find(sconn->file_bmap, sconn->first_file); + if (i == -1) { + DEBUG(0,("ERROR! Out of file structures\n")); + /* + * TODO: We have to unconditionally return a DOS error + * here, W2k3 even returns ERRDOS/ERRnofids for + * ntcreate&x with NTSTATUS negotiated + */ + return NT_STATUS_TOO_MANY_OPENED_FILES; + } } /* @@ -96,16 +103,24 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, fsp->fh->ref_count = 1; fsp->fh->fd = -1; + fsp->fnum = -1; fsp->conn = conn; fsp->fh->gen_id = get_gen_count(sconn); GetTimeOfDay(&fsp->open_time); - sconn->first_file = (i+1) % (sconn->real_max_open_files); + if (sconn->file_bmap != NULL) { + sconn->first_file = (i+1) % (sconn->real_max_open_files); + + bitmap_set(sconn->file_bmap, i); - bitmap_set(sconn->file_bmap, i); + fsp->fnum = i + FILE_HANDLE_OFFSET; + SMB_ASSERT(fsp->fnum < 65536); + } + + DLIST_ADD(sconn->files, fsp); + sconn->num_files += 1; - fsp->fnum = i + FILE_HANDLE_OFFSET; - SMB_ASSERT(fsp->fnum < 65536); + conn->num_files_open++; /* * Create an smb_filename with "" for the base_name. There are very @@ -115,13 +130,10 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, status = create_synthetic_smb_fname(fsp, "", NULL, NULL, &fsp->fsp_name); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(fsp); - TALLOC_FREE(fsp->fh); + file_free(NULL, fsp); + return status; } - DLIST_ADD(sconn->files, fsp); - sconn->num_files += 1; - DEBUG(5,("allocated file structure %d, fnum = %d (%u used)\n", i, fsp->fnum, (unsigned int)sconn->num_files)); @@ -136,8 +148,6 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, ZERO_STRUCT(sconn->fsp_fi_cache); - conn->num_files_open++; - *result = fsp; return NT_STATUS_OK; } @@ -454,7 +464,9 @@ void file_free(struct smb_request *req, files_struct *fsp) /* Ensure this event will never fire. */ TALLOC_FREE(fsp->update_write_time_event); - bitmap_clear(sconn->file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); + if (sconn->file_bmap != NULL) { + bitmap_clear(sconn->file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); + } DEBUG(5,("freed files structure %d (%u used)\n", fsp->fnum, (unsigned int)sconn->num_files)); @@ -501,6 +513,10 @@ static struct files_struct *file_fnum(struct smbd_server_connection *sconn, int count=0; for (fsp=sconn->files; fsp; fsp=fsp->next, count++) { + if (fsp->fnum == -1) { + continue; + } + if (fsp->fnum == fnum) { if (count > 10) { DLIST_PROMOTE(sconn->files, fsp); diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index b7a5052..9da8a8d 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -223,12 +223,13 @@ static NTSTATUS parse_dfs_path(connection_struct *conn, *********************************************************/ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, - struct smbd_server_connection *sconn, - connection_struct **pconn, - int snum, - const char *path, - const struct auth_session_info *session_info, - char **poldcwd) + 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 *connpath; @@ -254,6 +255,18 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } + conn->sconn = talloc_zero(conn, struct smbd_server_connection); + if (conn->sconn == NULL) { + TALLOC_FREE(conn); + return NT_STATUS_NO_MEMORY; + } + + conn->sconn->ev_ctx = ev; + conn->sconn->msg_ctx = msg; + conn->sconn->sock = -1; + conn->sconn->smb1.echo_handler.trusted_fd = -1; + conn->sconn->smb1.echo_handler.socket_lock_fd = -1; + /* needed for smbd_vfs_init() */ if (!(conn->params = talloc_zero(conn, struct share_params))) { @@ -265,8 +278,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, conn->params->service = snum; conn->cnum = (unsigned)-1; - conn->sconn = sconn; - DLIST_ADD(sconn->connections, conn); + DLIST_ADD(conn->sconn->connections, conn); conn->sconn->num_connections++; if (session_info != NULL) { @@ -844,7 +856,7 @@ static NTSTATUS self_ref(TALLOC_CTX *ctx, NTSTATUS get_referred_path(TALLOC_CTX *ctx, const char *dfs_path, - struct smbd_server_connection *sconn, + bool allow_broken_path, struct junction_map *jucn, int *consumedcntp, bool *self_referralp) @@ -863,7 +875,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, *self_referralp = False; - status = parse_dfs_path(NULL, dfs_path, False, !sconn->using_smb2, + status = parse_dfs_path(NULL, dfs_path, False, allow_broken_path, pdp, &dummy); if (!NT_STATUS_IS_OK(status)) { return status; @@ -967,7 +979,10 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, return NT_STATUS_OK; } - status = create_conn_struct(ctx, sconn, &conn, snum, + status = create_conn_struct(ctx, + server_event_context(), + server_messaging_context(), + &conn, snum, lp_pathname(snum), NULL, &oldpath); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(pdp); @@ -1143,7 +1158,10 @@ static bool junction_to_local_path(const struct junction_map *jucn, if(snum < 0) { return False; } - status = create_conn_struct(talloc_tos(), smbd_server_conn, conn_out, + status = create_conn_struct(talloc_tos(), + server_event_context(), + server_messaging_context(), + conn_out, snum, lp_pathname(snum), NULL, oldpath); if (!NT_STATUS_IS_OK(status)) { return False; @@ -1305,7 +1323,10 @@ 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(), smbd_server_conn, &conn, + status = create_conn_struct(talloc_tos(), + 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", @@ -1378,7 +1399,10 @@ static int form_junctions(TALLOC_CTX *ctx, * Fake up a connection struct for the VFS layer. */ - status = create_conn_struct(ctx, smbd_server_conn, &conn, snum, connect_path, NULL, + status = create_conn_struct(ctx, + 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", @@ -1531,6 +1555,7 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, bool dfs_pathnames, const char *name_in, bool allow_wcards, + bool allow_broken_path, char **pp_name_out, bool *ppath_contains_wcard) { @@ -1542,7 +1567,7 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, conn, name_in, allow_wcards, - !smbd_server_conn->using_smb2, + allow_broken_path, pp_name_out, &path_contains_wcard); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 4dc63cc..60f9a7d 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -457,7 +457,7 @@ bool is_msdfs_link(connection_struct *conn, struct junction_map; NTSTATUS get_referred_path(TALLOC_CTX *ctx, const char *dfs_path, - struct smbd_server_connection *sconn, + bool allow_broken_path, struct junction_map *jucn, int *consumedcntp, bool *self_referralp); @@ -477,15 +477,17 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, bool dfs_pathnames, const char *name_in, bool allow_wcards, + bool allow_broken_path, char **pp_name_out, bool *ppath_contains_wcard); NTSTATUS create_conn_struct(TALLOC_CTX *ctx, - struct smbd_server_connection *sconn, - connection_struct **pconn, - int snum, - const char *path, - const struct auth_session_info *session_info, - char **poldcwd); + 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 */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 590ee5b..d4b32ce 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6236,6 +6236,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, req->flags2 & FLAGS2_DFS_PATHNAMES, newname, true, + !conn->sconn->using_smb2, &newname, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { -- Samba Shared Repository