r19161: Add NET_GETANYDCNAME (getdcname only gives the PDC while getanydcname
authorGünther Deschner <gd@samba.org>
Sat, 7 Oct 2006 05:26:21 +0000 (05:26 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:15:18 +0000 (12:15 -0500)
gives just any DC), also make sure to set timeouts in rpcclient
accordingly so that we actually get the DC's reply.

Guenther
(This used to be commit 6091c8152a3998d2503cb0911a217ee904509633)

source3/include/rpc_netlogon.h
source3/rpc_client/cli_netlogon.c
source3/rpc_parse/parse_net.c
source3/rpcclient/cmd_netlogon.c

index c72a35749fe63d0aa9c85ca424e6d9733cb759c3..5c9e4c00d7dc237d149a544c4283248d4b55b197 100644 (file)
@@ -32,6 +32,7 @@
 #define NET_AUTH               0x05
 #define NET_SRVPWSET           0x06
 #define NET_SAM_DELTAS         0x07
+#define NET_GETANYDCNAME       0x0b
 #define NET_LOGON_CTRL         0x0c
 #define NET_GETDCNAME          0x0d
 #define NET_AUTH2              0x0f
@@ -424,6 +425,23 @@ typedef struct net_r_getdcname {
        WERROR status;
 } NET_R_GETDCNAME;
 
+
+/* NET_Q_GETANYDCNAME - Ask a DC for a trusted DC name */
+
+typedef struct net_q_getanydcname {
+       UNISTR2 uni_logon_server;
+       uint32  ptr_domainname;
+       UNISTR2 uni_domainname;
+} NET_Q_GETANYDCNAME;
+
+/* NET_R_GETANYDCNAME - Ask a DC for a trusted DC name */
+
+typedef struct net_r_getanydcname {
+       uint32  ptr_dcname;
+       UNISTR2 uni_dcname;
+       WERROR status;
+} NET_R_GETANYDCNAME;
+
 /* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
 typedef struct net_q_trust_dom_info {
        uint32       ptr;             /* undocumented buffer pointer */
index 5396de9bf078ba2d5e5b23cdb6b33eb754d50383..28395de067b0ad1a7037042738f95444a80b567a 100644 (file)
@@ -418,6 +418,44 @@ WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
        return result;
 }
 
+/* GetAnyDCName */
+
+WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli,
+                                   TALLOC_CTX *mem_ctx, const char *mydcname,
+                                   const char *domainname, fstring newdcname)
+{
+       prs_struct qbuf, rbuf;
+       NET_Q_GETANYDCNAME q;
+       NET_R_GETANYDCNAME r;
+       WERROR result;
+       fstring mydcname_slash;
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialise input parameters */
+
+       slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
+       init_net_q_getanydcname(&q, mydcname_slash, domainname);
+
+       /* Marshall data and send request */
+
+       CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME,
+               q, r,
+               qbuf, rbuf,
+               net_io_q_getanydcname,
+               net_io_r_getanydcname,
+               WERR_GENERAL_FAILURE);
+
+       result = r.status;
+
+       if (W_ERROR_IS_OK(result)) {
+               rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
+       }
+
+       return result;
+}
+
 /* Dsr_GetDCName */
 
 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
index 6f7c453edf506ead9f42f84ae06576a913756086..1bd75cf8b186c2489f40ecc91d214173d384e058 100644 (file)
@@ -566,6 +566,90 @@ BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps,
        return True;
 }
 
+
+/*******************************************************************
+ Inits an NET_R_GETANYDCNAME structure.
+********************************************************************/
+void init_net_q_getanydcname(NET_Q_GETANYDCNAME *r_t, const char *logon_server,
+                            const char *domainname)
+{
+       DEBUG(5,("init_r_getanydcname\n"));
+
+       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_GETANYDCNAME structure.
+********************************************************************/
+
+BOOL net_io_q_getanydcname(const char *desc, NET_Q_GETANYDCNAME *r_t, prs_struct *ps,
+                          int depth)
+{
+       if (r_t == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "net_io_q_getanydcname");
+       depth++;
+
+       if (!smb_io_unistr2("logon_server", &r_t->uni_logon_server,
+                           1, 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_GETANYDCNAME structure.
+********************************************************************/
+void init_net_r_getanydcname(NET_R_GETANYDCNAME *r_t, const char *dcname)
+{
+       DEBUG(5,("init_r_getanydcname\n"));
+
+       init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE);
+}
+
+/*******************************************************************
+ Reads or writes an NET_R_GETANYDCNAME structure.
+********************************************************************/
+
+BOOL net_io_r_getanydcname(const char *desc, NET_R_GETANYDCNAME *r_t, prs_struct *ps,
+                          int depth)
+{
+       if (r_t == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "net_io_r_getanydcname");
+       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_align(ps))
+               return False;
+
+       if (!prs_werror("status", ps, depth, &r_t->status))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  Inits an NET_R_TRUST_DOM_LIST structure.
 ********************************************************************/
index 1a145711cc7ac26b62c925c97716ea2590d532d0..5ae449a68c286d18ee32628f6ce61fe702c2f0c8 100644 (file)
@@ -51,14 +51,51 @@ static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
 {
        fstring dcname;
        WERROR result = WERR_GENERAL_FAILURE;
+       int old_timeout;
 
        if (argc != 2) {
                fprintf(stderr, "Usage: %s domainname\n", argv[0]);
                return WERR_OK;
        }
 
+       /* Make sure to wait for our DC's reply */
+       old_timeout = cli_set_timeout(cli->cli, 30000); /* 30 seconds. */
+
        result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
 
+       cli_set_timeout(cli->cli, old_timeout);
+
+       if (!W_ERROR_IS_OK(result))
+               goto done;
+
+       /* Display results */
+
+       printf("%s\n", dcname);
+
+ done:
+       return result;
+}
+
+static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, 
+                                       TALLOC_CTX *mem_ctx, int argc, 
+                                       const char **argv)
+{
+       fstring dcname;
+       WERROR result = WERR_GENERAL_FAILURE;
+       int old_timeout;
+
+       if (argc != 2) {
+               fprintf(stderr, "Usage: %s domainname\n", argv[0]);
+               return WERR_OK;
+       }
+
+       /* Make sure to wait for our DC's reply */
+       old_timeout = cli_set_timeout(cli->cli, 30000); /* 30 seconds. */
+
+       result = rpccli_netlogon_getanydcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
+
+       cli_set_timeout(cli->cli, old_timeout);
+
        if (!W_ERROR_IS_OK(result))
                goto done;
 
@@ -368,7 +405,8 @@ struct cmd_set netlogon_commands[] = {
        { "NETLOGON" },
 
        { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2",     "" },
-       { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
+       { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted PDC name",     "" },
+       { "getanydcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getanydcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
        { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
        { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename",     "" },
        { "logonctrl",  RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl,  NULL, PI_NETLOGON, NULL, "Logon Control",       "" },