mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
- 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 commit is contained in:
parent
cc2ce2b755
commit
25c70e3c98
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -220,6 +220,22 @@ BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth)
|
||||
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.
|
||||
********************************************************************/
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user