From 48a56c12e268845d037ea0c4115a0df37cb20e26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 Oct 2002 04:30:51 +0000 Subject: add a 'mangle prefix' option to allow people to tune the number of characters used in the prefix for 8.3 names in the hash2 algorithm. The longer the prefix the more readable the 8.3 names will be, but the weaker the hash. this was added because of someone complaining that the new hashing algorithm was unreadable but the old one was broken :) (This used to be commit 3ca3cc838e5b957c7244b21947daddc4ee4c3099) --- docs/docbook/manpages/smb.conf.5.sgml | 19 +++++++++--- source3/param/loadparm.c | 6 +++- source3/smbd/mangle_hash2.c | 57 +++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/docs/docbook/manpages/smb.conf.5.sgml b/docs/docbook/manpages/smb.conf.5.sgml index 0e03eabd03..a1f767185c 100644 --- a/docs/docbook/manpages/smb.conf.5.sgml +++ b/docs/docbook/manpages/smb.conf.5.sgml @@ -4292,10 +4292,21 @@ a better algorithm (generates less collisions) in the names. However, many Win32 applications store the mangled names and so changing to the new algorithm must not be done - lightly as these applications may break unless reinstalled. - New installations of Samba may set the default to hash2. - Default: mangling method = hash - Example: mangling method = hash2 + lightly as these applications may break unless reinstalled. + Default: mangling method = hash2 + Example: mangling method = hash + + + + + mangle prefix (G) + controls the number of prefix + characters from the original name used when generating + the mangled names. A larger value will give a weaker + hash and therefore more name collisions. The minimum + value is 1 and the maximum value is 6. + Default: mangle prefix = 1 + Example: mangle prefix = 4 diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5d1ef9b91f..7bec315631 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -167,6 +167,7 @@ typedef struct char *szDeleteShareCommand; char *szGuestaccount; char *szManglingMethod; + int mangle_prefix; int max_log_size; char *szLogLevel; int mangled_stack; @@ -911,6 +912,7 @@ static struct parm_struct parm_table[] = { {"Filename Handling", P_SEP, P_SEPARATOR}, {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE}, @@ -1247,8 +1249,9 @@ static void init_globals(void) string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE); string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR); - /* use the new 'hash2' method by default */ + /* use the new 'hash2' method by default, with a prefix of 1 */ string_set(&Globals.szManglingMethod, "hash2"); + Globals.mangle_prefix = 1; string_set(&Globals.szGuestaccount, GUEST_ACCOUNT); @@ -1535,6 +1538,7 @@ FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap) FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir) FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir) FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod) +FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix) #ifdef WITH_UTMP FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir) FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir) diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 5adde19eea..bbc9020eab 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -87,6 +87,13 @@ static unsigned char char_flags[256]; #define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag)) +/* + this determines how many characters are used from the original filename + in the 8.3 mangled name. A larger value leads to a weaker hash and more collisions. + The largest possible value is 6. +*/ +static unsigned mangle_prefix; + /* we will use a very simple direct mapped prefix cache. The big advantage of this cache structure is speed and low memory usage @@ -217,16 +224,18 @@ static BOOL is_mangled_component(const char *name) } } - /* check first character */ - if (! FLAG_CHECK(name[0], FLAG_ASCII)) { - return False; + /* check lead characters */ + for (i=0;i=1;i--) { + for (multiplier=36, i=5;i>=mangle_prefix;i--) { u32 v = base_reverse[(unsigned char)name[i]]; hash += multiplier * v; multiplier *= 36; @@ -478,7 +487,7 @@ static BOOL is_legal_name(const char *name) static void name_map(char *name, BOOL need83, BOOL cache83) { char *dot_p; - char lead_char; + char lead_chars[7]; char extension[4]; int extension_length, i; int prefix_len; @@ -516,15 +525,20 @@ static void name_map(char *name, BOOL need83, BOOL cache83) if (i == 0 || i == 4) dot_p = NULL; } - /* the leading character in the mangled name is taken from - the first character of the name, if it is ascii - otherwise '_' is used + /* the leading characters in the mangled name is taken from + the first characters of the name, if they are ascii otherwise + '_' is used */ - lead_char = name[0]; - if (! FLAG_CHECK(lead_char, FLAG_ASCII)) { - lead_char = '_'; + for (i=0;i=1; i--) { + for (i=5; i>=mangle_prefix; i--) { v = v / 36; new_name[i] = base_forward(v % 36); } @@ -594,7 +610,7 @@ static void init_tables(void) memset(char_flags, 0, sizeof(char_flags)); - for (i=0;i<128;i++) { + for (i=1;i<128;i++) { if ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')) { @@ -656,6 +672,15 @@ static struct mangle_fns mangle_fns = { /* return the methods for this mangling implementation */ struct mangle_fns *mangle_hash2_init(void) { + /* the mangle prefix can only be in the mange 1 to 6 */ + mangle_prefix = lp_mangle_prefix(); + if (mangle_prefix > 6) { + mangle_prefix = 6; + } + if (mangle_prefix < 1) { + mangle_prefix = 1; + } + init_tables(); mangle_reset(); -- cgit