mirror of
https://github.com/samba-team/samba.git
synced 2025-03-03 12:58:35 +03:00
Make us bug-for-bug compatible with W2K3 - to get delete on close semantics
on an initial open the desired_access field *must* contain DELETE_ACCESS, simply having it map from a GENERIC_ALL won't do. Fixes delete on close test. Jeremy. (This used to be commit 5c6f8b1053fd1f170fbb76640649653f8aa80f18)
This commit is contained in:
parent
9264194340
commit
7d7849b18a
@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
|
||||
/****************************************************************************
|
||||
send a qfileinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata)
|
||||
BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen)
|
||||
{
|
||||
unsigned int data_len = 0;
|
||||
unsigned int param_len = 0;
|
||||
@ -639,9 +639,13 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
|
||||
pstring param;
|
||||
char *rparam=NULL, *rdata=NULL;
|
||||
|
||||
*poutdata = NULL;
|
||||
*poutlen = 0;
|
||||
|
||||
/* if its a win95 server then fail this - win95 totally screws it
|
||||
up */
|
||||
if (cli->win95) return False;
|
||||
if (cli->win95)
|
||||
return False;
|
||||
|
||||
param_len = 4;
|
||||
|
||||
@ -665,7 +669,8 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
|
||||
return False;
|
||||
}
|
||||
|
||||
memcpy(outdata, rdata, data_len);
|
||||
memdup(poutdata, data_len);
|
||||
*poutlen = data_len;
|
||||
|
||||
SAFE_FREE(rdata);
|
||||
SAFE_FREE(rparam);
|
||||
|
@ -353,6 +353,7 @@ static int map_share_mode( char *fname, uint32 create_options,
|
||||
uint32 *desired_access, uint32 share_access, uint32 file_attributes)
|
||||
{
|
||||
int smb_open_mode = -1;
|
||||
uint32 original_desired_access = *desired_access;
|
||||
|
||||
/*
|
||||
* Convert GENERIC bits to specific bits.
|
||||
@ -424,6 +425,10 @@ static int map_share_mode( char *fname, uint32 create_options,
|
||||
DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
|
||||
}
|
||||
|
||||
if(*desired_access & DELETE_ACCESS) {
|
||||
DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to store the intent to open for Delete. This
|
||||
* is what determines if a delete on close flag can be set.
|
||||
@ -431,11 +436,19 @@ static int map_share_mode( char *fname, uint32 create_options,
|
||||
* is the only practical way. JRA.
|
||||
*/
|
||||
|
||||
if(*desired_access & DELETE_ACCESS) {
|
||||
DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
|
||||
}
|
||||
|
||||
if (create_options & FILE_DELETE_ON_CLOSE) {
|
||||
/*
|
||||
* W2K3 bug compatibility mode... To set delete on close
|
||||
* the redirector must have *specifically* set DELETE_ACCESS
|
||||
* in the desired_access field. Just asking for GENERIC_ALL won't do. JRA.
|
||||
*/
|
||||
|
||||
if (!(original_desired_access & DELETE_ACCESS)) {
|
||||
DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \
|
||||
DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n",
|
||||
fname, (unsigned long)*desired_access));
|
||||
return -1;
|
||||
}
|
||||
/* Implicit delete access is *NOT* requested... */
|
||||
smb_open_mode |= DELETE_ON_CLOSE_FLAG;
|
||||
DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
|
||||
@ -738,7 +751,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
|
||||
share_access,
|
||||
file_attributes)) == -1) {
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
|
||||
@ -1267,7 +1280,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
|
||||
if((smb_open_mode = map_share_mode( fname, create_options, &desired_access,
|
||||
share_access, file_attributes)) == -1)
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
|
||||
|
||||
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
|
||||
oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
|
||||
|
@ -2493,19 +2493,19 @@ static BOOL run_trans2test(int dummy)
|
||||
|
||||
static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
|
||||
{
|
||||
char buf[4096];
|
||||
char *buf = NULL;
|
||||
uint32 len;
|
||||
BOOL correct = True;
|
||||
|
||||
memset(buf, 0xff, sizeof(buf));
|
||||
|
||||
if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
|
||||
if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
|
||||
printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
|
||||
correct = False;
|
||||
} else {
|
||||
printf("qfileinfo: level %d\n", level);
|
||||
dump_data(0, buf, 256);
|
||||
printf("qfileinfo: level %d, len = %u\n", level, len);
|
||||
dump_data(0, buf, len);
|
||||
printf("\n");
|
||||
}
|
||||
SAFE_FREE(buf);
|
||||
return correct;
|
||||
}
|
||||
|
||||
@ -2812,8 +2812,8 @@ static BOOL run_deletetest(int dummy)
|
||||
cli_setatr(cli1, fname, 0, 0);
|
||||
cli_unlink(cli1, fname);
|
||||
|
||||
fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
|
||||
fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
|
||||
0, FILE_OVERWRITE_IF,
|
||||
FILE_DELETE_ON_CLOSE, 0);
|
||||
|
||||
if (fnum1 == -1) {
|
||||
@ -2821,7 +2821,15 @@ static BOOL run_deletetest(int dummy)
|
||||
correct = False;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
uint32 accinfo = 0;
|
||||
cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char *)&accinfo);
|
||||
printf("access mode = 0x%lx\n", accinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cli_close(cli1, fnum1)) {
|
||||
printf("[1] close failed (%s)\n", cli_errstr(cli1));
|
||||
correct = False;
|
||||
|
Loading…
x
Reference in New Issue
Block a user