Work in progress.
Jeremy Allison
jra at samba.org
Wed Sep 5 19:38:02 GMT 2007
Work in progress, part2. Still doesn't fully compile but getting
better. Shows the new (sane) mangling interface.
Jeremy.
-------------- next part --------------
Index: Makefile.in
===================================================================
--- Makefile.in (revision 24970)
+++ Makefile.in (working copy)
@@ -511,7 +511,7 @@
auth/auth_compat.o auth/auth_ntlmssp.o \
$(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
-MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
+MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_hash2.o
SMBD_OBJ_MAIN = smbd/server.o
Index: smbd/mangle_hash.c
===================================================================
--- smbd/mangle_hash.c (revision 24970)
+++ smbd/mangle_hash.c (working copy)
@@ -1,20 +1,21 @@
-/*
+/*
Unix SMB/CIFS implementation.
Name mangling
Copyright (C) Andrew Tridgell 1992-2002
Copyright (C) Simo Sorce 2001
Copyright (C) Andrew Bartlett 2002
-
+ Copyright (C) Jeremy Allison 2007
+
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/>.
*/
@@ -244,14 +245,14 @@
if (strlen_w(fname) > 12)
return NT_STATUS_UNSUCCESSFUL;
-
+
if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
return NT_STATUS_OK;
/* Name cannot start with '.' */
if (*fname == UCS2_CHAR('.'))
return NT_STATUS_UNSUCCESSFUL;
-
+
if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
goto done;
@@ -293,7 +294,7 @@
if (strlen(f) > 12)
return False;
-
+
size = push_ucs2_allocate(&ucs2name, f);
if (size == (size_t)-1) {
DEBUG(0,("is_8_3: internal error push_ucs2_allocate() failed!\n"));
@@ -305,15 +306,13 @@
done:
SAFE_FREE(ucs2name);
- if (!NT_STATUS_IS_OK(ret)) {
+ if (!NT_STATUS_IS_OK(ret)) {
return False;
}
-
+
return True;
}
-
-
/* -------------------------------------------------------------------------- **
* Functions...
*/
@@ -330,10 +329,11 @@
*
* ************************************************************************** **
*/
+
static void init_chartest( void )
{
const unsigned char *s;
-
+
memset( (char *)chartest, '\0', 256 );
for( s = (const unsigned char *)basechars; *s; s++ ) {
@@ -360,6 +360,7 @@
*
* ************************************************************************** **
*/
+
static BOOL is_mangled(const char *s, const struct share_params *p)
{
char *magic;
@@ -406,7 +407,8 @@
crh 07-Apr-1998
**************************************************************************/
-static void cache_mangled_name( const char mangled_name[13], char *raw_name )
+static void cache_mangled_name( const char mangled_name[13],
+ const char *raw_name )
{
TDB_DATA data_val;
char mangled_name_key[13];
@@ -459,30 +461,37 @@
* ************************************************************************** **
*/
-static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p )
+static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx,
+ const char *in,
+ char **out, /* talloced on the given context. */
+ const struct share_params *p)
{
TDB_DATA data_val;
- char *ext_start = NULL;
char *saved_ext = NULL;
+ char *s = talloc_strdup(ctx, in);
magic_char = lp_magicchar(p);
/* If the cache isn't initialized, give up. */
- if( !tdb_mangled_cache )
- return( False );
+ if(!s || !tdb_mangled_cache ) {
+ TALLOC_FREE(s);
+ return False;
+ }
data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
/* If we didn't find the name *with* the extension, try without. */
if(data_val.dptr == NULL || data_val.dsize == 0) {
- ext_start = strrchr( s, '.' );
+ char *ext_start = strrchr( s, '.' );
if( ext_start ) {
- if((saved_ext = SMB_STRDUP(ext_start)) == NULL)
+ if((saved_ext = talloc_strdup(ctx,ext_start)) == NULL) {
+ TALLOC_FREE(s);
return False;
+ }
*ext_start = '\0';
data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
- /*
+ /*
* At this point s is the name without the
* extension. We re-add the extension if saved_ext
* is not null, before freeing saved_ext.
@@ -492,31 +501,32 @@
/* Okay, if we haven't found it we're done. */
if(data_val.dptr == NULL || data_val.dsize == 0) {
- if(saved_ext) {
- /* Replace the saved_ext as it was truncated. */
- (void)safe_strcat( s, saved_ext, maxlen );
- SAFE_FREE(saved_ext);
- }
- return( False );
+ TALLOC_FREE(saved_ext);
+ TALLOC_FREE(s);
+ return False;
}
- /* If we *did* find it, we need to copy it into the string buffer. */
- (void)safe_strcpy( s, (const char *)data_val.dptr, maxlen );
- if( saved_ext ) {
- /* Replace the saved_ext as it was truncated. */
- (void)safe_strcat( s, saved_ext, maxlen );
- SAFE_FREE(saved_ext);
+ /* If we *did* find it, we need to talloc it on the given ctx. */
+ if (saved_ext) {
+ *out = talloc_asprintf(ctx, "%s%s",
+ (char *)data_val.dptr,
+ saved_ext);
+ } else {
+ *out = talloc_strdup(ctx, (char *)data_val.dptr);
}
+
+ TALLOC_FREE(s);
+ TALLOC_FREE(saved_ext);
SAFE_FREE(data_val.dptr);
- return( True );
+
+ return *out ? True : False;
}
/*****************************************************************************
- * do the actual mangling to 8.3 format
- * the buffer must be able to hold 13 characters (including the null)
- *****************************************************************************
- */
-static void to_8_3(char *s, int default_case)
+ Do the actual mangling to 8.3 format.
+*****************************************************************************/
+
+static BOOL to_8_3(const char *in, char out[13], int default_case)
{
int csum;
char *p;
@@ -524,11 +534,16 @@
char base[9];
int baselen = 0;
int extlen = 0;
+ char *s = SMB_STRDUP(in);
extension[0] = 0;
base[0] = 0;
- p = strrchr(s,'.');
+ if (!s) {
+ return False;
+ }
+
+ p = strrchr(s,'.');
if( p && (strlen(p+1) < (size_t)4) ) {
BOOL all_normal = ( strisnormal(p+1, default_case) ); /* XXXXXXXXX */
@@ -557,7 +572,7 @@
extension[extlen] = 0;
}
}
-
+
p = s;
while( *p && baselen < 5 ) {
@@ -567,79 +582,88 @@
p++;
}
base[baselen] = 0;
-
+
csum = csum % (MANGLE_BASE*MANGLE_BASE);
-
- (void)slprintf(s, 12, "%s%c%c%c",
- base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
-
+
+ memcpy(out, base, baselen);
+ out[baselen] = magic_char;
+ out[baselen+1] = mangle( csum/MANGLE_BASE );
+ out[baselen+2] = mangle( csum );
+
if( *extension ) {
- (void)pstrcat( s, "." );
- (void)pstrcat( s, extension );
+ out[baselen+3] = '.';
+ safe_strcpy(&out[baselen+4], extension, 3);
}
+
+ SAFE_FREE(s);
+ return True;
}
+static BOOL must_mangle(const char *name,
+ const struct share_params *p)
+{
+ smb_ucs2_t *name_ucs2 = NULL;
+ NTSTATUS status;
+ magic_char = lp_magicchar(p);
+
+ if (push_ucs2_allocate(&name_ucs2, name) == (size_t)-1) {
+ DEBUG(0, ("push_ucs2_allocate failed!\n"));
+ return False;
+ }
+ status = is_valid_name(name_ucs2, False, False);
+ SAFE_FREE(name_ucs2);
+ return NT_STATUS_IS_OK(status);
+}
+
/*****************************************************************************
* Convert a filename to DOS format. Return True if successful.
+ * Input: in Incoming name.
*
- * Input: OutName - Source *and* destination buffer.
+ * out 8.3 DOS name.
*
- * NOTE that OutName must point to a memory space that
- * is at least 13 bytes in size!
- *
- * need83 - If False, name mangling will be skipped unless the
- * name contains illegal characters. Mapping will still
- * be done, if appropriate. This is probably used to
- * signal that a client does not require name mangling,
- * thus skipping the name mangling even on shares which
- * have name-mangling turned on.
* cache83 - If False, the mangled name cache will not be updated.
* This is usually used to prevent that we overwrite
* a conflicting cache entry prematurely, i.e. before
* we know whether the client is really interested in the
* current name. (See PR#13758). UKD.
*
- * Output: Returns False only if the name wanted mangling but the share does
- * not have name mangling turned on.
- *
* ****************************************************************************
*/
-static void name_map(char *OutName, BOOL need83, BOOL cache83,
- int default_case, const struct share_params *p)
+static BOOL hash_name_to_8_3(const char *in,
+ char out[13],
+ BOOL cache83,
+ int default_case,
+ const struct share_params *p)
{
- smb_ucs2_t *OutName_ucs2;
+ smb_ucs2_t *in_ucs2 = NULL;
magic_char = lp_magicchar(p);
- DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName,
- need83 ? "True" : "False", cache83 ? "True" : "False"));
-
- if (push_ucs2_allocate(&OutName_ucs2, OutName) == (size_t)-1) {
+ DEBUG(5,("hash_name_to_8_3( %s, cache83 = %s)\n", in,
+ cache83 ? "True" : "False"));
+
+ if (push_ucs2_allocate(&in_ucs2, in) == (size_t)-1) {
DEBUG(0, ("push_ucs2_allocate failed!\n"));
- return;
+ return False;
}
- if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False)))
- need83 = True;
+ /* If it's already 8.3, just copy. */
+ if (NT_STATUS_IS_OK(is_valid_name(in_ucs2, False, False)) &&
+ NT_STATUS_IS_OK(is_8_3_w(in_ucs2, False))) {
+ SAFE_FREE(in_ucs2);
+ safe_strcpy(out, in, 12);
+ return True;
+ }
- /* check if it's already in 8.3 format */
- if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2, False))) {
- char *tmp = NULL;
+ SAFE_FREE(in_ucs2);
+ if (!to_8_3(in, out, default_case)) {
+ return False;
+ }
- /* mangle it into 8.3 */
- if (cache83)
- tmp = SMB_STRDUP(OutName);
+ cache_mangled_name(out, in);
- to_8_3(OutName, default_case);
-
- if(tmp != NULL) {
- cache_mangled_name(OutName, tmp);
- SAFE_FREE(tmp);
- }
- }
-
- DEBUG(5,("name_map() ==> [%s]\n", OutName));
- SAFE_FREE(OutName_ucs2);
+ DEBUG(5,("hash_name_to_8_3(%s) ==> [%s]\n", in, out));
+ return True;
}
/*
@@ -649,9 +673,10 @@
static struct mangle_fns mangle_fns = {
mangle_reset,
is_mangled,
+ must_mangle,
is_8_3,
- check_cache,
- name_map
+ lookup_name_from_8_3,
+ hash_name_to_8_3
};
/* return the methods for this mangling implementation */
Index: smbd/mangle_hash2.c
===================================================================
--- smbd/mangle_hash2.c (revision 24970)
+++ smbd/mangle_hash2.c (working copy)
@@ -368,18 +368,23 @@
/*
try to find a 8.3 name in the cache, and if found then
- replace the string with the original long name.
+ replace the string with the original long name.
*/
-static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
+static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx,
+ const char *name,
+ char **pp_out, /* talloced on the given context. */
+ const struct share_params *p)
{
unsigned int hash, multiplier;
unsigned int i;
const char *prefix;
char extension[4];
+ *pp_out = NULL;
+
/* make sure that this is a mangled name from this cache */
if (!is_mangled(name, p)) {
- M_DEBUG(10,("check_cache: %s -> not mangled\n", name));
+ M_DEBUG(10,("lookup_name_from_8_3: %s -> not mangled\n", name));
return False;
}
@@ -394,7 +399,8 @@
/* now look in the prefix cache for that hash */
prefix = cache_lookup(hash);
if (!prefix) {
- M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
+ M_DEBUG(10,("lookup_name_from_8_3: %s -> %08X -> not found\n",
+ name, hash));
return False;
}
@@ -407,17 +413,22 @@
}
if (extension[0]) {
- M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
- slprintf(name, maxlen, "%s.%s", prefix, extension);
+ M_DEBUG(10,("lookup_name_from_8_3: %s -> %s.%s\n",
+ name, prefix, extension));
+ *pp_out = talloc_asprintf(ctx, "%s.%s", prefix, extension);
} else {
- M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
- safe_strcpy(name, prefix, maxlen);
+ M_DEBUG(10,("lookup_name_from_8_3: %s -> %s\n", name, prefix));
+ *pp_out = talloc_strdup(ctx, prefix);
}
+ if (!pp_out) {
+ M_DEBUG(0,("talloc_fail"));
+ return False;
+ }
+
return True;
}
-
/*
look for a DOS reserved name
*/
@@ -499,18 +510,27 @@
return True;
}
+static BOOL must_mangle(const char *name,
+ const struct share_params *p)
+{
+ if (is_reserved_name(name)) {
+ return True;
+ }
+ return !is_legal_name(name);
+}
+
/*
the main forward mapping function, which converts a long filename to
a 8.3 name
- if need83 is not set then we only do the mangling if the name is illegal
- as a long name
-
if cache83 is not set then we don't cache the result
- the name parameter must be able to hold 13 bytes
*/
-static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
+static BOOL hash2_name_to_8_3(const char *name,
+ char new_name[13],
+ BOOL cache83,
+ int default_case,
+ const struct share_params *p)
{
char *dot_p;
char lead_chars[7];
@@ -518,21 +538,15 @@
unsigned int extension_length, i;
unsigned int prefix_len;
unsigned int hash, v;
- char new_name[13];
/* reserved names are handled specially */
if (!is_reserved_name(name)) {
- /* if the name is already a valid 8.3 name then we don't need to
- do anything */
- if (is_8_3(name, False, False, p)) {
- return;
+ /* if the name is already a valid 8.3 name then we don't need to
+ * change anything */
+ if (is_legal_name(name) && is_8_3(name, False, False, p)) {
+ safe_strcpy(new_name, name, 12);
+ return True;
}
-
- /* if the caller doesn't strictly need 8.3 then just check for illegal
- filenames */
- if (!need83 && is_legal_name(name)) {
- return;
- }
}
/* find the '.' if any */
@@ -548,7 +562,9 @@
break;
}
}
- if (i == 0 || i == 4) dot_p = NULL;
+ if (i == 0 || i == 4) {
+ dot_p = NULL;
+ }
}
/* the leading characters in the mangled name is taken from
@@ -580,11 +596,12 @@
for (i=1; extension_length < 3 && dot_p[i]; i++) {
char c = dot_p[i];
if (FLAG_CHECK(c, FLAG_ASCII)) {
- extension[extension_length++] = toupper_ascii(c);
+ extension[extension_length++] =
+ toupper_ascii(c);
}
}
}
-
+
/* find the hash for this prefix */
v = hash = mangle_hash(name, prefix_len);
@@ -593,7 +610,7 @@
new_name[i] = lead_chars[i];
}
new_name[7] = base_forward(v % 36);
- new_name[6] = '~';
+ new_name[6] = '~';
for (i=5; i>=mangle_prefix; i--) {
v = v / 36;
new_name[i] = base_forward(v % 36);
@@ -613,22 +630,18 @@
cache_insert(name, prefix_len, hash);
}
- M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n",
+ M_DEBUG(10,("hash2_name_to_8_3: %s -> %08X -> %s (cache=%d)\n",
name, hash, new_name, cache83));
- /* and overwrite the old name */
- fstrcpy(name, new_name);
-
- /* all done, we've managed to mangle it */
+ return True;
}
+/* initialise the flags table
-/* initialise the flags table
-
we allow only a very restricted set of characters as 'ascii' in this
mangling backend. This isn't a significant problem as modern clients
use the 'long' filenames anyway, and those don't have these
- restrictions.
+ restrictions.
*/
static void init_tables(void)
{
@@ -642,8 +655,8 @@
char_flags[i] |= FLAG_ILLEGAL;
}
- if ((i >= '0' && i <= '9') ||
- (i >= 'a' && i <= 'z') ||
+ if ((i >= '0' && i <= '9') ||
+ (i >= 'a' && i <= 'z') ||
(i >= 'A' && i <= 'Z')) {
char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR);
}
@@ -663,7 +676,7 @@
memset(base_reverse, 0, sizeof(base_reverse));
for (i=0;i<36;i++) {
base_reverse[(unsigned char)base_forward(i)] = i;
- }
+ }
/* fill in the reserved names flags. These are used as a very
fast filter for finding possible DOS reserved filenames */
@@ -694,9 +707,10 @@
static struct mangle_fns mangle_fns = {
mangle_reset,
is_mangled,
+ must_mangle,
is_8_3,
- check_cache,
- name_map
+ lookup_name_from_8_3,
+ hash2_name_to_8_3
};
/* return the methods for this mangling implementation */
@@ -729,30 +743,45 @@
return False;
}
-static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p)
+static BOOL posix_must_mangle(const char *s, const struct share_params *p)
{
return False;
}
-static BOOL posix_check_cache( char *s, size_t maxlen, const struct share_params *p )
+static BOOL posix_is_8_3(const char *fname,
+ BOOL check_case,
+ BOOL allow_wildcards,
+ const struct share_params *p)
{
return False;
}
-static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
+static BOOL posix_lookup_name_from_8_3(TALLOC_CTX *ctx,
+ const char *in,
+ char **out, /* talloced on the given context. */
+ const struct share_params *p)
{
- if (need83) {
- memset(OutName, '\0', 13);
- }
+ return False;
}
+static BOOL posix_name_to_8_3(const char *in,
+ char out[13],
+ BOOL cache83,
+ int default_case,
+ const struct share_params *p)
+{
+ memset(out, '\0', 13);
+ return True;
+}
+
/* POSIX paths backend - no mangle. */
static struct mangle_fns posix_mangle_fns = {
- posix_mangle_reset,
- posix_is_mangled,
- posix_is_8_3,
- posix_check_cache,
- posix_name_map
+ posix_mangle_reset,
+ posix_is_mangled,
+ posix_must_mangle,
+ posix_is_8_3,
+ posix_lookup_name_from_8_3,
+ posix_name_to_8_3
};
struct mangle_fns *posix_mangle_init(void)
Index: smbd/reply.c
===================================================================
--- smbd/reply.c (revision 24970)
+++ smbd/reply.c (working copy)
@@ -2302,7 +2302,7 @@
*/
if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params))
- mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+ mangle_lookup_name_from_8_3( mask, sizeof(pstring)-1, conn->params );
if (!has_wild) {
pstrcat(directory,"/");
@@ -5351,7 +5351,7 @@
*/
if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
- mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+ mangle_lookup_name_from_8_3( mask, sizeof(pstring)-1, conn->params );
}
if (!src_has_wild) {
@@ -5900,7 +5900,7 @@
*/
if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
- mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+ mangle_lookup_name_from_8_3( mask, sizeof(pstring)-1, conn->params );
}
if (!source_has_wild) {
Index: smbd/statcache.c
===================================================================
--- smbd/statcache.c (revision 24970)
+++ smbd/statcache.c (working copy)
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
stat cache code
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 1999-2004
+ Copyright (C) Jeremy Allison 1999-2007
Copyright (C) Andrew Bartlett <abartlet at samba.org> 2003
Copyright (C) Volker Lendecke 2007
@@ -48,9 +48,11 @@
char *original_path;
size_t original_path_length;
size_t sc_size = lp_max_stat_cache_size();
+ TALLOC_CTX *ctx = talloc_tos();
- if (!lp_stat_cache())
+ if (!lp_stat_cache()) {
return;
+ }
if (sc_size && (tdb_map_size(tdb_stat_cache) > sc_size*1024)) {
reset_stat_cache();
@@ -73,8 +75,9 @@
* would be a waste.
*/
- if (case_sensitive && (strcmp(full_orig_name, translated_path) == 0))
+ if (case_sensitive && (strcmp(full_orig_name, translated_path) == 0)) {
return;
+ }
/*
* Remove any trailing '/' characters from the
@@ -94,9 +97,9 @@
}
if(case_sensitive) {
- original_path = SMB_STRDUP(full_orig_name);
+ original_path = talloc_strdup(ctx,full_orig_name);
} else {
- original_path = strdup_upper(full_orig_name);
+ original_path = talloc_strdup_upper(ctx,full_orig_name);
}
if (!original_path) {
@@ -118,7 +121,7 @@
(unsigned long)original_path_length,
translated_path,
(unsigned long)translated_path_length));
- SAFE_FREE(original_path);
+ TALLOC_FREE(original_path);
return;
}
@@ -148,7 +151,7 @@
translated_path));
}
- SAFE_FREE(original_path);
+ TALLOC_FREE(original_path);
}
/**
@@ -179,9 +182,11 @@
size_t translated_path_length;
TDB_DATA data_val;
char *name;
+ TALLOC_CTX *ctx = talloc_tos();
- if (!lp_stat_cache())
+ if (!lp_stat_cache()) {
return False;
+ }
name = *pname;
namelen = strlen(name);
@@ -198,14 +203,14 @@
}
if (conn->case_sensitive) {
- chk_name = SMB_STRDUP(name);
+ chk_name = talloc_strdup(ctx,name);
if (!chk_name) {
DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
return False;
}
} else {
- chk_name = strdup_upper(name);
+ chk_name = talloc_strdup_upper(ctx,name);
if (!chk_name) {
DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n"));
return False;
@@ -239,7 +244,7 @@
* We reached the end of the name - no match.
*/
DO_PROFILE_INC(statcache_misses);
- SAFE_FREE(chk_name);
+ TALLOC_FREE(chk_name);
return False;
}
@@ -255,7 +260,7 @@
if ((*chk_name == '\0')
|| ISDOT(chk_name) || ISDOTDOT(chk_name)) {
DO_PROFILE_INC(statcache_misses);
- SAFE_FREE(chk_name);
+ TALLOC_FREE(chk_name);
return False;
}
}
@@ -276,7 +281,7 @@
if (SMB_VFS_STAT(conn, translated_path, pst) != 0) {
/* Discard this entry - it doesn't exist in the filesystem. */
tdb_delete_bystring(tdb_stat_cache, chk_name);
- SAFE_FREE(chk_name);
+ TALLOC_FREE(chk_name);
SAFE_FREE(data_val.dptr);
return False;
}
@@ -287,28 +292,29 @@
}
else {
if (num_components == 0) {
- name = SMB_STRNDUP(translated_path,
+ name = talloc_strndup(ctx, translated_path,
translated_path_length);
} else {
char *sp;
sp = strnrchr_m(name, '/', num_components);
if (sp) {
- asprintf(&name, "%.*s%s",
+ name = talloc_asprintf(ctx,"%.*s%s",
(int)translated_path_length,
translated_path, sp);
} else {
- name = SMB_STRNDUP(translated_path,
- translated_path_length);
+ name = talloc_strndup(ctx,
+ translated_path,
+ translated_path_length);
}
}
if (name == NULL) {
/*
* TODO: Get us out of here with a real error message
*/
- smb_panic("malloc failed");
+ smb_panic("talloc failed");
}
- SAFE_FREE(*pname);
+ TALLOC_FREE(*pname);
*pname = name;
}
@@ -319,7 +325,7 @@
++*start;
*dirpath = translated_path;
- SAFE_FREE(chk_name);
+ TALLOC_FREE(chk_name);
return (namelen == translated_path_length);
}
@@ -344,7 +350,7 @@
void stat_cache_delete(const char *name)
{
- char *lname = strdup_upper(name);
+ char *lname = talloc_strdup_upper(talloc_tos(), name);
if (!lname) {
return;
@@ -353,7 +359,7 @@
lname, name ));
tdb_delete_bystring(tdb_stat_cache, lname);
- SAFE_FREE(lname);
+ TALLOC_FREE(lname);
}
/***************************************************************
Index: smbd/mangle.c
===================================================================
--- smbd/mangle.c (revision 24970)
+++ smbd/mangle.c (working copy)
@@ -1,18 +1,18 @@
-/*
+/*
Unix SMB/CIFS implementation.
Name mangling interface
Copyright (C) Andrew Tridgell 2002
-
+
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/>.
*/
@@ -100,50 +100,51 @@
return mangle_fns->is_8_3(fname, check_case, True, p);
}
+BOOL mangle_must_mangle(const char *fname,
+ const struct share_params *p)
+{
+ if (!lp_manglednames(p)) {
+ return False;
+ }
+ return mangle_fns->must_mangle(fname, p);
+}
+
/*
- try to reverse map a 8.3 name to the original filename. This doesn't have to
+ try to reverse map a 8.3 name to the original filename. This doesn't have to
always succeed, as the directory handling code in smbd will scan the directory
looking for a matching name if it doesn't. It should succeed most of the time
or there will be a huge performance penalty
*/
-BOOL mangle_check_cache(char *s, size_t maxlen,
+BOOL mangle_lookup_name_from_8_3(TALLOC_CTX *ctx,
+ const char *in,
+ char **out, /* talloced on the given context. */
const struct share_params *p)
{
- return mangle_fns->check_cache(s, maxlen, p);
+ return mangle_fns->lookup_name_from_8_3(ctx, in, out, p);
}
-BOOL mangle_check_cache_alloc(const char *name, char **presult,
- const struct share_params *p)
-{
- pstring tmp;
- char *result;
- pstrcpy(tmp, name);
-
- if (!mangle_check_cache(tmp, sizeof(pstring)-1, p)
- || !(result = SMB_STRDUP(tmp))) {
- return False;
- }
- *presult = result;
- return True;
-}
-
-/*
- map a long filename to a 8.3 name.
+/*
+ mangle a long filename to a 8.3 name.
+ Return True if we did mangle the name (ie. out is filled in).
+ False on error.
+ JRA.
*/
-void mangle_map(pstring OutName, BOOL need83, BOOL cache83,
+BOOL name_to_8_3(const char *in,
+ char out[13],
+ BOOL cache83,
const struct share_params *p)
{
/* name mangling can be disabled for speed, in which case
we just truncate the string */
if (!lp_manglednames(p)) {
- if (need83) {
- string_truncate(OutName, 12);
- }
- return;
+ safe_strcpy(out,in,12);
+ return True;
}
- /* invoke the inane "mangled map" code */
- mangle_map_filename(OutName, p);
- mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(p->service), p);
+ return mangle_fns->name_to_8_3(in,
+ out,
+ cache83,
+ lp_defaultcase(p->service),
+ p);
}
Index: smbd/trans2.c
===================================================================
--- smbd/trans2.c (revision 24970)
+++ smbd/trans2.c (working copy)
@@ -1163,6 +1163,7 @@
uint32 nt_extmode; /* Used for NT connections instead of mode */
BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
BOOL check_mangled_names = lp_manglednames(conn->params);
+ char mangled_name[13]; /* mangled 8.3 name. */
*fname = 0;
*out_of_space = False;
@@ -1215,10 +1216,15 @@
* pathreal which is composed from dname.
*/
- pstrcpy(fname,dname);
+ pstrcpy(fname,dname);
- /* This will mangle fname if it's an illegal name. */
- mangle_map(fname,False,True,conn->params);
+ /* Mangle fname if it's an illegal name. */
+ if (mangle_must_mangle(fname,conn->params)) {
+ if (!name_to_8_3(fname,mangled_name,True,conn->params)) {
+ continue; /* Error - couldn't mangle. */
+ }
+ pstrcpy(fname,mangled_name);
+ }
if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
got_match = mask_match(fname, mask, conn->case_sensitive);
@@ -1226,19 +1232,17 @@
if(!got_match && check_mangled_names &&
!mangle_is_8_3(fname, False, conn->params)) {
- pstring mangled_name;
-
/*
* It turns out that NT matches wildcards against
* both long *and* short names. This may explain some
* of the wildcard wierdness from old DOS clients
* that some people have been seeing.... JRA.
*/
+ /* Force the mangling into 8.3. */
+ if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
+ continue; /* Error - couldn't mangle. */
+ }
- pstrcpy(mangled_name, fname);
-
- /* Force the mangling into 8.3. */
- mangle_map( mangled_name, True, False, conn->params);
if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
got_match = mask_match(mangled_name, mask, conn->case_sensitive);
}
@@ -1483,10 +1487,11 @@
* a Win2k client bug. JRA.
*/
if (!was_8_3 && check_mangled_names) {
- pstring mangled_name;
- pstrcpy(mangled_name, fname);
- mangle_map(mangled_name,True,True,
- conn->params);
+ if (!name_to_8_3(fname,mangled_name,True,
+ conn->params)) {
+ /* Error - mangle failed ! */
+ memset(mangled_name,'\0',12);
+ }
mangled_name[12] = 0;
len = srvstr_push(base_data, flags2,
p+2, mangled_name, 24,
@@ -1638,10 +1643,11 @@
* a Win2k client bug. JRA.
*/
if (!was_8_3 && check_mangled_names) {
- pstring mangled_name;
- pstrcpy(mangled_name, fname);
- mangle_map(mangled_name,True,True,
- conn->params);
+ if (!name_to_8_3(fname,mangled_name,True,
+ conn->params)) {
+ /* Error - mangle failed ! */
+ memset(mangled_name,'\0',12);
+ }
mangled_name[12] = 0;
len = srvstr_push(base_data, flags2,
p+2, mangled_name, 24,
@@ -2037,7 +2043,7 @@
smb_fn_name(CVAL(req->inbuf,smb_com)),
mask, directory, dirtype, numentries ) );
- /*
+ /*
* Force a name mangle here to ensure that the
* mask as an 8.3 name is top of the mangled cache.
* The reasons for this are subtle. Don't remove
@@ -2045,8 +2051,10 @@
* (see PR#13758). JRA.
*/
- if(!mangle_is_8_3_wildcards( mask, False, conn->params))
- mangle_map(mask, True, True, conn->params);
+ if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
+ char mangled_name[13];
+ name_to_8_3(mask, mangled_name, True, conn->params);
+ }
return;
}
@@ -2276,7 +2284,7 @@
*/
if (mangle_is_mangled(resume_name, conn->params)) {
- mangle_check_cache(resume_name, sizeof(resume_name)-1,
+ mangle_lookup_name_from_8_3(resume_name, sizeof(resume_name)-1,
conn->params);
}
@@ -3962,16 +3970,16 @@
case SMB_QUERY_FILE_ALT_NAME_INFO:
case SMB_FILE_ALTERNATE_NAME_INFORMATION:
{
- pstring short_name;
-
+ char mangled_name[13];
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
- pstrcpy(short_name,base_name);
- /* Mangle if not already 8.3 */
- if(!mangle_is_8_3(short_name, True, conn->params)) {
- mangle_map(short_name,True,True,conn->params);
+ if (!name_to_8_3(base_name,mangled_name,
+ True,conn->params)) {
+ reply_nterror(
+ req,
+ NT_STATUS_NO_MEMORY);
}
len = srvstr_push(dstart, req->flags2,
- pdata+4, short_name,
+ pdata+4, mangled_name,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
data_size = 4 + len;
Index: smbd/dir.c
===================================================================
--- smbd/dir.c (revision 24970)
+++ smbd/dir.c (working copy)
@@ -758,10 +758,15 @@
return True;
}
-static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
+static BOOL mangle_mask_match(connection_struct *conn, const char *filename,
+ char *mask)
{
- mangle_map(filename,True,False,conn->params);
- return mask_match_search(filename,mask,False);
+ char mname[13];
+
+ if (!name_to_8_3(filename,mname,False,conn->params)) {
+ return False;
+ }
+ return mask_match_search(mname,mask,False);
}
/****************************************************************************
@@ -806,9 +811,14 @@
mask_match_search(filename,mask,False) ||
mangle_mask_match(conn,filename,mask)) {
- if (!mangle_is_8_3(filename, False, conn->params))
- mangle_map(filename,True,False,
- conn->params);
+ if (!mangle_is_8_3(filename, False, conn->params)) {
+ char mname[13];
+ if (!name_to_8_3(filename,mname,False,
+ conn->params)) {
+ continue;
+ }
+ pstrcpy(filename,mname);
+ }
pstrcpy(fname,filename);
*path = 0;
Index: smbd/filename.c
===================================================================
--- smbd/filename.c (revision 24970)
+++ smbd/filename.c (working copy)
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
filename handling routines
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 1999-2004
+ Copyright (C) Jeremy Allison 1999-2007
Copyright (C) Ying Chen 2000
Copyright (C) Volker Lendecke 2007
@@ -37,11 +37,12 @@
const char *name2,
const struct share_params *p)
{
- pstring tmpname;
+ char mname[13];
- pstrcpy(tmpname, name2);
- mangle_map(tmpname, True, False, p);
- return strequal(name1, tmpname);
+ if (!name_to_8_3(name2, mname, False, p)) {
+ return False;
+ }
+ return strequal(name1, mname);
}
/****************************************************************************
@@ -107,9 +108,10 @@
****************************************************************************/
NTSTATUS unix_convert(connection_struct *conn,
- pstring orig_path,
+ const char *orig_path,
BOOL allow_wcard_last_component,
- char *saved_last_component,
+ char **pp_conv_path,
+ char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
{
SMB_STRUCT_STAT st;
@@ -119,16 +121,20 @@
BOOL component_was_mangled = False;
BOOL name_has_wildcard = False;
NTSTATUS result;
+ TALLOC_CTX *ctx = talloc_tos();
SET_STAT_INVALID(*pst);
-
- if(saved_last_component) {
- *saved_last_component = 0;
+ *pp_conv_path = NULL;
+ if(pp_saved_last_component) {
+ *pp_saved_last_component = NULL;
}
if (conn->printer) {
/* we don't ever use the filenames on a printer share as a
filename - so don't convert them */
+ if (!(*pp_conv_path = talloc_strdup(ctx,orig_path))) {
+ return NT_STATUS_NO_MEMORY;
+ }
return NT_STATUS_OK;
}
@@ -157,11 +163,13 @@
*/
if (!*orig_path) {
- if (!(name = SMB_STRDUP("."))) {
+ if (!(name = talloc_strdup(ctx,"."))) {
return NT_STATUS_NO_MEMORY;
}
if (SMB_VFS_STAT(conn,name,&st) == 0) {
*pst = st;
+ } else {
+ return map_nt_error_from_unix(errno);
}
DEBUG(5,("conversion finished \"\" -> %s\n",name));
goto done;
@@ -183,17 +191,18 @@
* Ensure saved_last_component is valid even if file exists.
*/
- if(saved_last_component) {
+ if(pp_saved_last_component) {
end = strrchr_m(orig_path, '/');
if (end) {
- pstrcpy(saved_last_component, end + 1);
+ *pp_saved_last_component = talloc_strdup(ctx, end + 1);
} else {
- pstrcpy(saved_last_component, orig_path);
+ *pp_saved_last_component = talloc_strdup(ctx,
+ orig_path);
}
}
- if (!(name = SMB_STRDUP(orig_path))) {
- DEBUG(0, ("strdup failed\n"));
+ if (!(name = talloc_strdup(ctx, orig_path))) {
+ DEBUG(0, ("talloc_strdup failed\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -224,9 +233,9 @@
* building the directories with asprintf and free it.
*/
- if ((dirpath == NULL) && (!(dirpath = SMB_STRDUP("")))) {
- DEBUG(0, ("strdup failed\n"));
- SAFE_FREE(name);
+ if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ TALLOC_FREE(name);
return NT_STATUS_NO_MEMORY;
}
@@ -264,8 +273,7 @@
*/
if (conn->case_sensitive &&
- !mangle_is_mangled(name, conn->params) &&
- !*lp_mangled_map(conn->params)) {
+ !mangle_is_mangled(name, conn->params)) {
goto done;
}
@@ -302,8 +310,14 @@
*end = 0;
}
- if (saved_last_component != 0) {
- pstrcpy(saved_last_component, end ? end + 1 : start);
+ if (pp_saved_last_component) {
+ TALLOC_FREE(*pp_saved_last_component);
+ *pp_saved_last_component = talloc_strdup(ctx,
+ end ? end + 1 : start);
+ if (!*pp_saved_last_component) {
+ DEBUG(0, ("talloc failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
}
/* The name cannot have a component of "." */
@@ -473,25 +487,27 @@
*/
if (mangle_is_mangled(start, conn->params)
- && mangle_check_cache_alloc(start,
- &unmangled,
- conn->params)) {
+ && mangle_lookup_name_from_8_3(ctx,
+ start,
+ &unmangled,
+ conn->params)) {
char *tmp;
size_t start_ofs = start - name;
if (*dirpath != '\0') {
- asprintf(&tmp, "%s/%s", dirpath,
- unmangled);
- SAFE_FREE(unmangled);
+ tmp = talloc_asprintf(ctx,
+ "%s/%s", dirpath,
+ unmangled);
+ TALLOC_FREE(unmangled);
}
else {
tmp = unmangled;
}
if (tmp == NULL) {
- DEBUG(0, ("malloc failed\n"));
- result = NT_STATUS_NO_MEMORY;
+ DEBUG(0, ("talloc failed\n"));
+ return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(name);
+ TALLOC_FREE(name);
name = tmp;
start = name + start_ofs;
end = start + strlen(start);
@@ -511,18 +527,20 @@
size_t start_ofs = start - name;
if (*dirpath != '\0') {
- asprintf(&tmp, "%s/%s/%s", dirpath,
- found_name, end+1);
+ tmp = talloc_asprintf(ctx,
+ "%s/%s/%s", dirpath,
+ found_name, end+1);
}
else {
- asprintf(&tmp, "%s/%s", found_name,
- end+1);
+ tmp = talloc_asprintf(ctx,
+ "%s/%s", found_name,
+ end+1);
}
if (tmp == NULL) {
- DEBUG(0, ("asprintf failed\n"));
- result = NT_STATUS_NO_MEMORY;
+ DEBUG(0, ("talloc_asprintf failed\n"));
+ return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(name);
+ TALLOC_FREE(name);
name = tmp;
start = name + start_ofs;
end = start + strlen(found_name);
@@ -532,18 +550,19 @@
size_t start_ofs = start - name;
if (*dirpath != '\0') {
- asprintf(&tmp, "%s/%s", dirpath,
- found_name);
+ tmp = talloc_asprintf(ctx,
+ "%s/%s", dirpath,
+ found_name);
}
else {
- tmp = SMB_STRDUP(found_name);
+ tmp = talloc_strdup(ctx,
+ found_name);
}
if (tmp == NULL) {
- DEBUG(0, ("malloc failed\n"));
- result = NT_STATUS_NO_MEMORY;
- goto fail;
+ DEBUG(0, ("talloc failed\n"));
+ return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(name);
+ TALLOC_FREE(name);
name = tmp;
start = name + start_ofs;
@@ -560,7 +579,7 @@
}
}
- SAFE_FREE(found_name);
+ TALLOC_FREE(found_name);
} /* end else */
#ifdef DEVELOPER
@@ -577,19 +596,19 @@
*/
if (*dirpath != '\0') {
- char *tmp;
-
- if (asprintf(&tmp, "%s/%s", dirpath, start) == -1) {
- DEBUG(0, ("asprintf failed\n"));
+ char *tmp = talloc_asprintf(ctx,
+ "%s/%s", dirpath, start);
+ if (!tmp) {
+ DEBUG(0, ("talloc_asprintf failed\n"));
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(dirpath);
+ TALLOC_FREE(dirpath);
dirpath = tmp;
}
else {
- SAFE_FREE(dirpath);
- if (!(dirpath = SMB_STRDUP(start))) {
- DEBUG(0, ("strdup failed\n"));
+ TALLOC_FREE(dirpath);
+ if (!(dirpath = talloc_strdup(ctx,start))) {
+ DEBUG(0, ("talloc_strdup failed\n"));
return NT_STATUS_NO_MEMORY;
}
}
@@ -628,17 +647,19 @@
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
done:
- pstrcpy(orig_path, name);
- SAFE_FREE(name);
- SAFE_FREE(dirpath);
+ *pp_conv_path = name;
+ TALLOC_FREE(dirpath);
return NT_STATUS_OK;
fail:
DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
- pstrcpy(orig_path, dirpath);
- pstrcat(orig_path, "/");
- pstrcat(orig_path, start);
- SAFE_FREE(name);
- SAFE_FREE(dirpath);
+ *pp_conv_path = talloc_asprintf(ctx,
+ "%s/%s", dirpath, start);
+ if (!*pp_conv_path) {
+ DEBUG(0, ("talloc_asprintf failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ TALLOC_FREE(name);
+ TALLOC_FREE(dirpath);
return result;
}
@@ -649,7 +670,7 @@
a valid one for the user to access.
****************************************************************************/
-NTSTATUS check_name(connection_struct *conn, const pstring name)
+NTSTATUS check_name(connection_struct *conn, const char *name)
{
if (IS_VETO_PATH(conn, name)) {
/* Is it not dot or dot dot. */
@@ -682,8 +703,9 @@
BOOL case_sensitive)
{
/* Normal filename handling */
- if (case_sensitive)
+ if (case_sensitive) {
return(strcmp(name1,name2) == 0);
+ }
return(strequal(name1,name2));
}
@@ -701,17 +723,19 @@
BOOL mangled;
char *unmangled_name = NULL;
long curpos;
+ TALLOC_CTX *ctx = talloc_tos();
mangled = mangle_is_mangled(name, conn->params);
/* handle null paths */
- if ((path == NULL) || (*path == 0))
+ if ((path == NULL) || (*path == 0)) {
path = ".";
+ }
/*
* The incoming name can be mangled, and if we de-mangle it
* here it will not compare correctly against the filename (name2)
- * read from the directory and then mangled by the mangle_map()
+ * read from the directory and then mangled by the name_to_8_3()
* call. We need to mangle both names or neither.
* (JRA).
*
@@ -724,15 +748,19 @@
*/
if (mangled && !conn->case_sensitive) {
- mangled = !mangle_check_cache_alloc(name, &unmangled_name,
- conn->params);
- name = unmangled_name;
+ mangled = !mangle_lookup_name_from_8_3(ctx,
+ name,
+ &unmangled_name,
+ conn->params);
+ if (mangled) {
+ name = unmangled_name;
+ }
}
/* open the directory */
if (!(cur_dir = OpenDir(conn, path, NULL, 0))) {
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
- SAFE_FREE(unmangled_name);
+ TALLOC_FREE(unmangled_name);
return(False);
}
@@ -741,8 +769,7 @@
while ((dname = ReadDirName(cur_dir, &curpos))) {
/* Is it dot or dot dot. */
- if ((dname[0] == '.') && (!dname[1] ||
- (dname[1] == '.' && !dname[2]))) {
+ if (ISDOT(dname) || ISDOTDOT(dname)) {
continue;
}
@@ -760,15 +787,19 @@
if ((mangled && mangled_equal(name,dname,conn->params)) ||
fname_equal(name, dname, conn->case_sensitive)) {
/* we've found the file, change it's name and return */
- *found_name = SMB_STRDUP(dname);
- SAFE_FREE(unmangled_name);
+ *found_name = talloc_strdup(ctx,dname);
+ TALLOC_FREE(unmangled_name);
CloseDir(cur_dir);
+ if (!*found_name) {
+ errno = ENOMEM;
+ return False;
+ }
return(True);
}
}
- SAFE_FREE(unmangled_name);
+ TALLOC_FREE(unmangled_name);
CloseDir(cur_dir);
errno = ENOENT;
- return(False);
+ return False;
}
Index: lib/charcnv.c
===================================================================
--- lib/charcnv.c (revision 24970)
+++ lib/charcnv.c (working copy)
@@ -804,6 +804,71 @@
return SMB_STRDUP(out_buffer);
}
+/**
+ talloc_strdup() a unix string to upper case.
+**/
+
+char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
+{
+ char *out_buffer = talloc_strdup(ctx,s);
+ const unsigned char *p = (const unsigned char *)s;
+ unsigned char *q = (unsigned char *)out_buffer;
+
+ if (!q) {
+ return NULL;
+ }
+
+ /* this is quite a common operation, so we want it to be
+ fast. We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars) */
+
+ while (1) {
+ if (*p & 0x80)
+ break;
+ *q++ = toupper_ascii(*p);
+ if (!*p)
+ break;
+ p++;
+ }
+
+ if (*p) {
+ /* MB case. */
+ size_t size;
+ smb_ucs2_t *ubuf = NULL;
+
+ /* We're not using the ascii buffer above. */
+ TALLOC_FREE(out_buffer);
+
+ size = convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE,
+ s, strlen(s),
+ (void *)&ubuf,
+ True);
+ if (size == (size_t)-1) {
+ return NULL;
+ }
+
+ strupper_w(ubuf);
+
+ size = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
+ ubuf, size,
+ (void *)&out_buffer,
+ True);
+
+ /* Don't need the intermediate buffer
+ * anymore.
+ */
+
+ TALLOC_FREE(ubuf);
+
+ if (size == (size_t)-1) {
+ return NULL;
+ }
+ }
+
+ return out_buffer;
+}
+
size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
{
size_t size;
Index: include/mangle.h
===================================================================
--- include/mangle.h (revision 24970)
+++ include/mangle.h (working copy)
@@ -7,12 +7,17 @@
struct mangle_fns {
void (*reset)(void);
BOOL (*is_mangled)(const char *s, const struct share_params *p);
+ BOOL (*must_mangle)(const char *s, const struct share_params *p);
BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards,
const struct share_params *p);
- BOOL (*check_cache)(char *s, size_t maxlen,
- const struct share_params *p);
- void (*name_map)(char *OutName, BOOL need83, BOOL cache83,
- int default_case,
- const struct share_params *p);
+ BOOL (*lookup_name_from_8_3)(TALLOC_CTX *ctx,
+ const char *in,
+ char **out, /* talloced on the given context. */
+ const struct share_params *p);
+ BOOL (*name_to_8_3)(const char *in,
+ char out[13],
+ BOOL cache83,
+ int default_case,
+ const struct share_params *p);
};
#endif /* _MANGLE_H_ */
More information about the samba-technical
mailing list