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