summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2004-03-26 22:26:33 +0000
committerVolker Lendecke <vlendec@samba.org>2004-03-26 22:26:33 +0000
commit87280e9a798895de827e5d1526fbac28a548f710 (patch)
tree94a3ac83b9b9ae1635ffabaedee37e6adf5abab1
parent1a50cf19d065bd3edf97ea975a7db6087e6139a5 (diff)
downloadsamba-87280e9a798895de827e5d1526fbac28a548f710.tar.gz
samba-87280e9a798895de827e5d1526fbac28a548f710.tar.bz2
samba-87280e9a798895de827e5d1526fbac28a548f710.zip
Move the Client-IP based msdfs target expansion to a VFS module.
Volker (This used to be commit 9cb6a4d76f87b28077861d3f4220541fbf704ddf)
-rw-r--r--source3/Makefile.in6
-rw-r--r--source3/configure.in3
-rw-r--r--source3/modules/vfs_expand_msdfs.c184
-rw-r--r--source3/msdfs/msdfs.c139
4 files changed, 197 insertions, 135 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index daa626af57..9a054a0a3a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -319,6 +319,7 @@ VFS_NETATALK_OBJ = modules/vfs_netatalk.o
VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o
VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
VFS_CAP_OBJ = modules/vfs_cap.o
+VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -1171,6 +1172,11 @@ bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@)
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \
@SONAMEFLAG@`basename $@`
+bin/expand_msdfs.@SHLIBEXT@: $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@)
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@) \
+ @SONAMEFLAG@`basename $@`
+
bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
diff --git a/source3/configure.in b/source3/configure.in
index f92ea2d080..59b1d062f6 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -360,7 +360,7 @@ dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs charset_CP850 charset_CP437"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_echo"
@@ -4371,6 +4371,7 @@ SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", V
SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHLIBEXT", VFS)
SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
diff --git a/source3/modules/vfs_expand_msdfs.c b/source3/modules/vfs_expand_msdfs.c
new file mode 100644
index 0000000000..954f28a411
--- /dev/null
+++ b/source3/modules/vfs_expand_msdfs.c
@@ -0,0 +1,184 @@
+/*
+ * Expand msdfs targets based on client IP
+ *
+ * Copyright (C) Volker Lendecke, 2004
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+/**********************************************************
+ Under mapfile we expect a table of the following format:
+
+ IP-Prefix whitespace expansion
+
+ For example:
+ 192.168.234 local.samba.org
+ 192.168 remote.samba.org
+ default.samba.org
+
+ This is to redirect a DFS client to a host close to it.
+***********************************************************/
+
+static BOOL read_target_host(const char *mapfile, pstring targethost)
+{
+ XFILE *f;
+ pstring buf;
+ char *s, *space = buf;
+ BOOL found = False;
+
+ f = x_fopen(mapfile, O_RDONLY, 0);
+
+ if (f == NULL) {
+ DEBUG(0,("can't open IP map %s. Error %s\n",
+ mapfile, strerror(errno) ));
+ return False;
+ }
+
+ DEBUG(10, ("Scanning mapfile [%s]\n", mapfile));
+
+ while ((s=fgets_slash(buf, sizeof(buf), f)) != NULL) {
+ space = strchr_m(buf, ' ');
+
+ if (space == NULL) {
+ DEBUG(0, ("Ignoring invalid line %s\n", buf));
+ continue;
+ }
+
+ *space = '\0';
+
+ if (strncmp(client_addr(), buf, strlen(buf)) == 0) {
+ found = True;
+ break;
+ }
+ }
+
+ x_fclose(f);
+
+ if (!found)
+ return False;
+
+ space += 1;
+
+ while (isspace(*space))
+ space += 1;
+
+ pstrcpy(targethost, space);
+ return True;
+}
+
+/**********************************************************
+
+ Expand the msdfs target host using read_target_host
+ explained above. The syntax used in the msdfs link is
+
+ msdfs:@table-filename@/share
+
+ Everything between and including the two @-signs is
+ replaced by the substitution string found in the table
+ described above.
+
+***********************************************************/
+
+static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
+{
+ pstring mapfilename;
+ char *filename_start = strchr_m(target, '@');
+ char *filename_end;
+ int filename_len;
+ pstring targethost;
+ pstring new_target;
+
+ if (filename_start == NULL) {
+ DEBUG(10, ("No filename start in %s\n", target));
+ return False;
+ }
+
+ filename_end = strchr_m(filename_start+1, '@');
+
+ if (filename_end == NULL) {
+ DEBUG(10, ("No filename end in %s\n", target));
+ return False;
+ }
+
+ filename_len = PTR_DIFF(filename_end, filename_start+1);
+ pstrcpy(mapfilename, filename_start+1);
+ mapfilename[filename_len] = '\0';
+
+ DEBUG(10, ("Expanding from table [%s]\n", mapfilename));
+
+ if (!read_target_host(mapfilename, targethost)) {
+ DEBUG(1, ("Could not expand target host from file %s\n",
+ mapfilename));
+ return False;
+ }
+
+ standard_sub_conn(conn, mapfilename, sizeof(mapfilename));
+
+ DEBUG(10, ("Expanded targethost to %s\n", targethost));
+
+ *filename_start = '\0';
+ pstrcpy(new_target, target);
+ pstrcat(new_target, targethost);
+ pstrcat(new_target, filename_end+1);
+
+ DEBUG(10, ("New DFS target: %s\n", new_target));
+ pstrcpy(target, new_target);
+ return True;
+}
+
+static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
+ struct connection_struct *conn,
+ const char *path, char *buf, size_t bufsiz)
+{
+ pstring target;
+ int result;
+
+ result = SMB_VFS_NEXT_READLINK(handle, conn, path, target,
+ sizeof(target));
+
+ if (result < 0)
+ return result;
+
+ target[result] = '\0';
+
+ if (strchr_m(target, '@') != NULL) {
+ if (!expand_msdfs_target(conn, target)) {
+ errno = ENOENT;
+ return -1;
+ }
+ }
+
+ safe_strcpy(buf, target, bufsiz-1);
+ return strlen(buf);
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple expand_msdfs_ops[] = {
+ {SMB_VFS_OP(expand_msdfs_readlink), SMB_VFS_OP_READLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_expand_msdfs_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "expand_msdfs",
+ expand_msdfs_ops);
+}
diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c
index 340e5c6750..2ac7bda175 100644
--- a/source3/msdfs/msdfs.c
+++ b/source3/msdfs/msdfs.c
@@ -158,134 +158,13 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
}
-/**********************************************************
- Under mapfile we expect a table of the following format:
-
- IP-Prefix whitespace expansion
-
- For example:
- 192.168.234 local.samba.org
- 192.168 remote.samba.org
- default.samba.org
-
- This is to redirect a DFS client to a host close to it.
-***********************************************************/
-
-static BOOL read_target_host(const char *mapfile, pstring targethost)
-{
- XFILE *f;
- pstring buf;
- char *s, *space = buf;
- BOOL found = False;
-
- f = x_fopen(mapfile, O_RDONLY, 0);
-
- if (f == NULL) {
- DEBUG(0,("can't open IP map %s. Error %s\n",
- mapfile, strerror(errno) ));
- return False;
- }
-
- DEBUG(10, ("Scanning mapfile [%s]\n", mapfile));
-
- while ((s=fgets_slash(buf, sizeof(buf), f)) != NULL) {
- space = strchr_m(buf, ' ');
-
- if (space == NULL) {
- DEBUG(0, ("Ignoring invalid line %s\n", buf));
- continue;
- }
-
- *space = '\0';
-
- if (strncmp(client_addr(), buf, strlen(buf)) == 0) {
- found = True;
- break;
- }
- }
-
- x_fclose(f);
-
- if (!found)
- return False;
-
- space += 1;
-
- while (isspace(*space))
- space += 1;
-
- pstrcpy(targethost, space);
- return True;
-}
-
-/**********************************************************
-
- Expand the msdfs target host using read_target_host
- explained above. The syntax used in the msdfs link is
-
- msdfs:@table-filename@/share
-
- Everything between and including the two @-signs is
- replaced by the substitution string found in the table
- described above.
-
-***********************************************************/
-
-static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
-{
- pstring mapfilename;
- char *filename_start = strchr_m(target, '@');
- char *filename_end;
- int filename_len;
- pstring targethost;
- pstring new_target;
-
- if (filename_start == NULL) {
- DEBUG(10, ("No filename start in %s\n", target));
- return False;
- }
-
- filename_end = strchr_m(filename_start+1, '@');
-
- if (filename_end == NULL) {
- DEBUG(10, ("No filename end in %s\n", target));
- return False;
- }
-
- filename_len = PTR_DIFF(filename_end, filename_start+1);
- pstrcpy(mapfilename, filename_start+1);
- mapfilename[filename_len] = '\0';
-
- DEBUG(10, ("Expanding from table [%s]\n", mapfilename));
-
- if (!read_target_host(mapfilename, targethost)) {
- DEBUG(1, ("Could not expand target host from file %s\n",
- mapfilename));
- return False;
- }
-
- standard_sub_conn(conn, mapfilename, sizeof(mapfilename));
-
- DEBUG(10, ("Expanded targethost to %s\n", targethost));
-
- *filename_start = '\0';
- pstrcpy(new_target, target);
- pstrcat(new_target, targethost);
- pstrcat(new_target, filename_end+1);
-
- DEBUG(10, ("New DFS target: %s\n", new_target));
- pstrcpy(target, new_target);
- return True;
-}
-
-
/**********************************************************************
Parse the contents of a symlink to verify if it is an msdfs referral
A valid referral is of the form: msdfs:server1\share1,server2\share2
**********************************************************************/
-static BOOL parse_symlink(connection_struct* conn, char* buf,
- struct referral** preflist, int* refcount)
+static BOOL parse_symlink(char* buf,struct referral** preflist,
+ int* refcount)
{
pstring temp;
char* prot;
@@ -318,22 +197,14 @@ static BOOL parse_symlink(connection_struct* conn, char* buf,
for(i=0;i<count;i++) {
char *p;
- pstring target;
-
- pstrcpy(target, alt_path[i]);
-
- if (strchr_m(target, '@') != NULL) {
- if (!expand_msdfs_target(conn, target))
- return False;
- }
/* replace all /'s in the alternate path by a \ */
- for(p = target; *p && ((p = strchr_m(p,'/'))!=NULL); p++) {
+ for(p = alt_path[i]; *p && ((p = strchr_m(p,'/'))!=NULL); p++) {
*p = '\\';
}
/* Remove leading '\\'s */
- p = target;
+ p = alt_path[i];
while (*p && (*p == '\\')) {
p++;
}
@@ -385,7 +256,7 @@ BOOL is_msdfs_link(connection_struct* conn, char * path,
referral[referral_len] = '\0';
DEBUG(5,("is_msdfs_link: %s -> %s\n",path,referral));
- if (parse_symlink(conn, referral, reflistp, refcnt))
+ if (parse_symlink(referral, reflistp, refcnt))
return True;
}
return False;