From 37ae7f419702c563bcd0d9c27c02bde7efd34dd7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Thu, 24 May 2007 23:11:11 +0000 Subject: [PATCH] r23127: Fill in some more netlogon dsgetdcname flavours (netr_DsRGetDCNameEx, netr_DsRGetDCNameEx2) and add new ds request and reply flags, also add some more WERROR codes. Guenther --- source/include/doserr.h | 3 + source/include/rpc_netlogon.h | 97 ++++++++++++- source/libsmb/doserr.c | 6 +- source/rpc_client/cli_netlogon.c | 238 +++++++++++++++++++++++-------- source/rpc_parse/parse_net.c | 209 +++++++++++++++++++++++++++ source/rpcclient/cmd_netlogon.c | 194 +++++++++++++++++++++++-- 6 files changed, 672 insertions(+), 75 deletions(-) diff --git a/source/include/doserr.h b/source/include/doserr.h index 3c3978a5b9f..5073cd005c1 100644 --- a/source/include/doserr.h +++ b/source/include/doserr.h @@ -184,6 +184,7 @@ #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) @@ -193,6 +194,7 @@ #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) @@ -214,6 +216,7 @@ #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) diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h index 7bbd9cc1cbd..2583a5bd409 100644 --- a/source/include/rpc_netlogon.h +++ b/source/include/rpc_netlogon.h @@ -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; diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c index 414c2d49168..022d9b62473 100644 --- a/source/libsmb/doserr.c +++ b/source/libsmb/doserr.c @@ -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) } }; diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c index 6fc2f692fc3..eaa398087b4 100644 --- a/source/rpc_client/cli_netlogon.c +++ b/source/rpc_client/cli_netlogon.c @@ -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, diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c index 01d77f4e07b..2f215dd9382 100644 --- a/source/rpc_parse/parse_net.c +++ b/source/rpc_parse/parse_net.c @@ -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. ********************************************************************/ diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c index 7794c809191..93d47eeb830 100644 --- a/source/rpcclient/cmd_netlogon.c +++ b/source/rpcclient/cmd_netlogon.c @@ -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", "" }, -- 2.34.1