r23127: Fill in some more netlogon dsgetdcname flavours (netr_DsRGetDCNameEx,
authorGünther Deschner <gd@samba.org>
Thu, 24 May 2007 23:11:11 +0000 (23:11 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:22:48 +0000 (12:22 -0500)
netr_DsRGetDCNameEx2) and add new ds request and reply flags, also add some
more WERROR codes.

Guenther
(This used to be commit 37ae7f419702c563bcd0d9c27c02bde7efd34dd7)

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

index 3c3978a5b9fa2797e7baf5b73eeb1dbffbe64937..5073cd005c186a3240f0183e1366ff197110e036 100644 (file)
 #define WERR_ALREADY_EXISTS W_ERROR(80)
 #define WERR_BAD_PASSWORD W_ERROR(86)
 #define WERR_INVALID_PARAM W_ERROR(87)
+#define WERR_SEM_TIMEOUT W_ERROR(121)
 #define WERR_INSUFFICIENT_BUFFER W_ERROR(122)
 #define WERR_INVALID_NAME W_ERROR(123)
 #define WERR_UNKNOWN_LEVEL W_ERROR(124)
 #define WERR_INVALID_OWNER W_ERROR(1307)
 #define WERR_IO_PENDING W_ERROR(997)
 #define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
+#define WERR_INVALID_FLAGS W_ERROR(1004)
 #define WERR_REG_CORRUPT W_ERROR(1015)
 #define WERR_REG_IO_FAILURE W_ERROR(1016)
 #define WERR_REG_FILE_INVALID W_ERROR(1017)
 #define WERR_JOB_NOT_FOUND W_ERROR(2151)
 #define WERR_DEST_NOT_FOUND W_ERROR(2152)
 #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320)
+#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453)
 #define WERR_STATUS_MORE_ENTRIES   W_ERROR(0x0105)
 
 #define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled)
index 7bbd9cc1cbd812c50cd0f6b6f9e2c88ba3229d44..2583a5bd4090d7de86ea2bef6f89a0631bc562a4 100644 (file)
@@ -41,7 +41,9 @@
 #define NET_TRUST_DOM_LIST     0x13
 #define NET_DSR_GETDCNAME      0x14
 #define NET_AUTH3              0x1a
+#define NET_DSR_GETDCNAMEEX    0x1b
 #define NET_DSR_GETSITENAME    0x1c
+#define NET_DSR_GETDCNAMEEX2   0x22
 #define NET_SAMLOGON_EX                0x27
 
 /* Returned delta types */
@@ -1043,7 +1045,63 @@ typedef struct net_r_sam_deltas_info {
        NTSTATUS status;
 } NET_R_SAM_DELTAS;
 
-/* NET_Q_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */
+#define DS_FORCE_REDISCOVERY            0x00000001
+#define DS_DIRECTORY_SERVICE_REQUIRED   0x00000010
+#define DS_DIRECTORY_SERVICE_PREFERRED  0x00000020
+#define DS_GC_SERVER_REQUIRED           0x00000040
+#define DS_PDC_REQUIRED                 0x00000080
+#define DS_BACKGROUND_ONLY              0x00000100
+#define DS_IP_REQUIRED                  0x00000200
+#define DS_KDC_REQUIRED                 0x00000400
+#define DS_TIMESERV_REQUIRED            0x00000800
+#define DS_WRITABLE_REQUIRED            0x00001000
+#define DS_GOOD_TIMESERV_PREFERRED      0x00002000
+#define DS_AVOID_SELF                   0x00004000
+#define DS_ONLY_LDAP_NEEDED             0x00008000
+
+#define DS_IS_FLAT_NAME                 0x00010000
+#define DS_IS_DNS_NAME                  0x00020000
+
+#define DS_RETURN_DNS_NAME              0x40000000
+#define DS_RETURN_FLAT_NAME             0x80000000
+
+#if 0 /* unknown yet */
+#define DS_IP_VERSION_AGNOSTIC
+#define DS_TRY_NEXTCLOSEST_SITE
+#endif
+
+#define DSGETDC_VALID_FLAGS ( \
+    DS_FORCE_REDISCOVERY | \
+    DS_DIRECTORY_SERVICE_REQUIRED | \
+    DS_DIRECTORY_SERVICE_PREFERRED | \
+    DS_GC_SERVER_REQUIRED | \
+    DS_PDC_REQUIRED | \
+    DS_BACKGROUND_ONLY | \
+    DS_IP_REQUIRED | \
+    DS_KDC_REQUIRED | \
+    DS_TIMESERV_REQUIRED | \
+    DS_WRITABLE_REQUIRED | \
+    DS_GOOD_TIMESERV_PREFERRED | \
+    DS_AVOID_SELF | \
+    DS_ONLY_LDAP_NEEDED | \
+    DS_IS_FLAT_NAME | \
+    DS_IS_DNS_NAME | \
+    DS_RETURN_FLAT_NAME  | \
+    DS_RETURN_DNS_NAME )
+
+struct DS_DOMAIN_CONTROLLER_INFO {
+       const char *domain_controller_name;
+       const char *domain_controller_address;
+       int32 domain_controller_address_type;
+       struct GUID *domain_guid;
+       const char *domain_name;
+       const char *dns_forest_name;
+       uint32 flags;
+       const char *dc_site_name;
+       const char *client_site_name;
+};
+
+/* NET_Q_DSR_GETDCNAME */
 typedef struct net_q_dsr_getdcname {
        uint32 ptr_server_unc;
        UNISTR2 uni_server_unc;
@@ -1056,7 +1114,7 @@ typedef struct net_q_dsr_getdcname {
        uint32 flags;
 } NET_Q_DSR_GETDCNAME;
 
-/* NET_R_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */
+/* NET_R_DSR_GETDCNAME */
 typedef struct net_r_dsr_getdcname {
        uint32 ptr_dc_unc;
        UNISTR2 uni_dc_unc;
@@ -1076,6 +1134,41 @@ typedef struct net_r_dsr_getdcname {
        WERROR result;
 } NET_R_DSR_GETDCNAME;
 
+/* NET_Q_DSR_GETDCNAMEEX */
+typedef struct net_q_dsr_getdcnameex {
+       uint32 ptr_server_unc;
+       UNISTR2 uni_server_unc;
+       uint32 ptr_domain_name;
+       UNISTR2 uni_domain_name;
+       uint32 ptr_domain_guid;
+       struct GUID *domain_guid;
+       uint32 ptr_site_name;
+       UNISTR2 uni_site_name;
+       uint32 flags;
+} NET_Q_DSR_GETDCNAMEEX;
+
+/* NET_R_DSR_GETDCNAMEEX */
+typedef struct NET_R_DSR_GETDCNAME NET_R_DSR_GETDCNAMEEX;
+
+/* NET_Q_DSR_GETDCNAMEEX2 */
+typedef struct net_q_dsr_getdcnameex2 {
+       uint32 ptr_server_unc;
+       UNISTR2 uni_server_unc;
+       uint32 ptr_client_account;
+       UNISTR2 uni_client_account;
+       uint32 mask;
+       uint32 ptr_domain_name;
+       UNISTR2 uni_domain_name;
+       uint32 ptr_domain_guid;
+       struct GUID *domain_guid;
+       uint32 ptr_site_name;
+       UNISTR2 uni_site_name;
+       uint32 flags;
+} NET_Q_DSR_GETDCNAMEEX2;
+
+/* NET_R_DSR_GETDCNAMEEX */
+typedef struct NET_R_DSR_GETDCNAME NET_R_DSR_GETDCNAMEEX2;
+
 /* NET_Q_DSR_GESITENAME */
 typedef struct net_q_dsr_getsitename {
        uint32 ptr_computer_name;
index 414c2d491681952d8af3f3f184e54d62c749b571..022d9b6247386215c8b8a5e4c45bbf388d14001f 100644 (file)
@@ -37,6 +37,7 @@ werror_code_struct dos_errs[] =
        { "WERR_BADFID", WERR_BADFID },
        { "WERR_BADFUNC", WERR_BADFUNC },
        { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER },
+       { "WERR_SEM_TIMEOUT", WERR_SEM_TIMEOUT },
        { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE },
        { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS },
        { "WERR_INVALID_PARAM", WERR_INVALID_PARAM },
@@ -59,6 +60,7 @@ werror_code_struct dos_errs[] =
        { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND },
        { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND },
        { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN },
+       { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS },
        { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE },
        { "WERR_STATUS_MORE_ENTRIES  ", WERR_STATUS_MORE_ENTRIES },
        { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL },
@@ -67,7 +69,7 @@ werror_code_struct dos_errs[] =
        { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR },
        { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT },
        { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED },
-       { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS },
+       { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND },
        { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE },
        { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN },
        { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
@@ -80,6 +82,8 @@ werror_code_struct dos_errs[] =
        { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE },
        { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID },
        { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED },
+       { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE},
+       { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS},
        { NULL, W_ERROR(0) }
 };
 
index 6fc2f692fc33ee40c5e84fc6f2df840f155933ef..eaa398087b41bb86f32f926c69299ac1d0e408fb 100644 (file)
@@ -456,6 +456,91 @@ WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli,
        return result;
 }
 
+static WERROR pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX *mem_ctx,
+                                                              struct DS_DOMAIN_CONTROLLER_INFO **info_out, 
+                                                              NET_R_DSR_GETDCNAME *r)
+{
+       struct DS_DOMAIN_CONTROLLER_INFO *info;
+
+       info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO);
+       if (!info) {
+               return WERR_NOMEM;
+       }
+
+       if (&r->uni_dc_unc) {
+
+               char *tmp;
+               tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_unc);
+               if (tmp == NULL) {
+                       return WERR_GENERAL_FAILURE;
+               }
+               if (*tmp == '\\') tmp += 1;
+               if (*tmp == '\\') tmp += 1;
+
+               info->domain_controller_name = talloc_strdup(mem_ctx, tmp);
+               if (info->domain_controller_name == NULL) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       if (&r->uni_dc_address) {
+
+               char *tmp;
+               tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_address);
+               if (tmp == NULL) {
+                       return WERR_GENERAL_FAILURE;
+               }
+               if (*tmp == '\\') tmp += 1;
+               if (*tmp == '\\') tmp += 1;
+
+               info->domain_controller_address = talloc_strdup(mem_ctx, tmp);
+               if (info->domain_controller_address == NULL) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       info->domain_controller_address_type = r->dc_address_type;
+
+       info->domain_guid = talloc_memdup(mem_ctx, &r->domain_guid, sizeof(struct GUID));
+       if (!info->domain_guid) {
+               return WERR_GENERAL_FAILURE;
+       }
+
+       if (&r->uni_domain_name) {
+               info->domain_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_domain_name);
+               if (!info->domain_name) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       if (&r->uni_forest_name) {
+               info->dns_forest_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_forest_name);
+               if (!info->dns_forest_name) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       info->flags = r->dc_flags;
+
+       if (&r->uni_dc_site_name) {
+               info->dc_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_site_name);
+               if (!info->dc_site_name) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       if (&r->uni_client_site_name) {
+               info->client_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_client_site_name);
+               if (!info->client_site_name) {
+                       return WERR_GENERAL_FAILURE;
+               }
+       }
+
+       *info_out = info;
+
+       return WERR_OK;
+}
+
 /* Dsr_GetDCName */
 
 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
@@ -465,14 +550,7 @@ WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
                                     struct GUID *domain_guid,
                                     struct GUID *site_guid,
                                     uint32_t flags,
-                                    char **dc_unc, char **dc_address,
-                                    int32 *dc_address_type,
-                                    struct GUID *domain_guid_out,
-                                    char **domain_name_out,
-                                    char **forest_name,
-                                    uint32 *dc_flags,
-                                    char **dc_site_name,
-                                    char **client_site_name)
+                                    struct DS_DOMAIN_CONTROLLER_INFO **info_out)
 {
        prs_struct qbuf, rbuf;
        NET_Q_DSR_GETDCNAME q;
@@ -505,79 +583,117 @@ WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
                return r.result;
        }
 
-       if (dc_unc != NULL) {
-               char *tmp;
-               tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_unc);
-               if (tmp == NULL) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               if (*tmp == '\\') tmp += 1;
-               if (*tmp == '\\') tmp += 1;
-
-               /* We have to talloc_strdup, otherwise a talloc_steal would
-                  fail */
-               *dc_unc = talloc_strdup(mem_ctx, tmp);
-               if (*dc_unc == NULL) {
-                       return WERR_NOMEM;
-               }
+       r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
+       if (!W_ERROR_IS_OK(r.result)) {
+               return r.result;
        }
 
-       if (dc_address != NULL) {
-               char *tmp;
-               tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_address);
-               if (tmp == NULL) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               if (*tmp == '\\') tmp += 1;
-               if (*tmp == '\\') tmp += 1;
+       return WERR_OK;
+}
 
-               /* We have to talloc_strdup, otherwise a talloc_steal would
-                  fail */
-               *dc_address = talloc_strdup(mem_ctx, tmp);
-               if (*dc_address == NULL) {
-                       return WERR_NOMEM;
-               }
-       }
+/* Dsr_GetDCNameEx */
 
-       if (dc_address_type != NULL) {
-               *dc_address_type = r.dc_address_type;
-       }
+WERROR rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
+                                      TALLOC_CTX *mem_ctx,
+                                      const char *server_name,
+                                      const char *domain_name,
+                                      struct GUID *domain_guid,
+                                      const char *site_name,
+                                      uint32_t flags,
+                                      struct DS_DOMAIN_CONTROLLER_INFO **info_out)
+{
+       prs_struct qbuf, rbuf;
+       NET_Q_DSR_GETDCNAMEEX q;
+       NET_R_DSR_GETDCNAME r;
+       char *tmp_str;
 
-       if (domain_guid_out != NULL) {
-               *domain_guid_out = r.domain_guid;
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialize input parameters */
+
+       tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
+       if (tmp_str == NULL) {
+               return WERR_NOMEM;
        }
 
-       if ((domain_name_out != NULL) &&
-           ((*domain_name_out = rpcstr_pull_unistr2_talloc(
-                   mem_ctx, &r.uni_domain_name)) == NULL)) {
-               return WERR_GENERAL_FAILURE;
+       init_net_q_dsr_getdcnameex(&q, server_name, domain_name, domain_guid,
+                                  site_name, flags);
+
+       /* Marshall data and send request */
+
+       CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX,
+                       q, r,
+                       qbuf, rbuf,
+                       net_io_q_dsr_getdcnameex,
+                       net_io_r_dsr_getdcname,
+                       WERR_GENERAL_FAILURE);
+
+       if (!W_ERROR_IS_OK(r.result)) {
+               return r.result;
        }
 
-       if ((forest_name != NULL) &&
-           ((*forest_name = rpcstr_pull_unistr2_talloc(
-                     mem_ctx, &r.uni_forest_name)) == NULL)) {
-               return WERR_GENERAL_FAILURE;
+       r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
+       if (!W_ERROR_IS_OK(r.result)) {
+               return r.result;
        }
 
-       if (dc_flags != NULL) {
-               *dc_flags = r.dc_flags;
+       return WERR_OK;
+}
+
+/* Dsr_GetDCNameEx */
+
+WERROR rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
+                                       TALLOC_CTX *mem_ctx,
+                                       const char *server_name,
+                                       const char *client_account,
+                                       uint32 mask,
+                                       const char *domain_name,
+                                       struct GUID *domain_guid,
+                                       const char *site_name,
+                                       uint32_t flags,
+                                       struct DS_DOMAIN_CONTROLLER_INFO **info_out)
+{
+       prs_struct qbuf, rbuf;
+       NET_Q_DSR_GETDCNAMEEX2 q;
+       NET_R_DSR_GETDCNAME r;
+       char *tmp_str;
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialize input parameters */
+
+       tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
+       if (tmp_str == NULL) {
+               return WERR_NOMEM;
        }
 
-       if ((dc_site_name != NULL) &&
-           ((*dc_site_name = rpcstr_pull_unistr2_talloc(
-                     mem_ctx, &r.uni_dc_site_name)) == NULL)) {
-               return WERR_GENERAL_FAILURE;
+       init_net_q_dsr_getdcnameex2(&q, server_name, domain_name, client_account,
+                                   mask, domain_guid, site_name, flags);
+
+       /* Marshall data and send request */
+
+       CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX2,
+                       q, r,
+                       qbuf, rbuf,
+                       net_io_q_dsr_getdcnameex2,
+                       net_io_r_dsr_getdcname,
+                       WERR_GENERAL_FAILURE);
+
+       if (!W_ERROR_IS_OK(r.result)) {
+               return r.result;
        }
 
-       if ((client_site_name != NULL) &&
-           ((*client_site_name = rpcstr_pull_unistr2_talloc(
-                     mem_ctx, &r.uni_client_site_name)) == NULL)) {
-               return WERR_GENERAL_FAILURE;
+       r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
+       if (!W_ERROR_IS_OK(r.result)) {
+               return r.result;
        }
 
        return WERR_OK;
 }
 
+
 /* Dsr_GetSiteName */
 
 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
index 01d77f4e07bfa1bb8e293af8a282b67bc01f626a..2f215dd938299934607a2c93cdd967ac14b7c5e4 100644 (file)
@@ -3434,6 +3434,67 @@ void init_net_q_dsr_getdcname(NET_Q_DSR_GETDCNAME *r_t, const char *server_unc,
        r_t->flags = flags;
 }
 
+/*******************************************************************
+ Inits a NET_Q_DSR_GETDCNAMEEX structure.
+********************************************************************/
+
+void init_net_q_dsr_getdcnameex(NET_Q_DSR_GETDCNAMEEX *r_t, const char *server_unc,
+                               const char *domain_name,
+                               struct GUID *domain_guid,
+                               const char *site_name,
+                               uint32_t flags)
+{
+       DEBUG(5, ("init_net_q_dsr_getdcnameex\n"));
+
+       r_t->ptr_server_unc = (server_unc != NULL);
+       init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE);
+
+       r_t->ptr_domain_name = (domain_name != NULL);
+       init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
+
+       r_t->ptr_domain_guid = (domain_guid != NULL);
+       r_t->domain_guid = domain_guid;
+
+       r_t->ptr_site_name = (site_name != NULL);
+       init_unistr2(&r_t->uni_site_name, site_name, UNI_STR_TERMINATE);
+
+       r_t->flags = flags;
+}
+
+/*******************************************************************
+ Inits a NET_Q_DSR_GETDCNAMEEX2 structure.
+********************************************************************/
+
+void init_net_q_dsr_getdcnameex2(NET_Q_DSR_GETDCNAMEEX2 *r_t, const char *server_unc,
+                                const char *domain_name,
+                                const char *client_account,
+                                uint32 mask,
+                                struct GUID *domain_guid,
+                                const char *site_name,
+                                uint32_t flags)
+{
+       DEBUG(5, ("init_net_q_dsr_getdcnameex2\n"));
+
+       r_t->ptr_server_unc = (server_unc != NULL);
+       init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE);
+
+       r_t->ptr_client_account = (client_account != NULL);
+       init_unistr2(&r_t->uni_client_account, client_account, UNI_STR_TERMINATE);
+
+       r_t->mask = mask;
+
+       r_t->ptr_domain_name = (domain_name != NULL);
+       init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
+
+       r_t->ptr_domain_guid = (domain_guid != NULL);
+       r_t->domain_guid = domain_guid;
+
+       r_t->ptr_site_name = (site_name != NULL);
+       init_unistr2(&r_t->uni_site_name, site_name, UNI_STR_TERMINATE);
+
+       r_t->flags = flags;
+}
+
 /*******************************************************************
  Reads or writes an NET_Q_DSR_GETDCNAME structure.
 ********************************************************************/
@@ -3505,6 +3566,154 @@ BOOL net_io_q_dsr_getdcname(const char *desc, NET_Q_DSR_GETDCNAME *r_t,
        return True;
 }
 
+/*******************************************************************
+ Reads or writes an NET_Q_DSR_GETDCNAMEEX structure.
+********************************************************************/
+
+BOOL net_io_q_dsr_getdcnameex(const char *desc, NET_Q_DSR_GETDCNAMEEX *r_t,
+                             prs_struct *ps, int depth)
+{
+       if (r_t == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "net_io_q_dsr_getdcnameex");
+       depth++;
+
+       if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc))
+               return False;
+
+       if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc,
+                           r_t->ptr_server_unc, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
+               return False;
+
+       if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
+                           r_t->ptr_domain_name, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid))
+               return False;
+
+       if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) {
+               r_t->domain_guid = PRS_ALLOC_MEM(ps, struct GUID, 1);
+               if (r_t->domain_guid == NULL)
+                       return False;
+       }
+
+       if ((r_t->ptr_domain_guid) &&
+           (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth)))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name))
+               return False;
+
+       if (!smb_io_unistr2("site_name", &r_t->uni_site_name,
+                           r_t->ptr_site_name, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("flags", ps, depth, &r_t->flags))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes an NET_Q_DSR_GETDCNAMEEX2 structure.
+********************************************************************/
+
+BOOL net_io_q_dsr_getdcnameex2(const char *desc, NET_Q_DSR_GETDCNAMEEX2 *r_t,
+                              prs_struct *ps, int depth)
+{
+       if (r_t == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "net_io_q_dsr_getdcnameex2");
+       depth++;
+
+       if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc))
+               return False;
+
+       if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc,
+                           r_t->ptr_server_unc, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_client_account", ps, depth, &r_t->ptr_client_account))
+               return False;
+
+       if (!smb_io_unistr2("client_account", &r_t->uni_client_account,
+                           r_t->ptr_client_account, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("mask", ps, depth, &r_t->mask))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
+               return False;
+
+       if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
+                           r_t->ptr_domain_name, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid))
+               return False;
+
+       if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) {
+               r_t->domain_guid = PRS_ALLOC_MEM(ps, struct GUID, 1);
+               if (r_t->domain_guid == NULL)
+                       return False;
+       }
+
+       if ((r_t->ptr_domain_guid) &&
+           (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth)))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name))
+               return False;
+
+       if (!smb_io_unistr2("site_name", &r_t->uni_site_name,
+                           r_t->ptr_site_name, ps, depth))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_uint32("flags", ps, depth, &r_t->flags))
+               return False;
+
+       return True;
+}
+
+
+
 /*******************************************************************
  Inits a NET_R_DSR_GETDCNAME structure.
 ********************************************************************/
index 7794c809191530a9a9fe43c0e7341854a9ed83b5..93d47eeb830062bc07e42639cd3b56c4b9470cbf 100644 (file)
@@ -107,35 +107,205 @@ static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli,
        return result;
 }
 
+static void display_ds_domain_controller_info(TALLOC_CTX *mem_ctx, const struct DS_DOMAIN_CONTROLLER_INFO *info)
+{
+       d_printf("domain_controller_name: %s\n", info->domain_controller_name);
+       d_printf("domain_controller_address: %s\n", info->domain_controller_address);
+       d_printf("domain_controller_address_type: %d\n", info->domain_controller_address_type);
+       d_printf("domain_guid: %s\n", GUID_string(mem_ctx, info->domain_guid));
+       d_printf("domain_name: %s\n", info->domain_name);
+       d_printf("dns_forest_name: %s\n", info->dns_forest_name);
+       d_printf("flags: 0x%08x\n"
+                "\tIs a PDC:                                   %s\n"
+                "\tIs a GC of the forest:                      %s\n"
+                "\tIs an LDAP server:                          %s\n"
+                "\tSupports DS:                                %s\n"
+                "\tIs running a KDC:                           %s\n"
+                "\tIs running time services:                   %s\n"
+                "\tIs the closest DC:                          %s\n"
+                "\tIs writable:                                %s\n"
+                "\tHas a hardware clock:                       %s\n"
+                "\tIs a non-domain NC serviced by LDAP server: %s\n"
+                "\tDomainControllerName is a DNS name:         %s\n"
+                "\tDomainName is a DNS name:                   %s\n"
+                "\tDnsForestName is a DNS name:                %s\n",
+                info->flags,
+                (info->flags & ADS_PDC) ? "yes" : "no",
+                (info->flags & ADS_GC) ? "yes" : "no",
+                (info->flags & ADS_LDAP) ? "yes" : "no",
+                (info->flags & ADS_DS) ? "yes" : "no",
+                (info->flags & ADS_KDC) ? "yes" : "no",
+                (info->flags & ADS_TIMESERV) ? "yes" : "no",
+                (info->flags & ADS_CLOSEST) ? "yes" : "no",
+                (info->flags & ADS_WRITABLE) ? "yes" : "no",
+                (info->flags & ADS_GOOD_TIMESERV) ? "yes" : "no",
+                (info->flags & ADS_NDNC) ? "yes" : "no",
+                (info->flags & ADS_DNS_CONTROLLER) ? "yes":"no",
+                (info->flags & ADS_DNS_DOMAIN) ? "yes":"no",
+                (info->flags & ADS_DNS_FOREST) ? "yes":"no");
+
+       d_printf("dc_site_name: %s\n", info->dc_site_name);
+       d_printf("client_site_name: %s\n", info->client_site_name);
+}
+
 static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
                                         TALLOC_CTX *mem_ctx, int argc,
                                         const char **argv)
 {
        WERROR result;
-       char *dcname, *dcaddress;
-
-       if (argc != 2) {
-               fprintf(stderr, "Usage: %s domainname\n", argv[0]);
+       uint32 flags = DS_RETURN_DNS_NAME;
+       const char *server_name = cli->cli->desthost;
+       const char *domain_name;
+       struct GUID domain_guid = GUID_zero();
+       struct GUID site_guid = GUID_zero();
+       struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
+
+       if (argc < 2) {
+               fprintf(stderr, "Usage: %s [domainname] [domain_name] [domain_guid] [site_guid] [flags]\n", argv[0]);
                return WERR_OK;
        }
 
-       result = rpccli_netlogon_dsr_getdcname(
-               cli, mem_ctx, cli->cli->desthost, argv[1], NULL, NULL,
-               0x40000000, &dcname, &dcaddress, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL);
+       if (argc >= 2)
+               domain_name = argv[1];
+
+       if (argc >= 3) {
+               if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
+                       return WERR_NOMEM;
+               }
+       }
+
+       if (argc >= 4) {
+               if (!NT_STATUS_IS_OK(GUID_from_string(argv[3], &site_guid))) {
+                       return WERR_NOMEM;
+               }
+       }
+
+       if (argc >= 5)
+               sscanf(argv[4], "%x", &flags);
+       
+       result = rpccli_netlogon_dsr_getdcname(cli, mem_ctx, server_name, domain_name, 
+                                              &domain_guid, &site_guid, flags,
+                                              &info);
 
        if (W_ERROR_IS_OK(result)) {
-               printf("Domain %s's DC is called %s at IP %s\n",
-                      argv[1], dcname, dcaddress);
+               d_printf("DsGetDcName gave\n");
+               display_ds_domain_controller_info(mem_ctx, info);
                return WERR_OK;
        }
 
        printf("rpccli_netlogon_dsr_getdcname returned %s\n",
-              nt_errstr(werror_to_ntstatus(result)));
+              dos_errstr(result));
+
+       return result;
+}
+
+static WERROR cmd_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
+                                          TALLOC_CTX *mem_ctx, int argc,
+                                          const char **argv)
+{
+       WERROR result;
+       uint32 flags = DS_RETURN_DNS_NAME;
+       const char *server_name = cli->cli->desthost;
+       const char *domain_name;
+       const char *site_name = NULL;
+       struct GUID domain_guid = GUID_zero();
+       struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
+
+       if (argc < 2) {
+               fprintf(stderr, "Usage: %s [domainname] [domain_name] [domain_guid] [site_name] [flags]\n", argv[0]);
+               return WERR_OK;
+       }
+
+       if (argc >= 2)
+               domain_name = argv[1];
+
+       if (argc >= 3) {
+               if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) {
+                       return WERR_NOMEM;
+               }
+       }
+
+       if (argc >= 4)
+               site_name = argv[3];
+
+       if (argc >= 5)
+               sscanf(argv[4], "%x", &flags);
+
+       result = rpccli_netlogon_dsr_getdcnameex(cli, mem_ctx, server_name, domain_name, 
+                                                &domain_guid, site_name, flags,
+                                                &info);
+
+       if (W_ERROR_IS_OK(result)) {
+               d_printf("DsGetDcNameEx gave\n");
+               display_ds_domain_controller_info(mem_ctx, info);
+               return WERR_OK;
+       }
+
+       printf("rpccli_netlogon_dsr_getdcnameex returned %s\n",
+              dos_errstr(result));
+
+       return result;
+}
+
+static WERROR cmd_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
+                                           TALLOC_CTX *mem_ctx, int argc,
+                                           const char **argv)
+{
+       WERROR result;
+       uint32 flags = DS_RETURN_DNS_NAME;
+       const char *server_name = cli->cli->desthost;
+       const char *domain_name;
+       const char *client_account = NULL;
+       uint32 mask = 0;
+       const char *site_name = NULL;
+       struct GUID domain_guid = GUID_zero();
+       struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
+
+       if (argc < 2) {
+               fprintf(stderr, "Usage: %s [domainname] [client_account] [acb_mask] [domain_name] [domain_guid] [site_name] [flags]\n", argv[0]);
+               return WERR_OK;
+       }
+
+       if (argc >= 2)
+               client_account = argv[1];
+
+       if (argc >= 3)
+               mask = atoi(argv[2]);
+       
+       if (argc >= 4)
+               domain_name = argv[3];
+
+       if (argc >= 5) {
+               if (!NT_STATUS_IS_OK(GUID_from_string(argv[4], &domain_guid))) {
+                       return WERR_NOMEM;
+               }
+       }
+
+       if (argc >= 6)
+               site_name = argv[5];
+
+       if (argc >= 7)
+               sscanf(argv[6], "%x", &flags);
+
+       result = rpccli_netlogon_dsr_getdcnameex2(cli, mem_ctx, server_name, 
+                                                 client_account, mask,
+                                                 domain_name, &domain_guid,
+                                                 site_name, flags,
+                                                 &info);
+
+       if (W_ERROR_IS_OK(result)) {
+               d_printf("DsGetDcNameEx2 gave\n");
+               display_ds_domain_controller_info(mem_ctx, info);
+               return WERR_OK;
+       }
+
+       printf("rpccli_netlogon_dsr_getdcnameex2 returned %s\n",
+              dos_errstr(result));
 
        return result;
 }
 
+
 static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx, int argc,
                                           const char **argv)
@@ -412,6 +582,8 @@ struct cmd_set netlogon_commands[] = {
        { "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_getdcnameex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex, PI_NETLOGON, NULL, "Get trusted DC name",     "" },
+       { "dsr_getdcnameex2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex2, 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",       "" },
        { "samsync",    RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync,    NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },