smbd: make use of smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers
authorStefan Metzmacher <metze@samba.org>
Thu, 22 Mar 2018 09:54:41 +0000 (10:54 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 12 Jul 2018 12:25:18 +0000 (14:25 +0200)
For now they just add debugging, but that will change shortly.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/modules/vfs_readonly.c
source3/smbd/conn.c
source3/smbd/msdfs.c
source3/smbd/process.c
source3/smbd/uid.c

index 570eb7c4d15a24b42f9cffe33a61025819f885fb..e7e12747a2225dab74794a67583d6039c4607b9a 100644 (file)
@@ -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;
index 3b9aaac7834bedd53ddc3545dd71f4aa243b51ea..cfff6404608f395414490e412d15d07139ba5bee 100644 (file)
@@ -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
index f0ec6b8489258b28f1dd2b3344e1cdbce1bf8e0e..c74de7acf880fa618f4a6fe0bfadc545c17dae01 100644 (file)
@@ -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);
 
index a3571ee811abefe8fb5255a54cdbf8b281cb73d8..dc95af17393bc710fe6fc10eb0aa9a747f3a028a 100644 (file)
@@ -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(),
index 18af3df2e63048077aeb491ccdff840a9d3fee5b..9799f8b59dd1477f9b26dcf0981b2dfc32ac4279 100644 (file)
@@ -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