From 7032daa88719697076c61fcee6f2140a80eb7128 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 1 Nov 1999 22:25:38 +0000 Subject: added lsaenumdomains command. attempting to get blood out of a stone^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H querysecret to work, it keeps returning access denied. (This used to be commit 953fe6ba9454fa4b8e69426527eca37b011f76ac) --- source3/include/proto.h | 20 ++++-- source3/include/rpc_lsa.h | 18 ++--- source3/rpc_client/cli_lsarpc.c | 143 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_lsa.c | 54 +++++++++++---- source3/rpcclient/cmd_lsarpc.c | 72 +++++++++++++++++++- source3/rpcclient/rpcclient.c | 6 ++ 6 files changed, 286 insertions(+), 27 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c570b9a4af..cc7e392959 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1739,6 +1739,9 @@ BOOL cli_nt_logoff(struct cli_state *cli, uint16 fnum, NET_ID_INFO_CTR *ctr); BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum, const char *server_name, POLICY_HND *hnd, BOOL sec_qos); +BOOL lsa_open_policy2(struct cli_state *cli, uint16 fnum, + const char *server_name, POLICY_HND *hnd, + BOOL sec_qos); BOOL lsa_open_secret(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd_pol, char *secret_name, uint32 des_access, POLICY_HND *hnd_secret); @@ -1762,6 +1765,10 @@ BOOL lsa_lookup_sids(struct cli_state *cli, uint16 fnum, BOOL lsa_query_info_pol(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, uint16 info_class, fstring domain_name, DOM_SID *domain_sid); +BOOL lsa_enum_trust_dom(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, uint32 *enum_ctx, + uint32 *num_doms, char ***names, + DOM_SID ***sids); BOOL lsa_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd); /*The following definitions come from rpc_client/cli_netlogon.c */ @@ -2124,7 +2131,7 @@ BOOL make_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name, LSA_SEC_QOS *qos); BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth); BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth); -BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name, +BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name, uint32 attributes, uint32 desired_access, LSA_SEC_QOS *qos); @@ -2141,11 +2148,15 @@ BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO *info, prs_struct *ps, int d BOOL make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol); BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET *q_q, prs_struct *ps, int depth); BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, int depth); +BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e, + POLICY_HND *pol, + uint32 enum_context, uint32 preferred_len); BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth); BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, - uint32 enum_context, char *domain_name, DOM_SID *domain_sid, - uint32 status); -BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth); + int32 enum_context, + char *domain_name, DOM_SID *domain_sid, + uint32 status); +BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth); BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth); BOOL make_lsa_sid_enum(LSA_SID_ENUM *sen, uint32 num_entries, DOM_SID **sids); BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd, @@ -3226,6 +3237,7 @@ void cmd_eventlog(struct client_info *info); /*The following definitions come from rpcclient/cmd_lsarpc.c */ +void cmd_lsa_enum_trust_dom(struct client_info *info); void cmd_lsa_query_info(struct client_info *info); void cmd_lsa_lookup_names(struct client_info *info); void cmd_lsa_lookup_sids(struct client_info *info); diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 02f8a63ab8..7c27df0238 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -94,7 +94,7 @@ typedef struct obj_attr_info typedef struct lsa_q_open_pol_info { uint32 ptr; /* undocumented buffer pointer */ - uint16 system_name; /* 0x5c - system name */ + uint16 system_name; /* system name BUG!!! (should be \\server!) */ LSA_OBJ_ATTR attr ; /* object attributes */ uint32 des_access; /* desired access attributes */ @@ -214,11 +214,13 @@ typedef struct lsa_r_query_secret_info typedef struct lsa_enum_trust_dom_info { POLICY_HND pol; /* policy handle */ - uint32 enum_context; /* enumeration context handle */ - uint32 preferred_len; /* preferred maximum length */ + uint32 enum_context; /* enumeration context handle */ + uint32 preferred_len; /* preferred maximum length */ } LSA_Q_ENUM_TRUST_DOM; +#define MAX_TRUSTED_DOMS 10 + /* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */ typedef struct lsa_r_enum_trust_dom_info { @@ -227,12 +229,12 @@ typedef struct lsa_r_enum_trust_dom_info uint32 ptr_enum_domains; /* buffer pointer to num domains */ /* this lot is only added if ptr_enum_domains is non-NULL */ - uint32 num_domains2; /* number of domains */ - UNIHDR2 hdr_domain_name; - UNISTR2 uni_domain_name; - DOM_SID2 other_domain_sid; + uint32 num_domains2; /* number of domains */ + UNIHDR2 hdr_domain_name[MAX_TRUSTED_DOMS]; + UNISTR2 uni_domain_name[MAX_TRUSTED_DOMS]; + DOM_SID2 domain_sid[MAX_TRUSTED_DOMS]; - uint32 status; /* return code */ + uint32 status; /* return code */ } LSA_R_ENUM_TRUST_DOM; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index b7134bebb6..66444e631b 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -98,6 +98,72 @@ BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum, return valid_pol; } +/**************************************************************************** +do a LSA Open Policy2 +****************************************************************************/ +BOOL lsa_open_policy2(struct cli_state *cli, uint16 fnum, + const char *server_name, POLICY_HND *hnd, + BOOL sec_qos) +{ + prs_struct rbuf; + prs_struct buf; + LSA_Q_OPEN_POL2 q_o; + LSA_SEC_QOS qos; + BOOL valid_pol = False; + + if (hnd == NULL) return False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api LSA_OPENPOLICY2 */ + + DEBUG(4,("LSA Open Policy2\n")); + + /* store the parameters */ + if (sec_qos) + { + make_lsa_sec_qos(&qos, 2, 1, 0, 0x000f0fff); + make_q_open_pol2(&q_o, server_name, 0, 0x02000000, &qos); + } + else + { + make_q_open_pol2(&q_o, server_name, 0, 0x1, NULL); + } + + /* turn parameters into data stream */ + lsa_io_q_open_pol2("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, LSA_OPENPOLICY2, &buf, &rbuf)) + { + LSA_R_OPEN_POL2 r_o; + BOOL p; + + lsa_io_r_open_pol2("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("LSA_OPENPOLICY2: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p) + { + /* ok, at last: we're happy. return the policy handle */ + memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); + valid_pol = True; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_pol; +} + /**************************************************************************** do a LSA Open Secret ****************************************************************************/ @@ -604,6 +670,83 @@ BOOL lsa_query_info_pol(struct cli_state *cli, uint16 fnum, return valid_response; } +/**************************************************************************** +do a LSA Enumerate Trusted Domain +****************************************************************************/ +BOOL lsa_enum_trust_dom(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, uint32 *enum_ctx, + uint32 *num_doms, char ***names, + DOM_SID ***sids) +{ + prs_struct rbuf; + prs_struct buf; + LSA_Q_ENUM_TRUST_DOM q_q; + BOOL valid_response = False; + + if (hnd == NULL || num_doms == NULL || names == NULL) return False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api LSA_ENUMTRUSTDOM */ + + DEBUG(4,("LSA Query Info Policy\n")); + + /* store the parameters */ + make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff); + + /* turn parameters into data stream */ + lsa_io_q_enum_trust_dom("", &q_q, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, LSA_ENUMTRUSTDOM, &buf, &rbuf)) + { + LSA_R_ENUM_TRUST_DOM r_q; + BOOL p; + + lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_q.status != 0) + { + /* report error code */ + DEBUG(0,("LSA_ENUMTRUSTDOM: %s\n", get_nt_error_msg(r_q.status))); + p = r_q.status == 0x8000001a; + } + + if (p) + { + uint32 i; + uint32 num_sids = 0; + valid_response = True; + + for (i = 0; i < r_q.num_domains; i++) + { + fstring tmp; + unistr2_to_ascii(tmp, &r_q.uni_domain_name[i], + sizeof(tmp)-1); + add_chars_to_array(num_doms, names, tmp); + add_sid_to_array(&num_sids, sids, + &r_q.domain_sid[i].sid); + } + + if (r_q.status == 0x0) + { + *enum_ctx = r_q.enum_context; + } + else + { + *enum_ctx = 0; + } + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_response; +} + /**************************************************************************** do a LSA Close ****************************************************************************/ diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 9f8c7d6403..57c22e88cb 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -314,7 +314,7 @@ BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int dep /******************************************************************* makes an LSA_Q_OPEN_POL2 structure. ********************************************************************/ -BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name, +BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name, uint32 attributes, uint32 desired_access, LSA_SEC_QOS *qos) @@ -540,11 +540,11 @@ BOOL make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol) memcpy(&(q_q->pol), pol, sizeof(q_q->pol)); /* Want secret */ - q_q->info.ptr_value = 0; + q_q->info.ptr_value = 1; q_q->info.value.ptr_secret = 0; /* Want last change time */ - q_q->info.ptr_update = 0; + q_q->info.ptr_update = 1; /* Don't care about old info */ q_q->oldinfo.ptr_value = 0; @@ -590,6 +590,24 @@ BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, return True; } +/******************************************************************* +makes an LSA_Q_ENUM_TRUST_DOM structure. +********************************************************************/ +BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e, + POLICY_HND *pol, + uint32 enum_context, uint32 preferred_len) +{ + if (q_e == NULL) return False; + + DEBUG(5,("make_q_enum_trust_dom\n")); + + memcpy(&(q_e->pol), pol, sizeof(q_e->pol)); + q_e->enum_context = enum_context; + q_e->preferred_len = preferred_len; + + return True; +} + /******************************************************************* reads or writes an LSA_Q_ENUM_TRUST_DOM structure. ********************************************************************/ @@ -613,8 +631,9 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct makes an LSA_R_ENUM_TRUST_DOM structure. ********************************************************************/ BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, - uint32 enum_context, char *domain_name, DOM_SID *domain_sid, - uint32 status) + int32 enum_context, + char *domain_name, DOM_SID *domain_sid, + uint32 status) { if (r_e == NULL) return False; @@ -630,9 +649,9 @@ BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, r_e->ptr_enum_domains = 1; r_e->num_domains2 = 1; - make_uni_hdr2(&(r_e->hdr_domain_name ), len_domain_name); - make_unistr2 (&(r_e->uni_domain_name ), domain_name, len_domain_name); - make_dom_sid2(&(r_e->other_domain_sid), domain_sid); + make_uni_hdr2(&(r_e->hdr_domain_name[0]), len_domain_name); + make_unistr2 (&(r_e->uni_domain_name[0]), domain_name, len_domain_name); + make_dom_sid2(&(r_e->domain_sid[0]), domain_sid); } else { @@ -648,7 +667,7 @@ BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, /******************************************************************* reads or writes an LSA_R_ENUM_TRUST_DOM structure. ********************************************************************/ -BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth) +BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth) { if (r_e == NULL) return False; @@ -661,10 +680,21 @@ BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct if (r_e->ptr_enum_domains != 0) { + uint32 i; prs_uint32("num_domains2", ps, depth, &(r_e->num_domains2)); - smb_io_unihdr2 ("", &(r_e->hdr_domain_name ), ps, depth); - smb_io_unistr2 ("", &(r_e->uni_domain_name ), r_e->hdr_domain_name.buffer, ps, depth); - smb_io_dom_sid2("", &(r_e->other_domain_sid), ps, depth); + + for (i = 0; i < r_e->num_domains2; i++) + { + + smb_io_unihdr2 ("", &(r_e->hdr_domain_name[i]), ps, depth); + } + + for (i = 0; i < r_e->num_domains2; i++) + { + smb_io_unistr2 ("", &(r_e->uni_domain_name[i] ), r_e->hdr_domain_name[i].buffer, ps, depth); + prs_align(ps); + smb_io_dom_sid2("", &(r_e->domain_sid[i]), ps, depth); + } } prs_uint32("status", ps, depth, &(r_e->status)); diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 104d739747..b2e0645788 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -37,6 +37,72 @@ extern FILE* out_hnd; extern struct cli_state *smb_cli; extern int smb_tidx; +/**************************************************************************** +nt enumerate trusted domains +****************************************************************************/ +void cmd_lsa_enum_trust_dom(struct client_info *info) +{ + uint16 nt_pipe_fnum; + fstring srv_name; + uint32 num_doms = 0; + char **domains = NULL; + DOM_SID **sids = NULL; + uint32 enum_ctx = 0; + + BOOL res = True; + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->myhostname); + strupper(srv_name); + + DEBUG(4,("cmd_lsa_enum_trust_dom: server:%s\n", srv_name)); + + /* open LSARPC session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &nt_pipe_fnum) : False; + + /* lookup domain controller; receive a policy handle */ + res = res ? lsa_open_policy(smb_cli, nt_pipe_fnum, + srv_name, + &info->dom.lsa_info_pol, False) : False; + + do + { + /* send enum trusted domains query */ + res = res ? lsa_enum_trust_dom(smb_cli, nt_pipe_fnum, + &info->dom.lsa_info_pol, + &enum_ctx, + &num_doms, &domains, &sids) : False; + + } while (res && enum_ctx != 0); + + res = res ? lsa_close(smb_cli, nt_pipe_fnum, &info->dom.lsa_info_pol) : False; + + /* close the session */ + cli_nt_session_close(smb_cli, nt_pipe_fnum); + + if (res) + { + uint32 i; + DEBUG(5,("cmd_lsa_enum_trust_dom: query succeeded\n")); + + report(out_hnd, "LSA Enumerate Trusted Domains\n"); + for (i = 0; i < num_doms; i++) + { + fstring sid; + sid_to_string(sid, sids[i]); + report(out_hnd, "Domain:\t%s\tSID:\t%s\n", + domains[i], sid); + } + } + else + { + DEBUG(5,("cmd_lsa_enum_trust_dom: query failed\n")); + } + + free_char_array(num_doms, domains); + free_sid_array(num_doms, sids); +} + /**************************************************************************** nt lsa query ****************************************************************************/ @@ -332,7 +398,7 @@ void cmd_lsa_query_secret(struct client_info *info) } fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->myhostname); + fstrcat(srv_name, info->dest_host); strupper(srv_name); DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name)); @@ -341,14 +407,14 @@ void cmd_lsa_query_secret(struct client_info *info) res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &nt_pipe_fnum) : False; /* lookup domain controller; receive a policy handle */ - res = res ? lsa_open_policy(smb_cli, nt_pipe_fnum, + res = res ? lsa_open_policy2(smb_cli, nt_pipe_fnum, srv_name, &info->dom.lsa_info_pol, True) : False; /* lookup domain controller; receive a policy handle */ res1 = res ? lsa_open_secret(smb_cli, nt_pipe_fnum, &info->dom.lsa_info_pol, - secret_name, 0x02000000, &hnd_secret) : False; + secret_name, 0x020003, &hnd_secret) : False; res2 = res1 ? lsa_query_secret(smb_cli, nt_pipe_fnum, &hnd_secret, &enc_secret, &last_update) : False; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 732aa9ceb7..f967a2ceac 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -293,6 +293,12 @@ commands[] = "Query Info Policy (domain member or server)", {COMPL_NONE, COMPL_NONE} }, + { + "lsaenumdomains", + cmd_lsa_enum_trust_dom, + "Enumerate Trusted Domains", + {COMPL_NONE, COMPL_NONE} + }, { "lookupsids", cmd_lsa_lookup_sids, -- cgit