summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/globals.c6
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/mangle_hash2.c243
3 files changed, 178 insertions, 74 deletions
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 98e4d51b088..1c7afb948eb 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -57,15 +57,12 @@ const struct mangle_fns *mangle_fns = NULL;
unsigned char *chartest = NULL;
TDB_CONTEXT *tdb_mangled_cache = NULL;
-/* these tables are used to provide fast tests for characters */
-unsigned char char_flags[256];
/*
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.
*/
unsigned mangle_prefix = 0;
-unsigned char base_reverse[256];
struct msg_state *smbd_msg_state = NULL;
@@ -146,9 +143,6 @@ struct memcache *smbd_memcache(void)
void smbd_init_globals(void)
{
- ZERO_STRUCT(char_flags);
- ZERO_STRUCT(base_reverse);
-
ZERO_STRUCT(conn_ctx_stack);
ZERO_STRUCT(sec_ctx_stack);
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 86e2c9b3f91..759fead1c3a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -54,15 +54,12 @@ extern const struct mangle_fns *mangle_fns;
extern unsigned char *chartest;
extern TDB_CONTEXT *tdb_mangled_cache;
-/* these tables are used to provide fast tests for characters */
-extern unsigned char char_flags[256];
/*
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.
*/
extern unsigned mangle_prefix;
-extern unsigned char base_reverse[256];
struct msg_state;
extern struct msg_state *smbd_msg_state;
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index b9e7d638726..298f348661d 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -49,6 +49,19 @@
===============================================================================
*/
+/*
+ * ============================================================================
+ * Whenever you change anything in the FLAG_ or other fields,
+ * re-initialize the tables char_flags and base_reverse by running the
+ * init_tables() routine once and dump its results. To do this, a
+ * single smbd run with
+ *
+ * #define DYNAMIC_MANGLE_TABLES 1
+ *
+ * and debug level 10 should be sufficient.
+ * ============================================================================
+ */
+
#include "includes.h"
#include "smbd/globals.h"
@@ -93,6 +106,169 @@ static const char * const reserved_names[] =
{ "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
"LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL };
+#define DYNAMIC_MANGLE_TABLES 0
+
+#if DYNAMIC_MANGLE_TABLES
+
+/* these tables are used to provide fast tests for characters */
+static unsigned char char_flags[256];
+static unsigned char base_reverse[256];
+
+/* 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.
+*/
+static void init_tables(void)
+{
+ int i;
+
+ memset(char_flags, 0, sizeof(char_flags));
+
+ for (i=1;i<128;i++) {
+ if (i <= 0x1f) {
+ /* Control characters. */
+ char_flags[i] |= FLAG_ILLEGAL;
+ }
+
+ if ((i >= '0' && i <= '9') ||
+ (i >= 'a' && i <= 'z') ||
+ (i >= 'A' && i <= 'Z')) {
+ char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR);
+ }
+ if (strchr("_-$~", i)) {
+ char_flags[i] |= FLAG_ASCII;
+ }
+
+ if (strchr("*\\/?<>|\":", i)) {
+ char_flags[i] |= FLAG_ILLEGAL;
+ }
+
+ if (strchr("*?\"<>", i)) {
+ char_flags[i] |= FLAG_WILDCARD;
+ }
+ }
+
+ 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 */
+ for (i=0; reserved_names[i]; i++) {
+ unsigned char c1, c2, c3, c4;
+
+ c1 = (unsigned char)reserved_names[i][0];
+ c2 = (unsigned char)reserved_names[i][1];
+ c3 = (unsigned char)reserved_names[i][2];
+ c4 = (unsigned char)reserved_names[i][3];
+
+ char_flags[c1] |= FLAG_POSSIBLE1;
+ char_flags[c2] |= FLAG_POSSIBLE2;
+ char_flags[c3] |= FLAG_POSSIBLE3;
+ char_flags[c4] |= FLAG_POSSIBLE4;
+ char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
+ char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
+ char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
+ char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
+
+ char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
+ }
+
+#if 0
+ DEBUG(10, ("char_flags\n"));
+ dump_data(10, char_flags, sizeof(char_flags));
+
+ DEBUG(10, ("base_reverse\n"));
+ dump_data(10, base_reverse, sizeof(base_reverse));
+#endif
+}
+
+#else
+
+/*
+ * These tables were initialized by a single run of the above
+ * init_tables() routine, dumping the tables and a simple emacs macro.
+ *
+ * Technically we could leave out the 0's at the end of the array
+ * initializers, but I'll leave it in: less surprise.
+ */
+
+static uint8_t char_flags[256] = {
+ 0x80, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x00, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0C, 0x00, 0x00, 0x02, 0x80, 0x04,
+ 0x03, 0x83, 0x83, 0x83, 0x83, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x04, 0x00, 0x0C, 0x00, 0x0C, 0x0C,
+ 0x00, 0x13, 0x03, 0x53, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x83, 0x53, 0x43, 0x53, 0x23,
+ 0x33, 0x03, 0x23, 0x03, 0x43, 0x23, 0x03, 0x03,
+ 0x43, 0x03, 0x03, 0x00, 0x04, 0x00, 0x00, 0x02,
+ 0x00, 0x13, 0x03, 0x53, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x83, 0x53, 0x43, 0x53, 0x23,
+ 0x33, 0x03, 0x23, 0x03, 0x43, 0x23, 0x03, 0x03,
+ 0x43, 0x03, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t base_reverse[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#endif
+
/*
hash a string of the specified length. The string does not need to be
null terminated
@@ -615,71 +791,6 @@ static bool hash2_name_to_8_3(const char *name,
return True;
}
-/* 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.
-*/
-static void init_tables(void)
-{
- int i;
-
- memset(char_flags, 0, sizeof(char_flags));
-
- for (i=1;i<128;i++) {
- if (i <= 0x1f) {
- /* Control characters. */
- char_flags[i] |= FLAG_ILLEGAL;
- }
-
- if ((i >= '0' && i <= '9') ||
- (i >= 'a' && i <= 'z') ||
- (i >= 'A' && i <= 'Z')) {
- char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR);
- }
- if (strchr("_-$~", i)) {
- char_flags[i] |= FLAG_ASCII;
- }
-
- if (strchr("*\\/?<>|\":", i)) {
- char_flags[i] |= FLAG_ILLEGAL;
- }
-
- if (strchr("*?\"<>", i)) {
- char_flags[i] |= FLAG_WILDCARD;
- }
- }
-
- 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 */
- for (i=0; reserved_names[i]; i++) {
- unsigned char c1, c2, c3, c4;
-
- c1 = (unsigned char)reserved_names[i][0];
- c2 = (unsigned char)reserved_names[i][1];
- c3 = (unsigned char)reserved_names[i][2];
- c4 = (unsigned char)reserved_names[i][3];
-
- char_flags[c1] |= FLAG_POSSIBLE1;
- char_flags[c2] |= FLAG_POSSIBLE2;
- char_flags[c3] |= FLAG_POSSIBLE3;
- char_flags[c4] |= FLAG_POSSIBLE4;
- char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
- char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
- char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
- char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
-
- char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
- }
-}
-
/*
the following provides the abstraction layer to make it easier
to drop in an alternative mangling implementation */
@@ -704,7 +815,9 @@ const struct mangle_fns *mangle_hash2_init(void)
mangle_prefix = 1;
}
+#if DYNAMIC_MANGLE_TABLES
init_tables();
+#endif
mangle_reset();
return &mangle_hash2_fns;