summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>2000-02-27 19:12:07 +0000
committerLuke Leighton <lkcl@samba.org>2000-02-27 19:12:07 +0000
commit648554f2e208106980074761a7bab30d369bf1d2 (patch)
treee632ff11eb95a162d5268f7bb9aa63e54f309ff6
parentd2b5af85ece76cba391bcba5fa463fdc335ff9e2 (diff)
downloadsamba-648554f2e208106980074761a7bab30d369bf1d2.tar.gz
added bind nack to server-side.
jeremy, the majority of "negative" responses are actually "fault" pdus. the only circumstances in which a bind nack is returned is if there is something wrong with a bind request. e.g the NTLMSSP auth bind-request (negotiate) stage, which contains the client hostname and client domain, contains an unrecognised name such as NULL. e.g the NETSEC (netlogon secure channel) auth bind-request stage which again happens (coincidentally) to contain the client hostname and client domain, contains a hostname/domainname tuple for which no NetrReqChal+ NetrAuth2 with flags 0x400001ff has just previously been done. i.e: NetrReqChal("\\myserver", "mydomain", ...); NetrAuth2("\\myserver", mydomain, 0x400001ff, ...); [now do netsec] NetSecBindRequest("\\somestupidservername", "totalgarbagedomainname") this should be rejected with a bind NACK.
-rw-r--r--source/include/lib_smb_proto.h55
-rw-r--r--source/include/proto.h56
-rw-r--r--source/include/rpc_dce.h36
-rw-r--r--source/include/rpc_parse_proto.h1
-rw-r--r--source/include/winbindd_proto.h56
-rw-r--r--source/rpc_parse/parse_rpc.c15
-rw-r--r--source/rpc_server/srv_pipe_ntlmssp.c305
-rw-r--r--source/rpc_server/srv_pipe_srv.c49
8 files changed, 339 insertions, 234 deletions
diff --git a/source/include/lib_smb_proto.h b/source/include/lib_smb_proto.h
index da8c7a71780..b343266106f 100644
--- a/source/include/lib_smb_proto.h
+++ b/source/include/lib_smb_proto.h
@@ -67,24 +67,22 @@ BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
/*The following definitions come from lib/vuser.c */
-BOOL is_valid_user_struct(const vuser_key *key);
-user_struct *get_valid_user_struct(const vuser_key *key);
-void invalidate_vuid(vuser_key *key);
-BOOL validated_username(vuser_key *key, char *name, size_t len);
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
uint16 create_vuid(pid_t pid,
- uid_t uid, gid_t gid,
- int n_groups, gid_t *groups,
- const char *unix_name,
- const char *requested_name,
- const char *real_name,
- BOOL guest, const NET_USER_INFO_3 *info3);
-uint16 register_vuid(pid_t pid,
- uid_t uid,gid_t gid,
- const char *unix_name,
- const char *requested_name,
- BOOL guest,
- const NET_USER_INFO_3 *info3);
-BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum);
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
/*The following definitions come from lib/vuser_db.c */
@@ -668,15 +666,16 @@ void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd);
/*The following definitions come from rpc_parse/parse_vuid.c */
-BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth);
-BOOL make_vuid_user_struct(user_struct *r_u,
- uid_t uid, gid_t gid,
- const char* name,
- const char* requested_name,
- const char* real_name,
- BOOL guest,
- uint32 n_groups, const gid_t *groups,
- const NET_USER_INFO_3 *usr);
-BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth);
-void vuid_free_user_struct(user_struct *r_u);
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
#endif /* _LIB_SMB_PROTO_H_ */
diff --git a/source/include/proto.h b/source/include/proto.h
index 88ff6cc98b8..fe33b910d47 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -827,24 +827,22 @@ void start_agent(struct vagent_ops *va);
/*The following definitions come from lib/vuser.c */
-BOOL is_valid_user_struct(const vuser_key *key);
-user_struct *get_valid_user_struct(const vuser_key *key);
-void invalidate_vuid(vuser_key *key);
-BOOL validated_username(vuser_key *key, char *name, size_t len);
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
uint16 create_vuid(pid_t pid,
- uid_t uid, gid_t gid,
- int n_groups, gid_t *groups,
- const char *unix_name,
- const char *requested_name,
- const char *real_name,
- BOOL guest, const NET_USER_INFO_3 *info3);
-uint16 register_vuid(pid_t pid,
- uid_t uid,gid_t gid,
- const char *unix_name,
- const char *requested_name,
- BOOL guest,
- const NET_USER_INFO_3 *info3);
-BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum);
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
/*The following definitions come from lib/vuser_db.c */
@@ -3194,6 +3192,7 @@ 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 is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *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,
@@ -3246,17 +3245,18 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_vuid.c */
-BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth);
-BOOL make_vuid_user_struct(user_struct *r_u,
- uid_t uid, gid_t gid,
- const char* name,
- const char* requested_name,
- const char* real_name,
- BOOL guest,
- uint32 n_groups, const gid_t *groups,
- const NET_USER_INFO_3 *usr);
-BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth);
-void vuid_free_user_struct(user_struct *r_u);
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
/*The following definitions come from rpc_server/srv_brs.c */
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index cd30fac10fa..d8a43f26697 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -2,9 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Paul Ashton 1997-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,20 +24,19 @@
#ifndef _DCE_RPC_H /* _DCE_RPC_H */
#define _DCE_RPC_H
-#include "rpc_misc.h" /* this only pulls in STRHDR */
-
/* DCE/RPC packet types */
enum RPC_PKT_TYPE
{
- RPC_REQUEST = 0x00,
- RPC_RESPONSE = 0x02,
- RPC_FAULT = 0x03,
- RPC_BIND = 0x0B,
- RPC_BINDACK = 0x0C,
+ RPC_REQUEST = 0x00,
+ RPC_RESPONSE = 0x02,
+ RPC_FAULT = 0x03,
+ RPC_BIND = 0x0B,
+ RPC_BINDACK = 0x0C,
+ RPC_BINDNACK = 0x0D,
RPC_ALTCONT = 0x0E,
RPC_ALTCONTRESP = 0x0F,
- RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
+ RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
};
/* DCE/RPC flags */
@@ -79,7 +78,7 @@ typedef struct rpc_hdr_info
} RPC_HDR;
-/* RPC_HDR_REQ - ms request rpc header */
+/* RPC_HDR_REQ - request rpc header */
typedef struct rpc_hdr_req_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
@@ -88,7 +87,7 @@ typedef struct rpc_hdr_req_info
} RPC_HDR_REQ;
-/* RPC_HDR_RESP - ms response rpc header */
+/* RPC_HDR_RESP - response rpc header */
typedef struct rpc_hdr_resp_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
@@ -98,7 +97,7 @@ typedef struct rpc_hdr_resp_info
} RPC_HDR_RESP;
-/* RPC_HDR_FAULT - ms fault rpc header */
+/* RPC_HDR_FAULT - fault rpc header */
typedef struct rpc_hdr_fault_info
{
uint32 status;
@@ -106,6 +105,13 @@ typedef struct rpc_hdr_fault_info
} RPC_HDR_FAULT;
+/* RPC_HDR_NACK - nack rpc header */
+typedef struct rpc_hdr_nack_info
+{
+ uint16 rej_code;
+
+} RPC_HDR_NACK;
+
/* 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"
@@ -165,7 +171,7 @@ typedef struct rpc_auth_ntlmssp_info
} RPC_AUTH_VERIFIER;
-/* RPC_BIND_REQ - ms req bind */
+/* RPC_BIND_REQ - req bind */
typedef struct rpc_bind_req_info
{
RPC_HDR_BBA bba;
diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h
index 8301c147c46..fe2df3aeefd 100644
--- a/source/include/rpc_parse_proto.h
+++ b/source/include/rpc_parse_proto.h
@@ -270,6 +270,7 @@ 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 is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *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,
diff --git a/source/include/winbindd_proto.h b/source/include/winbindd_proto.h
index 62ab8312c18..82e397e6e6a 100644
--- a/source/include/winbindd_proto.h
+++ b/source/include/winbindd_proto.h
@@ -607,24 +607,22 @@ void start_agent(struct vagent_ops *va);
/*The following definitions come from lib/vuser.c */
-BOOL is_valid_user_struct(const vuser_key *key);
-user_struct *get_valid_user_struct(const vuser_key *key);
-void invalidate_vuid(vuser_key *key);
-BOOL validated_username(vuser_key *key, char *name, size_t len);
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
uint16 create_vuid(pid_t pid,
- uid_t uid, gid_t gid,
- int n_groups, gid_t *groups,
- const char *unix_name,
- const char *requested_name,
- const char *real_name,
- BOOL guest, const NET_USER_INFO_3 *info3);
-uint16 register_vuid(pid_t pid,
- uid_t uid,gid_t gid,
- const char *unix_name,
- const char *requested_name,
- BOOL guest,
- const NET_USER_INFO_3 *info3);
-BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum);
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
/*The following definitions come from lib/vuser_db.c */
@@ -2103,6 +2101,7 @@ 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 is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *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,
@@ -2594,17 +2593,18 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_vuid.c */
-BOOL vuid_io_key(char *desc, vuser_key *r_u, prs_struct *ps, int depth);
-BOOL make_vuid_user_struct(user_struct *r_u,
- uid_t uid, gid_t gid,
- const char* name,
- const char* requested_name,
- const char* real_name,
- BOOL guest,
- uint32 n_groups, const gid_t *groups,
- const NET_USER_INFO_3 *usr);
-BOOL vuid_io_user_struct(char *desc, user_struct *r_u, prs_struct *ps, int depth);
-void vuid_free_user_struct(user_struct *r_u);
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
/*The following definitions come from tdb/tdb.c */
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index 167dc5ae0ea..f4782d24ba9 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -262,6 +262,21 @@ BOOL is_complete_pdu(prs_struct *ps)
}
/*******************************************************************
+reads or writes an RPC_HDR_NACK structure.
+********************************************************************/
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_nack");
+ depth++;
+
+ prs_uint16("rej_code", ps, depth, &(rpc->rej_code));
+
+ 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)
diff --git a/source/rpc_server/srv_pipe_ntlmssp.c b/source/rpc_server/srv_pipe_ntlmssp.c
index f91601f6948..19fa70aef73 100644
--- a/source/rpc_server/srv_pipe_ntlmssp.c
+++ b/source/rpc_server/srv_pipe_ntlmssp.c
@@ -26,14 +26,14 @@
extern int DEBUGLEVEL;
-static void NTLMSSPcalc_p( ntlmssp_auth_struct *a, uchar *data, int len)
+static void NTLMSSPcalc_p(ntlmssp_auth_struct * a, uchar * data, int len)
{
uchar *hash = a->ntlmssp_hash;
uchar index_i = hash[256];
uchar index_j = hash[257];
int ind;
- for( ind = 0; ind < len; ind++)
+ for (ind = 0; ind < len; ind++)
{
uchar tc;
uchar t;
@@ -60,14 +60,16 @@ this is where the data really should be split up into an array of
headers and data sections.
********************************************************************/
-static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
- prs_struct *resp)
+static BOOL api_ntlmssp_create_pdu(rpcsrv_struct * l, uint32 data_start,
+ prs_struct * resp)
{
- ntlmssp_auth_struct *a = (ntlmssp_auth_struct *)l->auth_info;
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
BOOL ret;
- BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
+ BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
uint32 data_len;
uint32 auth_len;
uint32 data_end = l->rdata.offset + (l->auth ? (8 + 16) : 0);
@@ -79,23 +81,24 @@ static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
prs_struct rauth;
prs_struct rverf;
- RPC_HDR_RESP hdr_resp;
+ RPC_HDR_RESP hdr_resp;
- DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
- data_start, data_end, l->hdr_ba.bba.max_tsize));
+ DEBUG(5,
+ ("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
+ data_start, data_end, l->hdr_ba.bba.max_tsize));
auth_len = l->hdr.auth_len;
- DEBUG(10,("create_rpc_reply: auth\n"));
+ DEBUG(10, ("create_rpc_reply: auth\n"));
if (auth_len != 16)
{
return False;
}
- prs_init(&rhdr , 0, 4, False);
+ prs_init(&rhdr, 0, 4, False);
- l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+ l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
/* set up rpc header (fragmentation issues) */
if (data_start == 0)
@@ -107,12 +110,12 @@ static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
l->hdr.flags = 0;
}
- hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
hdr_resp.cancel_count = 0x0;
- hdr_resp.context_id = 0x0;
+ hdr_resp.context_id = 0x0;
hdr_resp.reserved = 0x0;
- DEBUG(10,("alloc_hint: %d\n", hdr_resp.alloc_hint));
+ DEBUG(10, ("alloc_hint: %d\n", hdr_resp.alloc_hint));
if (hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
{
@@ -129,19 +132,19 @@ static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
rhdr.start = 0;
- rhdr.end = 0x18;
+ rhdr.end = 0x18;
- DEBUG(10,("hdr flags: %x\n", l->hdr.flags));
+ DEBUG(10, ("hdr flags: %x\n", l->hdr.flags));
/* store the header in the data stream */
- smb_io_rpc_hdr ("rhdr", &(l->hdr ), &(rhdr), 0);
+ smb_io_rpc_hdr("rhdr", &(l->hdr), &(rhdr), 0);
smb_io_rpc_hdr_resp("resp", &(hdr_resp), &(rhdr), 0);
/* don't use rdata: use rdata_i instead, which moves... */
/* make a pointer to the rdata data, NOT A COPY */
data = prs_data(&l->rdata, data_start);
- prs_create(&rdata_i, data, data_len, l->rdata.align, rdata_i.io);
+ prs_create(&rdata_i, data, data_len, l->rdata.align, rdata_i.io);
rdata_i.offset = data_len;
l->rdata_offset += data_len;
@@ -151,19 +154,21 @@ static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
prs_init(&rauth, 0, 4, False);
prs_init(&rverf, 0, 4, False);
- DEBUG(5,("create_ntlmssp_reply: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+ DEBUG(5, ("create_ntlmssp_reply: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len,
+ auth_len));
if (auth_seal)
{
crc32 = crc32_calc_buffer(data_len, data);
- NTLMSSPcalc_p(a, (uchar*)data, data_len);
+ NTLMSSPcalc_p(a, (uchar *) data, data_len);
}
if (auth_seal || auth_verify)
{
- RPC_HDR_AUTH auth_info;
- make_rpc_hdr_auth(&auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
+ RPC_HDR_AUTH auth_info;
+ make_rpc_hdr_auth(&auth_info, 0x0a, 0x06, 0x08,
+ (auth_verify ? 1 : 0));
smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &rauth, 0);
}
@@ -174,35 +179,36 @@ static BOOL api_ntlmssp_create_pdu(rpcsrv_struct *l, uint32 data_start,
make_rpc_auth_ntlmssp_chk(&ntlmssp_chk,
NTLMSSP_SIGN_VERSION, crc32,
a->ntlmssp_seq_num++);
- smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &rverf, 0);
- NTLMSSPcalc_p(a, (uchar*)prs_data(&rverf, 4), 12);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &rverf,
+ 0);
+ NTLMSSPcalc_p(a, (uchar *) prs_data(&rverf, 4), 12);
}
- prs_link(NULL , &rhdr , &rdata_i);
- prs_link(&rhdr , &rdata_i, &rauth );
- prs_link(&rdata_i, &rauth , &rverf );
- prs_link(&rauth , &rverf , NULL );
+ prs_link(NULL, &rhdr, &rdata_i);
+ prs_link(&rhdr, &rdata_i, &rauth);
+ prs_link(&rdata_i, &rauth, &rverf);
+ prs_link(&rauth, &rverf, NULL);
prs_init(resp, 0, 4, False);
ret = prs_copy(resp, &rhdr);
- prs_free_data(&rauth );
- prs_free_data(&rverf );
- prs_free_data(&rhdr );
+ prs_free_data(&rauth);
+ prs_free_data(&rverf);
+ prs_free_data(&rhdr);
if (IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_LAST) ||
l->hdr.pkt_type == RPC_BINDACK)
{
- DEBUG(10,("create_ntlmssp_reply: finished sending\n"));
+ DEBUG(10, ("create_ntlmssp_reply: finished sending\n"));
prs_free_data(&l->rdata);
}
return ret;
}
-static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
- RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
+static BOOL api_ntlmssp_verify(rpcsrv_struct * l,
+ RPC_AUTH_NTLMSSP_RESP * ntlmssp_resp)
{
- ntlmssp_auth_struct *a = (ntlmssp_auth_struct *)l->auth_info;
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
uchar lm_owf[24];
uchar nt_owf[128];
size_t lm_owf_len;
@@ -222,13 +228,13 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
ZERO_STRUCT(info3);
- DEBUG(5,("api_ntlmssp_verify: checking user details\n"));
+ DEBUG(5, ("api_ntlmssp_verify: checking user details\n"));
lm_owf_len = ntlmssp_resp->hdr_lm_resp.str_str_len;
nt_owf_len = ntlmssp_resp->hdr_nt_resp.str_str_len;
- usr_len = ntlmssp_resp->hdr_usr .str_str_len;
- dom_len = ntlmssp_resp->hdr_domain .str_str_len;
- wks_len = ntlmssp_resp->hdr_wks .str_str_len;
+ usr_len = ntlmssp_resp->hdr_usr.str_str_len;
+ dom_len = ntlmssp_resp->hdr_domain.str_str_len;
+ wks_len = ntlmssp_resp->hdr_wks.str_str_len;
if (lm_owf_len <= 1 && nt_owf_len == 0 &&
usr_len == 0 && dom_len == 0)
@@ -237,14 +243,20 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
}
else
{
- if (lm_owf_len == 0) return False;
- if (nt_owf_len == 0) return False;
- if (ntlmssp_resp->hdr_usr .str_str_len == 0) return False;
- if (ntlmssp_resp->hdr_wks .str_str_len == 0) return False;
+ if (lm_owf_len == 0)
+ return False;
+ if (nt_owf_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_usr.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_wks.str_str_len == 0)
+ return False;
}
- if (lm_owf_len > sizeof(lm_owf)) return False;
- if (nt_owf_len > sizeof(nt_owf)) return False;
+ if (lm_owf_len > sizeof(lm_owf))
+ return False;
+ if (nt_owf_len > sizeof(nt_owf))
+ return False;
memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
@@ -254,49 +266,50 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
dump_data_pw("chal:", a->ntlmssp_chal.challenge, 8);
memset(user_name, 0, sizeof(user_name));
- memset(domain , 0, sizeof(domain ));
- memset(wks , 0, sizeof(wks ));
+ memset(domain, 0, sizeof(domain));
+ memset(wks, 0, sizeof(wks));
- if (IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
+ if (IS_BITS_SET_ALL
+ (a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
{
unibuf_to_ascii(user_name, ntlmssp_resp->user,
- MIN(ntlmssp_resp->hdr_usr .str_str_len/2,
- sizeof(user_name)-1));
- unibuf_to_ascii(domain , ntlmssp_resp->domain,
- MIN(ntlmssp_resp->hdr_domain.str_str_len/2,
- sizeof(domain )-1));
- unibuf_to_ascii(wks , ntlmssp_resp->wks,
- MIN(ntlmssp_resp->hdr_wks .str_str_len/2,
- sizeof(wks )-1));
+ MIN(ntlmssp_resp->hdr_usr.str_str_len / 2,
+ sizeof(user_name) - 1));
+ unibuf_to_ascii(domain, ntlmssp_resp->domain,
+ MIN(ntlmssp_resp->hdr_domain.str_str_len / 2,
+ sizeof(domain) - 1));
+ unibuf_to_ascii(wks, ntlmssp_resp->wks,
+ MIN(ntlmssp_resp->hdr_wks.str_str_len / 2,
+ sizeof(wks) - 1));
}
else
{
- fstrcpy(user_name, ntlmssp_resp->user );
- fstrcpy(domain , ntlmssp_resp->domain);
- fstrcpy(wks , ntlmssp_resp->wks );
+ fstrcpy(user_name, ntlmssp_resp->user);
+ fstrcpy(domain, ntlmssp_resp->domain);
+ fstrcpy(wks, ntlmssp_resp->wks);
}
if (anonymous)
{
- DEBUG(5,("anonymous user session\n"));
+ DEBUG(5, ("anonymous user session\n"));
guest = True;
- safe_strcpy(unix_user, lp_guestaccount(-1), sizeof(unix_user)-1);
+ safe_strcpy(unix_user, lp_guestaccount(-1),
+ sizeof(unix_user) - 1);
nt_user[0] = 0;
pw = Get_Pwnam(unix_user, True);
}
- DEBUG(5,("user: %s domain: %s wks: %s\n",
- user_name, domain, wks));
+ DEBUG(5, ("user: %s domain: %s wks: %s\n", user_name, domain, wks));
l->auth_validated = check_domain_security(user_name, domain,
- (const uchar*)a->ntlmssp_chal.challenge,
- lm_owf, lm_owf_len,
- nt_owf, nt_owf_len,
- &info3) == 0x0;
+ (const uchar *)a->
+ ntlmssp_chal.challenge,
+ lm_owf, lm_owf_len, nt_owf,
+ nt_owf_len, &info3) == 0x0;
if (!anonymous && l->auth_validated)
{
pw = map_nt_and_unix_username(domain, user_name,
- unix_user, nt_user);
+ unix_user, nt_user);
l->auth_validated = pw != NULL;
}
@@ -304,9 +317,9 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
{
become_root(False);
l->key.pid = getpid();
- l->key.vuid = register_vuid(l->key.pid, pw->pw_uid, pw->pw_gid,
- unix_user, nt_user,
- guest, &info3);
+ l->key.vuid =
+ register_vuid(l->key.pid, pw->pw_uid, pw->pw_gid,
+ unix_user, nt_user, guest, &info3);
unbecome_root(False);
l->auth_validated = l->key.vuid != UID_FIELD_INVALID;
}
@@ -350,14 +363,14 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
for (ind = 0; ind < 256; ind++)
{
- a->ntlmssp_hash[ind] = (uchar)ind;
+ a->ntlmssp_hash[ind] = (uchar) ind;
}
for (ind = 0; ind < 256; ind++)
{
uchar tc;
- j += (a->ntlmssp_hash[ind] + k2[ind%len]);
+ j += (a->ntlmssp_hash[ind] + k2[ind % len]);
tc = a->ntlmssp_hash[ind];
a->ntlmssp_hash[ind] = a->ntlmssp_hash[j];
a->ntlmssp_hash[j] = tc;
@@ -375,7 +388,7 @@ static BOOL api_ntlmssp_verify(rpcsrv_struct *l,
return l->auth_validated;
}
-static BOOL api_ntlmssp(rpcsrv_struct *l, uint32 msg_type)
+static BOOL api_ntlmssp(rpcsrv_struct * l, uint32 msg_type)
{
/* receive a negotiate; send a challenge; receive a response */
switch (msg_type)
@@ -383,13 +396,25 @@ static BOOL api_ntlmssp(rpcsrv_struct *l, uint32 msg_type)
case NTLMSSP_NEGOTIATE:
{
RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
- smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, &l->data_i, 0);
+ if (!smb_io_rpc_auth_ntlmssp_neg
+ ("", &ntlmssp_neg, &l->data_i, 0))
+ {
+ return False;
+ }
+ if (strlen(ntlmssp_neg.myname) == 0 ||
+ strlen(ntlmssp_neg.domain) == 0)
+ {
+ return False;
+ }
+ DEBUG(10, ("ntlmssp neg: myname %s domain %s\n",
+ ntlmssp_neg.myname, ntlmssp_neg.domain));
break;
}
case NTLMSSP_AUTH:
{
RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
- smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, &l->data_i, 0);
+ smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp,
+ &l->data_i, 0);
if (!api_ntlmssp_verify(l, &ntlmssp_resp))
{
l->data_i.offset = 0;
@@ -399,8 +424,8 @@ static BOOL api_ntlmssp(rpcsrv_struct *l, uint32 msg_type)
default:
{
/* NTLMSSP expected: unexpected message type */
- DEBUG(3,("unexpected message type in NTLMSSP %d\n",
- msg_type));
+ DEBUG(3, ("unexpected message type in NTLMSSP %d\n",
+ msg_type));
return False;
}
}
@@ -408,32 +433,35 @@ static BOOL api_ntlmssp(rpcsrv_struct *l, uint32 msg_type)
return (l->data_i.offset != 0);
}
-static BOOL api_ntlmssp_bind_auth_resp(rpcsrv_struct *l)
+static BOOL api_ntlmssp_bind_auth_resp(rpcsrv_struct * l)
{
RPC_HDR_AUTHA autha_info;
RPC_AUTH_VERIFIER auth_verifier;
- DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+ DEBUG(5, ("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
- if (l->hdr.auth_len == 0) return False;
+ if (l->hdr.auth_len == 0)
+ return False;
/* decode the authentication verifier response */
smb_io_rpc_hdr_autha("", &autha_info, &l->data_i, 0);
- if (l->data_i.offset == 0) return False;
+ if (l->data_i.offset == 0)
+ return False;
smb_io_rpc_auth_verifier("", &auth_verifier, &l->data_i, 0);
- if (l->data_i.offset == 0) return False;
+ if (l->data_i.offset == 0)
+ return False;
if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH))
{
return False;
}
-
+
return api_ntlmssp(l, auth_verifier.msg_type);
}
-static BOOL api_ntlmssp_auth_chk(rpcsrv_struct *l,
- enum RPC_PKT_TYPE pkt_type)
+static BOOL api_ntlmssp_auth_chk(rpcsrv_struct * l,
+ enum RPC_PKT_TYPE pkt_type)
{
switch (pkt_type)
{
@@ -445,8 +473,13 @@ static BOOL api_ntlmssp_auth_chk(rpcsrv_struct *l,
case RPC_ALTCONTRESP:
{
RPC_AUTH_VERIFIER auth_verifier;
- smb_io_rpc_auth_verifier("", &auth_verifier, &l->data_i, 0);
- if (l->data_i.offset == 0) return False;
+ if (!smb_io_rpc_auth_verifier("", &auth_verifier,
+ &l->data_i, 0))
+ {
+ return False;
+ }
+ if (l->data_i.offset == 0)
+ return False;
if (strequal(auth_verifier.signature, "NTLMSSP"))
{
@@ -462,21 +495,21 @@ static BOOL api_ntlmssp_auth_chk(rpcsrv_struct *l,
return False;
}
-static BOOL api_ntlmssp_auth_gen(rpcsrv_struct *l, prs_struct *resp,
- enum RPC_PKT_TYPE pkt_type)
+static BOOL api_ntlmssp_auth_gen(rpcsrv_struct * l, prs_struct * resp,
+ enum RPC_PKT_TYPE pkt_type)
{
BOOL ret;
uint8 challenge[8];
- RPC_HDR_AUTH auth_info;
+ RPC_HDR_AUTH auth_info;
RPC_AUTH_VERIFIER auth_verifier;
prs_struct rhdr;
prs_struct rauth;
prs_struct rverf;
prs_struct rntlm;
- ntlmssp_auth_struct *a = (ntlmssp_auth_struct *)l->auth_info;
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
- prs_init(&(rhdr ), 0, 4, False);
+ prs_init(&(rhdr), 0, 4, False);
prs_init(&(rauth), 0, 4, False);
prs_init(&(rverf), 0, 4, False);
prs_init(&(rntlm), 0, 4, False);
@@ -491,15 +524,13 @@ static BOOL api_ntlmssp_auth_gen(rpcsrv_struct *l, prs_struct *resp,
/*** NTLMSSP verifier ***/
- make_rpc_auth_verifier(&auth_verifier,
- "NTLMSSP", NTLMSSP_CHALLENGE);
+ make_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
smb_io_rpc_auth_verifier("", &auth_verifier, &rauth, 0);
prs_realloc_data(&rauth, rauth.offset);
- /* NTLMSSP challenge ***/
+ /* NTLMSSP challenge ** */
- make_rpc_auth_ntlmssp_chal(&a->ntlmssp_chal,
- 0x000082b1, challenge);
+ make_rpc_auth_ntlmssp_chal(&a->ntlmssp_chal, 0x000082b1, challenge);
smb_io_rpc_auth_ntlmssp_chal("", &a->ntlmssp_chal, &rntlm, 0);
prs_realloc_data(&rntlm, rntlm.offset);
@@ -509,8 +540,8 @@ static BOOL api_ntlmssp_auth_gen(rpcsrv_struct *l, prs_struct *resp,
make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
l->hdr.call_id,
- l->rdata.offset + rverf.offset + rauth.offset + rntlm.offset + 0x10,
- rauth.offset + rntlm.offset);
+ l->rdata.offset + rverf.offset + rauth.offset +
+ rntlm.offset + 0x10, rauth.offset + rntlm.offset);
smb_io_rpc_hdr("", &l->hdr, &rhdr, 0);
prs_realloc_data(&rhdr, l->rdata.offset);
@@ -519,29 +550,31 @@ static BOOL api_ntlmssp_auth_gen(rpcsrv_struct *l, prs_struct *resp,
/*** link rpc header, bind ack and auth responses ***/
/***/
- prs_link(NULL , &rhdr , &l->rdata);
- prs_link(&rhdr , &l->rdata, &rverf );
- prs_link(&l->rdata, &rverf , &rauth );
- prs_link(&rverf , &rauth , &rntlm );
- prs_link(&rauth , &rntlm , NULL );
+ prs_link(NULL, &rhdr, &l->rdata);
+ prs_link(&rhdr, &l->rdata, &rverf);
+ prs_link(&l->rdata, &rverf, &rauth);
+ prs_link(&rverf, &rauth, &rntlm);
+ prs_link(&rauth, &rntlm, NULL);
prs_init(resp, 0, 4, False);
ret = prs_copy(resp, &rhdr);
prs_free_data(&l->rdata);
- prs_free_data(&rhdr );
- prs_free_data(&rauth );
- prs_free_data(&rverf );
- prs_free_data(&rntlm );
+ prs_free_data(&rhdr);
+ prs_free_data(&rauth);
+ prs_free_data(&rverf);
+ prs_free_data(&rntlm);
return ret;
}
-static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct *l)
+static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct * l)
{
- ntlmssp_auth_struct *a = (ntlmssp_auth_struct *)l->auth_info;
- BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
+ BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
int data_len;
int auth_len;
uint32 old_offset;
@@ -555,15 +588,17 @@ static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct *l)
}
data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
-
- DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+
+ DEBUG(5,
+ ("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
if (auth_seal)
{
char *data = prs_data(&l->data_i, l->data_i.offset);
- DEBUG(5,("api_pipe_auth_process: data %d\n", l->data_i.offset));
- NTLMSSPcalc_p(a, (uchar*)data, data_len);
+ DEBUG(5,
+ ("api_pipe_auth_process: data %d\n", l->data_i.offset));
+ NTLMSSPcalc_p(a, (uchar *) data, data_len);
crc32 = crc32_calc_buffer(data_len, data);
}
@@ -575,21 +610,23 @@ static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct *l)
RPC_HDR_AUTH auth_info;
l->data_i.offset += data_len;
smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &l->data_i, 0);
- if (!rpc_hdr_ntlmssp_auth_chk(&(auth_info))) return False;
+ if (!rpc_hdr_ntlmssp_auth_chk(&(auth_info)))
+ return False;
}
if (auth_verify)
{
RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
- DEBUG(5,("api_pipe_auth_process: auth %d\n",
- l->data_i.offset + 4));
- NTLMSSPcalc_p(a, (uchar*)prs_data(&l->data_i,
- l->data_i.offset + 4),
- 12);
- smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &l->data_i, 0);
+ DEBUG(5, ("api_pipe_auth_process: auth %d\n",
+ l->data_i.offset + 4));
+ NTLMSSPcalc_p(a, (uchar *) prs_data(&l->data_i,
+ l->data_i.offset + 4),
+ 12);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk,
+ &l->data_i, 0);
if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32,
- a->ntlmssp_seq_num))
+ a->ntlmssp_seq_num))
{
return False;
}
@@ -600,23 +637,21 @@ static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct *l)
return True;
}
-static BOOL api_ntlmssp_hdr_chk(RPC_HDR_AUTH *auth_info, void **auth_struct)
+static BOOL api_ntlmssp_hdr_chk(RPC_HDR_AUTH * auth_info, void **auth_struct)
{
- DEBUG(10,("api_ntlmssp_hdr_chk:\n"));
+ DEBUG(10, ("api_ntlmssp_hdr_chk:\n"));
if (!rpc_hdr_ntlmssp_auth_chk(auth_info))
{
return False;
}
- (*auth_struct) = (void*)malloc(sizeof(ntlmssp_auth_struct));
+ (*auth_struct) = (void *)malloc(sizeof(ntlmssp_auth_struct));
return (*auth_struct) != NULL;
}
-srv_auth_fns ntlmssp_fns =
-{
+srv_auth_fns ntlmssp_fns = {
api_ntlmssp_hdr_chk,
api_ntlmssp_auth_chk,
api_ntlmssp_auth_gen,
api_ntlmssp_decode_pdu,
api_ntlmssp_create_pdu,
};
-
diff --git a/source/rpc_server/srv_pipe_srv.c b/source/rpc_server/srv_pipe_srv.c
index fdf5683a88f..35bd79dc6e8 100644
--- a/source/rpc_server/srv_pipe_srv.c
+++ b/source/rpc_server/srv_pipe_srv.c
@@ -141,6 +141,51 @@ void add_msrpc_command_processor(char *pipe_name,
add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
}
+static BOOL api_pipe_nack_resp(rpcsrv_struct * l, uint16 rej_code,
+ prs_struct * resp)
+{
+ prs_struct rhdr;
+ prs_struct rnack;
+ RPC_HDR_NACK hdr_nack;
+
+ DEBUG(5, ("api_pipe_nack_resp: make response\n"));
+
+ l->faulted_once_before = True;
+
+ prs_init(&(rhdr), 0, 4, False);
+ prs_init(&(rnack), 0, 4, False);
+
+ /***/
+ /*** set up the header and nack status ***/
+ /***/
+
+ hdr_nack.rej_code = rej_code;
+
+ make_rpc_hdr(&l->hdr, RPC_BINDNACK,
+ RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id, 0x12, 0);
+
+ smb_io_rpc_hdr("hdr", &l->hdr, &rhdr, 0);
+ smb_io_rpc_hdr_nack("nack", &hdr_nack, &rnack, 0);
+ prs_realloc_data(&rhdr, rhdr.offset);
+ prs_realloc_data(&rnack, rnack.offset);
+
+ /***/
+ /*** link rpc header and nack together ***/
+ /***/
+
+ prs_link(NULL, &rhdr, &rnack);
+ prs_link(&rhdr, &rnack, NULL);
+
+ prs_init(resp, 0, 4, False);
+ if (!prs_copy(resp, &rhdr))
+ return False;
+ prs_free_data(&rnack);
+ prs_free_data(&rhdr);
+
+ return True;
+}
+
static BOOL api_pipe_fault_resp(rpcsrv_struct * l, uint32 status,
prs_struct * resp)
{
@@ -500,6 +545,10 @@ static BOOL rpc_redir_local(rpcsrv_struct * l, prs_struct * req,
case RPC_BIND:
{
reply = api_pipe_bind_req(l, name, resp);
+ if (!reply)
+ {
+ reply = api_pipe_nack_resp(l, 0x0, resp);
+ }
break;
}
case RPC_ALTCONT: