static void name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, int snum) { smb_ucs2_t *OutName_ucs2; magic_char = lp_magicchar(snum); 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(0, ("push_ucs2_allocate failed!\n")); return; } if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False))) need83 = 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; /* mangle it into 8.3 */ if (cache83) tmp = SMB_STRDUP(OutName); 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); }
static BOOL check_cache( char *s, size_t maxlen, int snum ) { TDB_DATA data_val; char *ext_start = NULL; char *saved_ext = NULL; magic_char = lp_magicchar(snum); /* If the cache isn't initialized, give up. */ if( !tdb_mangled_cache ) 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, '.' ); if( ext_start ) { if((saved_ext = SMB_STRDUP(ext_start)) == NULL) 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. */ } } /* 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 ); } /* If we *did* find it, we need to copy it into the string buffer. */ (void)safe_strcpy( s, 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); } SAFE_FREE(data_val.dptr); return( True ); }
static bool must_mangle(const char *name, const struct share_params *p) { smb_ucs2_t *name_ucs2 = NULL; NTSTATUS status; size_t converted_size; char magic_char; magic_char = lp_magicchar(p); if (!push_ucs2_talloc(NULL, &name_ucs2, name, &converted_size)) { DEBUG(0, ("push_ucs2_talloc failed!\n")); return False; } status = is_valid_name(name_ucs2, False, False); TALLOC_FREE(name_ucs2); return NT_STATUS_IS_OK(status); }
/* ************************************************************************** ** * Return True if the name *could be* a mangled name. * * Input: s - A path name - in UNIX pathname format. * * Output: True if the name matches the pattern described below in the * notes, else False. * * Notes: The input name is *not* tested for 8.3 compliance. This must be * done separately. This function returns true if the name contains * a magic character followed by excactly two characters from the * basechars list (above), which in turn are followed either by the * nul (end of string) byte or a dot (extension) or by a '/' (end of * a directory name). * * ************************************************************************** ** */ static BOOL is_mangled(const char *s, int snum) { char *magic; magic_char = lp_magicchar(snum); if( !ct_initialized ) init_chartest(); magic = strchr_m( s, magic_char ); while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */ if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */ && isbasechar( toupper_ascii(magic[1]) ) /* is 2nd char basechar? */ && isbasechar( toupper_ascii(magic[2]) ) ) /* is 3rd char basechar? */ return( True ); /* If all above, then true, */ magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */ } return( False ); }
static bool is_mangled(const char *s, const struct share_params *p) { char *magic; char magic_char; magic_char = lp_magicchar(p); if (chartest == NULL) { init_chartest(); } magic = strchr_m( s, magic_char ); while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */ if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */ && isbasechar( toupper_m(magic[1]) ) /* is 2nd char basechar? */ && isbasechar( toupper_m(magic[2]) ) ) /* is 3rd char basechar? */ return( True ); /* If all above, then true, */ magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */ } return( False ); }
static bool must_mangle(const char *name, const struct share_params *p) { smb_ucs2_t *name_ucs2 = NULL; NTSTATUS status; size_t converted_size; char magic_char; magic_char = lp_magicchar(p); if (!push_ucs2_talloc(NULL, &name_ucs2, name, &converted_size)) { DEBUG(0, ("push_ucs2_talloc failed!\n")); return False; } status = is_valid_name(name_ucs2, False, False); TALLOC_FREE(name_ucs2); /* We return true if we *must* mangle, so if it's * a valid name (status == OK) then we must return * false. Bug #6939. */ return !NT_STATUS_IS_OK(status); }
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 *in_ucs2 = NULL; size_t converted_size; char magic_char; magic_char = lp_magicchar(p); DEBUG(5,("hash_name_to_8_3( %s, cache83 = %s)\n", in, cache83 ? "True" : "False")); if (!push_ucs2_talloc(NULL, &in_ucs2, in, &converted_size)) { DEBUG(0, ("push_ucs2_talloc failed!\n")); return False; } /* 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))) { TALLOC_FREE(in_ucs2); strlcpy(out, in, 13); return True; } TALLOC_FREE(in_ucs2); if (!to_8_3(magic_char, in, out, default_case)) { return False; } cache_mangled_name(out, in); DEBUG(5,("hash_name_to_8_3(%s) ==> [%s]\n", in, out)); return True; }
static bool is_8_3(const char *fname, bool check_case, bool allow_wildcards, const struct share_params *p) { const char *f; smb_ucs2_t *ucs2name; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; size_t size; char magic_char; magic_char = lp_magicchar(p); if (!fname || !*fname) return False; if ((f = strrchr(fname, '/')) == NULL) f = fname; else f++; if (strlen(f) > 12) return False; if (!push_ucs2_talloc(NULL, &ucs2name, f, &size)) { DEBUG(0,("is_8_3: internal error push_ucs2_talloc() failed!\n")); goto done; } ret = is_8_3_w(ucs2name, allow_wildcards); done: TALLOC_FREE(ucs2name); if (!NT_STATUS_IS_OK(ret)) { return False; } return True; }
/**************************************************************************** load parameters specific to a connection/service ****************************************************************************/ BOOL become_service(connection_struct *conn,BOOL do_chdir) { extern char magic_char; static connection_struct *last_conn; int snum; if (!conn) { last_conn = NULL; return(False); } conn->lastused = smb_last_time.tv_sec; snum = SNUM(conn); if (do_chdir && dos_ChDir(conn->connectpath) != 0 && dos_ChDir(conn->origpath) != 0) { DEBUG(0,("chdir (%s) failed\n", conn->connectpath)); return(False); } if (conn == last_conn) return(True); last_conn = conn; case_default = lp_defaultcase(snum); case_preserve = lp_preservecase(snum); short_case_preserve = lp_shortpreservecase(snum); case_mangle = lp_casemangle(snum); case_sensitive = lp_casesensitive(snum); magic_char = lp_magicchar(snum); use_mangled_map = (*lp_mangled_map(snum) ? True:False); return(True); }
static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p) { const char *f; smb_ucs2_t *ucs2name; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; size_t size; magic_char = lp_magicchar(p); if (!fname || !*fname) return False; if ((f = strrchr(fname, '/')) == NULL) f = fname; else f++; 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")); goto done; } ret = is_8_3_w(ucs2name, allow_wildcards); done: SAFE_FREE(ucs2name); if (!NT_STATUS_IS_OK(ret)) { return False; } return True; }
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 *saved_ext = NULL; char *s = talloc_strdup(ctx, in); char magic_char; magic_char = lp_magicchar(p); /* If the cache isn't initialized, give up. */ 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) { char *ext_start = strrchr( s, '.' ); if( ext_start ) { 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. */ } } /* Okay, if we haven't found it we're done. */ if(data_val.dptr == NULL || data_val.dsize == 0) { TALLOC_FREE(saved_ext); TALLOC_FREE(s); return False; } /* 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 *out ? True : False; }