torture: do not reuse bindings between pipes
[idra/samba.git] / libcli / lsarpc / util_lsarpc.c
1 /*
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Sumit Bose 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/ndr_drsblobs.h"
22 #include "../librpc/gen_ndr/ndr_lsa.h"
23 #include "libcli/lsarpc/util_lsarpc.h"
24
25 static NTSTATUS ai_array_2_trust_domain_info_buffer(TALLOC_CTX *mem_ctx,
26                                 uint32_t count,
27                                 struct AuthenticationInformationArray *ai,
28                                 struct lsa_TrustDomainInfoBuffer **_b)
29 {
30         NTSTATUS status;
31         struct lsa_TrustDomainInfoBuffer *b;
32         int i;
33
34         b = talloc_array(mem_ctx, struct lsa_TrustDomainInfoBuffer, count);
35         if (b == NULL) {
36                 return NT_STATUS_NO_MEMORY;
37         }
38
39         for(i = 0; i < count; i++) {
40                 size_t size = 0;
41                 b[i].last_update_time = ai->array[i].LastUpdateTime;
42                 b[i].AuthType = ai->array[i].AuthType;
43                 switch(ai->array[i].AuthType) {
44                         case TRUST_AUTH_TYPE_NONE:
45                                 b[i].data.size = 0;
46                                 b[i].data.data = NULL;
47                                 break;
48                         case TRUST_AUTH_TYPE_NT4OWF:
49                                 if (ai->array[i].AuthInfo.nt4owf.size != 16) {
50                                         status = NT_STATUS_INVALID_PARAMETER;
51                                         goto fail;
52                                 }
53                                 b[i].data.data = (uint8_t *)talloc_memdup(b,
54                                     &ai->array[i].AuthInfo.nt4owf.password.hash,
55                                     16);
56                                 if (b[i].data.data == NULL) {
57                                         status = NT_STATUS_NO_MEMORY;
58                                         goto fail;
59                                 }
60                                 break;
61                         case TRUST_AUTH_TYPE_CLEAR:
62                                 if (!convert_string_talloc(b,
63                                                            CH_UTF16LE, CH_UNIX,
64                                                            ai->array[i].AuthInfo.clear.password,
65                                                            ai->array[i].AuthInfo.clear.size,
66                                                            &b[i].data.data,
67                                                            &size)) {
68                                         status = NT_STATUS_INVALID_PARAMETER;
69                                         goto fail;
70                                 }
71                                 b[i].data.size = size;
72                                 break;
73                         case TRUST_AUTH_TYPE_VERSION:
74                                 if (ai->array[i].AuthInfo.version.size != 4) {
75                                         status = NT_STATUS_INVALID_PARAMETER;
76                                         goto fail;
77                                 }
78                                 b[i].data.size = 4;
79                                 b[i].data.data = (uint8_t *)talloc_memdup(b,
80                                      &ai->array[i].AuthInfo.version.version, 4);
81                                 if (b[i].data.data == NULL) {
82                                         status = NT_STATUS_NO_MEMORY;
83                                         goto fail;
84                                 }
85                                 break;
86                         default:
87                                 status = NT_STATUS_INVALID_PARAMETER;
88                                 goto fail;
89                 }
90         }
91
92         *_b = b;
93
94         return NT_STATUS_OK;
95
96 fail:
97         talloc_free(b);
98         return status;
99 }
100
101 static NTSTATUS trustauth_inout_blob_2_auth_info(TALLOC_CTX *mem_ctx,
102                                     DATA_BLOB *inout_blob,
103                                     uint32_t *count,
104                                     struct lsa_TrustDomainInfoBuffer **current,
105                                     struct lsa_TrustDomainInfoBuffer **previous)
106 {
107         NTSTATUS status;
108         struct trustAuthInOutBlob iopw;
109         enum ndr_err_code ndr_err;
110         TALLOC_CTX *tmp_ctx;
111
112         tmp_ctx = talloc_new(mem_ctx);
113         if (tmp_ctx == NULL) {
114                 return NT_STATUS_NO_MEMORY;
115         }
116
117         ndr_err = ndr_pull_struct_blob(inout_blob, tmp_ctx, &iopw,
118                               (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
119         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
120                 status = NT_STATUS_INVALID_PARAMETER;
121                 goto done;
122         }
123
124         *count = iopw.count;
125
126         status = ai_array_2_trust_domain_info_buffer(mem_ctx, iopw.count,
127                                                       &iopw.current, current);
128         if (!NT_STATUS_IS_OK(status)) {
129                 goto done;
130         }
131
132         if (iopw.previous.count > 0) {
133                 status = ai_array_2_trust_domain_info_buffer(mem_ctx, iopw.count,
134                                                              &iopw.previous, previous);
135                 if (!NT_STATUS_IS_OK(status)) {
136                         goto done;
137                 }
138         } else {
139                 *previous = NULL;
140         }
141
142         status = NT_STATUS_OK;
143
144 done:
145         talloc_free(tmp_ctx);
146         return status;
147 }
148
149 NTSTATUS auth_blob_2_auth_info(TALLOC_CTX *mem_ctx,
150                                DATA_BLOB incoming, DATA_BLOB outgoing,
151                                struct lsa_TrustDomainInfoAuthInfo *auth_info)
152 {
153         NTSTATUS status;
154
155         if (incoming.length != 0) {
156                 status = trustauth_inout_blob_2_auth_info(mem_ctx,
157                                         &incoming,
158                                         &auth_info->incoming_count,
159                                         &auth_info->incoming_current_auth_info,
160                                         &auth_info->incoming_previous_auth_info);
161                 if (!NT_STATUS_IS_OK(status)) {
162                         return status;
163                 }
164         } else {
165                 auth_info->incoming_count = 0;
166                 auth_info->incoming_current_auth_info = NULL;
167                 auth_info->incoming_previous_auth_info = NULL;
168         }
169
170         if (outgoing.length != 0) {
171                 status = trustauth_inout_blob_2_auth_info(mem_ctx,
172                                         &outgoing,
173                                         &auth_info->outgoing_count,
174                                         &auth_info->outgoing_current_auth_info,
175                                         &auth_info->outgoing_previous_auth_info);
176                 if (!NT_STATUS_IS_OK(status)) {
177                         return status;
178                 }
179         } else {
180                 auth_info->outgoing_count = 0;
181                 auth_info->outgoing_current_auth_info = NULL;
182                 auth_info->outgoing_previous_auth_info = NULL;
183         }
184
185         return NT_STATUS_OK;
186 }
187
188 static NTSTATUS trust_domain_info_buffer_2_ai_array(TALLOC_CTX *mem_ctx,
189                                                     uint32_t count,
190                                                     struct lsa_TrustDomainInfoBuffer *b,
191                                                     struct AuthenticationInformationArray *ai)
192 {
193         NTSTATUS status;
194         int i;
195
196         ai->count = count;
197         ai->array = talloc_zero_array(mem_ctx, struct AuthenticationInformation,
198                                       count);
199         if (ai->array == NULL) {
200                 return NT_STATUS_NO_MEMORY;
201         }
202
203         for(i = 0; i < count; i++) {
204                 size_t size = 0;
205                 ai->array[i].LastUpdateTime = b[i].last_update_time;
206                 ai->array[i].AuthType = b[i].AuthType;
207                 switch(ai->array[i].AuthType) {
208                         case TRUST_AUTH_TYPE_NONE:
209                                 ai->array[i].AuthInfo.none.size = 0;
210                                 break;
211                         case TRUST_AUTH_TYPE_NT4OWF:
212                                 if (b[i].data.size != 16) {
213                                         status = NT_STATUS_INVALID_PARAMETER;
214                                         goto fail;
215                                 }
216                                 memcpy(&ai->array[i].AuthInfo.nt4owf.password.hash,
217                                        b[i].data.data, 16);
218                                 break;
219                         case TRUST_AUTH_TYPE_CLEAR:
220                                 if (!convert_string_talloc(ai->array,
221                                                            CH_UNIX, CH_UTF16,
222                                                            b[i].data.data,
223                                                            b[i].data.size,
224                                                            &ai->array[i].AuthInfo.clear.password,
225                                                            &size)) {
226                                         status = NT_STATUS_INVALID_PARAMETER;
227                                         goto fail;
228                                 }
229                                 ai->array[i].AuthInfo.clear.size = size;
230                                 break;
231                         case TRUST_AUTH_TYPE_VERSION:
232                                 if (b[i].data.size != 4) {
233                                         status = NT_STATUS_INVALID_PARAMETER;
234                                         goto fail;
235                                 }
236                                 ai->array[i].AuthInfo.version.size = 4;
237                                 memcpy(&ai->array[i].AuthInfo.version.version,
238                                        b[i].data.data, 4);
239                                 break;
240                         default:
241                                 status = NT_STATUS_INVALID_PARAMETER;
242                                 goto fail;
243                 }
244         }
245
246         return NT_STATUS_OK;
247
248 fail:
249         talloc_free(ai->array);
250         return status;
251 }
252
253 NTSTATUS auth_info_2_trustauth_inout(TALLOC_CTX *mem_ctx,
254                                      uint32_t count,
255                                      struct lsa_TrustDomainInfoBuffer *current,
256                                      struct lsa_TrustDomainInfoBuffer *previous,
257                                      struct trustAuthInOutBlob **iopw_out)
258 {
259         NTSTATUS status;
260         struct trustAuthInOutBlob *iopw;
261         enum ndr_err_code ndr_err;
262
263         iopw = talloc_zero(mem_ctx, struct trustAuthInOutBlob);
264         if (iopw == NULL) {
265                 return NT_STATUS_NO_MEMORY;
266         }
267
268         iopw->count = count;
269         status = trust_domain_info_buffer_2_ai_array(iopw, count, current,
270                                                      &iopw->current);
271         if (!NT_STATUS_IS_OK(status)) {
272                 goto done;
273         }
274
275         if (previous != NULL) {
276                 status = trust_domain_info_buffer_2_ai_array(iopw, count,
277                                                              previous,
278                                                              &iopw->previous);
279                 if (!NT_STATUS_IS_OK(status)) {
280                         goto done;
281                 }
282         } else {
283                 iopw->previous.count = 0;
284                 iopw->previous.array = NULL;
285         }
286
287         *iopw_out = iopw;
288
289         status = NT_STATUS_OK;
290
291 done:
292         return status;
293 }
294
295 static NTSTATUS auth_info_2_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
296                                      uint32_t count,
297                                      struct lsa_TrustDomainInfoBuffer *current,
298                                      struct lsa_TrustDomainInfoBuffer *previous,
299                                      DATA_BLOB *inout_blob)
300 {
301         NTSTATUS status;
302         struct trustAuthInOutBlob *iopw = NULL;
303         enum ndr_err_code ndr_err;
304
305         status = auth_info_2_trustauth_inout(mem_ctx, count, current, previous, &iopw);
306
307         if (!NT_STATUS_IS_OK(status)) {
308                 goto done;
309         }
310
311         ndr_err = ndr_push_struct_blob(inout_blob, mem_ctx,
312                               iopw,
313                               (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
314         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
315                 return NT_STATUS_INVALID_PARAMETER;
316         }
317
318         status = NT_STATUS_OK;
319
320 done:
321         talloc_free(iopw);
322         return status;
323 }
324
325 NTSTATUS auth_info_2_auth_blob(TALLOC_CTX *mem_ctx,
326                                struct lsa_TrustDomainInfoAuthInfo *auth_info,
327                                DATA_BLOB *incoming, DATA_BLOB *outgoing)
328 {
329         NTSTATUS status;
330
331         if (auth_info->incoming_count == 0) {
332                 incoming->length = 0;
333                 incoming->data = NULL;
334         } else {
335                 status = auth_info_2_trustauth_inout_blob(mem_ctx,
336                                          auth_info->incoming_count,
337                                          auth_info->incoming_current_auth_info,
338                                          auth_info->incoming_previous_auth_info,
339                                          incoming);
340                 if (!NT_STATUS_IS_OK(status)) {
341                         return status;
342                 }
343         }
344
345         if (auth_info->outgoing_count == 0) {
346                 outgoing->length = 0;
347                 outgoing->data = NULL;
348         } else {
349                 status = auth_info_2_trustauth_inout_blob(mem_ctx,
350                                          auth_info->outgoing_count,
351                                          auth_info->outgoing_current_auth_info,
352                                          auth_info->outgoing_previous_auth_info,
353                                          outgoing);
354                 if (!NT_STATUS_IS_OK(status)) {
355                         return status;
356                 }
357         }
358
359         return NT_STATUS_OK;
360 }