s3:modules: add vfs_dfs_samba4
authorStefan Metzmacher <metze@samba.org>
Tue, 4 Oct 2011 10:38:00 +0000 (12:38 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 7 Oct 2011 23:43:38 +0000 (01:43 +0200)
This module overloads the SMB_VFS_GET_DFS_REFERRAL() hooks,
in order to support the domain, dc and sysvol referrals
for a AD DC.

The config would look like this:

[IPC$]
    vfs objects = dfs_samba4

metze

source3/modules/vfs_dfs_samba4.c [new file with mode: 0644]
source3/modules/wscript_build
source3/wscript

diff --git a/source3/modules/vfs_dfs_samba4.c b/source3/modules/vfs_dfs_samba4.c
new file mode 100644 (file)
index 0000000..98da9c7
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * VFS module to alter the algorithm to calculate
+ * the struct file_id used as key for the share mode
+ * and byte range locking db's.
+ *
+ * Copyright (C) 2007, Stefan Metzmacher
+ *
+ * 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 "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "system/filesys.h"
+#include "source3/include/msdfs.h"
+#include "librpc/gen_ndr/ndr_dfsblobs.h"
+#include "source4/lib/events/events.h"
+#include "source4/auth/session.h"
+#include "source4/param/param.h"
+#include "source4/dsdb/samdb/samdb.h"
+#include "dfs_server/dfs_server_ad.h"
+
+static int vfs_dfs_samba4_debug_level = DBGC_VFS;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS vfs_dfs_samba4_debug_level
+
+struct dfs_samba4_handle_data {
+       struct tevent_context *ev;
+       struct loadparm_context *lp_ctx;
+       struct ldb_context *sam_ctx;
+};
+
+static int dfs_samba4_connect(struct vfs_handle_struct *handle,
+                             const char *service, const char *user)
+{
+       struct dfs_samba4_handle_data *data;
+       int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
+
+       if (ret < 0) {
+               return ret;
+       }
+
+       data = talloc_zero(handle->conn, struct dfs_samba4_handle_data);
+       if (!data) {
+               DEBUG(0, ("talloc_zero() failed\n"));
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
+
+       data->ev = s4_event_context_init(data);
+       if (!data->ev) {
+               DEBUG(0, ("s4_event_context_init failed\n"));
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
+
+       data->lp_ctx = loadparm_init_s3(data, loadparm_s3_context());
+       if (data->lp_ctx == NULL) {
+               DEBUG(0, ("loadparm_init_s3 failed\n"));
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
+
+       data->sam_ctx = samdb_connect(data,
+                                     data->ev,
+                                     data->lp_ctx,
+                                     system_session(data->lp_ctx), 0);
+       if (!data->sam_ctx) {
+               DEBUG(0, ("samdb_connect failed\n"));
+               SMB_VFS_NEXT_DISCONNECT(handle);
+               return -1;
+       }
+
+       SMB_VFS_HANDLE_SET_DATA(handle, data, NULL,
+                               struct dfs_samba4_handle_data,
+                               return -1);
+
+       DEBUG(10,("dfs_samba4: connect to service[%s]\n",
+                 service));
+
+       return 0;
+}
+
+static void dfs_samba4_disconnect(struct vfs_handle_struct *handle)
+{
+       DEBUG(10,("dfs_samba4_disconnect() connect to service[%s].\n",
+                 lp_servicename(SNUM(handle->conn))));
+
+       SMB_VFS_NEXT_DISCONNECT(handle);
+}
+
+static NTSTATUS dfs_samba4_get_referrals(struct vfs_handle_struct *handle,
+                                        struct dfs_GetDFSReferral *r)
+{
+       struct dfs_samba4_handle_data *data;
+       NTSTATUS status;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, data,
+                               struct dfs_samba4_handle_data,
+                               return NT_STATUS_INTERNAL_ERROR);
+
+       DEBUG(8, ("dfs_samba4: Requested DFS name: %s utf16-length: %u\n",
+                  r->in.req.servername,
+                  (unsigned int)strlen_m(r->in.req.servername)*2));
+
+       status = dfs_server_ad_get_referrals(data->lp_ctx,
+                                            data->sam_ctx,
+                                            handle->conn->sconn->remote_address,
+                                            r);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+               return SMB_VFS_NEXT_GET_DFS_REFERRALS(handle, r);
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
+static struct vfs_fn_pointers vfs_dfs_samba4_fns = {
+       .connect_fn = dfs_samba4_connect,
+       .disconnect = dfs_samba4_disconnect,
+       .get_dfs_referrals = dfs_samba4_get_referrals,
+};
+
+NTSTATUS vfs_dfs_samba4_init(void);
+NTSTATUS vfs_dfs_samba4_init(void)
+{
+       NTSTATUS ret;
+
+       ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "dfs_samba4",
+                              &vfs_dfs_samba4_fns);
+       if (!NT_STATUS_IS_OK(ret)) {
+               return ret;
+       }
+
+       vfs_dfs_samba4_debug_level = debug_add_class("dfs_samba4");
+       if (vfs_dfs_samba4_debug_level == -1) {
+               vfs_dfs_samba4_debug_level = DBGC_VFS;
+               DEBUG(0, ("vfs_dfs_samba4: Couldn't register custom debugging class!\n"));
+       } else {
+               DEBUG(10, ("vfs_dfs_samba4: Debug class number of 'fileid': %d\n",
+                     vfs_dfs_samba4_debug_level));
+       }
+
+       return ret;
+}
index b3ab734ac15ed08afcca580936d8d1b8222a0fdd..86fc64781a9c6183ef98f00d5c7e3a01e865533f 100644 (file)
@@ -444,7 +444,13 @@ bld.SAMBA3_MODULE('vfs_time_audit',
                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_time_audit'),
                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_time_audit'))
 
-
+bld.SAMBA3_MODULE('vfs_dfs_samba4',
+                 subsystem='vfs',
+                 source='vfs_dfs_samba4.c',
+                 deps='samba-util dfs_server_ad samdb',
+                 init_function='',
+                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_dfs_samba4'),
+                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_dfs_samba4'))
 
 PERFCOUNT_ONEFS_SRC = 'perfcount_onefs.c'
 PERFCOUNT_TEST_SRC = 'perfcount_test.c'
index 1d40998adbad43a441d0d888e6aabe3ce43ed573..87cc2d49759cf6aa6daf864549e9beb7f24bb02e 100644 (file)
@@ -1661,7 +1661,7 @@ main() {
         default_static_modules.extend(TO_LIST('pdb_ads auth_netlogond charset_weird'))
         default_shared_modules.extend(TO_LIST('perfcount_test'))
 
-    default_static_modules.extend(TO_LIST('pdb_samba4 auth_samba4'))
+    default_static_modules.extend(TO_LIST('pdb_samba4 auth_samba4 vfs_dfs_samba4'))
 
     if Options.options.with_acl_support and conf.CONFIG_SET('HAVE_POSIX_ACLS'):
         default_static_modules.extend(TO_LIST('vfs_posixacl'))