mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
r8805: Merge a duplicate struct. Get ready to support SPNEGO rpc binds.
Jeremy.
This commit is contained in:
parent
c2f69827de
commit
fd6e342746
@ -66,6 +66,9 @@ enum RPC_PKT_TYPE {
|
|||||||
#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20
|
#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20
|
||||||
#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18
|
#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18
|
||||||
|
|
||||||
|
/* SPNEGO auth type. */
|
||||||
|
#define SPNEGO_AUTH_TYPE 0x9
|
||||||
|
|
||||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||||
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
|
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
|
||||||
@ -169,32 +172,25 @@ typedef struct rpc_hdr_bba_info {
|
|||||||
|
|
||||||
#define RPC_HDR_BBA_LEN 8
|
#define RPC_HDR_BBA_LEN 8
|
||||||
|
|
||||||
|
/* RPC_HDR_AUTH */
|
||||||
|
typedef struct rpc_hdr_auth_info {
|
||||||
|
uint8 auth_type; /* See XXX_AUTH_TYPE above. */
|
||||||
|
uint8 auth_level; /* See RPC_PIPE_AUTH_XXX_LEVEL above. */
|
||||||
|
uint8 auth_pad_len;
|
||||||
|
uint8 auth_reserved;
|
||||||
|
uint32 auth_context_id;
|
||||||
|
} RPC_HDR_AUTH;
|
||||||
|
|
||||||
|
#define RPC_HDR_AUTH_LEN 8
|
||||||
|
|
||||||
/* RPC_HDR_AUTHA */
|
/* RPC_HDR_AUTHA */
|
||||||
typedef struct rpc_hdr_autha_info {
|
typedef struct rpc_hdr_autha_info {
|
||||||
uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
|
uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
|
||||||
uint16 max_rsize; /* max receive fragment size (0x1630) */
|
uint16 max_rsize; /* max receive fragment size (0x1630) */
|
||||||
|
RPC_HDR_AUTH auth;
|
||||||
uint8 auth_type; /* 0x0a */
|
|
||||||
uint8 auth_level; /* 0x06 */
|
|
||||||
uint8 stub_type_len; /* don't know */
|
|
||||||
uint8 padding; /* padding */
|
|
||||||
|
|
||||||
uint32 unknown; /* 0x0014a0c0 */
|
|
||||||
} RPC_HDR_AUTHA;
|
} RPC_HDR_AUTHA;
|
||||||
|
|
||||||
#define RPC_HDR_AUTHA_LEN 12
|
#define RPC_HDR_AUTHA_LEN (RPC_HDR_AUTH_LEN+4)
|
||||||
|
|
||||||
/* RPC_HDR_AUTH */
|
|
||||||
typedef struct rpc_hdr_auth_info {
|
|
||||||
uint8 auth_type; /* 0x0a */
|
|
||||||
uint8 auth_level; /* 0x06 */
|
|
||||||
uint8 padding;
|
|
||||||
uint8 reserved; /* padding */
|
|
||||||
|
|
||||||
uint32 auth_context; /* pointer */
|
|
||||||
} RPC_HDR_AUTH;
|
|
||||||
|
|
||||||
#define RPC_HDR_AUTH_LEN 8
|
|
||||||
|
|
||||||
/* this is TEMPORARILY coded up as a specific structure */
|
/* this is TEMPORARILY coded up as a specific structure */
|
||||||
/* this structure comes after the bind request */
|
/* this structure comes after the bind request */
|
||||||
|
@ -242,7 +242,7 @@ static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Let the caller know how much padding at the end of the data */
|
/* Let the caller know how much padding at the end of the data */
|
||||||
*pauth_padding_len = rhdr_auth.padding;
|
*pauth_padding_len = rhdr_auth.auth_pad_len;
|
||||||
|
|
||||||
/* Check it's the type of reply we were expecting to decode */
|
/* Check it's the type of reply we were expecting to decode */
|
||||||
|
|
||||||
@ -796,6 +796,7 @@ static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli,
|
|||||||
{
|
{
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
RPC_HDR hdr;
|
RPC_HDR hdr;
|
||||||
|
RPC_HDR_AUTH hdr_auth;
|
||||||
RPC_HDR_AUTHA hdr_autha;
|
RPC_HDR_AUTHA hdr_autha;
|
||||||
DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0);
|
DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0);
|
||||||
DATA_BLOB ntlmssp_reply;
|
DATA_BLOB ntlmssp_reply;
|
||||||
@ -826,8 +827,8 @@ static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli,
|
|||||||
get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
|
get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
|
||||||
|
|
||||||
/* Create the request RPC_HDR_AUTHA */
|
/* Create the request RPC_HDR_AUTHA */
|
||||||
init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN,
|
init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0, 0x0014a0c0);
|
||||||
auth_type, auth_level, 0x00);
|
init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, &hdr_auth);
|
||||||
|
|
||||||
if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
|
if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
|
||||||
DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
|
DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
|
||||||
|
@ -649,73 +649,20 @@ BOOL smb_io_rpc_hdr_fault(const char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
Init an RPC_HDR_AUTHA structure.
|
|
||||||
********************************************************************/
|
|
||||||
|
|
||||||
void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
|
|
||||||
uint16 max_tsize, uint16 max_rsize,
|
|
||||||
uint8 auth_type, uint8 auth_level,
|
|
||||||
uint8 stub_type_len)
|
|
||||||
{
|
|
||||||
rai->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
|
|
||||||
rai->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
|
|
||||||
|
|
||||||
rai->auth_type = auth_type; /* nt lm ssp 0x0a */
|
|
||||||
rai->auth_level = auth_level; /* 0x06 */
|
|
||||||
rai->stub_type_len = stub_type_len; /* 0x00 */
|
|
||||||
rai->padding = 0; /* padding 0x00 */
|
|
||||||
|
|
||||||
rai->unknown = 0x0014a0c0; /* non-zero pointer to something */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
Reads or writes an RPC_HDR_AUTHA structure.
|
|
||||||
********************************************************************/
|
|
||||||
|
|
||||||
BOOL smb_io_rpc_hdr_autha(const char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth)
|
|
||||||
{
|
|
||||||
if (rai == NULL)
|
|
||||||
return False;
|
|
||||||
|
|
||||||
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_autha");
|
|
||||||
depth++;
|
|
||||||
|
|
||||||
if(!prs_uint16("max_tsize ", ps, depth, &rai->max_tsize))
|
|
||||||
return False;
|
|
||||||
if(!prs_uint16("max_rsize ", ps, depth, &rai->max_rsize))
|
|
||||||
return False;
|
|
||||||
|
|
||||||
if(!prs_uint8 ("auth_type ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
|
|
||||||
return False;
|
|
||||||
if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
|
|
||||||
return False;
|
|
||||||
if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
|
|
||||||
return False;
|
|
||||||
if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
|
|
||||||
return False;
|
|
||||||
|
|
||||||
if(!prs_uint32("unknown ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
|
|
||||||
return False;
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
Inits an RPC_HDR_AUTH structure.
|
Inits an RPC_HDR_AUTH structure.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
|
void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
|
||||||
uint8 auth_type, uint8 auth_level,
|
uint8 auth_type, uint8 auth_level,
|
||||||
uint8 padding,
|
uint8 auth_pad_len,
|
||||||
uint32 ptr)
|
uint32 auth_context_id)
|
||||||
{
|
{
|
||||||
rai->auth_type = auth_type; /* nt lm ssp 0x0a */
|
rai->auth_type = auth_type; /* nt lm ssp 0x0a */
|
||||||
rai->auth_level = auth_level; /* 0x06 */
|
rai->auth_level = auth_level; /* 0x06 */
|
||||||
rai->padding = padding;
|
rai->auth_pad_len = auth_pad_len;
|
||||||
rai->reserved = 0;
|
rai->auth_reserved = 0;
|
||||||
|
rai->auth_context_id = auth_context_id;
|
||||||
rai->auth_context = ptr; /* non-zero pointer to something */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
@ -737,11 +684,48 @@ BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, in
|
|||||||
return False;
|
return False;
|
||||||
if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
|
if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
|
||||||
return False;
|
return False;
|
||||||
if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
|
if(!prs_uint8 ("auth_pad_len ", ps, depth, &rai->auth_pad_len))
|
||||||
return False;
|
return False;
|
||||||
if(!prs_uint8 ("reserved ", ps, depth, &rai->reserved))
|
if(!prs_uint8 ("auth_reserved", ps, depth, &rai->auth_reserved))
|
||||||
return False;
|
return False;
|
||||||
if(!prs_uint32("auth_context ", ps, depth, &rai->auth_context))
|
if(!prs_uint32("auth_context_id", ps, depth, &rai->auth_context_id))
|
||||||
|
return False;
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
Init an RPC_HDR_AUTHA structure.
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
|
||||||
|
uint16 max_tsize, uint16 max_rsize,
|
||||||
|
RPC_HDR_AUTH *auth)
|
||||||
|
{
|
||||||
|
rai->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
|
||||||
|
rai->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
|
||||||
|
rai->auth = *auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
Reads or writes an RPC_HDR_AUTHA structure.
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
BOOL smb_io_rpc_hdr_autha(const char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth)
|
||||||
|
{
|
||||||
|
if (rai == NULL)
|
||||||
|
return False;
|
||||||
|
|
||||||
|
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_autha");
|
||||||
|
depth++;
|
||||||
|
|
||||||
|
if(!prs_uint16("max_tsize ", ps, depth, &rai->max_tsize))
|
||||||
|
return False;
|
||||||
|
if(!prs_uint16("max_rsize ", ps, depth, &rai->max_rsize))
|
||||||
|
return False;
|
||||||
|
|
||||||
|
if(!smb_io_rpc_hdr_auth("auth", &rai->auth, ps, depth))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
|
@ -582,9 +582,9 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) {
|
if (autha_info.auth.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) {
|
||||||
DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
|
DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
|
||||||
(int)autha_info.auth_type, (int)autha_info.auth_level ));
|
(int)autha_info.auth.auth_type, (int)autha_info.auth.auth_level ));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,67 +941,72 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) {
|
switch(auth_info.auth_type) {
|
||||||
|
case NTLMSSP_AUTH_TYPE:
|
||||||
|
|
||||||
if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
|
if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
|
||||||
DEBUG(0,("api_pipe_bind_req: unable to "
|
DEBUG(0,("api_pipe_bind_req: unable to "
|
||||||
"unmarshall RPC_HDR_AUTH struct.\n"));
|
"unmarshall RPC_HDR_AUTH struct.\n"));
|
||||||
return False;
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strequal(auth_verifier.signature, "NTLMSSP")) {
|
||||||
|
DEBUG(0,("api_pipe_bind_req: "
|
||||||
|
"auth_verifier.signature != NTLMSSP\n"));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
|
||||||
|
DEBUG(0,("api_pipe_bind_req: "
|
||||||
|
"auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
|
||||||
|
auth_verifier.msg_type));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
|
||||||
|
DEBUG(0,("api_pipe_bind_req: "
|
||||||
|
"Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
|
||||||
|
p->ntlmssp_auth_requested = True;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETSEC_AUTH_TYPE:
|
||||||
|
{
|
||||||
|
RPC_AUTH_NETSEC_NEG neg;
|
||||||
|
struct netsec_auth_struct *a = &(p->netsec_auth);
|
||||||
|
|
||||||
|
if (!server_auth2_negotiated) {
|
||||||
|
DEBUG(0, ("Attempt to bind using schannel "
|
||||||
|
"without successful serverauth2\n"));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) {
|
||||||
|
DEBUG(0,("api_pipe_bind_req: "
|
||||||
|
"Could not unmarshal SCHANNEL auth neg\n"));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->netsec_auth_validated = True;
|
||||||
|
|
||||||
|
memset(a->sess_key, 0, sizeof(a->sess_key));
|
||||||
|
memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
|
||||||
|
|
||||||
|
a->seq_num = 0;
|
||||||
|
|
||||||
|
DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
|
||||||
|
neg.domain, neg.myname));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strequal(auth_verifier.signature, "NTLMSSP")) {
|
case SPNEGO_AUTH_TYPE:
|
||||||
DEBUG(0,("api_pipe_bind_req: "
|
default:
|
||||||
"auth_verifier.signature != NTLMSSP\n"));
|
DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
|
||||||
|
auth_info.auth_type ));
|
||||||
return False;
|
return False;
|
||||||
}
|
|
||||||
|
|
||||||
if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
|
|
||||||
DEBUG(0,("api_pipe_bind_req: "
|
|
||||||
"auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
|
|
||||||
auth_verifier.msg_type));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
|
|
||||||
DEBUG(0,("api_pipe_bind_req: "
|
|
||||||
"Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
|
|
||||||
p->ntlmssp_auth_requested = True;
|
|
||||||
|
|
||||||
} else if (auth_info.auth_type == NETSEC_AUTH_TYPE) {
|
|
||||||
|
|
||||||
RPC_AUTH_NETSEC_NEG neg;
|
|
||||||
struct netsec_auth_struct *a = &(p->netsec_auth);
|
|
||||||
|
|
||||||
if (!server_auth2_negotiated) {
|
|
||||||
DEBUG(0, ("Attempt to bind using schannel "
|
|
||||||
"without successful serverauth2\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) {
|
|
||||||
DEBUG(0,("api_pipe_bind_req: "
|
|
||||||
"Could not unmarshal SCHANNEL auth neg\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->netsec_auth_validated = True;
|
|
||||||
|
|
||||||
memset(a->sess_key, 0, sizeof(a->sess_key));
|
|
||||||
memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
|
|
||||||
|
|
||||||
a->seq_num = 0;
|
|
||||||
|
|
||||||
DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
|
|
||||||
neg.domain, neg.myname));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
|
|
||||||
auth_info.auth_type ));
|
|
||||||
return False;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user