Move the Client-IP based msdfs target expansion to a VFS module.
authorVolker Lendecke <vlendec@samba.org>
Fri, 26 Mar 2004 22:26:33 +0000 (22:26 +0000)
committerVolker Lendecke <vlendec@samba.org>
Fri, 26 Mar 2004 22:26:33 +0000 (22:26 +0000)
Volker
(This used to be commit 9cb6a4d76f87b28077861d3f4220541fbf704ddf)

source3/Makefile.in
source3/configure.in
source3/modules/vfs_expand_msdfs.c [new file with mode: 0644]
source3/msdfs/msdfs.c

index daa626af573646855405b2e29cf28fd186ec2eb8..9a054a0a3a435afbc3f7cf255123c9923819e885 100644 (file)
@@ -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@
index f92ea2d080682e4f182378505d22e5670900f28a..59b1d062f63e477e413538f88a5fef5ab0311988 100644 (file)
@@ -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 (file)
index 0000000..954f28a
--- /dev/null
@@ -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);
+}
index 340e5c6750ad8167ac389443fffd7e2541d2b176..2ac7bda17547631f1b477910d97eab91b2a60fa1 100644 (file)
@@ -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;