summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-10-21 04:30:51 +0000
committerAndrew Tridgell <tridge@samba.org>2002-10-21 04:30:51 +0000
commit48a56c12e268845d037ea0c4115a0df37cb20e26 (patch)
tree11af590e40cc94c973f3fca104ef9ddab0a6bbbb
parent354878f76fb6689e26a62ef988564c099991edc0 (diff)
downloadsamba-48a56c12e268845d037ea0c4115a0df37cb20e26.tar.gz
samba-48a56c12e268845d037ea0c4115a0df37cb20e26.tar.bz2
samba-48a56c12e268845d037ea0c4115a0df37cb20e26.zip
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)
-rw-r--r--docs/docbook/manpages/smb.conf.5.sgml19
-rw-r--r--source3/param/loadparm.c6
-rw-r--r--source3/smbd/mangle_hash2.c57
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.</para>
- <para>Default: <command>mangling method = hash</command></para>
- <para>Example: <command>mangling method = hash2</command></para>
+ lightly as these applications may break unless reinstalled.</para>
+ <para>Default: <command>mangling method = hash2</command></para>
+ <para>Example: <command>mangling method = hash</command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><anchor id="MANGLEPREFIX">mangle prefix (G)</term>
+ <listitem><para> 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.</para>
+ <para>Default: <command>mangle prefix = 1</command></para>
+ <para>Example: <command>mangle prefix = 4</command></para>
</listitem>
</varlistentry>
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<mangle_prefix;i++) {
+ if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
+ return False;
+ }
}
/* check rest of hash */
if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
return False;
}
- for (i=1;i<6;i++) {
+ for (i=mangle_prefix;i<6;i++) {
if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) {
return False;
}
@@ -371,7 +380,7 @@ static BOOL check_cache(char *name)
/* we need to extract the hash from the 8.3 name */
hash = base_reverse[(unsigned char)name[7]];
- for (multiplier=36, i=5;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<mangle_prefix && name[i];i++) {
+ lead_chars[i] = name[i];
+ if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
+ lead_chars[i] = '_';
+ }
+ lead_chars[i] = toupper(lead_chars[i]);
+ }
+ for (;i<mangle_prefix;i++) {
+ lead_chars[i] = '_';
}
- lead_char = toupper(lead_char);
/* the prefix is anything up to the first dot */
if (dot_p) {
@@ -549,10 +563,12 @@ static void name_map(char *name, BOOL need83, BOOL cache83)
v = hash = mangle_hash(name, prefix_len);
/* now form the mangled name. */
- new_name[0] = lead_char;
+ for (i=0;i<mangle_prefix;i++) {
+ new_name[i] = lead_chars[i];
+ }
new_name[7] = base_forward(v % 36);
new_name[6] = '~';
- for (i=5; 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();