[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1266-gc1b8eb8

Tim Prouty tprouty at samba.org
Fri Aug 28 17:40:34 MDT 2009


The branch, master has been updated
       via  c1b8eb884b71727fa12f4f62e0261c07b47c943a (commit)
       via  ad88284038104f57e383418e1a0a5abc938b18f6 (commit)
       via  e046b382f24f507a19bfb020b145ea2ec8acafcb (commit)
      from  77e2403f1314a28722f0fb21f6682320b2e9935d (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c1b8eb884b71727fa12f4f62e0261c07b47c943a
Author: Aravind Srinivasan <aravind.srinivasan at isilon.com>
Date:   Wed Aug 26 14:54:58 2009 -0700

    s3: Add catia to the list of modules compiled by default
    
    Signed-off-by: Tim Prouty <tprouty at samba.org>

commit ad88284038104f57e383418e1a0a5abc938b18f6
Author: Aravind Srinivasan <aravind.srinivasan at isilon.com>
Date:   Wed Aug 26 14:55:38 2009 -0700

    s3: Major revamp for catia vfs module
    
    This patch builds out catia to allow fully configurable mappings,
    including mappings from single byte to multi-byte characters.
    Additionally, a much more complete list of vfs operations are now
    covered.
    
    Signed-off-by: Tim Prouty <tprouty at samba.org>

commit e046b382f24f507a19bfb020b145ea2ec8acafcb
Author: Aravind Srinivasan <aravind.srinivasan at isilon.com>
Date:   Wed Aug 26 14:56:09 2009 -0700

    s3: Add a new VFS op called SMB_VFS_TRANSLATE_NAME
    
    This vop is designed to work in tandem with SMB_VFS_READDIR to allow
    vfs modules to make modifications to arbitrary filenames before
    they're consumed by callers.  Subsequently the core directory
    enumeration code in smbd is now changed to free the memory that may be
    allocated in a module.  This vop enables the new version of catia in
    the following patch.
    
    Signed-off-by: Tim Prouty <tprouty at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/configure.in                |    2 +-
 source3/include/proto.h             |    2 +-
 source3/include/vfs.h               |    7 +
 source3/include/vfs_macros.h        |    8 +
 source3/modules/vfs_catia.c         |  982 +++++++++++++++++++++++++++++-----
 source3/modules/vfs_default.c       |   11 +
 source3/modules/vfs_full_audit.c    |   15 +
 source3/modules/vfs_streams_depot.c |    5 +-
 source3/smbd/dir.c                  |   35 +-
 source3/smbd/filename.c             |    6 +-
 source3/smbd/msdfs.c                |    4 +
 source3/smbd/reply.c                |   50 ++-
 source3/smbd/vfs.c                  |   21 +-
 13 files changed, 976 insertions(+), 172 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/configure.in b/source3/configure.in
index 0e7594e..6a4fd08 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -384,7 +384,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
 
 dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen vfs_catia"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho pdb_ads"
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ac0eed2..9314e57 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6216,7 +6216,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
 bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto);
 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
 			const char *name, const char *mask, uint32 attr);
-const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+char *ReadDirName(struct smb_Dir *dirp, long *poffset,
 			SMB_STRUCT_STAT *sbuf);
 void RewindDir(struct smb_Dir *dirp, long *poffset);
 void SeekDir(struct smb_Dir *dirp, long offset);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 38a972f..38d60a0 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -123,6 +123,8 @@
 			   SMB_VFS_RENAME, SMB_VFS_UNLINK, SMB_VFS_NTIMES.  */
 /* Changed to version 27 - not yet released. Added enum timestamp_set_resolution
  * 			   return to fs_capabilities call. JRA. */
+/* Leave at 27 - not yet released. Add translate_name VFS call to convert
+		 UNIX names to Windows supported names -- asrinivasan. */
 #define SMB_VFS_INTERFACE_VERSION 27
 
 
@@ -299,6 +301,9 @@ struct vfs_fn_pointers {
 			      struct files_struct *fsp,
 			      struct lock_struct *plock);
 
+	NTSTATUS (*translate_name)(struct vfs_handle_struct *handle,
+				   char **mapped_name);
+
 	/* NT ACL operations. */
 
 	NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
@@ -644,6 +649,8 @@ bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
 				struct files_struct *fsp,
 				struct lock_struct *plock);
+NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
+				     char **mapped_name);
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
 				  struct files_struct *fsp,
 				  uint32 security_info,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e271cde..7cc5579 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -345,6 +345,14 @@
 #define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
 	smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
 
+#define SMB_VFS_TRANSLATE_NAME(conn, mapped_name) \
+	smb_vfs_call_translate_name((conn)->vfs_handles, (mapped_name))
+#define SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name) \
+	smb_vfs_call_translate_name((handle)->next, (mapped_name))
+
+#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
+	smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
+
 #define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) \
 	smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (ppdesc))
 #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) \
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 112c745..3c1ab81 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -9,6 +9,7 @@
  * under Windows...
  *
  * Copyright (C) Volker Lendecke, 2005
+ * Copyright (C) Aravind Srinivasan, 2009
  *
  * 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
@@ -27,110 +28,290 @@
 
 #include "includes.h"
 
-static char *catia_string_replace(TALLOC_CTX *ctx,
-			const char *s,
-			unsigned char oldc,
-			unsigned char newc)
+#define TO_UNIX    0
+#define TO_WINDOWS 1
+
+#define GLOBAL_SNUM     0xFFFFFFF
+#define MAP_SIZE        0xFF
+#define MAP_NUM         0x101 /* max unicode charval / MAP_SIZE */
+#define T_OFFSET(_v_)   ((_v_ % MAP_SIZE))
+#define T_START(_v_)    (((_v_ / MAP_SIZE) * MAP_SIZE))
+#define T_PICK(_v_)     ((_v_ / MAP_SIZE))
+
+struct char_mappings {
+	smb_ucs2_t entry[MAP_SIZE][2];
+};
+
+struct share_mapping_entry {
+	int snum;
+	struct share_mapping_entry *next;
+	struct char_mappings **mappings;
+};
+
+struct share_mapping_entry *srt_head = NULL;
+
+static bool build_table(struct char_mappings **cmaps, int value)
 {
-	smb_ucs2_t *tmpbuf = NULL;
-	smb_ucs2_t *ptr = NULL;
-	smb_ucs2_t old = oldc;
-	char *ret = NULL;
-	size_t converted_size;
+	int i;
+	int start = T_START(value);
 
-	if (!s) {
-		return NULL;
+	(*cmaps) = (struct char_mappings *)
+			TALLOC_ZERO(NULL, sizeof(struct char_mappings));
+
+	if (!*cmaps)
+		return False;
+
+	for (i = 0; i <= MAP_SIZE;i++) {
+		(*cmaps)->entry[i][TO_UNIX] = start + i;
+		(*cmaps)->entry[i][TO_WINDOWS] = start + i;
 	}
 
-	if (!push_ucs2_talloc(ctx, &tmpbuf, s, &converted_size)) {
-		return NULL;
+	return True;
+}
+
+static void set_tables(struct char_mappings **cmaps,
+		       long unix_map,
+		       long windows_map)
+{
+	int i;
+
+	/* set unix -> windows */
+	i = T_OFFSET(unix_map);
+	cmaps[T_PICK(unix_map)]->entry[i][TO_WINDOWS] = windows_map;
+
+	/* set windows -> unix */
+	i = T_OFFSET(windows_map);
+	cmaps[T_PICK(windows_map)]->entry[i][TO_UNIX] = unix_map;
+}
+
+static bool build_ranges(struct char_mappings **cmaps,
+			 long unix_map,
+			 long windows_map)
+{
+
+	if (!cmaps[T_PICK(unix_map)]) {
+		if (!build_table(&cmaps[T_PICK(unix_map)], unix_map))
+			return False;
 	}
 
-	ptr = tmpbuf;
+	if (!cmaps[T_PICK(windows_map)]) {
+		if (!build_table(&cmaps[T_PICK(windows_map)], windows_map))
+			return False;
+	}
 
-	for (;*ptr;ptr++) {
-		if (*ptr==old) {
-			*ptr=newc;
-		}
+	set_tables(cmaps, unix_map, windows_map);
+
+	return True;
+}
+
+struct share_mapping_entry *get_srt(connection_struct *conn,
+				    struct share_mapping_entry **global)
+{
+	struct share_mapping_entry *share;
+
+	for (share = srt_head; share != NULL; share = share->next) {
+		if (share->snum == GLOBAL_SNUM)
+			(*global) = share;
+
+		if (share->snum == SNUM(conn))
+			return share;
 	}
 
-	if (!pull_ucs2_talloc(ctx, &ret, tmpbuf, &converted_size)) {
-		TALLOC_FREE(tmpbuf);
-		return NULL;
+	return share;
+}
+
+struct share_mapping_entry *add_srt(int snum, const char **mappings)
+{
+
+	char *tmp;
+	fstring mapping;
+	int i;
+	long unix_map, windows_map;
+	struct share_mapping_entry *ret = NULL;
+
+	ret = (struct share_mapping_entry *)
+		TALLOC_ZERO(NULL, sizeof(struct share_mapping_entry) +
+		(mappings ? (MAP_NUM * sizeof(struct char_mappings *)) : 0));
+
+	if (!ret)
+		return ret;
+
+	ret->snum = snum;
+
+	if (mappings) {
+		ret->mappings = (struct char_mappings**) ((unsigned char*) ret +
+		    sizeof(struct share_mapping_entry));
+		memset(ret->mappings, 0,
+		    MAP_NUM * sizeof(struct char_mappings *));
+	} else {
+		ret->mappings = NULL;
+		return ret;
 	}
-	TALLOC_FREE(tmpbuf);
+
+	/*
+	 * catia mappings are of the form :
+	 * UNIX char (in 0xnn hex) : WINDOWS char (in 0xnn hex)
+	 *
+	 * multiple mappings are comma seperated in smb.conf
+	 */
+	for (i=0;mappings[i];i++) {
+		fstrcpy(mapping, mappings[i]);
+		unix_map = strtol(mapping, &tmp, 16);
+		if (unix_map == 0 && errno == EINVAL) {
+			DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
+			continue;
+		}
+		windows_map = strtol(++tmp, NULL, 16);
+		if (windows_map == 0 && errno == EINVAL) {
+			DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
+			continue;
+		}
+
+		if (!build_ranges(ret->mappings, unix_map, windows_map)) {
+			DEBUG(0, ("TABLE ERROR - CATIA MAPPINGS - %s\n", mapping));
+			continue;
+		}
+	}
+
+	ret->next = srt_head;
+	srt_head = ret;
+
 	return ret;
 }
 
-static char *from_unix(TALLOC_CTX *ctx, const char *s)
+static bool init_mappings(connection_struct *conn,
+			  struct share_mapping_entry **selected_out)
 {
-	char *ret = catia_string_replace(ctx, s, '\x22', '\xa8');
-	ret = catia_string_replace(ctx, ret, '\x2a', '\xa4');
-	ret = catia_string_replace(ctx, ret, '\x2f', '\xf8');
-	ret = catia_string_replace(ctx, ret, '\x3a', '\xf7');
-	ret = catia_string_replace(ctx, ret, '\x3c', '\xab');
-	ret = catia_string_replace(ctx, ret, '\x3e', '\xbb');
-	ret = catia_string_replace(ctx, ret, '\x3f', '\xbf');
-	ret = catia_string_replace(ctx, ret, '\x5c', '\xff');
-	ret = catia_string_replace(ctx, ret, '\x7c', '\xa6');
-	return catia_string_replace(ctx, ret, ' ', '\xb1');
+	const char **mappings = NULL;
+	struct share_mapping_entry *share_level = NULL;
+	struct share_mapping_entry *global = NULL;
+
+	/* check srt cache */
+	share_level = get_srt(conn, &global);
+	if (share_level) {
+		*selected_out = share_level;
+		return (share_level->mappings != NULL);
+	}
+
+	/* see if we have a global setting */
+	if (!global) {
+		/* global setting */
+		mappings = lp_parm_string_list(-1, "catia", "mappings", NULL);
+		global = add_srt(GLOBAL_SNUM, mappings);
+	}
+
+	/* no global setting - what about share level ? */
+	mappings = lp_parm_string_list(SNUM(conn), "catia", "mappings", NULL);
+	share_level = add_srt(SNUM(conn), mappings);
+
+	if (share_level->mappings) {
+		(*selected_out) = share_level;
+		return True;
+	} else if (global->mappings) {
+		share_level->mappings = global->mappings;
+		(*selected_out) = share_level;
+		return True;
+	}
+
+	return False;
 }
 
-static char *to_unix(TALLOC_CTX *ctx, const char *s)
+static NTSTATUS catia_string_replace_allocate(connection_struct *conn,
+					      const char *name_in,
+					      char **mapped_name,
+					      int direction)
 {
-	char *ret = catia_string_replace(ctx, s, '\xa8', '\x22');
-	ret = catia_string_replace(ctx, ret, '\xa4', '\x2a');
-	ret = catia_string_replace(ctx, ret, '\xf8', '\x2f');
-	ret = catia_string_replace(ctx, ret, '\xf7', '\x3a');
-	ret = catia_string_replace(ctx, ret, '\xab', '\x3c');
-	ret = catia_string_replace(ctx, ret, '\xbb', '\x3e');
-	ret = catia_string_replace(ctx, ret, '\xbf', '\x3f');
-	ret = catia_string_replace(ctx, ret, '\xff', '\x5c');
-	ret = catia_string_replace(ctx, ret, '\xa6', '\x7c');
-	return catia_string_replace(ctx, ret, '\xb1', ' ');
+	static smb_ucs2_t *tmpbuf = NULL;
+	smb_ucs2_t *ptr;
+	struct share_mapping_entry *selected;
+	struct char_mappings *map = NULL;
+	size_t converted_size;
+	TALLOC_CTX *ctx = talloc_tos();
+
+	if (!init_mappings(conn, &selected))
+		return NT_STATUS_OK;
+
+	if ((push_ucs2_talloc(ctx, &tmpbuf, name_in,
+			      &converted_size)) == -1) {
+		return map_nt_error_from_unix(errno);
+	}
+	ptr = tmpbuf;
+	for(;*ptr;ptr++) {
+		if (*ptr == 0)
+			break;
+		map = selected->mappings[T_PICK((*ptr))];
+
+		/* nothing to do */
+		if (!map)
+			continue;
+
+		*ptr = map->entry[T_OFFSET((*ptr))][direction];
+	}
+
+	if ((pull_ucs2_talloc(ctx, mapped_name, tmpbuf,
+			      &converted_size)) == -1) {
+		TALLOC_FREE(tmpbuf);
+		return map_nt_error_from_unix(errno);
+	}
+	TALLOC_FREE(tmpbuf);
+	return NT_STATUS_OK;
 }
 
 static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
-			  const char *fname, const char *mask, uint32 attr)
+				     const char *fname,
+				     const char *mask,
+				     uint32 attr)
 {
-	char *name = to_unix(talloc_tos(), fname);
+	char *name_mapped = NULL;
+	NTSTATUS status;
+	SMB_STRUCT_DIR *ret;
 
-	if (!name) {
-		errno = ENOMEM;
+	status = catia_string_replace_allocate(handle->conn, fname,
+					&name_mapped, TO_UNIX);
+	if (!NT_STATUS_IS_OK(status)) {
+		errno = map_errno_from_nt_status(status);
 		return NULL;
 	}
-        return SMB_VFS_NEXT_OPENDIR(handle, name, mask, attr);
+
+	ret = SMB_VFS_NEXT_OPENDIR(handle, name_mapped, mask, attr);
+	TALLOC_FREE(name_mapped);
+
+	return ret;
 }
 
-static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
-					SMB_STRUCT_DIR *dirp,
-					SMB_STRUCT_STAT *sbuf)
+/*
+ * TRANSLATE_NAME call which converts the given name to
+ * "WINDOWS displayable" name
+ */
+static NTSTATUS catia_translate_name(vfs_handle_struct *handle,
+				     char **mapped_name)
 {
-	SMB_STRUCT_DIRENT *result = NULL;
-	SMB_STRUCT_DIRENT *newdirent = NULL;
-	char *newname;
-	size_t newnamelen;
+	char *name = NULL;
+	NTSTATUS ret;
 
-	result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
-	if (result == NULL) {
-		return result;
+	/*
+	 * Copy the supplied name and free the memory for mapped_name,
+	 * already allocated by the caller.
+	 * We will be allocating new memory for mapped_name in
+	 * catia_string_replace_allocate
+	 */
+	name = talloc_strdup(talloc_tos(), *mapped_name);
+	if (!name) {
+		errno = ENOMEM;
+		return NT_STATUS_NO_MEMORY;
 	}
+	TALLOC_FREE(*mapped_name);
+	ret = catia_string_replace_allocate(handle->conn, name,
+			mapped_name, TO_WINDOWS);
 
-	newname = from_unix(talloc_tos(), result->d_name);
-	if (!newname) {
-		return NULL;
-	}
-	newnamelen = strlen(newname)+1;
-	newdirent = (SMB_STRUCT_DIRENT *)TALLOC_ARRAY(talloc_tos(),
-						char,
-						sizeof(SMB_STRUCT_DIRENT)+
-							newnamelen);
-	if (!newdirent) {
-		return NULL;
+	TALLOC_FREE(name);
+	if (!NT_STATUS_IS_OK(ret)) {
+		return ret;
 	}
-	memcpy(newdirent, result, sizeof(SMB_STRUCT_DIRENT));
-	memcpy(&newdirent->d_name, newname, newnamelen);
-	return newdirent;
+
+	ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name);
+
+	return ret;
 }
 
 static int catia_open(vfs_handle_struct *handle,
@@ -139,23 +320,69 @@ static int catia_open(vfs_handle_struct *handle,
 		      int flags,
 		      mode_t mode)
 {
-	char *name;
+	char *name_mapped = NULL;
 	char *tmp_base_name;
 	int ret;
+	NTSTATUS status;
 
-	name = to_unix(talloc_tos(), smb_fname->base_name);
-	if (!name) {
-		errno = ENOMEM;
+	tmp_base_name = smb_fname->base_name;
+	status = catia_string_replace_allocate(handle->conn,
+					smb_fname->base_name,
+					&name_mapped, TO_UNIX);
+	if (!NT_STATUS_IS_OK(status)) {
+		errno = map_errno_from_nt_status(status);
 		return -1;
 	}
 
-	tmp_base_name = smb_fname->base_name;
-	smb_fname->base_name = name;
-
+	smb_fname->base_name = name_mapped;
 	ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+	smb_fname->base_name = tmp_base_name;
+	TALLOC_FREE(name_mapped);
+
+	return ret;
+}
+
+/* @internal - Isilon create file support */
+static NTSTATUS catia_createfile(vfs_handle_struct *handle,
+				 struct smb_request *req,
+				 uint16_t root_dir_fid,
+				 struct smb_filename *smb_fname,
+				 uint32_t access_mask,
+				 uint32_t share_access,
+				 uint32_t create_disposition,
+				 uint32_t create_options,
+				 uint32_t file_attributes,
+				 uint32_t oplock_request,
+				 uint64_t allocation_size,
+				 struct security_descriptor *sd,
+				 struct ea_list *ea_list,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list