samba-tool group: Add --special parameter to add predefined special group
[Samba.git] / source3 / winbindd / winbindd_dsgetdcname.c
blobd001213c8752848ab64605ebd5eb81cf35109f63
1 /*
2 Unix SMB/CIFS implementation.
3 async implementation of WINBINDD_DSGETDCNAME
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "winbindd.h"
22 #include "librpc/gen_ndr/ndr_winbind_c.h"
23 #include "lib/util/string_wrappers.h"
25 struct winbindd_dsgetdcname_state {
26 struct GUID guid;
27 struct netr_DsRGetDCNameInfo *dc_info;
30 static uint32_t get_dsgetdc_flags(uint32_t wbc_flags);
31 static void winbindd_dsgetdcname_done(struct tevent_req *subreq);
33 struct tevent_req *winbindd_dsgetdcname_send(TALLOC_CTX *mem_ctx,
34 struct tevent_context *ev,
35 struct winbindd_cli_state *cli,
36 struct winbindd_request *request)
38 struct tevent_req *req, *subreq;
39 struct dcerpc_binding_handle *child_binding_handle = NULL;
40 struct winbindd_dsgetdcname_state *state;
41 struct GUID *guid_ptr = NULL;
42 uint32_t ds_flags = 0;
43 NTSTATUS status;
45 req = tevent_req_create(mem_ctx, &state,
46 struct winbindd_dsgetdcname_state);
47 if (req == NULL) {
48 return NULL;
51 request->data.dsgetdcname.domain_name
52 [sizeof(request->data.dsgetdcname.domain_name)-1] = '\0';
53 request->data.dsgetdcname.site_name
54 [sizeof(request->data.dsgetdcname.site_name)-1] = '\0';
55 request->data.dsgetdcname.domain_guid
56 [sizeof(request->data.dsgetdcname.domain_guid)-1] = '\0';
58 DEBUG(3, ("[%5lu]: dsgetdcname for %s\n", (unsigned long)cli->pid,
59 request->data.dsgetdcname.domain_name));
61 ds_flags = get_dsgetdc_flags(request->data.dsgetdcname.flags);
63 status = GUID_from_string(request->data.dsgetdcname.domain_guid,
64 &state->guid);
65 if (NT_STATUS_IS_OK(status) && !GUID_all_zero(&state->guid)) {
66 guid_ptr = &state->guid;
69 child_binding_handle = locator_child_handle();
71 subreq = dcerpc_wbint_DsGetDcName_send(
72 state, ev, child_binding_handle,
73 request->data.dsgetdcname.domain_name, guid_ptr,
74 request->data.dsgetdcname.site_name,
75 ds_flags, &state->dc_info);
76 if (tevent_req_nomem(subreq, req)) {
77 return tevent_req_post(req, ev);
79 tevent_req_set_callback(subreq, winbindd_dsgetdcname_done, req);
80 return req;
83 static void winbindd_dsgetdcname_done(struct tevent_req *subreq)
85 struct tevent_req *req = tevent_req_callback_data(
86 subreq, struct tevent_req);
87 struct winbindd_dsgetdcname_state *state = tevent_req_data(
88 req, struct winbindd_dsgetdcname_state);
89 NTSTATUS status, result;
91 status = dcerpc_wbint_DsGetDcName_recv(subreq, state, &result);
92 TALLOC_FREE(subreq);
93 if (any_nt_status_not_ok(status, result, &status)) {
94 tevent_req_nterror(req, status);
95 return;
97 tevent_req_done(req);
100 NTSTATUS winbindd_dsgetdcname_recv(struct tevent_req *req,
101 struct winbindd_response *response)
103 struct winbindd_dsgetdcname_state *state = tevent_req_data(
104 req, struct winbindd_dsgetdcname_state);
105 struct GUID_txt_buf guid_str_buf;
106 char *guid_str;
107 NTSTATUS status;
109 if (tevent_req_is_nterror(req, &status)) {
110 DEBUG(5, ("dsgetdcname failed: %s\n", nt_errstr(status)));
111 return status;
115 fstrcpy(response->data.dsgetdcname.dc_unc,
116 state->dc_info->dc_unc);
117 fstrcpy(response->data.dsgetdcname.dc_address,
118 state->dc_info->dc_address);
119 response->data.dsgetdcname.dc_address_type =
120 state->dc_info->dc_address_type;
122 guid_str = GUID_buf_string(&state->dc_info->domain_guid,
123 &guid_str_buf);
124 fstrcpy(response->data.dsgetdcname.domain_guid, guid_str);
126 fstrcpy(response->data.dsgetdcname.domain_name,
127 state->dc_info->domain_name);
128 fstrcpy(response->data.dsgetdcname.forest_name,
129 state->dc_info->forest_name);
130 response->data.dsgetdcname.dc_flags = state->dc_info->dc_flags;
131 fstrcpy(response->data.dsgetdcname.dc_site_name,
132 state->dc_info->dc_site_name);
133 fstrcpy(response->data.dsgetdcname.client_site_name,
134 state->dc_info->client_site_name);
136 return NT_STATUS_OK;
139 static uint32_t get_dsgetdc_flags(uint32_t wbc_flags)
141 struct wbc_flag_map {
142 uint32_t wbc_dc_flag;
143 uint32_t ds_dc_flags;
144 } lookup_dc_flags[] = {
145 { WBC_LOOKUP_DC_FORCE_REDISCOVERY,
146 DS_FORCE_REDISCOVERY },
147 { WBC_LOOKUP_DC_DS_REQUIRED,
148 DS_DIRECTORY_SERVICE_REQUIRED },
149 { WBC_LOOKUP_DC_DS_PREFERRED,
150 DS_DIRECTORY_SERVICE_PREFERRED},
151 { WBC_LOOKUP_DC_GC_SERVER_REQUIRED,
152 DS_GC_SERVER_REQUIRED },
153 { WBC_LOOKUP_DC_PDC_REQUIRED,
154 DS_PDC_REQUIRED},
155 { WBC_LOOKUP_DC_BACKGROUND_ONLY,
156 DS_BACKGROUND_ONLY },
157 { WBC_LOOKUP_DC_IP_REQUIRED,
158 DS_IP_REQUIRED },
159 { WBC_LOOKUP_DC_KDC_REQUIRED,
160 DS_KDC_REQUIRED },
161 { WBC_LOOKUP_DC_TIMESERV_REQUIRED,
162 DS_TIMESERV_REQUIRED },
163 { WBC_LOOKUP_DC_WRITABLE_REQUIRED,
164 DS_WRITABLE_REQUIRED },
165 { WBC_LOOKUP_DC_GOOD_TIMESERV_PREFERRED,
166 DS_GOOD_TIMESERV_PREFERRED },
167 { WBC_LOOKUP_DC_AVOID_SELF,
168 DS_AVOID_SELF },
169 { WBC_LOOKUP_DC_ONLY_LDAP_NEEDED,
170 DS_ONLY_LDAP_NEEDED },
171 { WBC_LOOKUP_DC_IS_FLAT_NAME,
172 DS_IS_FLAT_NAME },
173 { WBC_LOOKUP_DC_IS_DNS_NAME,
174 DS_IS_DNS_NAME },
175 { WBC_LOOKUP_DC_TRY_NEXTCLOSEST_SITE,
176 DS_TRY_NEXTCLOSEST_SITE },
177 { WBC_LOOKUP_DC_DS_6_REQUIRED,
178 DS_DIRECTORY_SERVICE_6_REQUIRED },
179 { WBC_LOOKUP_DC_RETURN_DNS_NAME,
180 DS_RETURN_DNS_NAME },
181 { WBC_LOOKUP_DC_RETURN_FLAT_NAME,
182 DS_RETURN_FLAT_NAME }
185 uint32_t ds_flags = 0;
186 size_t i = 0;
188 for (i=0; i<ARRAY_SIZE(lookup_dc_flags); i++) {
189 if (wbc_flags & lookup_dc_flags[i].wbc_dc_flag) {
190 ds_flags |= lookup_dc_flags[i].ds_dc_flags;
194 return ds_flags;