diff options
author | Luke Leighton <lkcl@samba.org> | 2000-02-27 19:12:07 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 2000-02-27 19:12:07 +0000 |
commit | 648554f2e208106980074761a7bab30d369bf1d2 (patch) | |
tree | e632ff11eb95a162d5268f7bb9aa63e54f309ff6 | |
parent | d2b5af85ece76cba391bcba5fa463fdc335ff9e2 (diff) | |
download | samba-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.h | 55 | ||||
-rw-r--r-- | source/include/proto.h | 56 | ||||
-rw-r--r-- | source/include/rpc_dce.h | 36 | ||||
-rw-r--r-- | source/include/rpc_parse_proto.h | 1 | ||||
-rw-r--r-- | source/include/winbindd_proto.h | 56 | ||||
-rw-r--r-- | source/rpc_parse/parse_rpc.c | 15 | ||||
-rw-r--r-- | source/rpc_server/srv_pipe_ntlmssp.c | 305 | ||||
-rw-r--r-- | source/rpc_server/srv_pipe_srv.c | 49 |
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: |