summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/mangle.c557
-rw-r--r--source3/smbd/server.c2
2 files changed, 317 insertions, 242 deletions
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c
index 829e307a85..bf26475715 100644
--- a/source3/smbd/mangle.c
+++ b/source3/smbd/mangle.c
@@ -26,27 +26,33 @@ extern int case_default;
extern BOOL case_mangle;
/****************************************************************************
-provide a checksum on a string
-****************************************************************************/
+ * Provide a checksum on a string
+ *
+ * Input: s - the nul-terminated character string for which the checksum
+ * will be calculated.
+ * Output: The checksum value calculated for s.
+ *
+ ****************************************************************************/
int str_checksum(char *s)
-{
+ {
int res = 0;
int c;
int i=0;
- while (*s)
+
+ while( *s )
{
- c = *s;
- res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
- s++; i++;
+ c = *s;
+ res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
+ s++; i++;
}
return(res);
-}
+ } /* str_checksum */
/****************************************************************************
return True if a name is a special msdos reserved name
****************************************************************************/
static BOOL is_reserved_msdos(char *fname)
-{
+ {
char upperFname[13];
char *p;
@@ -72,7 +78,7 @@ static BOOL is_reserved_msdos(char *fname)
return (True) ;
return (False);
-}
+ } /* is_reserved_msdos */
@@ -80,34 +86,37 @@ static BOOL is_reserved_msdos(char *fname)
return True if a name is in 8.3 dos format
****************************************************************************/
BOOL is_8_3(char *fname, BOOL check_case)
-{
+ {
int len;
char *dot_pos;
char *slash_pos = strrchr(fname,'/');
int l;
- if (slash_pos) fname = slash_pos+1;
+ if( slash_pos )
+ fname = slash_pos+1;
len = strlen(fname);
DEBUG(5,("checking %s for 8.3\n",fname));
- if (check_case && case_mangle)
+ if( check_case && case_mangle )
+ {
switch (case_default)
{
case CASE_LOWER:
- if (strhasupper(fname)) return(False);
- break;
+ if (strhasupper(fname)) return(False);
+ break;
case CASE_UPPER:
- if (strhaslower(fname)) return(False);
- break;
+ if (strhaslower(fname)) return(False);
+ break;
}
+ }
/* can't be longer than 12 chars */
- if (len == 0 || len > 12)
+ if( len == 0 || len > 12 )
return(False);
/* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
- if (is_reserved_msdos(fname))
+ if( is_reserved_msdos(fname) )
return(False);
/* can't contain invalid dos chars */
@@ -121,184 +130,218 @@ BOOL is_8_3(char *fname, BOOL check_case)
dot_pos = strchr(fname,'.');
- {
+ {
char *p = fname;
+
if(lp_client_code_page() == KANJI_CODEPAGE)
- {
+ {
dot_pos = 0;
while (*p)
- {
+ {
if (is_shift_jis (*p))
p += 2;
else if (is_kana (*p))
p ++;
else
- {
+ {
if (*p == '.' && !dot_pos)
dot_pos = (char *) p;
if (!isdoschar(*p))
return(False);
p++;
+ }
}
- }
- }
+ }
else
- {
- while (*p)
{
+ while (*p)
+ {
if (!isdoschar(*p))
return(False);
p++;
- }
+ }
+ }
}
- }
/* no dot and less than 9 means OK */
if (!dot_pos)
return(len <= 8);
-
+
l = PTR_DIFF(dot_pos,fname);
/* base must be at least 1 char except special cases . and .. */
- if (l == 0)
+ if( l == 0 )
return(strcmp(fname,".") == 0 || strcmp(fname,"..") == 0);
/* base can't be greater than 8 */
- if (l > 8)
+ if( l > 8 )
return(False);
- if (lp_strip_dot() &&
+ if( lp_strip_dot() &&
len - l == 1 &&
- !strchr(dot_pos+1,'.'))
+ !strchr(dot_pos+1,'.') )
{
- *dot_pos = 0;
- return(True);
+ *dot_pos = 0;
+ return(True);
}
/* extension must be between 1 and 3 */
- if ( (len - l < 2 ) || (len - l > 4) )
+ if( (len - l < 2 ) || (len - l > 4) )
return(False);
/* extension can't have a dot */
- if (strchr(dot_pos+1,'.'))
+ if( strchr(dot_pos+1,'.') )
return(False);
/* must be in 8.3 format */
return(True);
-}
+ } /* is_8_3 */
+
+/* -------------------------------------------------------------------------- **
+ * This section creates and maintains a stack of name mangling results.
+ * The original comments read: "keep a stack of name mangling results - just
+ * so file moves and copies have a chance of working" (whatever that means).
+ *
+ * There are three functions to manage the stack:
+ * reset_mangled_stack() -
+ * push_mangled_name() -
+ * check_mangled_stack() -
+ */
-
-
-/*
-keep a stack of name mangling results - just
-so file moves and copies have a chance of working
-*/
fstring *mangled_stack = NULL;
int mangled_stack_size = 0;
int mangled_stack_len = 0;
/****************************************************************************
-create the mangled stack
-****************************************************************************/
-void create_mangled_stack(int size)
-{
- if (mangled_stack)
+ * create the mangled stack CRH
+ ****************************************************************************/
+void reset_mangled_stack( int size )
+ {
+ if( mangled_stack )
+ {
+ free(mangled_stack);
+ mangled_stack_size = 0;
+ mangled_stack_len = 0;
+ }
+
+ if( size > 0 )
{
- free(mangled_stack);
- mangled_stack_size = 0;
- mangled_stack_len = 0;
+ mangled_stack = (fstring *)malloc( sizeof(fstring) * size );
+ if( mangled_stack )
+ mangled_stack_size = size;
}
- if (size > 0)
- mangled_stack = (fstring *)malloc(sizeof(fstring)*size);
- if (mangled_stack) mangled_stack_size = size;
-}
+ else
+ mangled_stack = NULL;
+ } /* create_mangled_stack */
/****************************************************************************
-push a mangled name onto the stack
-****************************************************************************/
+ * push a mangled name onto the stack CRH
+ ****************************************************************************/
static void push_mangled_name(char *s)
-{
+ {
int i;
char *p;
- if (!mangled_stack)
+ /* If the stack doesn't exist... Fail. */
+ if( !mangled_stack )
return;
- for (i=0;i<mangled_stack_len;i++)
- if (strcmp(s,mangled_stack[i]) == 0)
+ /* If name <s> is already on the stack, move it to the top. */
+ for( i=0; i<mangled_stack_len; i++ )
+ {
+ if( strcmp( s, mangled_stack[i] ) == 0 )
{
- array_promote(mangled_stack[0],sizeof(fstring),i);
- return;
+ array_promote( mangled_stack[0],sizeof(fstring), i );
+ return;
}
+ }
- memmove(mangled_stack[1],mangled_stack[0],
- sizeof(fstring)*MIN(mangled_stack_len,mangled_stack_size-1));
- strcpy(mangled_stack[0],s);
- p = strrchr(mangled_stack[0],'.');
- if (p && (!strhasupper(p+1)) && (strlen(p+1) < 4))
+ /* If name <s> wasn't already there, add it to the top of the stack. */
+ memmove( mangled_stack[1], mangled_stack[0],
+ sizeof(fstring) * MIN(mangled_stack_len, mangled_stack_size-1) );
+ strcpy( mangled_stack[0], s );
+ mangled_stack_len = MIN( mangled_stack_size, mangled_stack_len+1 );
+
+ /* Hmmm...
+ * Find the last dot '.' in the name,
+ * if there are any upper case characters past the last dot
+ * and there are no more than three characters past the last dot
+ * then terminate the name *at* the last dot.
+ */
+ p = strrchr( mangled_stack[0], '.' );
+ if( p && (!strhasupper(p+1)) && (strlen(p+1) < (size_t)4) )
*p = 0;
- mangled_stack_len = MIN(mangled_stack_size,mangled_stack_len+1);
-}
+
+ } /* push_mangled_name */
/****************************************************************************
-check for a name on the mangled name stack
-****************************************************************************/
+ * check for a name on the mangled name stack CRH
+ ****************************************************************************/
BOOL check_mangled_stack(char *s)
-{
+ {
int i;
pstring tmpname;
char extension[5];
- char *p = strrchr(s,'.');
+ char *p = strrchr( s, '.' );
BOOL check_extension = False;
extension[0] = 0;
- if (!mangled_stack) return(False);
+ /* If the stack doesn't exist, fail. */
+ if( !mangled_stack )
+ return(False);
- if (p)
+ /* If there is a file extension, then we need to play with it, too. */
+ if( p )
{
- check_extension = True;
- StrnCpy(extension,p,4);
- strlower(extension); /* XXXXXXX */
+ check_extension = True;
+ StrnCpy( extension, p, 4 );
+ strlower( extension ); /* XXXXXXX */
}
- for (i=0;i<mangled_stack_len;i++)
+ for( i=0; i<mangled_stack_len; i++ )
{
- strcpy(tmpname,mangled_stack[i]);
+ strcpy(tmpname,mangled_stack[i]);
+ mangle_name_83(tmpname);
+ if( strequal(tmpname,s) )
+ {
+ strcpy(s,mangled_stack[i]);
+ break;
+ }
+ if( check_extension && !strchr(mangled_stack[i],'.') )
+ {
+ pstrcpy(tmpname,mangled_stack[i]);
+ strcat(tmpname,extension);
mangle_name_83(tmpname);
- if (strequal(tmpname,s))
- {
- strcpy(s,mangled_stack[i]);
- break;
- }
- if (check_extension && !strchr(mangled_stack[i],'.'))
- {
- pstrcpy(tmpname,mangled_stack[i]);
- strcat(tmpname,extension);
- mangle_name_83(tmpname);
- if (strequal(tmpname,s))
- {
- strcpy(s,mangled_stack[i]);
- strcat(s,extension);
- break;
- }
- }
+ if( strequal(tmpname,s) )
+ {
+ strcpy(s,mangled_stack[i]);
+ strcat(s,extension);
+ break;
+ }
+ }
}
- if (i < mangled_stack_len)
+ if( i < mangled_stack_len )
{
- DEBUG(3,("Found %s on mangled stack as %s\n",s,mangled_stack[i]));
- array_promote(mangled_stack[0],sizeof(fstring),i);
- return(True);
+ DEBUG(3,("Found %s on mangled stack as %s\n",s,mangled_stack[i]));
+ array_promote(mangled_stack[0],sizeof(fstring),i);
+ return(True);
}
return(False);
-}
+ } /* check_mangled_stack */
+
+
+/* End of the mangled stack section.
+ * -------------------------------------------------------------------------- **
+ */
-static char *map_filename(char *s, /* This is null terminated */
- char *pattern, /* This isn't. */
- int len) /* This is the length of pattern. */
-{
+
+static char *map_filename( char *s, /* This is null terminated */
+ char *pattern, /* This isn't. */
+ int len ) /* This is the length of pattern. */
+ {
static pstring matching_bit; /* The bit of the string which matches */
/* a * in pattern if indeed there is a * */
char *sp; /* Pointer into s. */
@@ -307,57 +350,68 @@ static char *map_filename(char *s, /* This is null terminated */
pstring pat;
StrnCpy(pat, pattern, len); /* Get pattern into a proper string! */
- pstrcpy(matching_bit,""); /* Match but no star gets this. */
+ pstrcpy(matching_bit,""); /* Match but no star gets this. */
pp = pat; /* Initialise the pointers. */
sp = s;
- if ((len == 1) && (*pattern == '*')) {
+ if( (len == 1) && (*pattern == '*') )
+ {
return NULL; /* Impossible, too ambiguous for */
- /* words! */
- }
+ } /* words! */
while ((*sp) /* Not the end of the string. */
&& (*pp) /* Not the end of the pattern. */
&& (*sp == *pp) /* The two match. */
- && (*pp != '*')) { /* No wildcard. */
+ && (*pp != '*')) /* No wildcard. */
+ {
sp++; /* Keep looking. */
pp++;
- }
- if (!*sp && !*pp) /* End of pattern. */
- return matching_bit; /* Simple match. Return empty string. */
- if (*pp == '*') {
+ }
+
+ if( !*sp && !*pp ) /* End of pattern. */
+ return( matching_bit ); /* Simple match. Return empty string. */
+
+ if (*pp == '*')
+ {
pp++; /* Always interrested in the chacter */
/* after the '*' */
- if (!*pp) { /* It is at the end of the pattern. */
+ if (!*pp) /* It is at the end of the pattern. */
+ {
StrnCpy(matching_bit, s, sp-s);
return matching_bit;
- } else {
+ }
+ else
+ {
/* The next character in pattern must match a character further */
/* along s than sp so look for that character. */
match_start = sp;
- while ((*sp) /* Not the end of s. */
+ while( (*sp) /* Not the end of s. */
&& (*sp != *pp)) /* Not the same */
sp++; /* Keep looking. */
- if (!*sp) { /* Got to the end without a match. */
+ if (!*sp) /* Got to the end without a match. */
+ {
return NULL;
- } else { /* Still hope for a match. */
+ } /* Still hope for a match. */
+ else
+ {
/* Now sp should point to a matching character. */
StrnCpy(matching_bit, match_start, sp-match_start);
/* Back to needing a stright match again. */
- while ((*sp) /* Not the end of the string. */
+ while( (*sp) /* Not the end of the string. */
&& (*pp) /* Not the end of the pattern. */
- && (*sp == *pp)) { /* The two match. */
+ && (*sp == *pp) ) /* The two match. */
+ {
sp++; /* Keep looking. */
pp++;
- }
+ }
if (!*sp && !*pp) /* Both at end so it matched */
return matching_bit;
else
return NULL;
+ }
}
}
- }
return NULL; /* No match. */
-}
+ } /* map_filename */
/* this is the magic char used for mangling */
@@ -365,22 +419,24 @@ char magic_char = '~';
/****************************************************************************
-determine whther is name could be a mangled name
+return True if the name could be a mangled name
****************************************************************************/
-BOOL is_mangled(char *s)
-{
+BOOL is_mangled( char *s )
+ {
char *m = strchr(s,magic_char);
- if (!m) return(False);
- /* we use two base 36 chars efore the extension */
- if (m[1] == '.' || m[1] == 0 ||
+ if( !m )
+ return(False);
+
+ /* we use two base 36 chars before the extension */
+ if( m[1] == '.' || m[1] == 0 ||
m[2] == '.' || m[2] == 0 ||
- (m[3] != '.' && m[3] != 0))
- return(is_mangled(m+1));
+ (m[3] != '.' && m[3] != 0) )
+ return( is_mangled(m+1) );
/* it could be */
return(True);
-}
+ } /* is_mangled */
@@ -388,14 +444,14 @@ BOOL is_mangled(char *s)
return a base 36 character. v must be from 0 to 35.
****************************************************************************/
static char base36(unsigned int v)
-{
+ {
static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return basechars[v % 36];
-}
+ } /* base36 */
static void do_fwd_mangled_map(char *s, char *MangledMap)
-{
+ {
/* MangledMap is a series of name pairs in () separated by spaces.
* If s matches the first of the pair then the name given is the
* second of the pair. A * means any number of any character and if
@@ -415,7 +471,8 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
char *np; /* Points into new_string. */
DEBUG(5,("Mangled Mapping '%s' map '%s'\n", s, MangledMap));
- while (*start) {
+ while (*start)
+ {
while ((*start) && (*start != '('))
start++;
if (!*start)
@@ -425,12 +482,14 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
DEBUG(5,("Start of first in pair '%s'\n", start));
while ((*end) && !((*end == ' ') || (*end == ')')))
end++;
- if (!*end) {
+ if (!*end)
+ {
start = end;
continue; /* Always check for the end. */
- }
+ }
DEBUG(5,("End of first in pair '%s'\n", end));
- if ((match_string = map_filename(s, start, end-start))) {
+ if ((match_string = map_filename(s, start, end-start)))
+ {
DEBUG(5,("Found a match\n"));
/* Found a match. */
start = end+1; /* Point to start of what it is to become. */
@@ -441,11 +500,13 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
&& (*end != ')') /* Not the end of the pattern. */
&& (*end != '*')) /* Not a wildcard. */
*np++ = *end++;
- if (!*end) {
+ if (!*end)
+ {
start = end;
continue; /* Always check for the end. */
- }
- if (*end == '*') {
+ }
+ if (*end == '*')
+ {
pstrcpy(np, match_string);
np += strlen(match_string);
end++; /* Skip the '*' */
@@ -453,27 +514,28 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
&& (*end != ')') /* Not the end of the pattern. */
&& (*end != '*')) /* Not a wildcard. */
*np++ = *end++;
- }
- if (!*end) {
+ }
+ if (!*end)
+ {
start = end;
continue; /* Always check for the end. */
- }
+ }
*np++ = '\0'; /* NULL terminate it. */
DEBUG(5,("End of second in pair '%s'\n", end));
pstrcpy(s, new_string); /* Substitute with the new name. */
DEBUG(5,("s is now '%s'\n", s));
- }
+ }
start = end; /* Skip a bit which cannot be wanted */
/* anymore. */
start++;
- }
-}
+ }
+ } /* do_fwd_mangled_map */
/****************************************************************************
do the actual mangling to 8.3 format
****************************************************************************/
void mangle_name_83(char *s)
-{
+ {
int csum = str_checksum(s);
char *p;
char extension[4];
@@ -485,120 +547,127 @@ void mangle_name_83(char *s)
base[0]=0;
p = strrchr(s,'.');
- if (p && (strlen(p+1)<4) )
+ if( p && (strlen(p+1) < (size_t)4) )
{
- BOOL all_normal = (strisnormal(p+1)); /* XXXXXXXXX */
- if (all_normal && p[1] != 0)
- {
- *p = 0;
- csum = str_checksum(s);
- *p = '.';
- }
+ BOOL all_normal = (strisnormal(p+1)); /* XXXXXXXXX */
+
+ if (all_normal && p[1] != 0)
+ {
+ *p = 0;
+ csum = str_checksum(s);
+ *p = '.';
+ }
}
-
strupper(s);
DEBUG(5,("Mangling name %s to ",s));
- if (p)
- {
+ if( p )
+ {
if (p == s)
strcpy(extension,"___");
else
- {
- *p++ = 0;
- while (*p && extlen < 3)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ *p++ = 0;
+ while (*p && extlen < 3)
{
- if (is_shift_jis (*p))
+ if(lp_client_code_page() == KANJI_CODEPAGE)
{
- if (extlen < 2)
+ if (is_shift_jis (*p))
{
+ if (extlen < 2)
+ {
extension[extlen++] = p[0];
extension[extlen++] = p[1];
- }
+ }
else
- {
+ {
extension[extlen++] = base36 (((unsigned char) *p) % 36);
- }
+ }
p += 2;
- }
- else if (is_kana (*p))
- {
- extension[extlen++] = p[0];
- p++;
- }
- else
- {
- if (isdoschar (*p) && *p != '.')
+ }
+ else
+ {
+ if( is_kana (*p) )
+ {
extension[extlen++] = p[0];
- p++;
+ p++;
+ }
+ else
+ {
+ if (isdoschar (*p) && *p != '.')
+ extension[extlen++] = p[0];
+ p++;
+ }
+ }
}
- }
else
- {
+ {
if (isdoschar(*p) && *p != '.')
extension[extlen++] = *p;
p++;
+ }
}
+ extension[extlen] = 0;
}
- extension[extlen] = 0;
}
- }
p = s;
while (*p && baselen < 5)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
{
- if (is_shift_jis (*p))
+ if(lp_client_code_page() == KANJI_CODEPAGE)
{
- if (baselen < 4)
+ if (is_shift_jis (*p))
{
+ if (baselen < 4)
+ {
base[baselen++] = p[0];
base[baselen++] = p[1];
- }
+ }
else
- {
- base[baselen++] = base36 (((unsigned char) *p) % 36);
- }
+ {
+ base[baselen++] = base36 (((unsigned char) *p) % 36);
+ }
p += 2;
- }
- else if (is_kana (*p))
- {
- base[baselen++] = p[0];
- p++;
- }
- else
- {
- if (isdoschar (*p) && *p != '.')
+ }
+ else
+ {
+ if( is_kana (*p) )
+ {
base[baselen++] = p[0];
- p++;
+ p++;
+ }
+ else
+ {
+ if (isdoschar (*p) && *p != '.')
+ base[baselen++] = p[0];
+ p++;
+ }
+ }
}
- }
else
- {
+ {
if (isdoschar(*p) && *p != '.')
base[baselen++] = *p;
p++;
+ }
}
- }
base[baselen] = 0;
csum = csum % (36*36);
- sprintf(s,"%s%c%c%c",base,magic_char,base36(csum/36),base36(csum%36));
+ sprintf(s,"%s%c%c%c",base,magic_char,base36(csum/36),base36(csum%36));
- if (*extension)
+ if( *extension )
{
- strcat(s,".");
- strcat(s,extension);
+ strcat(s,".");
+ strcat(s,extension);
}
DEBUG(5,("%s\n",s));
-}
+
+ } /* mangle_name_83 */
@@ -606,68 +675,74 @@ void mangle_name_83(char *s)
work out if a name is illegal, even for long names
******************************************************************/
static BOOL illegal_name(char *name)
-{
+ {
static unsigned char illegal[256];
static BOOL initialised=False;
unsigned char *s;
- if (!initialised)
- {
+ if( !initialised )
+ {
char *ill = "*\\/?<>|\":";
initialised = True;
bzero((char *)illegal,256);
- for (s = (unsigned char *)ill; *s; s++)
+ for( s = (unsigned char *)ill; *s; s++ )
illegal[*s] = True;
- }
+ }
if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- for (s = (unsigned char *)name; *s;) {
- if (is_shift_jis (*s)) {
+ {
+ for (s = (unsigned char *)name; *s;)
+ {
+ if (is_shift_jis (*s))
s += 2;
- } else if (illegal[*s]) {
- return(True);
- } else {
- s++;
+ else
+ {
+ if (illegal[*s])
+ return(True);
+ else
+ s++;
+ }
}
}
- }
else
- {
+ {
for (s = (unsigned char *)name;*s;s++)
if (illegal[*s]) return(True);
- }
+ }
return(False);
-}
+ } /* illegal_name */
/****************************************************************************
convert a filename to DOS format. return True if successful.
****************************************************************************/
BOOL name_map_mangle(char *OutName,BOOL need83,int snum)
-{
+ {
#ifdef MANGLE_LONG_FILENAMES
- if (!need83 && illegal_name(OutName)) need83 = True;
+ if( !need83 && illegal_name(OutName) )
+ need83 = True;
#endif
/* apply any name mappings */
{
- char *map = lp_mangled_map(snum);
- if (map && *map)
- do_fwd_mangled_map(OutName,map);
+ char *map = lp_mangled_map(snum);
+
+ if (map && *map)
+ do_fwd_mangled_map(OutName,map);
}
/* check if it's already in 8.3 format */
- if (need83 && !is_8_3(OutName, True)) {
- if (!lp_manglednames(snum)) return(False);
+ if( need83 && !is_8_3(OutName, True) )
+ {
+ if( !lp_manglednames(snum) )
+ return(False);
/* mangle it into 8.3 */
push_mangled_name(OutName);
mangle_name_83(OutName);
- }
+ }
return(True);
-}
-
+ } /* name_map_mangle */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index e4e5872035..908cf984b8 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -3137,7 +3137,7 @@ BOOL reload_services(BOOL test)
}
}
- create_mangled_stack(lp_mangledstack());
+ reset_mangled_stack( lp_mangledstack() );
/* this forces service parameters to be flushed */
become_service(-1,True);