summaryrefslogtreecommitdiffstats
path: root/source/smbd/nttrans.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/nttrans.c')
-rw-r--r--source/smbd/nttrans.c103
1 files changed, 91 insertions, 12 deletions
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 2a49e1f4a64..fe2cb05bf3e 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -374,6 +374,7 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
int ret;
int pnum = -1;
char *p = NULL;
+ uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
@@ -385,7 +386,17 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
* Deal with pipe return.
*/
- set_message(outbuf,34,0,True);
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ /* This is very strange. We
+ * return 50 words, but only set
+ * the wcnt to 42 ? It's definately
+ * what happens on the wire....
+ */
+ set_message(outbuf,50,0,True);
+ SCVAL(outbuf,smb_wct,42);
+ } else {
+ set_message(outbuf,34,0,True);
+ }
p = outbuf + smb_vwv2;
p++;
@@ -400,6 +411,18 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
/* Device state. */
SSVAL(p,2, 0x5FF); /* ? */
+ p += 4;
+
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ p += 26;
+ SIVAL(p,0,FILE_GENERIC_ALL);
+ /*
+ * For pipes W2K3 seems to return
+ * 0x12019B next.
+ * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
+ */
+ SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
+ }
DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
@@ -847,13 +870,18 @@ int reply_ntcreate_and_X(connection_struct *conn,
extended_oplock_granted = True;
}
-#if 0
- /* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
- set_message(outbuf,42,0,True);
-#else
- set_message(outbuf,34,0,True);
-#endif
-
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ /* This is very strange. We
+ * return 50 words, but only set
+ * the wcnt to 42 ? It's definately
+ * what happens on the wire....
+ */
+ set_message(outbuf,50,0,True);
+ SCVAL(outbuf,smb_wct,42);
+ } else {
+ set_message(outbuf,34,0,True);
+ }
+
p = outbuf + smb_vwv2;
/*
@@ -914,6 +942,17 @@ int reply_ntcreate_and_X(connection_struct *conn,
p += 4;
SCVAL(p,0,fsp->is_directory ? 1 : 0);
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ uint32 perms = 0;
+ p += 26;
+ if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
+ perms = FILE_GENERIC_ALL;
+ } else {
+ perms = FILE_GENERIC_READ|FILE_EXECUTE;
+ }
+ SIVAL(p,0,perms);
+ }
+
DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
result = chain_reply(inbuf,outbuf,length,bufsize);
@@ -936,6 +975,8 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
int pnum = -1;
char *p = NULL;
NTSTATUS status;
+ size_t param_len;
+ uint32 flags;
/*
* Ensure minimum number of parameters sent.
@@ -946,6 +987,8 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
+ flags = IVAL(params,0);
+
srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
@@ -956,7 +999,13 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
}
/* Realloc the size of parameters and data we will return */
- params = nttrans_realloc(ppparams, 69);
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ /* Extended response is 32 more byyes. */
+ param_len = 101;
+ } else {
+ param_len = 69;
+ }
+ params = nttrans_realloc(ppparams, param_len);
if(params == NULL) {
return ERROR_DOS(ERRDOS,ERRnomem);
}
@@ -977,11 +1026,23 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
/* Device state. */
SSVAL(p,2, 0x5FF); /* ? */
+ p += 4;
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ p += 26;
+ SIVAL(p,0,FILE_GENERIC_ALL);
+ /*
+ * For pipes W2K3 seems to return
+ * 0x12019B next.
+ * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
+ */
+ SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
+ }
+
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
+ send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
return -1;
}
@@ -1126,6 +1187,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
TALLOC_CTX *ctx = NULL;
char *pdata = NULL;
NTSTATUS status;
+ size_t param_len;
DEBUG(5,("call_nt_transact_create\n"));
@@ -1496,7 +1558,13 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
/* Realloc the size of parameters and data we will return */
- params = nttrans_realloc(ppparams, 69);
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ /* Extended response is 32 more byyes. */
+ param_len = 101;
+ } else {
+ param_len = 69;
+ }
+ params = nttrans_realloc(ppparams, param_len);
if(params == NULL) {
return ERROR_DOS(ERRDOS,ERRnomem);
}
@@ -1555,10 +1623,21 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
p += 4;
SCVAL(p,0,fsp->is_directory ? 1 : 0);
+ if (flags & EXTENDED_RESPONSE_REQUIRED) {
+ uint32 perms = 0;
+ p += 26;
+ if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
+ perms = FILE_GENERIC_ALL;
+ } else {
+ perms = FILE_GENERIC_READ|FILE_EXECUTE;
+ }
+ SIVAL(p,0,perms);
+ }
+
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
+ send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
return -1;
}