summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-10-04 12:38:00 +0200
committerStefan Metzmacher <metze@samba.org>2011-10-08 01:43:38 +0200
commit29dbda56b5ba6db9fd04cdea1de377630bea9016 (patch)
tree5576242084d79a7ea041ed7e60010d0374d78641
parent09731c76877137291f0041711f01b40e33eb3d1c (diff)
downloadsamba-29dbda56b5ba6db9fd04cdea1de377630bea9016.tar.gz
samba-29dbda56b5ba6db9fd04cdea1de377630bea9016.tar.bz2
samba-29dbda56b5ba6db9fd04cdea1de377630bea9016.zip
s3:modules: add vfs_dfs_samba4
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
-rw-r--r--source3/modules/vfs_dfs_samba4.c159
-rw-r--r--source3/modules/wscript_build8
-rw-r--r--source3/wscript2
3 files changed, 167 insertions, 2 deletions
diff --git a/source3/modules/vfs_dfs_samba4.c b/source3/modules/vfs_dfs_samba4.c
new file mode 100644
index 0000000000..98da9c70bb
--- /dev/null
+++ b/source3/modules/vfs_dfs_samba4.c
@@ -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;
+}
diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build
index b3ab734ac1..86fc64781a 100644
--- a/source3/modules/wscript_build
+++ b/source3/modules/wscript_build
@@ -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'
diff --git a/source3/wscript b/source3/wscript
index 1d40998adb..87cc2d4975 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -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'))