summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-11-15 22:11:10 +0000
committerLuke Leighton <lkcl@samba.org>1999-11-15 22:11:10 +0000
commitb231d2fafaff8dc67ef2dbaec778f716524d4f6a (patch)
tree054f060f9d6cd60535ebee5501177d8b839b7577 /source3
parent4c479f0574019afb2fc8a3dbfc802c75fde89244 (diff)
downloadsamba-b231d2fafaff8dc67ef2dbaec778f716524d4f6a.tar.gz
samba-b231d2fafaff8dc67ef2dbaec778f716524d4f6a.tar.bz2
samba-b231d2fafaff8dc67ef2dbaec778f716524d4f6a.zip
- added DCE/RPC "fault" PDU support.
- disabled (AGAIN) the GETDC "if (MAILSLOT\NTLOGON)" code that will get NT5rc2 to work but WILL break win95 (AGAIN). this needs _not_ to be re-enabled but to be replaced with a better mechanism. - added SMBwrite support (note: SMBwriteX already existed) as NT5rc2 is sending DCE/RPC over SMBwrite not SMBwriteX. (This used to be commit 25c70e3c984c4fed19763ed405741e83fe14f87e)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/nameserv.h1
-rw-r--r--source3/include/ntdomain.h12
-rw-r--r--source3/include/proto.h5
-rw-r--r--source3/include/rpc_dce.h9
-rw-r--r--source3/nmbd/nmbd_processlogon.c26
-rw-r--r--source3/rpc_parse/parse_rpc.c16
-rw-r--r--source3/rpc_server/srv_pipe.c43
-rw-r--r--source3/smbd/ipc.c9
-rw-r--r--source3/smbd/pipes.c41
-rw-r--r--source3/smbd/process.c2
-rw-r--r--source3/smbd/reply.c4
11 files changed, 152 insertions, 16 deletions
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 995a47b2fa..ad25131481 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -501,6 +501,7 @@ struct packet_struct
#define QUERYFORPDC_R 12 /* Response to Query for PDC. */
#define SAMLOGON 18
#define SAMLOGON_R 19
+#define SAMLOGON_UNK_R 21
/* Ids for netbios packet types. */
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index c36f619ef2..7f58874475 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -74,17 +74,19 @@ typedef struct pipes_struct
fstring pipe_srv_name;
prs_struct rhdr; /* output header */
+ prs_struct rfault; /* fault */
prs_struct rdata; /* output data */
prs_struct rdata_i; /* output data (intermediate, for fragments) */
prs_struct rauth; /* output authentication verifier */
prs_struct rverf; /* output verifier */
prs_struct rntlm; /* output ntlmssp */
- RPC_HDR hdr;
- RPC_HDR_BA hdr_ba;
- RPC_HDR_RB hdr_rb;
- RPC_HDR_REQ hdr_req;
- RPC_HDR_RESP hdr_resp;
+ RPC_HDR hdr;
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_REQ hdr_req;
+ RPC_HDR_RESP hdr_resp;
+ RPC_HDR_FAULT hdr_fault;
RPC_HDR_AUTH auth_info;
RPC_HDR_AUTHA autha_info;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0b0ca16c54..df05f2d7be 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -480,6 +480,9 @@ int set_maxfiles(int requested_max);
void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name);
BOOL become_user_permanently(uid_t uid, gid_t gid);
+
+/*The following definitions come from lib/util_array.c */
+
void free_void_array(uint32 num_entries, void **entries,
void(free_item)(void*));
void* add_item_to_array(uint32 *len, void ***array, const void *item,
@@ -2511,6 +2514,7 @@ BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int dep
BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
uint32 call_id, int data_len, int auth_len);
BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc,
uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
@@ -3912,6 +3916,7 @@ BOOL domain_client_validate( char *user, char *domain,
int reply_open_pipe_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
+int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 3b2b3071d2..52544ac642 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -43,6 +43,7 @@ enum RPC_PKT_TYPE
/* DCE/RPC flags */
#define RPC_FLG_FIRST 0x01
#define RPC_FLG_LAST 0x02
+#define RPC_FLG_NOCALL 0x20
/* NTLMSSP message types */
enum NTLM_MESSAGE_TYPE
@@ -127,6 +128,14 @@ typedef struct rpc_hdr_resp_info
} RPC_HDR_RESP;
+/* RPC_HDR_FAULT - ms fault rpc header */
+typedef struct rpc_hdr_fault_info
+{
+ uint32 status;
+ uint32 reserved; /* 0x0000 0000 */
+
+} RPC_HDR_FAULT;
+
/* this seems to be the same string name depending on the name of the pipe,
* but is more likely to be linked to the interface name
* "srvsvc", "\\PIPE\\ntsvcs"
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 0fc44a40c9..6ddf47fc5f 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -137,7 +137,9 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
q = skip_string(q, 1); /* PDC name */
/* PDC and domain name */
+#if 0
if (strcmp(mailslot, NT_LOGON_MAILSLOT)==0)
+#endif
{
q = align2(q, buf);
@@ -179,13 +181,16 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
uniuser = skip_unibuf(unicomp, buf+len-q);
getdc = skip_unibuf(uniuser, buf+len-q);
q = skip_string(getdc,1);
- q += 4;
+ q += 4; /* skip Account Control Bits */
domainsidsize = IVAL(q, 0);
q += 4;
- q += domainsidsize;
- q = align4(q, buf);
- q += 2;
+ if (domainsidsize != 0)
+ {
+ q += domainsidsize;
+ q += 2;
+ q = align4(q, buf);
+ }
ntversion = IVAL(q, 0);
q += 4;
@@ -205,6 +210,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
fstrcpy(reply_name+2,my_name);
+ ntversion = 0x01;
+ lmnttoken = 0xffff;
+ lm20token = 0xffff;
+
if (DEBUGLVL(3))
{
fstring ascuser;
@@ -221,7 +230,14 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* Construct reply. */
q = outbuf;
- SSVAL(q, 0, SAMLOGON_R);
+ if (uniuser[0] == 0)
+ {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ }
+ else
+ {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
q += 2;
/* Logon server, trust account, domain */
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index b902ee1414..82b0be2802 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -221,6 +221,22 @@ BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth)
}
/*******************************************************************
+reads or writes an RPC_HDR_FAULT structure.
+********************************************************************/
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
+ depth++;
+
+ prs_uint32("status ", ps, depth, &(rpc->status ));
+ prs_uint32("reserved", ps, depth, &(rpc->reserved));
+
+ return True;
+}
+
+/*******************************************************************
reads or writes an RPC_IFACE structure.
********************************************************************/
static BOOL smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 458d7e883c..1073ba2179 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -396,6 +396,45 @@ static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
return api_pipe_ntlmssp(p, pd);
}
+static BOOL api_pipe_fault_resp(pipes_struct *p, prs_struct *pd, uint32 status)
+{
+ DEBUG(5,("api_pipe_fault_resp: make response\n"));
+
+ prs_init(&(p->rhdr ), 0x18, 4, 0, False);
+ prs_init(&(p->rfault ), 0x8 , 4, 0, False);
+
+ /***/
+ /*** set up the header, response header and fault status ***/
+ /***/
+
+ p->hdr_fault.status = status;
+ p->hdr_fault.reserved = 0x0;
+
+ p->hdr_resp.alloc_hint = 0x0;
+ p->hdr_resp.cancel_count = 0x0;
+ p->hdr_resp.reserved = 0x0;
+
+ make_rpc_hdr(&p->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id,
+ 0x20,
+ 0);
+
+ smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0);
+ smb_io_rpc_hdr_resp ("resp" , &(p->hdr_resp ), &(p->rhdr), 0);
+ smb_io_rpc_hdr_fault("fault", &(p->hdr_fault), &(p->rfault), 0);
+ mem_realloc_data(p->rhdr.data, p->rhdr.offset);
+ mem_realloc_data(p->rfault.data, p->rfault.offset);
+
+ /***/
+ /*** link rpc header and fault together ***/
+ /***/
+
+ prs_link(NULL , &p->rhdr , &p->rfault);
+ prs_link(&p->rhdr, &p->rfault, NULL );
+
+ return True;
+}
+
static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type)
{
uint16 assoc_gid;
@@ -669,6 +708,8 @@ static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd)
BOOL rpc_command(pipes_struct *p, prs_struct *pd)
{
BOOL reply = False;
+ DEBUG(10,("rpc_command\n"));
+
if (pd->data == NULL) return False;
/* process the rpc header */
@@ -715,7 +756,7 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd)
if (!reply)
{
- DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
+ reply = api_pipe_fault_resp(p, pd, 0x1c010002);
}
return reply;
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 10c859d266..a3e7932529 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -3127,11 +3127,12 @@ static void api_rpc_trans_reply(char *outbuf,
{
/* all of data was sent: no need to wait for SMBreadX calls */
mem_free_data(p->rhdr .data);
- mem_free_data(p->rdata.data);
+ mem_free_data(p->rfault .data);
+ mem_free_data(p->rdata .data);
mem_free_data(p->rdata_i.data);
- mem_free_data(p->rauth.data);
- mem_free_data(p->rverf.data);
- mem_free_data(p->rntlm.data);
+ mem_free_data(p->rauth .data);
+ mem_free_data(p->rverf .data);
+ mem_free_data(p->rntlm .data);
}
}
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 374aa70d0f..e20d049834 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -104,6 +104,47 @@ int reply_open_pipe_and_X(connection_struct *conn,
return chain_reply(inbuf,outbuf,length,bufsize);
}
+/****************************************************************************
+ reply to a write
+
+ This code is basically stolen from reply_write with some
+ wrinkles to handle pipes.
+****************************************************************************/
+int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
+{
+ pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ size_t numtowrite = SVAL(inbuf,smb_vwv1);
+ int nwritten = -1;
+ char *data;
+ size_t outsize;
+
+ if (!p) return(ERROR(ERRDOS,ERRbadfid));
+
+ data = smb_buf(inbuf) + 3;
+
+ if (numtowrite == 0)
+ {
+ nwritten = 0;
+ }
+ else
+ {
+ nwritten = write_pipe(p, data, numtowrite);
+ }
+
+ if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
+ {
+ return (UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVAL(outbuf,smb_vwv0,nwritten);
+
+ DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
+ p->pnum, nwritten));
+
+ return outsize;
+}
/****************************************************************************
reply to a write and X
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index e9fb230624..1a6ec320e1 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -283,7 +283,7 @@ struct smb_message_struct
{SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
{SMBread,"SMBread",reply_read,AS_USER},
- {SMBwrite,"SMBwrite",reply_write,AS_USER},
+ {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC},
{SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
{SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
{SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 8723779d30..0c4fb2003c 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2348,6 +2348,10 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
int outsize = 0;
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn))
+ return reply_pipe_write(inbuf,outbuf,dum_size,dum_buffsize);
+
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
CHECK_ERROR(fsp);