return WINBINDD_OK;
}
+static void ndr_child_get_dc_info_comapt_nt4(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state,
+ struct winbind_get_dc_info *r)
+{
+ const char *dcname_slash;
+ const char *p;
+ struct rpc_pipe_client *netlogon_pipe;
+ NTSTATUS result;
+ WERROR werr;
+ unsigned int orig_timeout;
+ struct winbindd_domain *req_domain;
+
+ DEBUG(3, ("Get DC name for '%s'\n", r->in.domain_name));
+
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(1, ("Can't contact the NETLOGON pipe\n"));
+ r->out.result = WINBIND_STATUS_FOOBAR;
+ return;
+ }
+
+ /* This call can take a long time - allow the server to time out.
+ 35 seconds should do it. */
+
+ orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
+
+ /*
+ * if the requested domain name matches the current one
+ * we need to use GetDCName(), because GetAnyDCName() only
+ * works for trusted domains
+ */
+ req_domain = find_domain_from_name_noinit(r->in.domain_name);
+ if (req_domain == domain) {
+ result = rpccli_netr_GetDcName(netlogon_pipe,
+ r,
+ domain->dcname,
+ r->in.domain_name,
+ &dcname_slash,
+ &werr);
+ } else {
+ result = rpccli_netr_GetAnyDCName(netlogon_pipe,
+ r,
+ domain->dcname,
+ r->in.domain_name,
+ &dcname_slash,
+ &werr);
+ }
+ /* And restore our original timeout. */
+ cli_set_timeout(netlogon_pipe->cli, orig_timeout);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(5,("Error requesting DCname for domain %s: %s\n",
+ r->in.domain_name, nt_errstr(result)));
+ r->out.result = WINBIND_STATUS_FOOBAR;
+ return;
+ }
+
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
+ r->in.domain_name, dos_errstr(werr)));
+ r->out.result = WINBIND_STATUS_FOOBAR;
+ return;
+ }
+
+ p = dcname_slash;
+ if (*p == '\\') {
+ p+=1;
+ }
+ if (*p == '\\') {
+ p+=1;
+ }
+
+ r->out.dc_info->name = talloc_strdup(r, p);
+ if (!r->out.dc_info->name) {
+ r->out.result = WINBIND_STATUS_NO_MEMORY;
+ return;
+ }
+ r->out.result = WINBIND_STATUS_OK;
+}
+
+void winbindd_ndr_domain_child_get_dc_info(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct winbind_get_dc_info *r;
+
+ r = talloc_get_type_abort(state->c.ndr.r,
+ struct winbind_get_dc_info);
+
+ switch (*r->in.level) {
+ case WINBIND_DC_INFO_LEVEL_COMPAT_NT4:
+ ndr_child_get_dc_info_comapt_nt4(domain, state, r);
+ return;
+
+ case WINBIND_DC_INFO_LEVEL_COMPAT_DS:
+ r->out.result = WINBIND_STATUS_INVALID_LEVEL;
+ return;
+ }
+
+ r->out.result = WINBIND_STATUS_UNKNOWN_LEVEL;
+ return;
+}
+
struct sequence_state {
TALLOC_CTX *mem_ctx;
struct winbindd_cli_state *cli_state;