From 85160e654e5a1fc4fcb0d6cecc5187cc3b62f6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 11 Feb 2006 05:36:27 +0000 Subject: [PATCH] r13458: Add parsing functions - but stub internals for lookupnames3 and 4. Jeremy. (This used to be commit f1a362580ae37730dc8393a79f832aed5d0ea4be) --- source3/include/rpc_lsa.h | 79 ++++++++++- source3/rpc_parse/parse_lsa.c | 298 +++++++++++++++++++++++++++++++++++++++- source3/rpc_server/srv_lsa.c | 66 ++++++++- source3/rpc_server/srv_lsa_nt.c | 17 +++ 4 files changed, 455 insertions(+), 5 deletions(-) diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 73ce4967882..493ac1ab00d 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -528,7 +528,7 @@ typedef struct lsa_q_lookup_names uint32 num_trans_entries; uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint32 lookup_level; + uint16 lookup_level; uint32 mapped_count; } LSA_Q_LOOKUP_NAMES; @@ -560,7 +560,7 @@ typedef struct lsa_q_lookup_names2 uint32 num_trans_entries; uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint32 lookup_level; + uint16 lookup_level; uint32 mapped_count; uint32 unknown1; uint32 unknown2; @@ -583,6 +583,81 @@ typedef struct lsa_r_lookup_names2 NTSTATUS status; /* return code */ } LSA_R_LOOKUP_NAMES2; +/* LSA_Q_LOOKUP_NAMES3 - LSA Lookup NAMEs 3 */ +typedef struct lsa_q_lookup_names3 +{ + POLICY_HND pol; /* policy handle */ + uint32 num_entries; + uint32 num_entries2; + UNIHDR *hdr_name; /* name buffer pointers */ + UNISTR2 *uni_name; /* names to be looked up */ + + uint32 num_trans_entries; + uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ + uint16 lookup_level; + uint32 mapped_count; + uint32 unknown1; + uint32 unknown2; + +} LSA_Q_LOOKUP_NAMES3; + +/* Sid type used in lookupnames3 and lookupnames4. */ +typedef struct lsa_translatedsid3 { + uint8 sid_type; + DOM_SID2 *sid2; + uint32 sid_idx; + uint32 unknown; +} LSA_TRANSLATED_SID3; + +/* LSA_R_LOOKUP_NAMES3 - response to LSA Lookup NAMEs by name 3 */ +typedef struct lsa_r_lookup_names3 +{ + uint32 ptr_dom_ref; + DOM_R_REF *dom_ref; /* domain reference info */ + + uint32 num_entries; + uint32 ptr_entries; + uint32 num_entries2; + LSA_TRANSLATED_SID3 *trans_sids; + + uint32 mapped_count; + + NTSTATUS status; /* return code */ +} LSA_R_LOOKUP_NAMES3; + +/* LSA_Q_LOOKUP_NAMES4 - LSA Lookup NAMEs 4 */ +typedef struct lsa_q_lookup_names4 +{ + uint32 num_entries; + uint32 num_entries2; + UNIHDR *hdr_name; /* name buffer pointers */ + UNISTR2 *uni_name; /* names to be looked up */ + + uint32 num_trans_entries; + uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ + uint16 lookup_level; + uint32 mapped_count; + uint32 unknown1; + uint32 unknown2; + +} LSA_Q_LOOKUP_NAMES4; + +/* LSA_R_LOOKUP_NAMES3 - response to LSA Lookup NAMEs by name 4 */ +typedef struct lsa_r_lookup_names4 +{ + uint32 ptr_dom_ref; + DOM_R_REF *dom_ref; /* domain reference info */ + + uint32 num_entries; + uint32 ptr_entries; + uint32 num_entries2; + LSA_TRANSLATED_SID3 *trans_sids; + + uint32 mapped_count; + + NTSTATUS status; /* return code */ +} LSA_R_LOOKUP_NAMES4; + typedef struct lsa_enum_priv_entry { UNIHDR hdr_name; diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index d041553e148..86df5fcc11e 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -1368,7 +1368,9 @@ BOOL lsa_io_q_lookup_names(const char *desc, LSA_Q_LOOKUP_NAMES *q_r, return False; if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) return False; - if(!prs_uint32("lookup_level ", ps, depth, &q_r->lookup_level)) + if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) + return False; + if(!prs_align(ps)) return False; if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) return False; @@ -1487,7 +1489,9 @@ BOOL lsa_io_q_lookup_names2(const char *desc, LSA_Q_LOOKUP_NAMES2 *q_r, return False; if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) return False; - if(!prs_uint32("lookup_level ", ps, depth, &q_r->lookup_level)) + if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) + return False; + if(!prs_align(ps)) return False; if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) return False; @@ -1556,7 +1560,297 @@ BOOL lsa_io_r_lookup_names2(const char *desc, LSA_R_LOOKUP_NAMES2 *out, prs_stru return True; } +/******************************************************************* + Internal lsa data type io. + Following pass must read DOM_SID2 types. +********************************************************************/ + +BOOL smb_io_lsa_translated_sids3(const char *desc, LSA_TRANSLATED_SID3 *q_r, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "smb_io_lsa_translated_sids3"); + depth++; + + if(!prs_align(ps)) + return False; + if(!prs_uint8 ("sid_type ", ps, depth, &q_r->sid_type )) + return False; + if(!prs_align(ps)) + return False; + /* Second pass will read/write these. */ + if (!smb_io_dom_sid2_p("sid_header", ps, depth, &q_r->sid2)) + return False; + if(!prs_uint32("sid_idx ", ps, depth, &q_r->sid_idx )) + return False; + if(!prs_uint32("unknown ", ps, depth, &q_r->unknown )) + return False; + + return True; +} + +/******************************************************************* + Identical to lsa_io_q_lookup_names2. +********************************************************************/ + +BOOL lsa_io_q_lookup_names3(const char *desc, LSA_Q_LOOKUP_NAMES3 *q_r, + prs_struct *ps, int depth) +{ + unsigned int i; + + prs_debug(ps, depth, desc, "lsa_io_q_lookup_names3"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */ + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) + return False; + if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) + return False; + + if (UNMARSHALLING(ps)) { + if (q_r->num_entries) { + if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) + return False; + if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) + return False; + } + } + + for (i = 0; i < q_r->num_entries; i++) { + if(!prs_align(ps)) + return False; + if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ + return False; + } + + for (i = 0; i < q_r->num_entries; i++) { + if(!prs_align(ps)) + return False; + if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ + return False; + } + + if(!prs_align(ps)) + return False; + if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) + return False; + if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) + return False; + if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) + return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) + return False; + if(!prs_uint32("unknown1 ", ps, depth, &q_r->unknown1)) + return False; + if(!prs_uint32("unknown2 ", ps, depth, &q_r->unknown2)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL lsa_io_r_lookup_names3(const char *desc, LSA_R_LOOKUP_NAMES3 *out, prs_struct *ps, int depth) +{ + unsigned int i; + + prs_debug(ps, depth, desc, "lsa_io_r_lookup_names3"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) + return False; + + if (out->ptr_dom_ref != 0) + if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) + return False; + + if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) + return False; + if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) + return False; + + if (out->ptr_entries != 0) { + if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) + return False; + + if (out->num_entries2 != out->num_entries) { + /* RPC fault */ + return False; + } + + if (UNMARSHALLING(ps)) { + if ((out->trans_sids = PRS_ALLOC_MEM(ps, LSA_TRANSLATED_SID3, out->num_entries2)) + == NULL) { + DEBUG(3, ("lsa_io_r_lookup_names3(): out of memory\n")); + return False; + } + } + for (i = 0; i < out->num_entries2; i++) { + if(!smb_io_lsa_translated_sids3("", &out->trans_sids[i], ps, depth)) { + return False; + } + } + /* Now process the DOM_SID2 entries. */ + for (i = 0; i < out->num_entries2; i++) { + if (out->trans_sids[i].sid2) { + if( !smb_io_dom_sid2("sid2", out->trans_sids[i].sid2, ps, depth) ) { + return False; + } + } + } + } + + if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) + return False; + + if(!prs_ntstatus("status ", ps, depth, &out->status)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + +BOOL lsa_io_q_lookup_names4(const char *desc, LSA_Q_LOOKUP_NAMES4 *q_r, + prs_struct *ps, int depth) +{ + unsigned int i; + + prs_debug(ps, depth, desc, "lsa_io_q_lookup_names3"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) + return False; + if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) + return False; + + if (UNMARSHALLING(ps)) { + if (q_r->num_entries) { + if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) + return False; + if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) + return False; + } + } + + for (i = 0; i < q_r->num_entries; i++) { + if(!prs_align(ps)) + return False; + if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ + return False; + } + + for (i = 0; i < q_r->num_entries; i++) { + if(!prs_align(ps)) + return False; + if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ + return False; + } + + if(!prs_align(ps)) + return False; + if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) + return False; + if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) + return False; + if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) + return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) + return False; + if(!prs_uint32("unknown1 ", ps, depth, &q_r->unknown1)) + return False; + if(!prs_uint32("unknown2 ", ps, depth, &q_r->unknown2)) + return False; + + return True; +} + +/******************************************************************* + Identical to lsa_io_r_lookup_names3. +********************************************************************/ + +BOOL lsa_io_r_lookup_names4(const char *desc, LSA_R_LOOKUP_NAMES4 *out, prs_struct *ps, int depth) +{ + unsigned int i; + + prs_debug(ps, depth, desc, "lsa_io_r_lookup_names4"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) + return False; + + if (out->ptr_dom_ref != 0) + if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) + return False; + + if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) + return False; + if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) + return False; + + if (out->ptr_entries != 0) { + if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) + return False; + + if (out->num_entries2 != out->num_entries) { + /* RPC fault */ + return False; + } + + if (UNMARSHALLING(ps)) { + if ((out->trans_sids = PRS_ALLOC_MEM(ps, LSA_TRANSLATED_SID3, out->num_entries2)) + == NULL) { + DEBUG(3, ("lsa_io_r_lookup_names4(): out of memory\n")); + return False; + } + } + + for (i = 0; i < out->num_entries2; i++) { + if(!smb_io_lsa_translated_sids3("", &out->trans_sids[i], ps, depth)) { + return False; + } + } + /* Now process the DOM_SID2 entries. */ + for (i = 0; i < out->num_entries2; i++) { + if (out->trans_sids[i].sid2) { + if( !smb_io_dom_sid2("sid2", out->trans_sids[i].sid2, ps, depth) ) { + return False; + } + } + } + } + + if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) + return False; + + if(!prs_ntstatus("status ", ps, depth, &out->status)) + return False; + + return True; +} /******************************************************************* Inits an LSA_Q_CLOSE structure. diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index e20b4e18b49..286266f30de 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -1007,6 +1007,68 @@ static BOOL api_lsa_lookup_names2(pipes_struct *p) return True; } +/*************************************************************************** + api_lsa_lookup_names3 + ***************************************************************************/ + +static BOOL api_lsa_lookup_names3(pipes_struct *p) +{ + LSA_Q_LOOKUP_NAMES3 q_u; + LSA_R_LOOKUP_NAMES3 r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the info class and policy handle */ + if(!lsa_io_q_lookup_names3("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_lookup_names3: failed to unmarshall LSA_Q_LOOKUP_NAMES3.\n")); + return False; + } + + r_u.status = _lsa_lookup_names3(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_lookup_names3("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_lookup_names3: Failed to marshall LSA_R_LOOKUP_NAMES3.\n")); + return False; + } + + return True; +} + +/*************************************************************************** + api_lsa_lookup_names4 + ***************************************************************************/ + +static BOOL api_lsa_lookup_names4(pipes_struct *p) +{ + LSA_Q_LOOKUP_NAMES4 q_u; + LSA_R_LOOKUP_NAMES4 r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the info class and policy handle */ + if(!lsa_io_q_lookup_names4("", &q_u, data, 0)) { + DEBUG(0,("api_lsa_lookup_names4: failed to unmarshall LSA_Q_LOOKUP_NAMES4.\n")); + return False; + } + + r_u.status = _lsa_lookup_names4(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!lsa_io_r_lookup_names4("", &r_u, rdata, 0)) { + DEBUG(0,("api_lsa_lookup_names4: Failed to marshall LSA_R_LOOKUP_NAMES4.\n")); + return False; + } + + return True; +} + #if 0 /* AD DC work in ongoing in Samba 4 */ /*************************************************************************** @@ -1078,7 +1140,9 @@ static struct api_struct api_lsa_cmds[] = { "LSA_DELETEOBJECT" , LSA_DELETEOBJECT , api_lsa_delete_object }, { "LSA_LOOKUPSIDS2" , LSA_LOOKUPSIDS2 , api_lsa_lookup_sids2 }, { "LSA_LOOKUPNAMES2" , LSA_LOOKUPNAMES2 , api_lsa_lookup_names2 }, - { "LSA_LOOKUPSIDS3" , LSA_LOOKUPSIDS3 , api_lsa_lookup_sids3 } + { "LSA_LOOKUPNAMES3" , LSA_LOOKUPNAMES3 , api_lsa_lookup_names3 }, + { "LSA_LOOKUPSIDS3" , LSA_LOOKUPSIDS3 , api_lsa_lookup_sids3 }, + { "LSA_LOOKUPNAMES4" , LSA_LOOKUPNAMES4 , api_lsa_lookup_names4 } #if 0 /* AD DC work in ongoing in Samba 4 */ /* be careful of the adding of new RPC's. See commentrs below about ADS DC capabilities */ diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 200cdb8d9e5..038ec06715b 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1026,6 +1026,23 @@ done: return r_u->status; } +/*************************************************************************** +lsa_reply_lookup_names3 - stub for now. + ***************************************************************************/ + +NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/*************************************************************************** +lsa_reply_lookup_names4 - stub for now. + ***************************************************************************/ + +NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u) +{ + return NT_STATUS_ACCESS_DENIED; +} /*************************************************************************** _lsa_close. Also weird - needs to check if lsa handle is correct. JRA. -- 2.11.4.GIT