1
0
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:
Jeremy Allison 2004-02-20 22:45:53 +00:00
parent 9264194340
commit 7d7849b18a
3 changed files with 44 additions and 18 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;