summaryrefslogtreecommitdiffstats
path: root/source3/modules/vfs_dfs_samba4.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /source3/modules/vfs_dfs_samba4.c
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/modules/vfs_dfs_samba4.c')
-rw-r--r--source3/modules/vfs_dfs_samba4.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/source3/modules/vfs_dfs_samba4.c b/source3/modules/vfs_dfs_samba4.c
new file mode 100644
index 0000000..8b4724f
--- /dev/null
+++ b/source3/modules/vfs_dfs_samba4.c
@@ -0,0 +1,162 @@
+/*
+ * VFS module to retrieve DFS referrals from AD
+ *
+ * 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 "lib/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_helpers());
+ 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),
+ NULL,
+ 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)
+{
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
+
+ DEBUG(10,("dfs_samba4_disconnect() connect to service[%s].\n",
+ lp_servicename(talloc_tos(), lp_sub, 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_fn = dfs_samba4_disconnect,
+ .get_dfs_referrals_fn = dfs_samba4_get_referrals,
+};
+
+static_decl_vfs;
+NTSTATUS vfs_dfs_samba4_init(TALLOC_CTX *ctx)
+{
+ 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;
+}