start source3/smbd/tevent_impersonate.c master3-impersonate
authorStefan Metzmacher <metze@samba.org>
Fri, 11 May 2012 13:51:42 +0000 (15:51 +0200)
committerStefan Metzmacher <metze@samba.org>
Sat, 10 Aug 2013 15:05:35 +0000 (17:05 +0200)
source3/smbd/service.c
source3/smbd/tevent_impersonate.c [new file with mode: 0644]

index a7464f0722c5011c44ccb3c845a6e7ad54cf6da9..24e126c83988dce5ddc001c29399748207c59857 100644 (file)
@@ -627,6 +627,9 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
 
        /* Initialise VFS function pointers */
 
+//tevent_impersonate_create_context
+//conn->ev_ctx,
+
        if (!smbd_vfs_init(conn)) {
                DEBUG(0, ("vfs_init failed for service %s\n",
                          lp_servicename(talloc_tos(), snum)));
diff --git a/source3/smbd/tevent_impersonate.c b/source3/smbd/tevent_impersonate.c
new file mode 100644 (file)
index 0000000..d6d5878
--- /dev/null
@@ -0,0 +1,189 @@
+/* 
+   Unix SMB/CIFS implementation.
+   async uid/user handling
+   Copyright (C) Stefan Metzmacher 2012
+   Copyright (C) David Disseldorp 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include <tevent.h>
+//#include "lib/tevent/tevent_internal.h"
+//#include "../lib/util/select.h"
+//#include "system/select.h"
+
+struct tevent_impersonate_context {
+       struct tevent_context *main_ev;
+       struct connection_struct *conn;
+       uint64_t vuid;
+};
+
+static const struct tevent_ops s3_event_ops = {
+       .context_init           = s3_event_context_init,
+       .add_fd                 = tevent_common_add_fd,
+       .set_fd_close_fn        = tevent_common_fd_set_close_fn,
+       .get_fd_flags           = tevent_common_fd_get_flags,
+       .set_fd_flags           = tevent_common_fd_set_flags,
+       .add_timer              = tevent_common_add_timer,
+       .schedule_immediate     = tevent_common_schedule_immediate,
+       .add_signal             = tevent_common_add_signal,
+       .loop_once              = s3_event_loop_once,
+       .loop_wait              = tevent_common_loop_wait,
+};
+
+static int tevent_impersonate_init(struct tevent_context *ev)
+{
+       struct tevent_impersonate_context *a =
+               talloc_get_type_abort(ev->additional_data,
+               struct tevent_impersonate_context)
+
+       talloc_steal(ev, a);
+
+       return 0;
+}
+
+struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
+                                      int fd, uint16_t flags,
+                                      tevent_fd_handler_t handler,
+                                      void *private_data,
+                                      const char *handler_name,
+                                      const char *location)
+{
+       struct tevent_fd *fde;
+
+       /* tevent will crash later on select() if we save
+        * a negative file descriptor. Better to fail here
+        * so that consumers will be able to debug it
+        */
+       if (fd < 0) return NULL;
+
+       fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
+       if (!fde) return NULL;
+
+       fde->event_ctx          = ev;
+       fde->fd                 = fd;
+       fde->flags              = flags;
+       fde->handler            = handler;
+       fde->close_fn           = NULL;
+       fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
+       fde->additional_flags   = 0;
+       fde->additional_data    = NULL;
+
+       DLIST_ADD(ev->fd_events, fde);
+
+       talloc_set_destructor(fde, tevent_common_fd_destructor);
+
+       return fde;
+}
+
+struct tevent_fd *tevent_impersonate_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
+                                      int fd, uint16_t flags,
+                                      tevent_fd_handler_t handler,
+                                      void *private_data,
+                                      const char *handler_name,
+                                      const char *location)
+{
+       struct tevent_fd *fde;
+
+       /* tevent will crash later on select() if we save
+        * a negative file descriptor. Better to fail here
+        * so that consumers will be able to debug it
+        */
+       if (fd < 0) return NULL;
+
+       fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
+       if (!fde) return NULL;
+
+       fde->event_ctx          = ev;
+       fde->fd                 = fd;
+       fde->flags              = flags;
+       fde->handler            = handler;
+       fde->close_fn           = NULL;
+       fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
+       fde->additional_flags   = 0;
+       fde->additional_data    = NULL;
+
+       DLIST_ADD(ev->fd_events, fde);
+
+       main_fde = tevent_add_fd(ev, fde, fd, flags,
+                                tevent_impersonate_fd_handler, fde);
+                                //TODO handler name...
+       if (main_fde == NULL) {
+               talloc_free(fde);
+               return NULL;
+       }
+
+       fde->additional_data = main_fde;
+
+       return fde;
+}
+
+static void tevent_impersonate_fd_handler(struct tevent_context *main_ev,
+                                   struct tevent_fd *main_fde,
+                                   uint16_t flags,
+                                   void *private_data)
+{
+       struct tevent_fd *fde = private_data;
+       struct tevent_context *ev = fde->ev;
+       struct tevent_impersonate_context *ctx;
+
+       become_user_user(ctx->conn, ctx->vuid);
+       fde->handler(ev, fde, fde->flags, fde->private_data);
+       //TODO unbecome???
+}
+
+static const struct tevent_ops tevent_impersonate_ops = {
+       .context_init           = tevent_impersonate_init,
+       .add_fd                 = tevent_impersonate_add_fd,
+       .set_fd_close_fn        = tevent_impersonate_fd_set_close_fn,
+       .get_fd_flags           = tevent_impersonate_fd_get_flags,
+       .set_fd_flags           = tevent_impersonate_fd_set_flags,
+       .add_timer              = tevent_impersonate_add_timer,
+       .schedule_immediate     = tevent_impersonate_schedule_immediate,
+       .add_signal             = tevent_impersonate_add_signal,
+       .loop_once              = tevent_impersonate_once,
+       .loop_wait              = tevent_impersonate_loop_wait,
+       //TODO add all!
+};
+
+struct tevent_context *tevent_impersonate_create_context(struct tevent_context *main_ev,
+                                               struct connection_struct *conn,
+                                               uint64_t vuid)
+{
+       TALLOC_CTX *mem_ctx = main_ev; // TODO???
+       struct tevent_context *ev;
+       struct tevent_impersonate_context *a;
+       
+       a = talloc_zero(mem_ctx, struct tevent_impersonate_context);
+       if (a == NULL) {
+               return NULL;
+       }
+       a->main_ev = main_ev;
+       a->conn = conn;
+       a->vuid = vuid;
+
+       ev = tevent_context_init_ops(mem_ctx, &tevent_impersonate_ops, a);
+       if (ev == NULL) {
+               talloc_free(a);
+               return NULL;
+       }
+
+       return ev;
+}
+