From: Stefan Metzmacher Date: Thu, 22 Mar 2018 09:54:41 +0000 (+0100) Subject: smbd: make use of smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers X-Git-Tag: ldb-1.5.0~342 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0dcaa0707bad67f7bfaa10ccaf167bfefbe87a0c;p=thirdparty%2Fsamba.git smbd: make use of smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers For now they just add debugging, but that will change shortly. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c index 570eb7c4d15..e7e12747a22 100644 --- a/source3/modules/vfs_readonly.c +++ b/source3/modules/vfs_readonly.c @@ -84,7 +84,7 @@ static int readonly_connect(vfs_handle_struct *handle, for (i=0; i< VUID_CACHE_SIZE; i++) { struct vuid_cache_entry *ent = &conn->vuid_cache->array[i]; ent->vuid = UID_FIELD_INVALID; - ent->user_ev_ctx = NULL; + TALLOC_FREE(ent->user_ev_ctx); TALLOC_FREE(ent->session_info); ent->read_only = false; ent->share_access = 0; diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 3b9aaac7834..cfff6404608 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -98,7 +98,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid) if (conn->user_ev_ctx == ent->user_ev_ctx) { conn->user_ev_ctx = NULL; } - ent->user_ev_ctx = NULL; + TALLOC_FREE(ent->user_ev_ctx); /* * We need to keep conn->session_info around diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index f0ec6b84892..c74de7acf88 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -263,8 +263,17 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } - sconn->root_ev_ctx = sconn->raw_ev_ctx; - sconn->guest_ev_ctx = sconn->raw_ev_ctx; + sconn->root_ev_ctx = smbd_impersonate_root_create(sconn->raw_ev_ctx); + if (sconn->root_ev_ctx == NULL) { + TALLOC_FREE(sconn); + return NT_STATUS_NO_MEMORY; + } + sconn->guest_ev_ctx = smbd_impersonate_guest_create(sconn->raw_ev_ctx); + if (sconn->guest_ev_ctx == NULL) { + TALLOC_FREE(sconn); + return NT_STATUS_NO_MEMORY; + } + sconn->msg_ctx = msg; conn = conn_new(sconn); @@ -318,7 +327,26 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx, vfs_user = get_current_username(); } - conn->user_ev_ctx = sconn->raw_ev_ctx; + /* + * The impersonation has to be done by the caller + * of create_conn_struct_tos[_cwd](). + * + * Note: the context can't be changed anyway + * as we're using our own tevent_context + * and not a global one were other requests + * could change the current unix token. + * + * We just use a wrapper tevent_context in order + * to avoid crashes because TALLOC_FREE(conn->user_ev_ctx) + * would also remove sconn->raw_ev_ctx. + */ + conn->user_ev_ctx = smbd_impersonate_debug_create(sconn->raw_ev_ctx, + "FAKE impersonation", + DBGLVL_DEBUG); + if (conn->user_ev_ctx == NULL) { + TALLOC_FREE(conn); + return NT_STATUS_NO_MEMORY; + } set_conn_connectpath(conn, connpath); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index a3571ee811a..dc95af17393 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -3900,6 +3900,8 @@ void smbd_process(struct tevent_context *ev_ctx, .ev = ev_ctx, .frame = talloc_stackframe(), }; + struct tevent_context *root_ev_ctx = NULL; + struct tevent_context *guest_ev_ctx = NULL; struct smbXsrv_client *client = NULL; struct smbd_server_connection *sconn = NULL; struct smbXsrv_connection *xconn = NULL; @@ -3912,6 +3914,18 @@ void smbd_process(struct tevent_context *ev_ctx, char *chroot_dir = NULL; int rc; + root_ev_ctx = smbd_impersonate_root_create(ev_ctx); + if (root_ev_ctx == NULL) { + DEBUG(0,("smbd_impersonate_root_create() failed\n")); + exit_server_cleanly("smbd_impersonate_root_create().\n"); + } + + guest_ev_ctx = smbd_impersonate_guest_create(ev_ctx); + if (guest_ev_ctx == NULL) { + DEBUG(0,("smbd_impersonate_guest_create() failed\n")); + exit_server_cleanly("smbd_impersonate_guest_create().\n"); + } + status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status)); @@ -3932,8 +3946,8 @@ void smbd_process(struct tevent_context *ev_ctx, sconn->client = client; sconn->raw_ev_ctx = ev_ctx; - sconn->root_ev_ctx = ev_ctx; - sconn->guest_ev_ctx = ev_ctx; + sconn->root_ev_ctx = root_ev_ctx; + sconn->guest_ev_ctx = guest_ev_ctx; sconn->msg_ctx = msg_ctx; ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(), diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 18af3df2e63..9799f8b59dd 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -306,7 +306,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn) } } /* Not used, safe to free. */ - conn->user_ev_ctx = NULL; + TALLOC_FREE(conn->user_ev_ctx); TALLOC_FREE(conn->session_info); } @@ -481,7 +481,23 @@ static bool check_user_ok(connection_struct *conn, ent->session_info->unix_token->uid = sec_initial_uid(); } - ent->user_ev_ctx = conn->sconn->raw_ev_ctx; + if (vuid == UID_FIELD_INVALID) { + ent->user_ev_ctx = smbd_impersonate_conn_sess_create( + conn->sconn->raw_ev_ctx, conn, ent->session_info); + if (ent->user_ev_ctx == NULL) { + TALLOC_FREE(ent->session_info); + ent->vuid = UID_FIELD_INVALID; + return false; + } + } else { + ent->user_ev_ctx = smbd_impersonate_conn_vuid_create( + conn->sconn->raw_ev_ctx, conn, vuid); + if (ent->user_ev_ctx == NULL) { + TALLOC_FREE(ent->session_info); + ent->vuid = UID_FIELD_INVALID; + return false; + } + } /* * It's actually OK to call check_user_ok() with