diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 6 | ||||
-rw-r--r-- | source3/configure.in | 3 | ||||
-rw-r--r-- | source3/modules/vfs_expand_msdfs.c | 184 | ||||
-rw-r--r-- | source3/msdfs/msdfs.c | 139 |
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; |