Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Authentication utility functions
4 : Copyright (C) Volker Lendecke 2010
5 :
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.
10 :
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.
15 :
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/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "../librpc/gen_ndr/netlogon.h"
22 : #include "../libcli/security/security.h"
23 : #include "rpc_client/util_netlogon.h"
24 :
25 : #define COPY_LSA_STRING(mem_ctx, in, out, name) do { \
26 : if (in->name.string) { \
27 : out->name.string = talloc_strdup(mem_ctx, in->name.string); \
28 : NT_STATUS_HAVE_NO_MEMORY(out->name.string); \
29 : } \
30 : } while (0)
31 :
32 8422 : NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
33 : const struct netr_SamBaseInfo *in,
34 : struct netr_SamBaseInfo *out)
35 : {
36 : /* first copy all, then realloc pointers */
37 8422 : *out = *in;
38 :
39 8422 : COPY_LSA_STRING(mem_ctx, in, out, account_name);
40 8422 : COPY_LSA_STRING(mem_ctx, in, out, full_name);
41 8422 : COPY_LSA_STRING(mem_ctx, in, out, logon_script);
42 8422 : COPY_LSA_STRING(mem_ctx, in, out, profile_path);
43 8422 : COPY_LSA_STRING(mem_ctx, in, out, home_directory);
44 8422 : COPY_LSA_STRING(mem_ctx, in, out, home_drive);
45 :
46 8422 : if (in->groups.count) {
47 6376 : out->groups.rids = (struct samr_RidWithAttribute *)
48 6376 : talloc_memdup(mem_ctx, in->groups.rids,
49 : (sizeof(struct samr_RidWithAttribute) *
50 : in->groups.count));
51 6376 : NT_STATUS_HAVE_NO_MEMORY(out->groups.rids);
52 : }
53 :
54 8422 : COPY_LSA_STRING(mem_ctx, in, out, logon_server);
55 8422 : COPY_LSA_STRING(mem_ctx, in, out, logon_domain);
56 :
57 8422 : if (in->domain_sid) {
58 8422 : out->domain_sid = dom_sid_dup(mem_ctx, in->domain_sid);
59 8422 : NT_STATUS_HAVE_NO_MEMORY(out->domain_sid);
60 : }
61 :
62 8422 : return NT_STATUS_OK;
63 : }
64 :
65 4043 : NTSTATUS copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
66 : const struct netr_SamInfo3 *in,
67 : struct netr_SamInfo3 **pout)
68 : {
69 4043 : struct netr_SamInfo3 *info3 = NULL;
70 0 : unsigned int i;
71 0 : NTSTATUS status;
72 :
73 4043 : info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
74 4043 : if (info3 == NULL) {
75 0 : status = NT_STATUS_NO_MEMORY;
76 0 : goto out;
77 : }
78 :
79 4043 : status = copy_netr_SamBaseInfo(info3, &in->base, &info3->base);
80 4043 : if (!NT_STATUS_IS_OK(status)) {
81 0 : goto out;
82 : }
83 :
84 4043 : if (in->sidcount) {
85 1799 : info3->sidcount = in->sidcount;
86 1799 : info3->sids = talloc_array(info3, struct netr_SidAttr,
87 : in->sidcount);
88 1799 : if (info3->sids == NULL) {
89 0 : status = NT_STATUS_NO_MEMORY;
90 0 : goto out;
91 : }
92 :
93 5384 : for (i = 0; i < in->sidcount; i++) {
94 7170 : info3->sids[i].sid = dom_sid_dup(info3->sids,
95 3585 : in->sids[i].sid);
96 3585 : if (info3->sids[i].sid == NULL) {
97 0 : status = NT_STATUS_NO_MEMORY;
98 0 : goto out;
99 : }
100 3585 : info3->sids[i].attributes = in->sids[i].attributes;
101 : }
102 : }
103 :
104 4043 : *pout = info3;
105 4043 : info3 = NULL;
106 :
107 4043 : status = NT_STATUS_OK;
108 4043 : out:
109 4043 : TALLOC_FREE(info3);
110 4043 : return status;
111 : }
112 :
113 3957 : NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
114 : uint16_t validation_level,
115 : union netr_Validation *validation,
116 : struct netr_SamInfo3 **info3_p)
117 : {
118 3957 : struct netr_SamInfo3 *info3 = NULL;
119 3957 : struct netr_SamInfo6 *info6 = NULL;
120 0 : NTSTATUS status;
121 :
122 3957 : if (validation == NULL) {
123 0 : return NT_STATUS_INVALID_PARAMETER;
124 : }
125 :
126 3957 : switch (validation_level) {
127 446 : case 3:
128 446 : if (validation->sam3 == NULL) {
129 0 : return NT_STATUS_INVALID_PARAMETER;
130 : }
131 :
132 446 : status = copy_netr_SamInfo3(mem_ctx,
133 446 : validation->sam3,
134 : &info3);
135 446 : if (!NT_STATUS_IS_OK(status)) {
136 0 : return status;
137 : }
138 :
139 446 : break;
140 3511 : case 6:
141 3511 : if (validation->sam6 == NULL) {
142 0 : return NT_STATUS_INVALID_PARAMETER;
143 : }
144 3511 : info6 = validation->sam6;
145 :
146 3511 : info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
147 3511 : if (info3 == NULL) {
148 0 : return NT_STATUS_NO_MEMORY;
149 : }
150 :
151 3511 : status = copy_netr_SamBaseInfo(info3,
152 3511 : &info6->base,
153 3511 : &info3->base);
154 3511 : if (!NT_STATUS_IS_OK(status)) {
155 0 : TALLOC_FREE(info3);
156 0 : return status;
157 : }
158 :
159 3511 : if (validation->sam6->sidcount > 0) {
160 0 : int i;
161 :
162 3039 : info3->sidcount = info6->sidcount;
163 :
164 3039 : info3->sids = talloc_array(info3,
165 : struct netr_SidAttr,
166 : info3->sidcount);
167 3039 : if (info3->sids == NULL) {
168 0 : TALLOC_FREE(info3);
169 0 : return NT_STATUS_NO_MEMORY;
170 : }
171 :
172 10484 : for (i = 0; i < info3->sidcount; i++) {
173 14890 : info3->sids[i].sid = dom_sid_dup(
174 7445 : info3->sids, info6->sids[i].sid);
175 7445 : if (info3->sids[i].sid == NULL) {
176 0 : TALLOC_FREE(info3);
177 0 : return NT_STATUS_NO_MEMORY;
178 : }
179 7445 : info3->sids[i].attributes =
180 7445 : info6->sids[i].attributes;
181 : }
182 : }
183 3511 : break;
184 0 : default:
185 0 : return NT_STATUS_BAD_VALIDATION_CLASS;
186 : }
187 :
188 3957 : *info3_p = info3;
189 :
190 3957 : return NT_STATUS_OK;
191 : }
192 :
193 868 : NTSTATUS copy_netr_SamInfo6(TALLOC_CTX *mem_ctx,
194 : const struct netr_SamInfo6 *in,
195 : struct netr_SamInfo6 **pout)
196 : {
197 868 : struct netr_SamInfo6 *info6 = NULL;
198 0 : unsigned int i;
199 0 : NTSTATUS status;
200 :
201 868 : info6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
202 868 : if (info6 == NULL) {
203 0 : status = NT_STATUS_NO_MEMORY;
204 0 : goto out;
205 : }
206 :
207 868 : status = copy_netr_SamBaseInfo(info6, &in->base, &info6->base);
208 868 : if (!NT_STATUS_IS_OK(status)) {
209 0 : goto out;
210 : }
211 :
212 868 : if (in->sidcount) {
213 744 : info6->sidcount = in->sidcount;
214 744 : info6->sids = talloc_array(info6, struct netr_SidAttr,
215 : in->sidcount);
216 744 : if (info6->sids == NULL) {
217 0 : status = NT_STATUS_NO_MEMORY;
218 0 : goto out;
219 : }
220 :
221 2910 : for (i = 0; i < in->sidcount; i++) {
222 4332 : info6->sids[i].sid = dom_sid_dup(info6->sids,
223 2166 : in->sids[i].sid);
224 2166 : if (info6->sids[i].sid == NULL) {
225 0 : status = NT_STATUS_NO_MEMORY;
226 0 : goto out;
227 : }
228 2166 : info6->sids[i].attributes = in->sids[i].attributes;
229 : }
230 : }
231 :
232 868 : if (in->dns_domainname.string != NULL) {
233 1488 : info6->dns_domainname.string = talloc_strdup(info6,
234 744 : in->dns_domainname.string);
235 744 : if (info6->dns_domainname.string == NULL) {
236 0 : status = NT_STATUS_NO_MEMORY;
237 0 : goto out;
238 : }
239 : }
240 :
241 868 : if (in->principal_name.string != NULL) {
242 1488 : info6->principal_name.string = talloc_strdup(info6,
243 744 : in->principal_name.string);
244 744 : if (info6->principal_name.string == NULL) {
245 0 : status = NT_STATUS_NO_MEMORY;
246 0 : goto out;
247 : }
248 : }
249 :
250 868 : *pout = info6;
251 868 : info6 = NULL;
252 :
253 868 : status = NT_STATUS_OK;
254 868 : out:
255 868 : TALLOC_FREE(info6);
256 868 : return status;
257 : }
258 :
259 0 : NTSTATUS map_validation_to_info6(TALLOC_CTX *mem_ctx,
260 : uint16_t validation_level,
261 : union netr_Validation *validation,
262 : struct netr_SamInfo6 **info6_p)
263 : {
264 0 : struct netr_SamInfo3 *info3 = NULL;
265 0 : struct netr_SamInfo6 *info6 = NULL;
266 0 : NTSTATUS status;
267 :
268 0 : if (validation == NULL) {
269 0 : return NT_STATUS_INVALID_PARAMETER;
270 : }
271 :
272 0 : switch (validation_level) {
273 0 : case 3:
274 0 : if (validation->sam3 == NULL) {
275 0 : return NT_STATUS_INVALID_PARAMETER;
276 : }
277 0 : info3 = validation->sam3;
278 :
279 0 : info6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
280 0 : if (info6 == NULL) {
281 0 : return NT_STATUS_NO_MEMORY;
282 : }
283 :
284 0 : status = copy_netr_SamBaseInfo(info6,
285 0 : &info3->base,
286 0 : &info6->base);
287 0 : if (!NT_STATUS_IS_OK(status)) {
288 0 : TALLOC_FREE(info6);
289 0 : return status;
290 : }
291 :
292 0 : if (validation->sam3->sidcount > 0) {
293 0 : int i;
294 :
295 0 : info6->sidcount = info3->sidcount;
296 :
297 0 : info6->sids = talloc_array(info6,
298 : struct netr_SidAttr,
299 : info6->sidcount);
300 0 : if (info6->sids == NULL) {
301 0 : TALLOC_FREE(info6);
302 0 : return NT_STATUS_NO_MEMORY;
303 : }
304 :
305 0 : for (i = 0; i < info6->sidcount; i++) {
306 0 : info6->sids[i].sid = dom_sid_dup(
307 0 : info6->sids, info3->sids[i].sid);
308 0 : if (info6->sids[i].sid == NULL) {
309 0 : TALLOC_FREE(info6);
310 0 : return NT_STATUS_NO_MEMORY;
311 : }
312 0 : info6->sids[i].attributes =
313 0 : info3->sids[i].attributes;
314 : }
315 : }
316 0 : break;
317 0 : case 6:
318 0 : if (validation->sam6 == NULL) {
319 0 : return NT_STATUS_INVALID_PARAMETER;
320 : }
321 :
322 0 : status = copy_netr_SamInfo6(mem_ctx,
323 0 : validation->sam6,
324 : &info6);
325 0 : if (!NT_STATUS_IS_OK(status)) {
326 0 : return status;
327 : }
328 :
329 0 : break;
330 0 : default:
331 0 : return NT_STATUS_BAD_VALIDATION_CLASS;
332 : }
333 :
334 0 : *info6_p = info6;
335 :
336 0 : return NT_STATUS_OK;
337 : }
338 :
339 0 : NTSTATUS map_info3_to_validation(TALLOC_CTX *mem_ctx,
340 : struct netr_SamInfo3 *info3,
341 : uint16_t *_validation_level,
342 : union netr_Validation **_validation)
343 : {
344 0 : union netr_Validation *validation = NULL;
345 0 : NTSTATUS status;
346 :
347 0 : validation = talloc_zero(mem_ctx, union netr_Validation);
348 0 : if (validation == NULL) {
349 0 : return NT_STATUS_NO_MEMORY;
350 : }
351 :
352 0 : status = copy_netr_SamInfo3(mem_ctx,
353 : info3,
354 : &validation->sam3);
355 0 : if (!NT_STATUS_IS_OK(status)) {
356 0 : TALLOC_FREE(validation);
357 0 : return status;
358 : }
359 :
360 0 : * _validation_level = 3;
361 0 : *_validation = validation;
362 0 : return NT_STATUS_OK;
363 : }
364 :
365 868 : NTSTATUS map_info6_to_validation(TALLOC_CTX *mem_ctx,
366 : const struct netr_SamInfo6 *info6,
367 : uint16_t *_validation_level,
368 : union netr_Validation **_validation)
369 : {
370 868 : union netr_Validation *validation = NULL;
371 0 : NTSTATUS status;
372 :
373 868 : validation = talloc_zero(mem_ctx, union netr_Validation);
374 868 : if (validation == NULL) {
375 0 : return NT_STATUS_NO_MEMORY;
376 : }
377 :
378 868 : status = copy_netr_SamInfo6(validation,
379 : info6,
380 : &validation->sam6);
381 868 : if (!NT_STATUS_IS_OK(status)) {
382 0 : TALLOC_FREE(validation);
383 0 : return status;
384 : }
385 :
386 868 : * _validation_level = 6;
387 868 : *_validation = validation;
388 868 : return NT_STATUS_OK;
389 : }
390 :
391 : /****************************************************************
392 : ****************************************************************/
393 :
394 18 : NTSTATUS copy_netr_DsRGetDCNameInfo(TALLOC_CTX *mem_ctx,
395 : const struct netr_DsRGetDCNameInfo *in,
396 : struct netr_DsRGetDCNameInfo **pout)
397 : {
398 0 : struct netr_DsRGetDCNameInfo *r;
399 :
400 18 : r = talloc_zero(mem_ctx, struct netr_DsRGetDCNameInfo);
401 18 : if (r == NULL) {
402 0 : return NT_STATUS_NO_MEMORY;
403 : }
404 :
405 18 : r->dc_unc = talloc_strdup(r, in->dc_unc);
406 18 : if (r->dc_unc == NULL) {
407 0 : talloc_free(r);
408 0 : return NT_STATUS_NO_MEMORY;
409 : }
410 18 : r->dc_address = talloc_strdup(r, in->dc_address);
411 18 : if (r->dc_address == NULL) {
412 0 : talloc_free(r);
413 0 : return NT_STATUS_NO_MEMORY;
414 : }
415 18 : r->dc_address_type = in->dc_address_type;
416 18 : r->domain_guid = in->domain_guid;
417 18 : r->domain_name = talloc_strdup(r, in->domain_name);
418 18 : if (r->domain_name == NULL) {
419 0 : talloc_free(r);
420 0 : return NT_STATUS_NO_MEMORY;
421 : }
422 : /* forest could be empty */
423 18 : if (in->forest_name != NULL) {
424 18 : r->forest_name = talloc_strdup(r, in->forest_name);
425 18 : if (r->forest_name == NULL) {
426 0 : talloc_free(r);
427 0 : return NT_STATUS_NO_MEMORY;
428 : }
429 : }
430 18 : r->dc_flags = in->dc_flags;
431 18 : if (in->dc_site_name != NULL) {
432 12 : r->dc_site_name = talloc_strdup(r, in->dc_site_name);
433 12 : if (r->dc_site_name == NULL) {
434 0 : talloc_free(r);
435 0 : return NT_STATUS_NO_MEMORY;
436 : }
437 : }
438 18 : if (in->client_site_name != NULL) {
439 12 : r->client_site_name = talloc_strdup(r, in->client_site_name);
440 12 : if (r->client_site_name == NULL) {
441 0 : talloc_free(r);
442 0 : return NT_STATUS_NO_MEMORY;
443 : }
444 : }
445 :
446 18 : *pout = r;
447 :
448 18 : return NT_STATUS_OK;
449 : }
|