From 044c6f513dca21d4fc01db4a686c75d43d4952d2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 2 Apr 2004 12:56:18 +0000 Subject: Implement NETLOGON GetDCName client side. You can ask a DC for the name of a DC it trusts. Volker (This used to be commit ae6840320ff47827c2817549fe3133a57e3fe77f) --- source3/include/rpc_netlogon.h | 20 ++++++++++ source3/rpc_client/cli_netlogon.c | 49 +++++++++++++++++++++++ source3/rpc_parse/parse_net.c | 84 +++++++++++++++++++++++++++++++++++++++ source3/rpcclient/cmd_netlogon.c | 26 ++++++++++++ 4 files changed, 179 insertions(+) diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h index 74e3a50ee4..a5b93b0238 100644 --- a/source3/include/rpc_netlogon.h +++ b/source3/include/rpc_netlogon.h @@ -33,6 +33,7 @@ #define NET_SRVPWSET 0x06 #define NET_SAM_DELTAS 0x07 #define NET_LOGON_CTRL 0x0c +#define NET_GETDCNAME 0x0d #define NET_AUTH2 0x0f #define NET_LOGON_CTRL2 0x0e #define NET_SAM_SYNC 0x10 @@ -298,6 +299,25 @@ typedef struct net_r_logon_ctrl2_info } NET_R_LOGON_CTRL2; +/* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */ + +typedef struct net_q_getdcname +{ + uint32 ptr_logon_server; + UNISTR2 uni_logon_server; + uint32 ptr_domainname; + UNISTR2 uni_domainname; +} NET_Q_GETDCNAME; + +/* NET_R_GETDCNAME - Ask a DC for a trusted DC name */ + +typedef struct net_r_getdcname +{ + uint32 ptr_dcname; + UNISTR2 uni_dcname; + NTSTATUS status; +} NET_R_GETDCNAME; + /* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */ typedef struct net_q_trust_dom_info { diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 70ac460303..f6d88a1950 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -331,6 +331,55 @@ NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* GetDCName */ + +NTSTATUS cli_netlogon_getdcname(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *domainname, fstring dcname) +{ + prs_struct qbuf, rbuf; + NET_Q_GETDCNAME q; + NET_R_GETDCNAME r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_net_q_getdcname(&q, cli->srv_name_slash, domainname); + + /* Marshall data and send request */ + + if (!net_io_q_getdcname("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_GETDCNAME, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_getdcname("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + if (NT_STATUS_IS_OK(result)) + rpcstr_pull_unistr2_fstring(dcname, &r.uni_dcname); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /**************************************************************************** Generate the next creds to use. ****************************************************************************/ diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index 90cd348f5a..a98738b51f 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -424,6 +424,90 @@ BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps return True; } +/******************************************************************* + Inits an NET_R_GETDCNAME structure. +********************************************************************/ +void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server, + const char *domainname) +{ + DEBUG(5,("init_r_getdcname\n")); + + r_t->ptr_logon_server = (logon_server != NULL); + init_unistr2(&r_t->uni_logon_server, logon_server, UNI_STR_TERMINATE); + r_t->ptr_domainname = (domainname != NULL); + init_unistr2(&r_t->uni_domainname, domainname, UNI_STR_TERMINATE); +} + +/******************************************************************* + Reads or writes an NET_Q_GETDCNAME structure. +********************************************************************/ + +BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps, + int depth) +{ + if (r_t == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_q_getdcname"); + depth++; + + if (!prs_uint32("ptr_logon_server", ps, depth, &r_t->ptr_logon_server)) + return False; + + if (!smb_io_unistr2("logon_server", &r_t->uni_logon_server, + r_t->ptr_logon_server, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_domainname", ps, depth, &r_t->ptr_domainname)) + return False; + + if (!smb_io_unistr2("domainname", &r_t->uni_domainname, + r_t->ptr_domainname, ps, depth)) + return False; + + return True; +} + + +/******************************************************************* + Inits an NET_R_GETDCNAME structure. +********************************************************************/ +void init_net_r_getdcname(NET_R_GETDCNAME *r_t, const char *dcname) +{ + DEBUG(5,("init_r_getdcname\n")); + + init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE); +} + +/******************************************************************* + Reads or writes an NET_R_GETDCNAME structure. +********************************************************************/ + +BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps, + int depth) +{ + if (r_t == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_r_getdcname"); + depth++; + + if (!prs_uint32("ptr_dcname", ps, depth, &r_t->ptr_dcname)) + return False; + + if (!smb_io_unistr2("dcname", &r_t->uni_dcname, + r_t->ptr_dcname, ps, depth)) + return False; + + if (!prs_ntstatus("status", ps, depth, &r_t->status)) + return False; + + return True; +} + /******************************************************************* Inits an NET_R_TRUST_DOM_LIST structure. ********************************************************************/ diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index a48b59bf6a..9e281fefce 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -45,6 +45,31 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli, return result; } +static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + fstring dcname; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + if (argc != 2) { + fprintf(stderr, "Usage: %s domainname\n", argv[0]); + return NT_STATUS_OK; + } + + result = cli_netlogon_getdcname(cli, mem_ctx, argv[1], dcname); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + /* Display results */ + + printf("%s\n", dcname); + + done: + return result; +} + static NTSTATUS cmd_netlogon_logon_ctrl(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -309,6 +334,7 @@ struct cmd_set netlogon_commands[] = { { "NETLOGON" }, { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, "Logon Control 2", "" }, + { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, "Get trusted DC name", "" }, { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, "Logon Control", "" }, { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, "Sam Synchronisation", "" }, { "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, "Query Sam Deltas", "" }, -- cgit