summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2003-04-04 15:21:04 +0000
committerVolker Lendecke <vlendec@samba.org>2003-04-04 15:21:04 +0000
commit02bb4e1b8ae931d9eefa2fbd4a6f5456aca99b2b (patch)
tree099bc90dbf63fd218f7f6d45cf88223b172c0c34 /source3/rpc_server
parentd9613a1a3c37dca9f695b1361a0fd5d2b3f503cd (diff)
downloadsamba-02bb4e1b8ae931d9eefa2fbd4a6f5456aca99b2b.tar.gz
samba-02bb4e1b8ae931d9eefa2fbd4a6f5456aca99b2b.tar.bz2
samba-02bb4e1b8ae931d9eefa2fbd4a6f5456aca99b2b.zip
This is a merge of the NETLOGON schannel server code from Samba
TNG. Actually, it exists in the main Samba cvs tree in APPLIANCE_TNG as I found out later :-) It adds a new parameter: server schannel = yes/auto/no defaulting to auto. What does this mean to the user: No requireSignOrSeal registry patch for XP anymore. Many thanks for this code to Luke Leighton, Elrond and anybody else I forgot to mention. My next thing will be to see if this applies cleanly to 3_0. Please test and comment! Volker (This used to be commit e1f953241eb020f19fe657f29afdae28dcf5a03b)
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_netlog_nt.c34
-rw-r--r--source3/rpc_server/srv_pipe.c422
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c15
3 files changed, 438 insertions, 33 deletions
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 6182da53d9..76c1d98dab 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -334,6 +334,13 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
srv_time.time = 0;
+ if ( (lp_server_schannel() == True) &&
+ ((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) {
+
+ /* schannel must be used, but client did not offer it. */
+ status = NT_STATUS_ACCESS_DENIED;
+ }
+
rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
@@ -366,9 +373,18 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
srv_flgs.neg_flags = 0x000001ff;
+ if (lp_server_schannel() != False) {
+ srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL;
+ }
+
/* set up the LSA AUTH 2 response */
init_net_r_auth_2(r_u, &srv_cred, &srv_flgs, status);
+ if (NT_STATUS_IS_OK(status)) {
+ extern struct dcinfo last_dcinfo;
+ last_dcinfo = p->dc;
+ }
+
return r_u->status;
}
@@ -523,7 +539,23 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
if (!get_valid_user_struct(p->vuid))
return NT_STATUS_NO_SUCH_USER;
-
+
+
+ if ( (lp_server_schannel() == True) && (!p->netsec_auth_validated) ) {
+ /* 'server schannel = yes' should enforce use of
+ schannel, the client did offer it in auth2, but
+ obviously did not use it. */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (p->netsec_auth_validated) {
+ /* The client opens a second RPC NETLOGON pipe without
+ doing a auth2. The session key for the schannel is
+ re-used from the auth2 the client did before. */
+ extern struct dcinfo last_dcinfo;
+ p->dc = last_dcinfo;
+ }
+
/* checks and updates credentials. creates reply credentials */
if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
return NT_STATUS_INVALID_HANDLE;
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 5d8b7d39e9..9425ccbe4d 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -43,6 +43,13 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+/*************************************************************
+ HACK Alert!
+ We need to transfer the session key from one rpc bind to the
+ next. This is the way the netlogon schannel works.
+**************************************************************/
+struct dcinfo last_dcinfo;
+
static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
unsigned char *hash = p->ntlmssp_hash;
@@ -115,6 +122,9 @@ BOOL create_next_pdu(pipes_struct *p)
if(p->ntlmssp_auth_validated)
data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
+ if(p->netsec_auth_validated)
+ data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN);
+
/*
* The amount we send is the minimum of the available
* space and the amount left to send.
@@ -148,6 +158,10 @@ BOOL create_next_pdu(pipes_struct *p)
p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
+ } else if (p->netsec_auth_validated) {
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
+ RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN;
+ p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN;
} else {
p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
p->hdr.auth_len = 0;
@@ -192,7 +206,7 @@ BOOL create_next_pdu(pipes_struct *p)
return False;
}
- if (p->hdr.auth_len > 0) {
+ if (p->ntlmssp_auth_validated) {
uint32 crc32 = 0;
char *data;
@@ -239,6 +253,47 @@ BOOL create_next_pdu(pipes_struct *p)
}
}
+ if (p->netsec_auth_validated) {
+ char *data;
+ RPC_HDR_AUTH auth_info;
+ static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
+ static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
+
+ RPC_AUTH_NETSEC_CHK verf;
+ prs_struct rverf;
+ prs_struct rauth;
+
+ uchar sign[8];
+
+ data = prs_data_p(&outgoing_pdu) + data_pos;
+
+ init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL,
+ RPC_HDR_AUTH_LEN, 1);
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
+ prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
+
+ memset(sign, 0, sizeof(sign));
+ sign[3] = 0x01;
+
+ init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes);
+
+ if (!netsec_encode(&p->netsec_auth, &verf, data, data_len)) {
+ DEBUG(0,("create_next_pdu: failed encode data.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0);
+ p->netsec_auth.seq_num++;
+ }
+
/*
* Setup the counts for this PDU.
*/
@@ -775,6 +830,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
enum RPC_PKT_TYPE reply_pkt_type;
p->ntlmssp_auth_requested = False;
+ p->netsec_auth_validated = False;
DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
@@ -840,39 +896,62 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
return False;
}
- /*
- * We only support NTLMSSP_AUTH_TYPE requests.
- */
+ if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) {
- if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) {
- DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
- auth_info.auth_type ));
- return False;
- }
+ if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_bind_req: unable to "
+ "unmarshall RPC_HDR_AUTH struct.\n"));
+ return False;
+ }
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
- return False;
- }
+ if(!strequal(auth_verifier.signature, "NTLMSSP")) {
+ DEBUG(0,("api_pipe_bind_req: "
+ "auth_verifier.signature != NTLMSSP\n"));
+ 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(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 (!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;
+ }
- 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"));
+ 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;
}
-
- p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
- p->ntlmssp_auth_requested = True;
}
switch(p->hdr.pkt_type) {
@@ -1003,6 +1082,33 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
}
+ if (p->netsec_auth_validated) {
+ RPC_AUTH_VERIFIER auth_verifier;
+ uint32 flags;
+
+ init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1);
+ if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
+ goto err_exit;
+ }
+
+ /*** NETSEC verifier ***/
+
+ init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
+ if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
+ goto err_exit;
+ }
+
+ prs_align(&out_auth);
+
+ flags = 5;
+ if(!prs_uint32("flags ", &out_auth, 0, &flags))
+ goto err_exit;
+
+ auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
+ }
+
/*
* Create the header, now we know the length.
*/
@@ -1030,7 +1136,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
goto err_exit;
}
- if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+ if((p->ntlmssp_auth_requested|p->netsec_auth_validated) &&
+ !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
goto err_exit;
}
@@ -1162,6 +1269,265 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
return True;
}
+static void netsechash(uchar * key, uchar * data, int data_len)
+{
+ uchar hash[256];
+ uchar index_i = 0;
+ uchar index_j = 0;
+ uchar j = 0;
+ int ind;
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ hash[ind] = (uchar) ind;
+ }
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ uchar tc;
+
+ j += (hash[ind] + key[ind % 16]);
+
+ tc = hash[ind];
+ hash[ind] = hash[j];
+ hash[j] = tc;
+ }
+
+ for (ind = 0; ind < data_len; ind++)
+ {
+ uchar tc;
+ uchar t;
+
+ index_i++;
+ index_j += hash[index_i];
+
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
+
+ t = hash[index_i] + hash[index_j];
+ data[ind] ^= hash[t];
+ }
+}
+
+void dump_data_pw(const char *msg, const uchar * data, size_t len)
+{
+#ifdef DEBUG_PASSWORD
+ DEBUG(11, ("%s", msg));
+ if (data != NULL && len > 0)
+ {
+ dump_data(11, data, len);
+ }
+#endif
+}
+
+BOOL netsec_encode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
+{
+ uchar dataN[4];
+ uchar digest1[16];
+ struct MD5Context ctx3;
+ uchar sess_kf0[16];
+ int i;
+
+ /* store the sequence number */
+ SIVAL(dataN, 0, a->seq_num);
+
+ for (i = 0; i < sizeof(sess_kf0); i++)
+ {
+ sess_kf0[i] = a->sess_key[i] ^ 0xf0;
+ }
+
+ dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
+ dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
+
+ MD5Init(&ctx3);
+ MD5Update(&ctx3, dataN, 0x4);
+ MD5Update(&ctx3, verf->sig, 8);
+
+ MD5Update(&ctx3, verf->data8, 8);
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+ dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
+
+ hmac_md5(sess_kf0, dataN, 0x4, digest1);
+ dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
+ hmac_md5(digest1, verf->data3, 8, digest1);
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+ netsechash(digest1, verf->data8, 8);
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+
+ dump_data_pw("data :\n", data, data_len);
+ MD5Update(&ctx3, data, data_len);
+
+ {
+ char digest_tmp[16];
+ char digest2[16];
+ MD5Final(digest_tmp, &ctx3);
+ hmac_md5(a->sess_key, digest_tmp, 16, digest2);
+ dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp));
+ dump_data_pw("digest:\n", digest2, sizeof(digest2));
+ memcpy(verf->data1, digest2, sizeof(verf->data1));
+ }
+
+ netsechash(digest1, data, data_len);
+ dump_data_pw("data:\n", data, data_len);
+
+ hmac_md5(a->sess_key, dataN, 0x4, digest1);
+ dump_data_pw("ctx:\n", digest1, sizeof(digest1));
+
+ hmac_md5(digest1, verf->data1, 8, digest1);
+
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+ netsechash(digest1, verf->data3, 8);
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+
+ return True;
+}
+
+BOOL netsec_decode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
+{
+ uchar dataN[4];
+ uchar digest1[16];
+ struct MD5Context ctx3;
+ uchar sess_kf0[16];
+ int i;
+
+ /* store the sequence number */
+ SIVAL(dataN, 0, a->seq_num);
+
+ for (i = 0; i < sizeof(sess_kf0); i++)
+ {
+ sess_kf0[i] = a->sess_key[i] ^ 0xf0;
+ }
+
+ dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
+ dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
+ hmac_md5(a->sess_key, dataN, 0x4, digest1);
+ dump_data_pw("ctx:\n", digest1, sizeof(digest1));
+
+ hmac_md5(digest1, verf->data1, 8, digest1);
+
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+ netsechash(digest1, verf->data3, 8);
+ dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3));
+
+ MD5Init(&ctx3);
+ MD5Update(&ctx3, dataN, 0x4);
+ MD5Update(&ctx3, verf->sig, 8);
+
+ dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
+
+ hmac_md5(sess_kf0, dataN, 0x4, digest1);
+ dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
+ hmac_md5(digest1, verf->data3, 8, digest1);
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+ netsechash(digest1, verf->data8, 8);
+ dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8));
+ MD5Update(&ctx3, verf->data8, 8);
+
+ dump_data_pw("data :\n", data, data_len);
+ netsechash(digest1, data, data_len);
+ dump_data_pw("datadec:\n", data, data_len);
+
+ MD5Update(&ctx3, data, data_len);
+ {
+ uchar digest_tmp[16];
+ MD5Final(digest_tmp, &ctx3);
+ hmac_md5(a->sess_key, digest_tmp, 16, digest1);
+ dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp));
+ }
+
+ dump_data_pw("digest:\n", digest1, sizeof(digest1));
+ dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1));
+
+ return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0;
+}
+
+/****************************************************************************
+ Deal with schannel processing on an RPC request.
+****************************************************************************/
+BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
+{
+ /*
+ * We always negotiate the following two bits....
+ */
+ int data_len;
+ int auth_len;
+ uint32 old_offset;
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_NETSEC_CHK netsec_chk;
+
+
+ auth_len = p->hdr.auth_len;
+
+ if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
+ DEBUG(0,("Incorrect auth_len %d.\n", auth_len ));
+ return False;
+ }
+
+ /*
+ * The following is that length of the data we must verify or unseal.
+ * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
+ * preceeding the auth_data.
+ */
+
+ data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
+ RPC_HDR_AUTH_LEN - auth_len;
+
+ DEBUG(5,("data %d auth %d\n", data_len, auth_len));
+
+ old_offset = prs_offset(rpc_in);
+
+ if(!prs_set_offset(rpc_in, old_offset + data_len)) {
+ DEBUG(0,("cannot move offset to %u.\n",
+ (unsigned int)old_offset + data_len ));
+ return False;
+ }
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
+ DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n"));
+ return False;
+ }
+
+ if ((auth_info.auth_type != NETSEC_AUTH_TYPE) ||
+ (auth_info.auth_level != NETSEC_AUTH_LEVEL)) {
+ DEBUG(0,("Invalid auth info %d or level %d on schannel\n",
+ auth_info.auth_type, auth_info.auth_level));
+ return False;
+ }
+
+ if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) {
+ DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n"));
+ return False;
+ }
+
+ if (!netsec_decode(&p->netsec_auth, &netsec_chk,
+ prs_data_p(rpc_in)+old_offset, data_len)) {
+ DEBUG(0,("failed to decode PDU\n"));
+ return False;
+ }
+
+ /*
+ * Return the current pointer to the data offset.
+ */
+
+ if(!prs_set_offset(rpc_in, old_offset)) {
+ DEBUG(0,("failed to set offset back to %u\n",
+ (unsigned int)old_offset ));
+ return False;
+ }
+
+ return True;
+}
+
/****************************************************************************
Return a user struct for a pipe user.
****************************************************************************/
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 8cb81b9c6d..125f603771 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -594,11 +594,18 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
* Authentication _was_ requested and it already failed.
*/
- DEBUG(0,("process_request_pdu: RPC request received on pipe %s where \
-authentication failed. Denying the request.\n", p->name));
+ DEBUG(0,("process_request_pdu: RPC request received on pipe %s "
+ "where authentication failed. Denying the request.\n",
+ p->name));
set_incoming_fault(p);
- return False;
- }
+ return False;
+ }
+
+ if (p->netsec_auth_validated && !api_pipe_netsec_process(p, rpc_in_p)) {
+ DEBUG(0,("process_request_pdu: failed to do schannel processing.\n"));
+ set_incoming_fault(p);
+ return False;
+ }
/*
* Check the data length doesn't go over the 15Mb limit.