mirror of
https://github.com/samba-team/samba.git
synced 2025-03-26 18:50:30 +03:00
r25009: Large patch discussed with Volker. Move unix_convert to a talloc-based
interface. More development will come on top of this. Remove the "mangled map" parameter. Jeremy. (This used to be commit dee8beba7a92b8a3f68bbcc59fd0a827f68c7736)
This commit is contained in:
parent
c5d8fd3772
commit
132ee3990a
@ -511,7 +511,7 @@ AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \
|
||||
auth/auth_compat.o auth/auth_ntlmssp.o \
|
||||
$(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
|
||||
|
||||
MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
|
||||
MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_hash2.o
|
||||
|
||||
SMBD_OBJ_MAIN = smbd/server.o
|
||||
|
||||
|
@ -7,12 +7,17 @@
|
||||
struct mangle_fns {
|
||||
void (*reset)(void);
|
||||
BOOL (*is_mangled)(const char *s, const struct share_params *p);
|
||||
BOOL (*must_mangle)(const char *s, const struct share_params *p);
|
||||
BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards,
|
||||
const struct share_params *p);
|
||||
BOOL (*check_cache)(char *s, size_t maxlen,
|
||||
const struct share_params *p);
|
||||
void (*name_map)(char *OutName, BOOL need83, BOOL cache83,
|
||||
int default_case,
|
||||
const struct share_params *p);
|
||||
BOOL (*lookup_name_from_8_3)(TALLOC_CTX *ctx,
|
||||
const char *in,
|
||||
char **out, /* talloced on the given context. */
|
||||
const struct share_params *p);
|
||||
BOOL (*name_to_8_3)(const char *in,
|
||||
char out[13],
|
||||
BOOL cache83,
|
||||
int default_case,
|
||||
const struct share_params *p);
|
||||
};
|
||||
#endif /* _MANGLE_H_ */
|
||||
|
@ -804,6 +804,71 @@ char *strdup_upper(const char *s)
|
||||
return SMB_STRDUP(out_buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
talloc_strdup() a unix string to upper case.
|
||||
**/
|
||||
|
||||
char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
|
||||
{
|
||||
char *out_buffer = talloc_strdup(ctx,s);
|
||||
const unsigned char *p = (const unsigned char *)s;
|
||||
unsigned char *q = (unsigned char *)out_buffer;
|
||||
|
||||
if (!q) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this is quite a common operation, so we want it to be
|
||||
fast. We optimise for the ascii case, knowing that all our
|
||||
supported multi-byte character sets are ascii-compatible
|
||||
(ie. they match for the first 128 chars) */
|
||||
|
||||
while (1) {
|
||||
if (*p & 0x80)
|
||||
break;
|
||||
*q++ = toupper_ascii(*p);
|
||||
if (!*p)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p) {
|
||||
/* MB case. */
|
||||
size_t size;
|
||||
smb_ucs2_t *ubuf = NULL;
|
||||
|
||||
/* We're not using the ascii buffer above. */
|
||||
TALLOC_FREE(out_buffer);
|
||||
|
||||
size = convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE,
|
||||
s, strlen(s),
|
||||
(void *)&ubuf,
|
||||
True);
|
||||
if (size == (size_t)-1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strupper_w(ubuf);
|
||||
|
||||
size = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
|
||||
ubuf, size,
|
||||
(void *)&out_buffer,
|
||||
True);
|
||||
|
||||
/* Don't need the intermediate buffer
|
||||
* anymore.
|
||||
*/
|
||||
|
||||
TALLOC_FREE(ubuf);
|
||||
|
||||
if (size == (size_t)-1) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return out_buffer;
|
||||
}
|
||||
|
||||
size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
|
||||
{
|
||||
size_t size;
|
||||
|
@ -370,7 +370,6 @@ typedef struct {
|
||||
char **szHostsdeny;
|
||||
char *szMagicScript;
|
||||
char *szMagicOutput;
|
||||
char *szMangledMap;
|
||||
char *szVetoFiles;
|
||||
char *szHideFiles;
|
||||
char *szVetoOplockFiles;
|
||||
@ -511,7 +510,6 @@ static service sDefault = {
|
||||
NULL, /* szHostsdeny */
|
||||
NULL, /* szMagicScript */
|
||||
NULL, /* szMagicOutput */
|
||||
NULL, /* szMangledMap */
|
||||
NULL, /* szVetoFiles */
|
||||
NULL, /* szHideFiles */
|
||||
NULL, /* szVetoOplockFiles */
|
||||
@ -1122,7 +1120,6 @@ static struct parm_struct parm_table[] = {
|
||||
{"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
|
||||
{"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
|
||||
{"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
|
||||
{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
|
||||
{"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
|
||||
@ -2068,7 +2065,6 @@ FN_LOCAL_STRING(lp_fstype, fstype)
|
||||
FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
|
||||
FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
|
||||
static FN_LOCAL_STRING(lp_volume, volume)
|
||||
FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
|
||||
FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
|
||||
FN_LOCAL_STRING(lp_hide_files, szHideFiles)
|
||||
FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
|
||||
|
@ -659,13 +659,18 @@ BOOL nt_printing_init(struct messaging_context *msg_ctx)
|
||||
Function to allow filename parsing "the old way".
|
||||
********************************************************************/
|
||||
|
||||
static void driver_unix_convert(char *name,connection_struct *conn,
|
||||
char *saved_last_component, SMB_STRUCT_STAT *pst)
|
||||
static void driver_unix_convert(connection_struct *conn,
|
||||
pstring name,
|
||||
SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
char *new_name = NULL;
|
||||
unix_format(name);
|
||||
unix_clean_name(name);
|
||||
trim_string(name,"/","/");
|
||||
unix_convert(conn, name, False, saved_last_component, pst);
|
||||
unix_convert(conn, name, False, &new_name, NULL, pst);
|
||||
if (new_name) {
|
||||
pstrcpy(name, new_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -1288,7 +1293,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
/* Get file version info (if available) for previous file (if it exists) */
|
||||
pstrcpy(filepath, old_file);
|
||||
|
||||
driver_unix_convert(filepath,conn,NULL,&stat_buf);
|
||||
driver_unix_convert(conn,filepath,&stat_buf);
|
||||
|
||||
status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
|
||||
FILE_GENERIC_READ,
|
||||
@ -1324,7 +1329,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
|
||||
|
||||
/* Get file version info (if available) for new file */
|
||||
pstrcpy(filepath, new_file);
|
||||
driver_unix_convert(filepath,conn,NULL,&stat_buf);
|
||||
driver_unix_convert(conn,filepath,&stat_buf);
|
||||
|
||||
status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
|
||||
FILE_GENERIC_READ,
|
||||
@ -1452,7 +1457,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
|
||||
* deriver the cversion. */
|
||||
slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
|
||||
|
||||
driver_unix_convert(driverpath,conn,NULL,&st);
|
||||
driver_unix_convert(conn,driverpath,&st);
|
||||
|
||||
if ( !vfs_file_exist( conn, driverpath, &st ) ) {
|
||||
*perr = WERR_BADFILE;
|
||||
@ -1793,7 +1798,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
*/
|
||||
DEBUG(5,("Creating first directory\n"));
|
||||
slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
|
||||
driver_unix_convert(new_dir, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_dir,&st);
|
||||
create_directory(conn, new_dir);
|
||||
|
||||
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
|
||||
@ -1819,7 +1824,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_name,&st);
|
||||
if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
@ -1835,7 +1840,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_name,&st);
|
||||
if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
@ -1853,7 +1858,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_name,&st);
|
||||
if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
@ -1872,7 +1877,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_name,&st);
|
||||
if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
|
||||
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
|
||||
@ -1900,7 +1905,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
|
||||
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
|
||||
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
|
||||
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
|
||||
driver_unix_convert(new_name, conn, NULL, &st);
|
||||
driver_unix_convert(conn,new_name,&st);
|
||||
if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name,
|
||||
OPENX_FILE_EXISTS_TRUNCATE|
|
||||
OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
|
||||
@ -4938,7 +4943,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
|
||||
if ( *info_3->driverpath ) {
|
||||
if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
|
||||
pstrcpy( file, s );
|
||||
driver_unix_convert(file, conn, NULL, &st);
|
||||
driver_unix_convert(conn,file,&st);
|
||||
DEBUG(10,("deleting driverfile [%s]\n", s));
|
||||
unlink_internals(conn, NULL, 0, file, False);
|
||||
}
|
||||
@ -4947,7 +4952,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
|
||||
if ( *info_3->configfile ) {
|
||||
if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
|
||||
pstrcpy( file, s );
|
||||
driver_unix_convert(file, conn, NULL, &st);
|
||||
driver_unix_convert(conn,file,&st);
|
||||
DEBUG(10,("deleting configfile [%s]\n", s));
|
||||
unlink_internals(conn, NULL, 0, file, False);
|
||||
}
|
||||
@ -4956,7 +4961,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
|
||||
if ( *info_3->datafile ) {
|
||||
if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
|
||||
pstrcpy( file, s );
|
||||
driver_unix_convert(file, conn, NULL, &st);
|
||||
driver_unix_convert(conn,file,&st);
|
||||
DEBUG(10,("deleting datafile [%s]\n", s));
|
||||
unlink_internals(conn, NULL, 0, file, False);
|
||||
}
|
||||
@ -4965,7 +4970,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
|
||||
if ( *info_3->helpfile ) {
|
||||
if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
|
||||
pstrcpy( file, s );
|
||||
driver_unix_convert(file, conn, NULL, &st);
|
||||
driver_unix_convert(conn,file,&st);
|
||||
DEBUG(10,("deleting helpfile [%s]\n", s));
|
||||
unlink_internals(conn, NULL, 0, file, False);
|
||||
}
|
||||
@ -4981,7 +4986,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
|
||||
|
||||
if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
|
||||
pstrcpy( file, p );
|
||||
driver_unix_convert(file, conn, NULL, &st);
|
||||
driver_unix_convert(conn,file,&st);
|
||||
DEBUG(10,("deleting dependent file [%s]\n", file));
|
||||
unlink_internals(conn, NULL, 0, file, False);
|
||||
}
|
||||
|
@ -2047,7 +2047,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur
|
||||
connection_struct *conn = NULL;
|
||||
BOOL became_user = False;
|
||||
WERROR status = WERR_OK;
|
||||
pstring tmp_file;
|
||||
char *tmp_file = NULL;
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
@ -2072,26 +2072,29 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur
|
||||
}
|
||||
became_user = True;
|
||||
|
||||
pstrcpy(tmp_file, r->in.file);
|
||||
nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
|
||||
if (!r->in.file) {
|
||||
status = WERR_INVALID_PARAM;
|
||||
goto error_exit;
|
||||
}
|
||||
nt_status = unix_convert(conn, r->in.file, False, &tmp_file, NULL, &st);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
nt_status = check_name(conn, r->in.file);
|
||||
nt_status = check_name(conn, tmp_file);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
|
||||
nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
/* Perhaps it is a directory */
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
|
||||
nt_status = open_directory(conn, NULL, r->in.file, &st,
|
||||
nt_status = open_directory(conn, NULL, tmp_file, &st,
|
||||
READ_CONTROL_ACCESS,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
@ -2100,7 +2103,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur
|
||||
NULL, &fsp);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
@ -2109,7 +2112,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur
|
||||
sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
|
||||
|
||||
if (sd_size == 0) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
@ -2152,7 +2155,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
|
||||
connection_struct *conn = NULL;
|
||||
BOOL became_user = False;
|
||||
WERROR status = WERR_OK;
|
||||
pstring tmp_file;
|
||||
char *tmp_file = NULL;
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
@ -2176,28 +2179,31 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
|
||||
}
|
||||
became_user = True;
|
||||
|
||||
pstrcpy(tmp_file, r->in.file);
|
||||
nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
|
||||
if (!r->in.file) {
|
||||
status = WERR_INVALID_PARAM;
|
||||
goto error_exit;
|
||||
}
|
||||
nt_status = unix_convert(conn, r->in.file, False, &tmp_file, NULL, &st);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
nt_status = check_name(conn, r->in.file);
|
||||
nt_status = check_name(conn, tmp_file);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
|
||||
nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
|
||||
nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
/* Perhaps it is a directory */
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
|
||||
nt_status = open_directory(conn, NULL, r->in.file, &st,
|
||||
nt_status = open_directory(conn, NULL, tmp_file, &st,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
@ -2206,7 +2212,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
|
||||
NULL, &fsp);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
@ -2215,7 +2221,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
|
||||
nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_file));
|
||||
status = WERR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
@ -380,12 +380,11 @@ static void dptr_close_oldest(BOOL old)
|
||||
wcard must not be zero.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid,
|
||||
NTSTATUS dptr_create(connection_struct *conn, const char *path, BOOL old_handle, BOOL expect_close,uint16 spid,
|
||||
const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret)
|
||||
{
|
||||
struct dptr_struct *dptr = NULL;
|
||||
struct smb_Dir *dir_hnd;
|
||||
const char *dir2;
|
||||
NTSTATUS status;
|
||||
|
||||
DEBUG(5,("dptr_create dir=%s\n", path));
|
||||
@ -399,17 +398,12 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO
|
||||
return status;
|
||||
}
|
||||
|
||||
/* use a const pointer from here on */
|
||||
dir2 = path;
|
||||
if (!*dir2)
|
||||
dir2 = ".";
|
||||
|
||||
dir_hnd = OpenDir(conn, dir2, wcard, attr);
|
||||
dir_hnd = OpenDir(conn, path, wcard, attr);
|
||||
if (!dir_hnd) {
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
string_set(&conn->dirpath,dir2);
|
||||
string_set(&conn->dirpath,path);
|
||||
|
||||
if (dirhandles_open >= MAX_OPEN_DIRECTORIES) {
|
||||
dptr_idleoldest();
|
||||
@ -488,7 +482,7 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO
|
||||
|
||||
dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
|
||||
|
||||
string_set(&dptr->path,dir2);
|
||||
string_set(&dptr->path,path);
|
||||
dptr->conn = conn;
|
||||
dptr->dir_hnd = dir_hnd;
|
||||
dptr->spid = spid;
|
||||
@ -758,10 +752,15 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype)
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
|
||||
static BOOL mangle_mask_match(connection_struct *conn, const char *filename,
|
||||
char *mask)
|
||||
{
|
||||
mangle_map(filename,True,False,conn->params);
|
||||
return mask_match_search(filename,mask,False);
|
||||
char mname[13];
|
||||
|
||||
if (!name_to_8_3(filename,mname,False,conn->params)) {
|
||||
return False;
|
||||
}
|
||||
return mask_match_search(mname,mask,False);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -806,9 +805,14 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn
|
||||
mask_match_search(filename,mask,False) ||
|
||||
mangle_mask_match(conn,filename,mask)) {
|
||||
|
||||
if (!mangle_is_8_3(filename, False, conn->params))
|
||||
mangle_map(filename,True,False,
|
||||
conn->params);
|
||||
if (!mangle_is_8_3(filename, False, conn->params)) {
|
||||
char mname[13];
|
||||
if (!name_to_8_3(filename,mname,False,
|
||||
conn->params)) {
|
||||
continue;
|
||||
}
|
||||
pstrcpy(filename,mname);
|
||||
}
|
||||
|
||||
pstrcpy(fname,filename);
|
||||
*path = 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
filename handling routines
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Jeremy Allison 1999-2004
|
||||
Copyright (C) Jeremy Allison 1999-2007
|
||||
Copyright (C) Ying Chen 2000
|
||||
Copyright (C) Volker Lendecke 2007
|
||||
|
||||
@ -37,11 +37,12 @@ static BOOL mangled_equal(const char *name1,
|
||||
const char *name2,
|
||||
const struct share_params *p)
|
||||
{
|
||||
pstring tmpname;
|
||||
char mname[13];
|
||||
|
||||
pstrcpy(tmpname, name2);
|
||||
mangle_map(tmpname, True, False, p);
|
||||
return strequal(name1, tmpname);
|
||||
if (!name_to_8_3(name2, mname, False, p)) {
|
||||
return False;
|
||||
}
|
||||
return strequal(name1, mname);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -107,9 +108,10 @@ for nlinks = 0, which can never be true for any file).
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS unix_convert(connection_struct *conn,
|
||||
pstring orig_path,
|
||||
const char *orig_path,
|
||||
BOOL allow_wcard_last_component,
|
||||
char *saved_last_component,
|
||||
char **pp_conv_path,
|
||||
char **pp_saved_last_component,
|
||||
SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
SMB_STRUCT_STAT st;
|
||||
@ -119,16 +121,20 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
BOOL component_was_mangled = False;
|
||||
BOOL name_has_wildcard = False;
|
||||
NTSTATUS result;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
|
||||
SET_STAT_INVALID(*pst);
|
||||
|
||||
if(saved_last_component) {
|
||||
*saved_last_component = 0;
|
||||
*pp_conv_path = NULL;
|
||||
if(pp_saved_last_component) {
|
||||
*pp_saved_last_component = NULL;
|
||||
}
|
||||
|
||||
if (conn->printer) {
|
||||
/* we don't ever use the filenames on a printer share as a
|
||||
filename - so don't convert them */
|
||||
if (!(*pp_conv_path = talloc_strdup(ctx,orig_path))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -157,11 +163,13 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if (!*orig_path) {
|
||||
if (!(name = SMB_STRDUP("."))) {
|
||||
if (!(name = talloc_strdup(ctx,"."))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (SMB_VFS_STAT(conn,name,&st) == 0) {
|
||||
*pst = st;
|
||||
} else {
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
DEBUG(5,("conversion finished \"\" -> %s\n",name));
|
||||
goto done;
|
||||
@ -183,17 +191,18 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
* Ensure saved_last_component is valid even if file exists.
|
||||
*/
|
||||
|
||||
if(saved_last_component) {
|
||||
if(pp_saved_last_component) {
|
||||
end = strrchr_m(orig_path, '/');
|
||||
if (end) {
|
||||
pstrcpy(saved_last_component, end + 1);
|
||||
*pp_saved_last_component = talloc_strdup(ctx, end + 1);
|
||||
} else {
|
||||
pstrcpy(saved_last_component, orig_path);
|
||||
*pp_saved_last_component = talloc_strdup(ctx,
|
||||
orig_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(name = SMB_STRDUP(orig_path))) {
|
||||
DEBUG(0, ("strdup failed\n"));
|
||||
if (!(name = talloc_strdup(ctx, orig_path))) {
|
||||
DEBUG(0, ("talloc_strdup failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -224,9 +233,9 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
* building the directories with asprintf and free it.
|
||||
*/
|
||||
|
||||
if ((dirpath == NULL) && (!(dirpath = SMB_STRDUP("")))) {
|
||||
DEBUG(0, ("strdup failed\n"));
|
||||
SAFE_FREE(name);
|
||||
if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
|
||||
DEBUG(0, ("talloc_strdup failed\n"));
|
||||
TALLOC_FREE(name);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -264,8 +273,7 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if (conn->case_sensitive &&
|
||||
!mangle_is_mangled(name, conn->params) &&
|
||||
!*lp_mangled_map(conn->params)) {
|
||||
!mangle_is_mangled(name, conn->params)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -302,8 +310,14 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
*end = 0;
|
||||
}
|
||||
|
||||
if (saved_last_component != 0) {
|
||||
pstrcpy(saved_last_component, end ? end + 1 : start);
|
||||
if (pp_saved_last_component) {
|
||||
TALLOC_FREE(*pp_saved_last_component);
|
||||
*pp_saved_last_component = talloc_strdup(ctx,
|
||||
end ? end + 1 : start);
|
||||
if (!*pp_saved_last_component) {
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* The name cannot have a component of "." */
|
||||
@ -473,25 +487,27 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if (mangle_is_mangled(start, conn->params)
|
||||
&& mangle_check_cache_alloc(start,
|
||||
&unmangled,
|
||||
conn->params)) {
|
||||
&& mangle_lookup_name_from_8_3(ctx,
|
||||
start,
|
||||
&unmangled,
|
||||
conn->params)) {
|
||||
char *tmp;
|
||||
size_t start_ofs = start - name;
|
||||
|
||||
if (*dirpath != '\0') {
|
||||
asprintf(&tmp, "%s/%s", dirpath,
|
||||
unmangled);
|
||||
SAFE_FREE(unmangled);
|
||||
tmp = talloc_asprintf(ctx,
|
||||
"%s/%s", dirpath,
|
||||
unmangled);
|
||||
TALLOC_FREE(unmangled);
|
||||
}
|
||||
else {
|
||||
tmp = unmangled;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
DEBUG(0, ("malloc failed\n"));
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
SAFE_FREE(name);
|
||||
TALLOC_FREE(name);
|
||||
name = tmp;
|
||||
start = name + start_ofs;
|
||||
end = start + strlen(start);
|
||||
@ -511,18 +527,20 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
size_t start_ofs = start - name;
|
||||
|
||||
if (*dirpath != '\0') {
|
||||
asprintf(&tmp, "%s/%s/%s", dirpath,
|
||||
found_name, end+1);
|
||||
tmp = talloc_asprintf(ctx,
|
||||
"%s/%s/%s", dirpath,
|
||||
found_name, end+1);
|
||||
}
|
||||
else {
|
||||
asprintf(&tmp, "%s/%s", found_name,
|
||||
end+1);
|
||||
tmp = talloc_asprintf(ctx,
|
||||
"%s/%s", found_name,
|
||||
end+1);
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
DEBUG(0, ("asprintf failed\n"));
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
DEBUG(0, ("talloc_asprintf failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
SAFE_FREE(name);
|
||||
TALLOC_FREE(name);
|
||||
name = tmp;
|
||||
start = name + start_ofs;
|
||||
end = start + strlen(found_name);
|
||||
@ -532,18 +550,19 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
size_t start_ofs = start - name;
|
||||
|
||||
if (*dirpath != '\0') {
|
||||
asprintf(&tmp, "%s/%s", dirpath,
|
||||
found_name);
|
||||
tmp = talloc_asprintf(ctx,
|
||||
"%s/%s", dirpath,
|
||||
found_name);
|
||||
}
|
||||
else {
|
||||
tmp = SMB_STRDUP(found_name);
|
||||
tmp = talloc_strdup(ctx,
|
||||
found_name);
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
DEBUG(0, ("malloc failed\n"));
|
||||
result = NT_STATUS_NO_MEMORY;
|
||||
goto fail;
|
||||
DEBUG(0, ("talloc failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
SAFE_FREE(name);
|
||||
TALLOC_FREE(name);
|
||||
name = tmp;
|
||||
start = name + start_ofs;
|
||||
|
||||
@ -560,7 +579,7 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(found_name);
|
||||
TALLOC_FREE(found_name);
|
||||
} /* end else */
|
||||
|
||||
#ifdef DEVELOPER
|
||||
@ -577,19 +596,19 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
*/
|
||||
|
||||
if (*dirpath != '\0') {
|
||||
char *tmp;
|
||||
|
||||
if (asprintf(&tmp, "%s/%s", dirpath, start) == -1) {
|
||||
DEBUG(0, ("asprintf failed\n"));
|
||||
char *tmp = talloc_asprintf(ctx,
|
||||
"%s/%s", dirpath, start);
|
||||
if (!tmp) {
|
||||
DEBUG(0, ("talloc_asprintf failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
SAFE_FREE(dirpath);
|
||||
TALLOC_FREE(dirpath);
|
||||
dirpath = tmp;
|
||||
}
|
||||
else {
|
||||
SAFE_FREE(dirpath);
|
||||
if (!(dirpath = SMB_STRDUP(start))) {
|
||||
DEBUG(0, ("strdup failed\n"));
|
||||
TALLOC_FREE(dirpath);
|
||||
if (!(dirpath = talloc_strdup(ctx,start))) {
|
||||
DEBUG(0, ("talloc_strdup failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -628,17 +647,23 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
|
||||
|
||||
done:
|
||||
pstrcpy(orig_path, name);
|
||||
SAFE_FREE(name);
|
||||
SAFE_FREE(dirpath);
|
||||
*pp_conv_path = name;
|
||||
TALLOC_FREE(dirpath);
|
||||
return NT_STATUS_OK;
|
||||
fail:
|
||||
DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
|
||||
pstrcpy(orig_path, dirpath);
|
||||
pstrcat(orig_path, "/");
|
||||
pstrcat(orig_path, start);
|
||||
SAFE_FREE(name);
|
||||
SAFE_FREE(dirpath);
|
||||
if (*dirpath != '\0') {
|
||||
*pp_conv_path = talloc_asprintf(ctx,
|
||||
"%s/%s", dirpath, start);
|
||||
} else {
|
||||
*pp_conv_path = talloc_strdup(ctx, start);
|
||||
}
|
||||
if (!*pp_conv_path) {
|
||||
DEBUG(0, ("talloc_asprintf failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
TALLOC_FREE(name);
|
||||
TALLOC_FREE(dirpath);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -649,7 +674,7 @@ NTSTATUS unix_convert(connection_struct *conn,
|
||||
a valid one for the user to access.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS check_name(connection_struct *conn, const pstring name)
|
||||
NTSTATUS check_name(connection_struct *conn, const char *name)
|
||||
{
|
||||
if (IS_VETO_PATH(conn, name)) {
|
||||
/* Is it not dot or dot dot. */
|
||||
@ -682,8 +707,9 @@ static BOOL fname_equal(const char *name1, const char *name2,
|
||||
BOOL case_sensitive)
|
||||
{
|
||||
/* Normal filename handling */
|
||||
if (case_sensitive)
|
||||
if (case_sensitive) {
|
||||
return(strcmp(name1,name2) == 0);
|
||||
}
|
||||
|
||||
return(strequal(name1,name2));
|
||||
}
|
||||
@ -701,17 +727,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path,
|
||||
BOOL mangled;
|
||||
char *unmangled_name = NULL;
|
||||
long curpos;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
|
||||
mangled = mangle_is_mangled(name, conn->params);
|
||||
|
||||
/* handle null paths */
|
||||
if ((path == NULL) || (*path == 0))
|
||||
if ((path == NULL) || (*path == 0)) {
|
||||
path = ".";
|
||||
}
|
||||
|
||||
/*
|
||||
* The incoming name can be mangled, and if we de-mangle it
|
||||
* here it will not compare correctly against the filename (name2)
|
||||
* read from the directory and then mangled by the mangle_map()
|
||||
* read from the directory and then mangled by the name_to_8_3()
|
||||
* call. We need to mangle both names or neither.
|
||||
* (JRA).
|
||||
*
|
||||
@ -724,15 +752,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path,
|
||||
*/
|
||||
|
||||
if (mangled && !conn->case_sensitive) {
|
||||
mangled = !mangle_check_cache_alloc(name, &unmangled_name,
|
||||
conn->params);
|
||||
name = unmangled_name;
|
||||
mangled = !mangle_lookup_name_from_8_3(ctx,
|
||||
name,
|
||||
&unmangled_name,
|
||||
conn->params);
|
||||
if (mangled) {
|
||||
name = unmangled_name;
|
||||
}
|
||||
}
|
||||
|
||||
/* open the directory */
|
||||
if (!(cur_dir = OpenDir(conn, path, NULL, 0))) {
|
||||
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
|
||||
SAFE_FREE(unmangled_name);
|
||||
TALLOC_FREE(unmangled_name);
|
||||
return(False);
|
||||
}
|
||||
|
||||
@ -741,8 +773,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path,
|
||||
while ((dname = ReadDirName(cur_dir, &curpos))) {
|
||||
|
||||
/* Is it dot or dot dot. */
|
||||
if ((dname[0] == '.') && (!dname[1] ||
|
||||
(dname[1] == '.' && !dname[2]))) {
|
||||
if (ISDOT(dname) || ISDOTDOT(dname)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -760,15 +791,19 @@ static BOOL scan_directory(connection_struct *conn, const char *path,
|
||||
if ((mangled && mangled_equal(name,dname,conn->params)) ||
|
||||
fname_equal(name, dname, conn->case_sensitive)) {
|
||||
/* we've found the file, change it's name and return */
|
||||
*found_name = SMB_STRDUP(dname);
|
||||
SAFE_FREE(unmangled_name);
|
||||
*found_name = talloc_strdup(ctx,dname);
|
||||
TALLOC_FREE(unmangled_name);
|
||||
CloseDir(cur_dir);
|
||||
if (!*found_name) {
|
||||
errno = ENOMEM;
|
||||
return False;
|
||||
}
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(unmangled_name);
|
||||
TALLOC_FREE(unmangled_name);
|
||||
CloseDir(cur_dir);
|
||||
errno = ENOENT;
|
||||
return(False);
|
||||
return False;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Name mangling interface
|
||||
Copyright (C) Andrew Tridgell 2002
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@ -100,50 +100,51 @@ BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case,
|
||||
return mangle_fns->is_8_3(fname, check_case, True, p);
|
||||
}
|
||||
|
||||
BOOL mangle_must_mangle(const char *fname,
|
||||
const struct share_params *p)
|
||||
{
|
||||
if (!lp_manglednames(p)) {
|
||||
return False;
|
||||
}
|
||||
return mangle_fns->must_mangle(fname, p);
|
||||
}
|
||||
|
||||
/*
|
||||
try to reverse map a 8.3 name to the original filename. This doesn't have to
|
||||
try to reverse map a 8.3 name to the original filename. This doesn't have to
|
||||
always succeed, as the directory handling code in smbd will scan the directory
|
||||
looking for a matching name if it doesn't. It should succeed most of the time
|
||||
or there will be a huge performance penalty
|
||||
*/
|
||||
BOOL mangle_check_cache(char *s, size_t maxlen,
|
||||
BOOL mangle_lookup_name_from_8_3(TALLOC_CTX *ctx,
|
||||
const char *in,
|
||||
char **out, /* talloced on the given context. */
|
||||
const struct share_params *p)
|
||||
{
|
||||
return mangle_fns->check_cache(s, maxlen, p);
|
||||
return mangle_fns->lookup_name_from_8_3(ctx, in, out, p);
|
||||
}
|
||||
|
||||
BOOL mangle_check_cache_alloc(const char *name, char **presult,
|
||||
const struct share_params *p)
|
||||
{
|
||||
pstring tmp;
|
||||
char *result;
|
||||
pstrcpy(tmp, name);
|
||||
|
||||
if (!mangle_check_cache(tmp, sizeof(pstring)-1, p)
|
||||
|| !(result = SMB_STRDUP(tmp))) {
|
||||
return False;
|
||||
}
|
||||
*presult = result;
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
map a long filename to a 8.3 name.
|
||||
/*
|
||||
mangle a long filename to a 8.3 name.
|
||||
Return True if we did mangle the name (ie. out is filled in).
|
||||
False on error.
|
||||
JRA.
|
||||
*/
|
||||
|
||||
void mangle_map(pstring OutName, BOOL need83, BOOL cache83,
|
||||
BOOL name_to_8_3(const char *in,
|
||||
char out[13],
|
||||
BOOL cache83,
|
||||
const struct share_params *p)
|
||||
{
|
||||
/* name mangling can be disabled for speed, in which case
|
||||
we just truncate the string */
|
||||
if (!lp_manglednames(p)) {
|
||||
if (need83) {
|
||||
string_truncate(OutName, 12);
|
||||
}
|
||||
return;
|
||||
safe_strcpy(out,in,12);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* invoke the inane "mangled map" code */
|
||||
mangle_map_filename(OutName, p);
|
||||
mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(p->service), p);
|
||||
return mangle_fns->name_to_8_3(in,
|
||||
out,
|
||||
cache83,
|
||||
lp_defaultcase(p->service),
|
||||
p);
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
/*
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Name mangling
|
||||
Copyright (C) Andrew Tridgell 1992-2002
|
||||
Copyright (C) Simo Sorce 2001
|
||||
Copyright (C) Andrew Bartlett 2002
|
||||
|
||||
Copyright (C) Jeremy Allison 2007
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@ -244,14 +245,14 @@ static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards)
|
||||
|
||||
if (strlen_w(fname) > 12)
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
|
||||
if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
|
||||
return NT_STATUS_OK;
|
||||
|
||||
/* Name cannot start with '.' */
|
||||
if (*fname == UCS2_CHAR('.'))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
|
||||
if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
|
||||
goto done;
|
||||
|
||||
@ -293,7 +294,7 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards,
|
||||
|
||||
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"));
|
||||
@ -305,15 +306,13 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards,
|
||||
done:
|
||||
SAFE_FREE(ucs2name);
|
||||
|
||||
if (!NT_STATUS_IS_OK(ret)) {
|
||||
if (!NT_STATUS_IS_OK(ret)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Functions...
|
||||
*/
|
||||
@ -330,10 +329,11 @@ done:
|
||||
*
|
||||
* ************************************************************************** **
|
||||
*/
|
||||
|
||||
static void init_chartest( void )
|
||||
{
|
||||
const unsigned char *s;
|
||||
|
||||
|
||||
memset( (char *)chartest, '\0', 256 );
|
||||
|
||||
for( s = (const unsigned char *)basechars; *s; s++ ) {
|
||||
@ -360,6 +360,7 @@ static void init_chartest( void )
|
||||
*
|
||||
* ************************************************************************** **
|
||||
*/
|
||||
|
||||
static BOOL is_mangled(const char *s, const struct share_params *p)
|
||||
{
|
||||
char *magic;
|
||||
@ -406,7 +407,8 @@ static void mangle_reset( void )
|
||||
crh 07-Apr-1998
|
||||
**************************************************************************/
|
||||
|
||||
static void cache_mangled_name( const char mangled_name[13], char *raw_name )
|
||||
static void cache_mangled_name( const char mangled_name[13],
|
||||
const char *raw_name )
|
||||
{
|
||||
TDB_DATA data_val;
|
||||
char mangled_name_key[13];
|
||||
@ -459,30 +461,37 @@ static void cache_mangled_name( const char mangled_name[13], char *raw_name )
|
||||
* ************************************************************************** **
|
||||
*/
|
||||
|
||||
static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p )
|
||||
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 *ext_start = NULL;
|
||||
char *saved_ext = NULL;
|
||||
char *s = talloc_strdup(ctx, in);
|
||||
|
||||
magic_char = lp_magicchar(p);
|
||||
|
||||
/* If the cache isn't initialized, give up. */
|
||||
if( !tdb_mangled_cache )
|
||||
return( False );
|
||||
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) {
|
||||
ext_start = strrchr( s, '.' );
|
||||
char *ext_start = strrchr( s, '.' );
|
||||
if( ext_start ) {
|
||||
if((saved_ext = SMB_STRDUP(ext_start)) == NULL)
|
||||
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.
|
||||
@ -492,31 +501,32 @@ static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p )
|
||||
|
||||
/* 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 );
|
||||
TALLOC_FREE(saved_ext);
|
||||
TALLOC_FREE(s);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* If we *did* find it, we need to copy it into the string buffer. */
|
||||
(void)safe_strcpy( s, (const char *)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);
|
||||
/* 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( True );
|
||||
|
||||
return *out ? True : False;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* do the actual mangling to 8.3 format
|
||||
* the buffer must be able to hold 13 characters (including the null)
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void to_8_3(char *s, int default_case)
|
||||
Do the actual mangling to 8.3 format.
|
||||
*****************************************************************************/
|
||||
|
||||
static BOOL to_8_3(const char *in, char out[13], int default_case)
|
||||
{
|
||||
int csum;
|
||||
char *p;
|
||||
@ -524,11 +534,16 @@ static void to_8_3(char *s, int default_case)
|
||||
char base[9];
|
||||
int baselen = 0;
|
||||
int extlen = 0;
|
||||
char *s = SMB_STRDUP(in);
|
||||
|
||||
extension[0] = 0;
|
||||
base[0] = 0;
|
||||
|
||||
p = strrchr(s,'.');
|
||||
if (!s) {
|
||||
return False;
|
||||
}
|
||||
|
||||
p = strrchr(s,'.');
|
||||
if( p && (strlen(p+1) < (size_t)4) ) {
|
||||
BOOL all_normal = ( strisnormal(p+1, default_case) ); /* XXXXXXXXX */
|
||||
|
||||
@ -557,7 +572,7 @@ static void to_8_3(char *s, int default_case)
|
||||
extension[extlen] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p = s;
|
||||
|
||||
while( *p && baselen < 5 ) {
|
||||
@ -567,79 +582,88 @@ static void to_8_3(char *s, int default_case)
|
||||
p++;
|
||||
}
|
||||
base[baselen] = 0;
|
||||
|
||||
|
||||
csum = csum % (MANGLE_BASE*MANGLE_BASE);
|
||||
|
||||
(void)slprintf(s, 12, "%s%c%c%c",
|
||||
base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
|
||||
|
||||
|
||||
memcpy(out, base, baselen);
|
||||
out[baselen] = magic_char;
|
||||
out[baselen+1] = mangle( csum/MANGLE_BASE );
|
||||
out[baselen+2] = mangle( csum );
|
||||
|
||||
if( *extension ) {
|
||||
(void)pstrcat( s, "." );
|
||||
(void)pstrcat( s, extension );
|
||||
out[baselen+3] = '.';
|
||||
safe_strcpy(&out[baselen+4], extension, 3);
|
||||
}
|
||||
|
||||
SAFE_FREE(s);
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL must_mangle(const char *name,
|
||||
const struct share_params *p)
|
||||
{
|
||||
smb_ucs2_t *name_ucs2 = NULL;
|
||||
NTSTATUS status;
|
||||
magic_char = lp_magicchar(p);
|
||||
|
||||
if (push_ucs2_allocate(&name_ucs2, name) == (size_t)-1) {
|
||||
DEBUG(0, ("push_ucs2_allocate failed!\n"));
|
||||
return False;
|
||||
}
|
||||
status = is_valid_name(name_ucs2, False, False);
|
||||
SAFE_FREE(name_ucs2);
|
||||
return NT_STATUS_IS_OK(status);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Convert a filename to DOS format. Return True if successful.
|
||||
* Input: in Incoming name.
|
||||
*
|
||||
* Input: OutName - Source *and* destination buffer.
|
||||
* out 8.3 DOS name.
|
||||
*
|
||||
* NOTE that OutName must point to a memory space that
|
||||
* is at least 13 bytes in size!
|
||||
*
|
||||
* need83 - If False, name mangling will be skipped unless the
|
||||
* name contains illegal characters. Mapping will still
|
||||
* be done, if appropriate. This is probably used to
|
||||
* signal that a client does not require name mangling,
|
||||
* thus skipping the name mangling even on shares which
|
||||
* have name-mangling turned on.
|
||||
* cache83 - If False, the mangled name cache will not be updated.
|
||||
* This is usually used to prevent that we overwrite
|
||||
* a conflicting cache entry prematurely, i.e. before
|
||||
* we know whether the client is really interested in the
|
||||
* current name. (See PR#13758). UKD.
|
||||
*
|
||||
* Output: Returns False only if the name wanted mangling but the share does
|
||||
* not have name mangling turned on.
|
||||
*
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
static void name_map(char *OutName, BOOL need83, BOOL cache83,
|
||||
int default_case, const struct share_params *p)
|
||||
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 *OutName_ucs2;
|
||||
smb_ucs2_t *in_ucs2 = NULL;
|
||||
magic_char = lp_magicchar(p);
|
||||
|
||||
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(5,("hash_name_to_8_3( %s, cache83 = %s)\n", in,
|
||||
cache83 ? "True" : "False"));
|
||||
|
||||
if (push_ucs2_allocate(&in_ucs2, in) == (size_t)-1) {
|
||||
DEBUG(0, ("push_ucs2_allocate failed!\n"));
|
||||
return;
|
||||
return False;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/* 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))) {
|
||||
SAFE_FREE(in_ucs2);
|
||||
safe_strcpy(out, in, 12);
|
||||
return True;
|
||||
}
|
||||
|
||||
DEBUG(5,("name_map() ==> [%s]\n", OutName));
|
||||
SAFE_FREE(OutName_ucs2);
|
||||
SAFE_FREE(in_ucs2);
|
||||
if (!to_8_3(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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -649,9 +673,10 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83,
|
||||
static struct mangle_fns mangle_fns = {
|
||||
mangle_reset,
|
||||
is_mangled,
|
||||
must_mangle,
|
||||
is_8_3,
|
||||
check_cache,
|
||||
name_map
|
||||
lookup_name_from_8_3,
|
||||
hash_name_to_8_3
|
||||
};
|
||||
|
||||
/* return the methods for this mangling implementation */
|
||||
|
@ -368,18 +368,23 @@ static void mangle_reset(void)
|
||||
|
||||
/*
|
||||
try to find a 8.3 name in the cache, and if found then
|
||||
replace the string with the original long name.
|
||||
replace the string with the original long name.
|
||||
*/
|
||||
static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
|
||||
static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx,
|
||||
const char *name,
|
||||
char **pp_out, /* talloced on the given context. */
|
||||
const struct share_params *p)
|
||||
{
|
||||
unsigned int hash, multiplier;
|
||||
unsigned int i;
|
||||
const char *prefix;
|
||||
char extension[4];
|
||||
|
||||
*pp_out = NULL;
|
||||
|
||||
/* make sure that this is a mangled name from this cache */
|
||||
if (!is_mangled(name, p)) {
|
||||
M_DEBUG(10,("check_cache: %s -> not mangled\n", name));
|
||||
M_DEBUG(10,("lookup_name_from_8_3: %s -> not mangled\n", name));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -394,7 +399,8 @@ static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
|
||||
/* now look in the prefix cache for that hash */
|
||||
prefix = cache_lookup(hash);
|
||||
if (!prefix) {
|
||||
M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash));
|
||||
M_DEBUG(10,("lookup_name_from_8_3: %s -> %08X -> not found\n",
|
||||
name, hash));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -407,17 +413,22 @@ static BOOL check_cache(char *name, size_t maxlen, const struct share_params *p)
|
||||
}
|
||||
|
||||
if (extension[0]) {
|
||||
M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
|
||||
slprintf(name, maxlen, "%s.%s", prefix, extension);
|
||||
M_DEBUG(10,("lookup_name_from_8_3: %s -> %s.%s\n",
|
||||
name, prefix, extension));
|
||||
*pp_out = talloc_asprintf(ctx, "%s.%s", prefix, extension);
|
||||
} else {
|
||||
M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
|
||||
safe_strcpy(name, prefix, maxlen);
|
||||
M_DEBUG(10,("lookup_name_from_8_3: %s -> %s\n", name, prefix));
|
||||
*pp_out = talloc_strdup(ctx, prefix);
|
||||
}
|
||||
|
||||
if (!pp_out) {
|
||||
M_DEBUG(0,("talloc_fail"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
look for a DOS reserved name
|
||||
*/
|
||||
@ -499,18 +510,27 @@ static BOOL is_legal_name(const char *name)
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL must_mangle(const char *name,
|
||||
const struct share_params *p)
|
||||
{
|
||||
if (is_reserved_name(name)) {
|
||||
return True;
|
||||
}
|
||||
return !is_legal_name(name);
|
||||
}
|
||||
|
||||
/*
|
||||
the main forward mapping function, which converts a long filename to
|
||||
a 8.3 name
|
||||
|
||||
if need83 is not set then we only do the mangling if the name is illegal
|
||||
as a long name
|
||||
|
||||
if cache83 is not set then we don't cache the result
|
||||
|
||||
the name parameter must be able to hold 13 bytes
|
||||
*/
|
||||
static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
|
||||
static BOOL hash2_name_to_8_3(const char *name,
|
||||
char new_name[13],
|
||||
BOOL cache83,
|
||||
int default_case,
|
||||
const struct share_params *p)
|
||||
{
|
||||
char *dot_p;
|
||||
char lead_chars[7];
|
||||
@ -518,20 +538,14 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
|
||||
unsigned int extension_length, i;
|
||||
unsigned int prefix_len;
|
||||
unsigned int hash, v;
|
||||
char new_name[13];
|
||||
|
||||
/* reserved names are handled specially */
|
||||
if (!is_reserved_name(name)) {
|
||||
/* if the name is already a valid 8.3 name then we don't need to
|
||||
do anything */
|
||||
if (is_8_3(name, False, False, p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the caller doesn't strictly need 8.3 then just check for illegal
|
||||
filenames */
|
||||
if (!need83 && is_legal_name(name)) {
|
||||
return;
|
||||
/* if the name is already a valid 8.3 name then we don't need to
|
||||
* change anything */
|
||||
if (is_legal_name(name) && is_8_3(name, False, False, p)) {
|
||||
safe_strcpy(new_name, name, 12);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,7 +562,9 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 0 || i == 4) dot_p = NULL;
|
||||
if (i == 0 || i == 4) {
|
||||
dot_p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* the leading characters in the mangled name is taken from
|
||||
@ -580,11 +596,12 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
|
||||
for (i=1; extension_length < 3 && dot_p[i]; i++) {
|
||||
char c = dot_p[i];
|
||||
if (FLAG_CHECK(c, FLAG_ASCII)) {
|
||||
extension[extension_length++] = toupper_ascii(c);
|
||||
extension[extension_length++] =
|
||||
toupper_ascii(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* find the hash for this prefix */
|
||||
v = hash = mangle_hash(name, prefix_len);
|
||||
|
||||
@ -593,7 +610,7 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
|
||||
new_name[i] = lead_chars[i];
|
||||
}
|
||||
new_name[7] = base_forward(v % 36);
|
||||
new_name[6] = '~';
|
||||
new_name[6] = '~';
|
||||
for (i=5; i>=mangle_prefix; i--) {
|
||||
v = v / 36;
|
||||
new_name[i] = base_forward(v % 36);
|
||||
@ -613,22 +630,18 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
|
||||
cache_insert(name, prefix_len, hash);
|
||||
}
|
||||
|
||||
M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n",
|
||||
M_DEBUG(10,("hash2_name_to_8_3: %s -> %08X -> %s (cache=%d)\n",
|
||||
name, hash, new_name, cache83));
|
||||
|
||||
/* and overwrite the old name */
|
||||
fstrcpy(name, new_name);
|
||||
|
||||
/* all done, we've managed to mangle it */
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/* initialise the flags table
|
||||
/* 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.
|
||||
restrictions.
|
||||
*/
|
||||
static void init_tables(void)
|
||||
{
|
||||
@ -642,8 +655,8 @@ static void init_tables(void)
|
||||
char_flags[i] |= FLAG_ILLEGAL;
|
||||
}
|
||||
|
||||
if ((i >= '0' && i <= '9') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
if ((i >= '0' && i <= '9') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
(i >= 'A' && i <= 'Z')) {
|
||||
char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR);
|
||||
}
|
||||
@ -663,7 +676,7 @@ static void init_tables(void)
|
||||
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 */
|
||||
@ -694,9 +707,10 @@ static void init_tables(void)
|
||||
static struct mangle_fns mangle_fns = {
|
||||
mangle_reset,
|
||||
is_mangled,
|
||||
must_mangle,
|
||||
is_8_3,
|
||||
check_cache,
|
||||
name_map
|
||||
lookup_name_from_8_3,
|
||||
hash2_name_to_8_3
|
||||
};
|
||||
|
||||
/* return the methods for this mangling implementation */
|
||||
@ -729,30 +743,45 @@ static BOOL posix_is_mangled(const char *s, const struct share_params *p)
|
||||
return False;
|
||||
}
|
||||
|
||||
static BOOL posix_is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards, const struct share_params *p)
|
||||
static BOOL posix_must_mangle(const char *s, const struct share_params *p)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
static BOOL posix_check_cache( char *s, size_t maxlen, const struct share_params *p )
|
||||
static BOOL posix_is_8_3(const char *fname,
|
||||
BOOL check_case,
|
||||
BOOL allow_wildcards,
|
||||
const struct share_params *p)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
static void posix_name_map(char *OutName, BOOL need83, BOOL cache83, int default_case, const struct share_params *p)
|
||||
static BOOL posix_lookup_name_from_8_3(TALLOC_CTX *ctx,
|
||||
const char *in,
|
||||
char **out, /* talloced on the given context. */
|
||||
const struct share_params *p)
|
||||
{
|
||||
if (need83) {
|
||||
memset(OutName, '\0', 13);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static BOOL posix_name_to_8_3(const char *in,
|
||||
char out[13],
|
||||
BOOL cache83,
|
||||
int default_case,
|
||||
const struct share_params *p)
|
||||
{
|
||||
memset(out, '\0', 13);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* POSIX paths backend - no mangle. */
|
||||
static struct mangle_fns posix_mangle_fns = {
|
||||
posix_mangle_reset,
|
||||
posix_is_mangled,
|
||||
posix_is_8_3,
|
||||
posix_check_cache,
|
||||
posix_name_map
|
||||
posix_mangle_reset,
|
||||
posix_is_mangled,
|
||||
posix_must_mangle,
|
||||
posix_is_8_3,
|
||||
posix_lookup_name_from_8_3,
|
||||
posix_name_to_8_3
|
||||
};
|
||||
|
||||
struct mangle_fns *posix_mangle_init(void)
|
||||
|
@ -369,7 +369,8 @@ static NTSTATUS dfs_path_lookup(connection_struct *conn,
|
||||
char *q = NULL;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
NTSTATUS status;
|
||||
pstring localpath;
|
||||
pstring localpath_in;
|
||||
char *localpath = NULL;
|
||||
pstring canon_dfspath; /* Canonicalized dfs path. (only '/' components). */
|
||||
|
||||
DEBUG(10,("dfs_path_lookup: Conn path = %s reqpath = %s\n",
|
||||
@ -387,8 +388,8 @@ static NTSTATUS dfs_path_lookup(connection_struct *conn,
|
||||
* think this is needed. JRA.
|
||||
*/
|
||||
|
||||
pstrcpy(localpath, pdp->reqpath);
|
||||
status = unix_convert(conn, localpath, search_flag, NULL, &sbuf);
|
||||
pstrcpy(localpath_in, pdp->reqpath);
|
||||
status = unix_convert(conn, localpath_in, search_flag, &localpath, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,
|
||||
NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
|
||||
return status;
|
||||
|
@ -489,7 +489,8 @@ static void reply_ntcreate_and_X_quota(connection_struct *conn,
|
||||
void reply_ntcreate_and_X(connection_struct *conn,
|
||||
struct smb_request *req)
|
||||
{
|
||||
pstring fname;
|
||||
pstring fname_in;
|
||||
char *fname = NULL;
|
||||
uint32 flags;
|
||||
uint32 access_mask;
|
||||
uint32 file_attributes;
|
||||
@ -589,8 +590,8 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
|
||||
if(!dir_fsp->is_directory) {
|
||||
|
||||
srvstr_get_path((char *)req->inbuf, req->flags2, fname,
|
||||
smb_buf(req->inbuf), sizeof(fname), 0,
|
||||
srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
|
||||
smb_buf(req->inbuf), sizeof(fname_in), 0,
|
||||
STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -602,7 +603,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
* Check to see if this is a mac fork of some kind.
|
||||
*/
|
||||
|
||||
if( is_ntfs_stream_name(fname)) {
|
||||
if( is_ntfs_stream_name(fname_in)) {
|
||||
reply_nterror(
|
||||
req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
@ -625,15 +626,15 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
* Copy in the base directory name.
|
||||
*/
|
||||
|
||||
pstrcpy( fname, dir_fsp->fsp_name );
|
||||
dir_name_len = strlen(fname);
|
||||
pstrcpy( fname_in, dir_fsp->fsp_name );
|
||||
dir_name_len = strlen(fname_in);
|
||||
|
||||
/*
|
||||
* Ensure it ends in a '\'.
|
||||
*/
|
||||
|
||||
if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
|
||||
pstrcat(fname, "/");
|
||||
if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) {
|
||||
pstrcat(fname_in, "/");
|
||||
dir_name_len++;
|
||||
}
|
||||
|
||||
@ -645,10 +646,10 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return;
|
||||
}
|
||||
pstrcat(fname, rel_fname);
|
||||
pstrcat(fname_in, rel_fname);
|
||||
} else {
|
||||
srvstr_get_path((char *)req->inbuf, req->flags2, fname,
|
||||
smb_buf(req->inbuf), sizeof(fname), 0,
|
||||
srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
|
||||
smb_buf(req->inbuf), sizeof(fname_in), 0,
|
||||
STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -660,8 +661,8 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
* Check to see if this is a mac fork of some kind.
|
||||
*/
|
||||
|
||||
if( is_ntfs_stream_name(fname)) {
|
||||
enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
|
||||
if( is_ntfs_stream_name(fname_in)) {
|
||||
enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname_in);
|
||||
if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
|
||||
/*
|
||||
* Here we go! support for changing the disk quotas --metze
|
||||
@ -673,7 +674,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
* xp also tries a QUERY_FILE_INFO on the file and then close it
|
||||
*/
|
||||
reply_ntcreate_and_X_quota(conn, req,
|
||||
fake_file_type, fname);
|
||||
fake_file_type, fname_in);
|
||||
} else {
|
||||
reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
}
|
||||
@ -686,7 +687,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
* Now contruct the smb_open_mode value from the filename,
|
||||
* desired access and the share access.
|
||||
*/
|
||||
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname);
|
||||
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, fname_in);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
|
||||
@ -707,17 +708,17 @@ void reply_ntcreate_and_X(connection_struct *conn,
|
||||
/*
|
||||
* Ordinary file or directory.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Check if POSIX semantics are wanted.
|
||||
*/
|
||||
|
||||
|
||||
if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
|
||||
case_state = set_posix_case_semantics(NULL, conn);
|
||||
file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, fname, False, NULL, &sbuf);
|
||||
|
||||
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(case_state);
|
||||
reply_nterror(req, status);
|
||||
@ -1200,7 +1201,7 @@ static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata,
|
||||
}
|
||||
offset += next_offset;
|
||||
}
|
||||
|
||||
|
||||
return ea_list_head;
|
||||
}
|
||||
|
||||
@ -1215,7 +1216,8 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
char **ppdata, uint32 data_count,
|
||||
uint32 max_data_count)
|
||||
{
|
||||
pstring fname;
|
||||
pstring fname_in;
|
||||
char *fname = NULL;
|
||||
char *params = *ppparams;
|
||||
char *data = *ppdata;
|
||||
/* Breakout the oplock request bits so we can set the reply bits separately. */
|
||||
@ -1334,8 +1336,8 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
}
|
||||
|
||||
if(!dir_fsp->is_directory) {
|
||||
srvstr_get_path(params, req->flags2, fname,
|
||||
params+53, sizeof(fname),
|
||||
srvstr_get_path(params, req->flags2, fname_in,
|
||||
params+53, sizeof(fname_in),
|
||||
parameter_count-53, STR_TERMINATE,
|
||||
&status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -1347,7 +1349,7 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
* Check to see if this is a mac fork of some kind.
|
||||
*/
|
||||
|
||||
if( is_ntfs_stream_name(fname)) {
|
||||
if( is_ntfs_stream_name(fname_in)) {
|
||||
reply_nterror(req,
|
||||
NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
return;
|
||||
@ -1361,15 +1363,15 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
* Copy in the base directory name.
|
||||
*/
|
||||
|
||||
pstrcpy( fname, dir_fsp->fsp_name );
|
||||
dir_name_len = strlen(fname);
|
||||
pstrcpy( fname_in, dir_fsp->fsp_name );
|
||||
dir_name_len = strlen(fname_in);
|
||||
|
||||
/*
|
||||
* Ensure it ends in a '\'.
|
||||
*/
|
||||
|
||||
if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
|
||||
pstrcat(fname, "/");
|
||||
if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) {
|
||||
pstrcat(fname_in, "/");
|
||||
dir_name_len++;
|
||||
}
|
||||
|
||||
@ -1383,11 +1385,11 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
pstrcat(fname, tmpname);
|
||||
pstrcat(fname_in, tmpname);
|
||||
}
|
||||
} else {
|
||||
srvstr_get_path(params, req->flags2, fname, params+53,
|
||||
sizeof(fname), parameter_count-53,
|
||||
srvstr_get_path(params, req->flags2, fname_in, params+53,
|
||||
sizeof(fname_in), parameter_count-53,
|
||||
STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -1398,7 +1400,7 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
* Check to see if this is a mac fork of some kind.
|
||||
*/
|
||||
|
||||
if( is_ntfs_stream_name(fname)) {
|
||||
if( is_ntfs_stream_name(fname_in)) {
|
||||
reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
@ -1412,7 +1414,7 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
/*
|
||||
* Ordinary file or directory.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Check if POSIX semantics are wanted.
|
||||
*/
|
||||
@ -1421,9 +1423,9 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
case_state = set_posix_case_semantics(NULL, conn);
|
||||
file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
|
||||
}
|
||||
|
||||
|
||||
status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
fname);
|
||||
fname_in);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(case_state);
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
@ -1435,7 +1437,7 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, fname, False, NULL, &sbuf);
|
||||
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(case_state);
|
||||
reply_nterror(req, status);
|
||||
@ -1776,11 +1778,15 @@ void reply_ntcancel(connection_struct *conn, struct smb_request *req)
|
||||
|
||||
static NTSTATUS copy_internals(connection_struct *conn,
|
||||
struct smb_request *req,
|
||||
char *oldname, char *newname, uint32 attrs)
|
||||
const char *oldname_in,
|
||||
const char *newname_in,
|
||||
uint32 attrs)
|
||||
{
|
||||
SMB_STRUCT_STAT sbuf1, sbuf2;
|
||||
pstring last_component_oldname;
|
||||
pstring last_component_newname;
|
||||
char *oldname = NULL;
|
||||
char *newname = NULL;
|
||||
char *last_component_oldname = NULL;
|
||||
char *last_component_newname = NULL;
|
||||
files_struct *fsp1,*fsp2;
|
||||
uint32 fattr;
|
||||
int info;
|
||||
@ -1794,7 +1800,8 @@ static NTSTATUS copy_internals(connection_struct *conn,
|
||||
return NT_STATUS_MEDIA_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
|
||||
status = unix_convert(conn, oldname_in, False, &oldname,
|
||||
&last_component_oldname, &sbuf1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -1814,7 +1821,8 @@ static NTSTATUS copy_internals(connection_struct *conn,
|
||||
return NT_STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
|
||||
status = unix_convert(conn, newname_in, False, &newname,
|
||||
&last_component_newname, &sbuf2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -1840,7 +1848,8 @@ static NTSTATUS copy_internals(connection_struct *conn,
|
||||
return status;
|
||||
}
|
||||
|
||||
DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
|
||||
DEBUG(10,("copy_internals: doing file copy %s to %s\n",
|
||||
oldname, newname));
|
||||
|
||||
status = open_file_ntcreate(conn, req, oldname, &sbuf1,
|
||||
FILE_READ_DATA, /* Read-only. */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
stat cache code
|
||||
Copyright (C) Andrew Tridgell 1992-2000
|
||||
Copyright (C) Jeremy Allison 1999-2004
|
||||
Copyright (C) Jeremy Allison 1999-2007
|
||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
|
||||
Copyright (C) Volker Lendecke 2007
|
||||
|
||||
@ -40,7 +40,8 @@ static TDB_CONTEXT *tdb_stat_cache;
|
||||
*
|
||||
*/
|
||||
|
||||
void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
void stat_cache_add( const char *full_orig_name,
|
||||
char *translated_path,
|
||||
BOOL case_sensitive)
|
||||
{
|
||||
size_t translated_path_length;
|
||||
@ -48,9 +49,12 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
char *original_path;
|
||||
size_t original_path_length;
|
||||
size_t sc_size = lp_max_stat_cache_size();
|
||||
char saved_char;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
|
||||
if (!lp_stat_cache())
|
||||
if (!lp_stat_cache()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc_size && (tdb_map_size(tdb_stat_cache) > sc_size*1024)) {
|
||||
reset_stat_cache();
|
||||
@ -73,20 +77,15 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
* would be a waste.
|
||||
*/
|
||||
|
||||
if (case_sensitive && (strcmp(full_orig_name, translated_path) == 0))
|
||||
if (case_sensitive && (strcmp(full_orig_name, translated_path) == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove any trailing '/' characters from the
|
||||
* translated path.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To save a strdup we don't necessarily 0-terminate the translated
|
||||
* path in the tdb. Instead, we do it directly after the tdb_fetch in
|
||||
* stat_cache_lookup.
|
||||
*/
|
||||
|
||||
translated_path_length = strlen(translated_path);
|
||||
|
||||
if(translated_path[translated_path_length-1] == '/') {
|
||||
@ -94,9 +93,9 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
}
|
||||
|
||||
if(case_sensitive) {
|
||||
original_path = SMB_STRDUP(full_orig_name);
|
||||
original_path = talloc_strdup(ctx,full_orig_name);
|
||||
} else {
|
||||
original_path = strdup_upper(full_orig_name);
|
||||
original_path = talloc_strdup_upper(ctx,full_orig_name);
|
||||
}
|
||||
|
||||
if (!original_path) {
|
||||
@ -118,7 +117,7 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
(unsigned long)original_path_length,
|
||||
translated_path,
|
||||
(unsigned long)translated_path_length));
|
||||
SAFE_FREE(original_path);
|
||||
TALLOC_FREE(original_path);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -129,13 +128,17 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
original_path_length = translated_path_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* New entry or replace old entry.
|
||||
*/
|
||||
/* Ensure we're null terminated. */
|
||||
saved_char = translated_path[translated_path_length];
|
||||
translated_path[translated_path_length] = '\0';
|
||||
|
||||
data_val.dsize = translated_path_length + 1;
|
||||
data_val.dptr = (uint8 *)translated_path;
|
||||
|
||||
/*
|
||||
* New entry or replace old entry.
|
||||
*/
|
||||
|
||||
if (tdb_store_bystring(tdb_stat_cache, original_path, data_val,
|
||||
TDB_REPLACE) != 0) {
|
||||
DEBUG(0,("stat_cache_add: Error storing entry %s -> %s\n",
|
||||
@ -148,7 +151,8 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
translated_path));
|
||||
}
|
||||
|
||||
SAFE_FREE(original_path);
|
||||
translated_path[translated_path_length] = saved_char;
|
||||
TALLOC_FREE(original_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,8 +161,10 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
* @param conn A connection struct to do the stat() with.
|
||||
* @param name The path we are attempting to cache, modified by this routine
|
||||
* to be correct as far as the cache can tell us. We assume that
|
||||
* it is a malloc'ed string, we free it if necessary.
|
||||
* @param dirpath The path as far as the stat cache told us.
|
||||
* it is a talloc'ed string from top of stack, we free it if
|
||||
* necessary.
|
||||
* @param dirpath The path as far as the stat cache told us. Also talloced
|
||||
* from top of stack.
|
||||
* @param start A pointer into name, for where to 'start' in fixing the rest
|
||||
* of the name up.
|
||||
* @param psd A stat buffer, NOT from the cache, but just a side-effect.
|
||||
@ -168,8 +174,11 @@ void stat_cache_add( const char *full_orig_name, const char *translated_path,
|
||||
*
|
||||
*/
|
||||
|
||||
BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
char **start, SMB_STRUCT_STAT *pst)
|
||||
BOOL stat_cache_lookup(connection_struct *conn,
|
||||
char **pp_name,
|
||||
char **pp_dirpath,
|
||||
char **pp_start,
|
||||
SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
char *chk_name;
|
||||
size_t namelen;
|
||||
@ -179,15 +188,18 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
size_t translated_path_length;
|
||||
TDB_DATA data_val;
|
||||
char *name;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
|
||||
if (!lp_stat_cache())
|
||||
*pp_dirpath = NULL;
|
||||
*pp_start = *pp_name;
|
||||
|
||||
if (!lp_stat_cache()) {
|
||||
return False;
|
||||
}
|
||||
|
||||
name = *pname;
|
||||
name = *pp_name;
|
||||
namelen = strlen(name);
|
||||
|
||||
*start = name;
|
||||
|
||||
DO_PROFILE_INC(statcache_lookups);
|
||||
|
||||
/*
|
||||
@ -198,14 +210,14 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
}
|
||||
|
||||
if (conn->case_sensitive) {
|
||||
chk_name = SMB_STRDUP(name);
|
||||
chk_name = talloc_strdup(ctx,name);
|
||||
if (!chk_name) {
|
||||
DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
} else {
|
||||
chk_name = strdup_upper(name);
|
||||
chk_name = talloc_strdup_upper(ctx,name);
|
||||
if (!chk_name) {
|
||||
DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n"));
|
||||
return False;
|
||||
@ -216,8 +228,9 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
* if we uppercase. We need to treat this differently
|
||||
* below.
|
||||
*/
|
||||
if (strlen(chk_name) != namelen)
|
||||
if (strlen(chk_name) != namelen) {
|
||||
sizechanged = True;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
@ -239,7 +252,7 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
* We reached the end of the name - no match.
|
||||
*/
|
||||
DO_PROFILE_INC(statcache_misses);
|
||||
SAFE_FREE(chk_name);
|
||||
TALLOC_FREE(chk_name);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -249,25 +262,25 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
* Count the number of times we have done this, we'll
|
||||
* need it when reconstructing the string.
|
||||
*/
|
||||
if (sizechanged)
|
||||
|
||||
if (sizechanged) {
|
||||
num_components++;
|
||||
}
|
||||
|
||||
if ((*chk_name == '\0')
|
||||
|| ISDOT(chk_name) || ISDOTDOT(chk_name)) {
|
||||
DO_PROFILE_INC(statcache_misses);
|
||||
SAFE_FREE(chk_name);
|
||||
TALLOC_FREE(chk_name);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
translated_path = (char *)data_val.dptr;
|
||||
translated_path = talloc_strdup(ctx,(char *)data_val.dptr);
|
||||
if (!translated_path) {
|
||||
smb_panic("talloc failed");
|
||||
}
|
||||
translated_path_length = data_val.dsize - 1;
|
||||
|
||||
/*
|
||||
* In stat_cache_add we did not necessarily 0-terminate the translated
|
||||
* path. Do it here, where we do have a freshly malloc'ed blob.
|
||||
*/
|
||||
translated_path[translated_path_length] = '\0';
|
||||
SAFE_FREE(data_val.dptr);
|
||||
|
||||
DEBUG(10,("stat_cache_lookup: lookup succeeded for name [%s] "
|
||||
"-> [%s]\n", chk_name, translated_path ));
|
||||
@ -276,50 +289,51 @@ BOOL stat_cache_lookup(connection_struct *conn, char **pname, char **dirpath,
|
||||
if (SMB_VFS_STAT(conn, translated_path, pst) != 0) {
|
||||
/* Discard this entry - it doesn't exist in the filesystem. */
|
||||
tdb_delete_bystring(tdb_stat_cache, chk_name);
|
||||
SAFE_FREE(chk_name);
|
||||
SAFE_FREE(data_val.dptr);
|
||||
TALLOC_FREE(chk_name);
|
||||
TALLOC_FREE(translated_path);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!sizechanged) {
|
||||
memcpy(name, translated_path,
|
||||
memcpy(*pp_name, translated_path,
|
||||
MIN(namelen, translated_path_length));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (num_components == 0) {
|
||||
name = SMB_STRNDUP(translated_path,
|
||||
name = talloc_strndup(ctx, translated_path,
|
||||
translated_path_length);
|
||||
} else {
|
||||
char *sp;
|
||||
|
||||
sp = strnrchr_m(name, '/', num_components);
|
||||
if (sp) {
|
||||
asprintf(&name, "%.*s%s",
|
||||
name = talloc_asprintf(ctx,"%.*s%s",
|
||||
(int)translated_path_length,
|
||||
translated_path, sp);
|
||||
} else {
|
||||
name = SMB_STRNDUP(translated_path,
|
||||
translated_path_length);
|
||||
name = talloc_strndup(ctx,
|
||||
translated_path,
|
||||
translated_path_length);
|
||||
}
|
||||
}
|
||||
if (name == NULL) {
|
||||
/*
|
||||
* TODO: Get us out of here with a real error message
|
||||
*/
|
||||
smb_panic("malloc failed");
|
||||
smb_panic("talloc failed");
|
||||
}
|
||||
SAFE_FREE(*pname);
|
||||
*pname = name;
|
||||
TALLOC_FREE(*pp_name);
|
||||
*pp_name = name;
|
||||
}
|
||||
|
||||
|
||||
/* set pointer for 'where to start' on fixing the rest of the name */
|
||||
*start = &name[translated_path_length];
|
||||
if (**start == '/')
|
||||
++*start;
|
||||
*pp_start = &name[translated_path_length];
|
||||
if (**pp_start == '/') {
|
||||
++*pp_start;
|
||||
}
|
||||
|
||||
*dirpath = translated_path;
|
||||
SAFE_FREE(chk_name);
|
||||
*pp_dirpath = translated_path;
|
||||
TALLOC_FREE(chk_name);
|
||||
return (namelen == translated_path_length);
|
||||
}
|
||||
|
||||
@ -344,7 +358,7 @@ void send_stat_cache_delete_message(const char *name)
|
||||
|
||||
void stat_cache_delete(const char *name)
|
||||
{
|
||||
char *lname = strdup_upper(name);
|
||||
char *lname = talloc_strdup_upper(talloc_tos(), name);
|
||||
|
||||
if (!lname) {
|
||||
return;
|
||||
@ -353,7 +367,7 @@ void stat_cache_delete(const char *name)
|
||||
lname, name ));
|
||||
|
||||
tdb_delete_bystring(tdb_stat_cache, lname);
|
||||
SAFE_FREE(lname);
|
||||
TALLOC_FREE(lname);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
@ -783,7 +783,8 @@ static void call_trans2open(connection_struct *conn,
|
||||
int open_ofun;
|
||||
uint32 open_size;
|
||||
char *pname;
|
||||
pstring fname;
|
||||
pstring fname_in;
|
||||
char *fname = NULL;
|
||||
SMB_OFF_T size=0;
|
||||
int fattr=0,mtime=0;
|
||||
SMB_INO_T inode = 0;
|
||||
@ -829,8 +830,8 @@ static void call_trans2open(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
srvstr_get_path(params, req->flags2, fname, pname,
|
||||
sizeof(fname), total_params - 28, STR_TERMINATE,
|
||||
srvstr_get_path(params, req->flags2, fname_in, pname,
|
||||
sizeof(fname_in), total_params - 28, STR_TERMINATE,
|
||||
&status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -843,7 +844,7 @@ static void call_trans2open(connection_struct *conn,
|
||||
|
||||
/* XXXX we need to handle passed times, sattr and flags */
|
||||
|
||||
status = unix_convert(conn, fname, False, NULL, &sbuf);
|
||||
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
@ -1163,6 +1164,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
|
||||
uint32 nt_extmode; /* Used for NT connections instead of mode */
|
||||
BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
|
||||
BOOL check_mangled_names = lp_manglednames(conn->params);
|
||||
char mangled_name[13]; /* mangled 8.3 name. */
|
||||
|
||||
*fname = 0;
|
||||
*out_of_space = False;
|
||||
@ -1215,10 +1217,15 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
|
||||
* pathreal which is composed from dname.
|
||||
*/
|
||||
|
||||
pstrcpy(fname,dname);
|
||||
pstrcpy(fname,dname);
|
||||
|
||||
/* This will mangle fname if it's an illegal name. */
|
||||
mangle_map(fname,False,True,conn->params);
|
||||
/* Mangle fname if it's an illegal name. */
|
||||
if (mangle_must_mangle(fname,conn->params)) {
|
||||
if (!name_to_8_3(fname,mangled_name,True,conn->params)) {
|
||||
continue; /* Error - couldn't mangle. */
|
||||
}
|
||||
pstrcpy(fname,mangled_name);
|
||||
}
|
||||
|
||||
if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
|
||||
got_match = mask_match(fname, mask, conn->case_sensitive);
|
||||
@ -1226,19 +1233,17 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
|
||||
|
||||
if(!got_match && check_mangled_names &&
|
||||
!mangle_is_8_3(fname, False, conn->params)) {
|
||||
pstring mangled_name;
|
||||
|
||||
/*
|
||||
* It turns out that NT matches wildcards against
|
||||
* both long *and* short names. This may explain some
|
||||
* of the wildcard wierdness from old DOS clients
|
||||
* that some people have been seeing.... JRA.
|
||||
*/
|
||||
|
||||
pstrcpy(mangled_name, fname);
|
||||
|
||||
/* Force the mangling into 8.3. */
|
||||
mangle_map( mangled_name, True, False, conn->params);
|
||||
if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
|
||||
continue; /* Error - couldn't mangle. */
|
||||
}
|
||||
|
||||
if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
|
||||
got_match = mask_match(mangled_name, mask, conn->case_sensitive);
|
||||
}
|
||||
@ -1483,10 +1488,11 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
|
||||
* a Win2k client bug. JRA.
|
||||
*/
|
||||
if (!was_8_3 && check_mangled_names) {
|
||||
pstring mangled_name;
|
||||
pstrcpy(mangled_name, fname);
|
||||
mangle_map(mangled_name,True,True,
|
||||
conn->params);
|
||||
if (!name_to_8_3(fname,mangled_name,True,
|
||||
conn->params)) {
|
||||
/* Error - mangle failed ! */
|
||||
memset(mangled_name,'\0',12);
|
||||
}
|
||||
mangled_name[12] = 0;
|
||||
len = srvstr_push(base_data, flags2,
|
||||
p+2, mangled_name, 24,
|
||||
@ -1638,10 +1644,11 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
|
||||
* a Win2k client bug. JRA.
|
||||
*/
|
||||
if (!was_8_3 && check_mangled_names) {
|
||||
pstring mangled_name;
|
||||
pstrcpy(mangled_name, fname);
|
||||
mangle_map(mangled_name,True,True,
|
||||
conn->params);
|
||||
if (!name_to_8_3(fname,mangled_name,True,
|
||||
conn->params)) {
|
||||
/* Error - mangle failed ! */
|
||||
memset(mangled_name,'\0',12);
|
||||
}
|
||||
mangled_name[12] = 0;
|
||||
len = srvstr_push(base_data, flags2,
|
||||
p+2, mangled_name, 24,
|
||||
@ -1754,7 +1761,8 @@ static void call_trans2findfirst(connection_struct *conn,
|
||||
BOOL close_if_end;
|
||||
BOOL requires_resume_key;
|
||||
int info_level;
|
||||
pstring directory;
|
||||
pstring directory_in;
|
||||
char *directory = NULL;
|
||||
pstring mask;
|
||||
char *p;
|
||||
int last_entry_off=0;
|
||||
@ -1784,7 +1792,7 @@ static void call_trans2findfirst(connection_struct *conn,
|
||||
requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
|
||||
info_level = SVAL(params,6);
|
||||
|
||||
*directory = *mask = 0;
|
||||
*directory_in = *mask = 0;
|
||||
|
||||
DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
|
||||
close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
|
||||
@ -1819,15 +1827,15 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
|
||||
return;
|
||||
}
|
||||
|
||||
srvstr_get_path_wcard(params, req->flags2, directory,
|
||||
params+12, sizeof(directory), total_params - 12,
|
||||
srvstr_get_path_wcard(params, req->flags2, directory_in,
|
||||
params+12, sizeof(directory_in), total_params - 12,
|
||||
STR_TERMINATE, &ntstatus, &mask_contains_wcard);
|
||||
if (!NT_STATUS_IS_OK(ntstatus)) {
|
||||
reply_nterror(req, ntstatus);
|
||||
return;
|
||||
}
|
||||
|
||||
ntstatus = resolve_dfspath_wcard(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, &mask_contains_wcard);
|
||||
ntstatus = resolve_dfspath_wcard(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory_in, &mask_contains_wcard);
|
||||
if (!NT_STATUS_IS_OK(ntstatus)) {
|
||||
if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
|
||||
@ -1838,11 +1846,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
|
||||
return;
|
||||
}
|
||||
|
||||
ntstatus = unix_convert(conn, directory, True, NULL, &sbuf);
|
||||
ntstatus = unix_convert(conn, directory_in, True, &directory, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(ntstatus)) {
|
||||
reply_nterror(req, ntstatus);
|
||||
return;
|
||||
}
|
||||
|
||||
ntstatus = check_name(conn, directory);
|
||||
if (!NT_STATUS_IS_OK(ntstatus)) {
|
||||
reply_nterror(req, ntstatus);
|
||||
@ -1858,7 +1867,11 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
|
||||
} else {
|
||||
pstrcpy(mask,directory);
|
||||
}
|
||||
pstrcpy(directory,"./");
|
||||
directory = talloc_strdup(talloc_tos(), "./");
|
||||
if (!directory) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pstrcpy(mask,p+1);
|
||||
*p = 0;
|
||||
@ -2030,14 +2043,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
send_trans2_replies(req, params, 10, pdata, PTR_DIFF(p,pdata),
|
||||
max_data_bytes);
|
||||
|
||||
if ((! *directory) && dptr_path(dptr_num))
|
||||
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
|
||||
if ((! *directory) && dptr_path(dptr_num)) {
|
||||
directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
|
||||
if (!directory) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
|
||||
smb_fn_name(CVAL(req->inbuf,smb_com)),
|
||||
mask, directory, dirtype, numentries ) );
|
||||
|
||||
/*
|
||||
/*
|
||||
* Force a name mangle here to ensure that the
|
||||
* mask as an 8.3 name is top of the mangled cache.
|
||||
* The reasons for this are subtle. Don't remove
|
||||
@ -2045,8 +2062,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
* (see PR#13758). JRA.
|
||||
*/
|
||||
|
||||
if(!mangle_is_8_3_wildcards( mask, False, conn->params))
|
||||
mangle_map(mask, True, True, conn->params);
|
||||
if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
|
||||
char mangled_name[13];
|
||||
name_to_8_3(mask, mangled_name, True, conn->params);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2270,14 +2289,20 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
|
||||
long current_pos = 0;
|
||||
/*
|
||||
* Remember, mangle_map is called by
|
||||
* Remember, name_to_8_3 is called by
|
||||
* get_lanman2_dir_entry(), so the resume name
|
||||
* could be mangled. Ensure we check the unmangled name.
|
||||
*/
|
||||
|
||||
if (mangle_is_mangled(resume_name, conn->params)) {
|
||||
mangle_check_cache(resume_name, sizeof(resume_name)-1,
|
||||
conn->params);
|
||||
char *new_resume_name = NULL;
|
||||
mangle_lookup_name_from_8_3(talloc_tos(),
|
||||
resume_name,
|
||||
&new_resume_name,
|
||||
conn->params);
|
||||
if (new_resume_name) {
|
||||
pstrcpy(resume_name, new_resume_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3483,7 +3508,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
unsigned int data_size = 0;
|
||||
unsigned int param_size = 2;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
pstring fname, dos_fname;
|
||||
pstring dos_fname;
|
||||
char *fname = NULL;
|
||||
char *fullpathname;
|
||||
char *base_name;
|
||||
char *p;
|
||||
@ -3530,23 +3556,31 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
if(fsp && (fsp->fake_file_handle)) {
|
||||
/* Initial check for valid fsp ptr. */
|
||||
if (!check_fsp_open(conn, req, fsp, ¤t_user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
|
||||
if (!fname) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fsp->fake_file_handle) {
|
||||
/*
|
||||
* This is actually for the QUOTA_FAKE_FILE --metze
|
||||
*/
|
||||
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
|
||||
/* We know this name is ok, it's already passed the checks. */
|
||||
|
||||
|
||||
} else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
|
||||
/*
|
||||
* This is actually a QFILEINFO on a directory
|
||||
* handle (returned from an NT SMB). NT5.0 seems
|
||||
* to do this call. JRA.
|
||||
*/
|
||||
/* We know this name is ok, it's already passed the checks. */
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
|
||||
|
||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||
/* Always do lstat for UNIX calls. */
|
||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
|
||||
@ -3570,7 +3604,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
|
||||
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
|
||||
reply_unixerror(req, ERRDOS, ERRbadfid);
|
||||
@ -3581,7 +3614,9 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
delete_pending = get_delete_on_close_flag(fileid);
|
||||
access_mask = fsp->access_mask;
|
||||
}
|
||||
|
||||
} else {
|
||||
pstring fname_in;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
|
||||
/* qpathinfo */
|
||||
@ -3599,8 +3634,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
srvstr_get_path(params, req->flags2, fname, ¶ms[6],
|
||||
sizeof(fname), total_params - 6,
|
||||
srvstr_get_path(params, req->flags2, fname_in, ¶ms[6],
|
||||
sizeof(fname_in), total_params - 6,
|
||||
STR_TERMINATE, &status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -3609,7 +3644,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
|
||||
status = resolve_dfspath(conn,
|
||||
req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
fname);
|
||||
fname_in);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req,
|
||||
@ -3620,7 +3655,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, fname, False, NULL, &sbuf);
|
||||
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
@ -3962,16 +3997,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
case SMB_QUERY_FILE_ALT_NAME_INFO:
|
||||
case SMB_FILE_ALTERNATE_NAME_INFORMATION:
|
||||
{
|
||||
pstring short_name;
|
||||
|
||||
char mangled_name[13];
|
||||
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
|
||||
pstrcpy(short_name,base_name);
|
||||
/* Mangle if not already 8.3 */
|
||||
if(!mangle_is_8_3(short_name, True, conn->params)) {
|
||||
mangle_map(short_name,True,True,conn->params);
|
||||
if (!name_to_8_3(base_name,mangled_name,
|
||||
True,conn->params)) {
|
||||
reply_nterror(
|
||||
req,
|
||||
NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
len = srvstr_push(dstart, req->flags2,
|
||||
pdata+4, short_name,
|
||||
pdata+4, mangled_name,
|
||||
PTR_DIFF(dend, pdata+4),
|
||||
STR_UNICODE);
|
||||
data_size = 4 + len;
|
||||
@ -4395,17 +4430,22 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
code.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS hardlink_internals(connection_struct *conn, pstring oldname, pstring newname)
|
||||
NTSTATUS hardlink_internals(connection_struct *conn,
|
||||
char *oldname_in,
|
||||
char *newname_in)
|
||||
{
|
||||
SMB_STRUCT_STAT sbuf1, sbuf2;
|
||||
pstring last_component_oldname;
|
||||
pstring last_component_newname;
|
||||
char *last_component_oldname = NULL;
|
||||
char *last_component_newname = NULL;
|
||||
char *oldname = NULL;
|
||||
char *newname = NULL;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
|
||||
ZERO_STRUCT(sbuf1);
|
||||
ZERO_STRUCT(sbuf2);
|
||||
|
||||
status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
|
||||
status = unix_convert(conn, oldname_in, False, &oldname,
|
||||
&last_component_oldname, &sbuf1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -4420,7 +4460,8 @@ NTSTATUS hardlink_internals(connection_struct *conn, pstring oldname, pstring ne
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
|
||||
status = unix_convert(conn, newname_in, False, &newname,
|
||||
&last_component_newname, &sbuf2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -4882,13 +4923,15 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
|
||||
|
||||
static NTSTATUS smb_file_rename_information(connection_struct *conn,
|
||||
struct smb_request *req,
|
||||
const char *pdata, int total_data,
|
||||
files_struct *fsp, pstring fname)
|
||||
const char *pdata,
|
||||
int total_data,
|
||||
files_struct *fsp,
|
||||
const char *fname)
|
||||
{
|
||||
BOOL overwrite;
|
||||
uint32 root_fid;
|
||||
uint32 len;
|
||||
pstring newname;
|
||||
pstring newname_in;
|
||||
pstring base_name;
|
||||
BOOL dest_has_wcard = False;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
@ -4906,8 +4949,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
srvstr_get_path_wcard(pdata, req->flags2, newname, &pdata[12],
|
||||
sizeof(newname), len, 0, &status,
|
||||
srvstr_get_path_wcard(pdata, req->flags2, newname_in, &pdata[12],
|
||||
sizeof(newname_in), len, 0, &status,
|
||||
&dest_has_wcard);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
@ -4915,13 +4958,13 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
|
||||
|
||||
status = resolve_dfspath_wcard(conn,
|
||||
req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
newname, &dest_has_wcard);
|
||||
newname_in, &dest_has_wcard);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check the new name has no '/' characters. */
|
||||
if (strchr_m(newname, '/')) {
|
||||
if (strchr_m(newname_in, '/')) {
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@ -4934,16 +4977,19 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
|
||||
pstrcpy(base_name, "./");
|
||||
}
|
||||
/* Append the new name. */
|
||||
pstrcat(base_name, newname);
|
||||
pstrcat(base_name, newname_in);
|
||||
|
||||
if (fsp) {
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
pstring newname_last_component;
|
||||
char *newname = NULL;
|
||||
char *newname_last_component = NULL;
|
||||
|
||||
ZERO_STRUCT(sbuf);
|
||||
|
||||
status = unix_convert(conn, newname, False,
|
||||
newname_last_component, &sbuf);
|
||||
status = unix_convert(conn, newname_in, False,
|
||||
&newname,
|
||||
&newname_last_component,
|
||||
&sbuf);
|
||||
|
||||
/* If an error we expect this to be
|
||||
* NT_STATUS_OBJECT_PATH_NOT_FOUND */
|
||||
@ -4961,7 +5007,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
|
||||
overwrite);
|
||||
} else {
|
||||
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
|
||||
fname, newname ));
|
||||
fname, base_name ));
|
||||
status = rename_internals(conn, req, fname, base_name, 0,
|
||||
overwrite, False, dest_has_wcard);
|
||||
}
|
||||
@ -6121,7 +6167,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
char *pdata = *ppdata;
|
||||
uint16 info_level;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
pstring fname;
|
||||
char *fname = NULL;
|
||||
files_struct *fsp = NULL;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
int data_return_size = 0;
|
||||
@ -6140,15 +6186,24 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
}
|
||||
|
||||
fsp = file_fsp(SVAL(params,0));
|
||||
info_level = SVAL(params,2);
|
||||
/* Basic check for non-null fsp. */
|
||||
if (!check_fsp_open(conn, req, fsp, ¤t_user)) {
|
||||
return;
|
||||
}
|
||||
info_level = SVAL(params,2);
|
||||
|
||||
if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
|
||||
fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
|
||||
if (!fname) {
|
||||
reply_nterror(req, NT_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fsp->is_directory || fsp->fh->fd == -1) {
|
||||
/*
|
||||
* This is actually a SETFILEINFO on a directory
|
||||
* handle (returned from an NT SMB). NT5.0 seems
|
||||
* to do this call. JRA.
|
||||
*/
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||
/* Always do lstat for UNIX calls. */
|
||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
|
||||
@ -6163,7 +6218,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (fsp && fsp->print_file) {
|
||||
} else if (fsp->print_file) {
|
||||
/*
|
||||
* Doing a DELETE_ON_CLOSE should cancel a print job.
|
||||
*/
|
||||
@ -6171,18 +6226,17 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
|
||||
|
||||
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
|
||||
|
||||
|
||||
SSVAL(params,0,0);
|
||||
send_trans2_replies(req, params, 2,
|
||||
*ppdata, 0,
|
||||
max_data_bytes);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
reply_unixerror(req, ERRDOS, ERRbadpath);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
/*
|
||||
* Original code - this is an open file.
|
||||
*/
|
||||
@ -6190,8 +6244,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
pstrcpy(fname, fsp->fsp_name);
|
||||
|
||||
if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &sbuf) != 0) {
|
||||
DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
||||
reply_unixerror(req, ERRDOS, ERRbadfid);
|
||||
@ -6199,15 +6251,17 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pstring fname_in;
|
||||
|
||||
/* set path info */
|
||||
if (total_params < 7) {
|
||||
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
info_level = SVAL(params,0);
|
||||
srvstr_get_path(params, req->flags2, fname, ¶ms[6],
|
||||
sizeof(fname), total_params - 6, STR_TERMINATE,
|
||||
info_level = SVAL(params,0);
|
||||
srvstr_get_path(params, req->flags2, fname_in, ¶ms[6],
|
||||
sizeof(fname_in), total_params - 6, STR_TERMINATE,
|
||||
&status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
@ -6216,7 +6270,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
|
||||
status = resolve_dfspath(conn,
|
||||
req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
fname);
|
||||
fname_in);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req,
|
||||
@ -6228,7 +6282,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
return;
|
||||
}
|
||||
|
||||
status = unix_convert(conn, fname, False, NULL, &sbuf);
|
||||
status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
@ -6550,7 +6604,8 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
|
||||
{
|
||||
char *params = *pparams;
|
||||
char *pdata = *ppdata;
|
||||
pstring directory;
|
||||
pstring directory_in;
|
||||
char *directory = NULL;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
struct ea_list *ea_list = NULL;
|
||||
@ -6565,17 +6620,17 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
|
||||
return;
|
||||
}
|
||||
|
||||
srvstr_get_path(params, req->flags2, directory, ¶ms[4],
|
||||
sizeof(directory), total_params - 4, STR_TERMINATE,
|
||||
srvstr_get_path(params, req->flags2, directory_in, ¶ms[4],
|
||||
sizeof(directory_in), total_params - 4, STR_TERMINATE,
|
||||
&status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
|
||||
DEBUG(3,("call_trans2mkdir : name = %s\n", directory_in));
|
||||
|
||||
status = unix_convert(conn, directory, False, NULL, &sbuf);
|
||||
status = unix_convert(conn, directory_in, False, &directory, NULL, &sbuf);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user