#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. */
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;
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,
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,
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);
/* 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
} 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"
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);
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;
fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
fstrcpy(reply_name+2,my_name);
+ ntversion = 0x01;
+ lmnttoken = 0xffff;
+ lm20token = 0xffff;
+
if (DEBUGLVL(3))
{
fstring ascuser;
/* 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 */
return True;
}
+/*******************************************************************
+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.
********************************************************************/
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;
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 */
if (!reply)
{
- DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
+ reply = api_pipe_fault_resp(p, pd, 0x1c010002);
}
return reply;
{
/* 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);
}
}
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
{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},
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);