Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * NetApi LocalGroup Support
4 : * Copyright (C) Guenther Deschner 2008
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 :
22 : #include "librpc/gen_ndr/libnetapi.h"
23 : #include "lib/netapi/netapi.h"
24 : #include "lib/netapi/netapi_private.h"
25 : #include "lib/netapi/libnetapi.h"
26 : #include "rpc_client/rpc_client.h"
27 : #include "../librpc/gen_ndr/ndr_samr_c.h"
28 : #include "../librpc/gen_ndr/ndr_lsa_c.h"
29 : #include "rpc_client/cli_lsarpc.h"
30 : #include "rpc_client/init_lsa.h"
31 : #include "../libcli/security/security.h"
32 :
33 0 : static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
34 : struct rpc_pipe_client *pipe_cli,
35 : struct policy_handle *domain_handle,
36 : const char *group_name,
37 : uint32_t access_rights,
38 : struct policy_handle *alias_handle)
39 : {
40 0 : NTSTATUS status, result;
41 :
42 0 : struct lsa_String lsa_account_name;
43 0 : struct samr_Ids user_rids, name_types;
44 0 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
45 :
46 0 : init_lsa_String(&lsa_account_name, group_name);
47 :
48 0 : status = dcerpc_samr_LookupNames(b, mem_ctx,
49 : domain_handle,
50 : 1,
51 : &lsa_account_name,
52 : &user_rids,
53 : &name_types,
54 : &result);
55 0 : if (any_nt_status_not_ok(status, result, &status)) {
56 0 : return status;
57 : }
58 0 : if (user_rids.count != 1) {
59 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
60 : }
61 0 : if (name_types.count != 1) {
62 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
63 : }
64 :
65 0 : switch (name_types.ids[0]) {
66 0 : case SID_NAME_ALIAS:
67 : case SID_NAME_WKN_GRP:
68 0 : break;
69 0 : default:
70 0 : return NT_STATUS_INVALID_SID;
71 : }
72 :
73 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
74 : domain_handle,
75 : access_rights,
76 0 : user_rids.ids[0],
77 : alias_handle,
78 : &result);
79 0 : if (!NT_STATUS_IS_OK(status)) {
80 0 : return status;
81 : }
82 :
83 0 : return result;
84 : }
85 :
86 : /****************************************************************
87 : ****************************************************************/
88 :
89 0 : static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
90 : struct rpc_pipe_client *pipe_cli,
91 : struct policy_handle *handle,
92 : uint32_t rid,
93 : uint32_t access_rights,
94 : enum samr_AliasInfoEnum level,
95 : union samr_AliasInfo **alias_info)
96 : {
97 0 : NTSTATUS status, result;
98 0 : struct policy_handle alias_handle;
99 0 : union samr_AliasInfo *_alias_info = NULL;
100 0 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
101 :
102 0 : ZERO_STRUCT(alias_handle);
103 :
104 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
105 : handle,
106 : access_rights,
107 : rid,
108 : &alias_handle,
109 : &result);
110 0 : if (any_nt_status_not_ok(status, result, &status)) {
111 0 : goto done;
112 : }
113 :
114 0 : status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
115 : &alias_handle,
116 : level,
117 : &_alias_info,
118 : &result);
119 0 : if (any_nt_status_not_ok(status, result, &status)) {
120 0 : goto done;
121 : }
122 :
123 0 : *alias_info = _alias_info;
124 :
125 0 : done:
126 0 : if (is_valid_policy_hnd(&alias_handle)) {
127 0 : dcerpc_samr_Close(b, mem_ctx, &alias_handle, &result);
128 : }
129 :
130 0 : return status;
131 : }
132 :
133 : /****************************************************************
134 : ****************************************************************/
135 :
136 0 : WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
137 : struct NetLocalGroupAdd *r)
138 : {
139 0 : struct rpc_pipe_client *pipe_cli = NULL;
140 0 : NTSTATUS status, result;
141 0 : WERROR werr;
142 0 : struct lsa_String lsa_account_name;
143 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
144 0 : struct dom_sid2 *domain_sid = NULL;
145 0 : uint32_t rid;
146 0 : struct dcerpc_binding_handle *b = NULL;
147 :
148 0 : struct LOCALGROUP_INFO_0 *info0 = NULL;
149 0 : struct LOCALGROUP_INFO_1 *info1 = NULL;
150 :
151 0 : const char *alias_name = NULL;
152 :
153 0 : if (!r->in.buffer) {
154 0 : return WERR_INVALID_PARAMETER;
155 : }
156 :
157 0 : ZERO_STRUCT(connect_handle);
158 0 : ZERO_STRUCT(builtin_handle);
159 0 : ZERO_STRUCT(domain_handle);
160 0 : ZERO_STRUCT(alias_handle);
161 :
162 0 : switch (r->in.level) {
163 0 : case 0:
164 0 : info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
165 0 : alias_name = info0->lgrpi0_name;
166 0 : break;
167 0 : case 1:
168 0 : info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
169 0 : alias_name = info1->lgrpi1_name;
170 0 : break;
171 0 : default:
172 0 : werr = WERR_INVALID_LEVEL;
173 0 : goto done;
174 : }
175 :
176 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
177 : &ndr_table_samr,
178 : &pipe_cli);
179 0 : if (!W_ERROR_IS_OK(werr)) {
180 0 : goto done;
181 : }
182 :
183 0 : b = pipe_cli->binding_handle;
184 :
185 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
186 : SAMR_ACCESS_LOOKUP_DOMAIN |
187 : SAMR_ACCESS_ENUM_DOMAINS,
188 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
189 : &connect_handle,
190 : &builtin_handle);
191 0 : if (!W_ERROR_IS_OK(werr)) {
192 0 : goto done;
193 : }
194 :
195 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
196 : &builtin_handle,
197 : alias_name,
198 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
199 : &alias_handle);
200 0 : if (ctx->disable_policy_handle_cache) {
201 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
202 : }
203 :
204 0 : if (NT_STATUS_IS_OK(status)) {
205 0 : werr = WERR_ALIAS_EXISTS;
206 0 : goto done;
207 : }
208 :
209 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
210 : SAMR_ACCESS_ENUM_DOMAINS |
211 : SAMR_ACCESS_LOOKUP_DOMAIN,
212 : SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
213 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
214 : &connect_handle,
215 : &domain_handle,
216 : &domain_sid);
217 0 : if (!W_ERROR_IS_OK(werr)) {
218 0 : goto done;
219 : }
220 :
221 0 : init_lsa_String(&lsa_account_name, alias_name);
222 :
223 0 : status = dcerpc_samr_CreateDomAlias(b, talloc_tos(),
224 : &domain_handle,
225 : &lsa_account_name,
226 : SEC_STD_DELETE |
227 : SAMR_ALIAS_ACCESS_SET_INFO,
228 : &alias_handle,
229 : &rid,
230 : &result);
231 0 : if (any_nt_status_not_ok(status, result, &status)) {
232 0 : werr = ntstatus_to_werror(status);
233 0 : goto done;
234 : }
235 :
236 0 : if (r->in.level == 1 && info1->lgrpi1_comment) {
237 :
238 0 : union samr_AliasInfo alias_info;
239 :
240 0 : init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
241 :
242 0 : status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
243 : &alias_handle,
244 : ALIASINFODESCRIPTION,
245 : &alias_info,
246 : &result);
247 0 : if (any_nt_status_not_ok(status, result, &status)) {
248 0 : werr = ntstatus_to_werror(status);
249 0 : goto done;
250 : }
251 : }
252 :
253 0 : werr = WERR_OK;
254 :
255 0 : done:
256 0 : if (is_valid_policy_hnd(&alias_handle)) {
257 0 : dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
258 : }
259 :
260 0 : if (ctx->disable_policy_handle_cache) {
261 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
262 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
263 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
264 : }
265 :
266 0 : return werr;
267 : }
268 :
269 : /****************************************************************
270 : ****************************************************************/
271 :
272 0 : WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
273 : struct NetLocalGroupAdd *r)
274 : {
275 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
276 : }
277 :
278 : /****************************************************************
279 : ****************************************************************/
280 :
281 :
282 0 : WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
283 : struct NetLocalGroupDel *r)
284 : {
285 0 : struct rpc_pipe_client *pipe_cli = NULL;
286 0 : NTSTATUS status, result;
287 0 : WERROR werr;
288 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
289 0 : struct dom_sid2 *domain_sid = NULL;
290 0 : struct dcerpc_binding_handle *b = NULL;
291 :
292 0 : if (!r->in.group_name) {
293 0 : return WERR_INVALID_PARAMETER;
294 : }
295 :
296 0 : ZERO_STRUCT(connect_handle);
297 0 : ZERO_STRUCT(builtin_handle);
298 0 : ZERO_STRUCT(domain_handle);
299 0 : ZERO_STRUCT(alias_handle);
300 :
301 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
302 : &ndr_table_samr,
303 : &pipe_cli);
304 0 : if (!W_ERROR_IS_OK(werr)) {
305 0 : goto done;
306 : }
307 :
308 0 : b = pipe_cli->binding_handle;
309 :
310 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
311 : SAMR_ACCESS_LOOKUP_DOMAIN |
312 : SAMR_ACCESS_ENUM_DOMAINS,
313 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
314 : &connect_handle,
315 : &builtin_handle);
316 0 : if (!W_ERROR_IS_OK(werr)) {
317 0 : goto done;
318 : }
319 :
320 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
321 : &builtin_handle,
322 : r->in.group_name,
323 : SEC_STD_DELETE,
324 : &alias_handle);
325 :
326 0 : if (ctx->disable_policy_handle_cache) {
327 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
328 : }
329 :
330 0 : if (NT_STATUS_IS_OK(status)) {
331 0 : goto delete_alias;
332 : }
333 :
334 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
335 : SAMR_ACCESS_ENUM_DOMAINS |
336 : SAMR_ACCESS_LOOKUP_DOMAIN,
337 : SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
338 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
339 : &connect_handle,
340 : &domain_handle,
341 : &domain_sid);
342 0 : if (!W_ERROR_IS_OK(werr)) {
343 0 : goto done;
344 : }
345 :
346 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
347 : &domain_handle,
348 : r->in.group_name,
349 : SEC_STD_DELETE,
350 : &alias_handle);
351 :
352 0 : if (ctx->disable_policy_handle_cache) {
353 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
354 : }
355 :
356 0 : if (!NT_STATUS_IS_OK(status)) {
357 0 : werr = ntstatus_to_werror(status);
358 0 : goto done;
359 : }
360 :
361 :
362 0 : delete_alias:
363 0 : status = dcerpc_samr_DeleteDomAlias(b, talloc_tos(),
364 : &alias_handle,
365 : &result);
366 0 : if (any_nt_status_not_ok(status, result, &status)) {
367 0 : werr = ntstatus_to_werror(status);
368 0 : goto done;
369 : }
370 :
371 0 : ZERO_STRUCT(alias_handle);
372 :
373 0 : werr = WERR_OK;
374 :
375 0 : done:
376 0 : if (is_valid_policy_hnd(&alias_handle)) {
377 0 : dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
378 : }
379 :
380 0 : if (ctx->disable_policy_handle_cache) {
381 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
382 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
383 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
384 : }
385 :
386 0 : return werr;
387 : }
388 :
389 : /****************************************************************
390 : ****************************************************************/
391 :
392 0 : WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
393 : struct NetLocalGroupDel *r)
394 : {
395 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
396 : }
397 :
398 : /****************************************************************
399 : ****************************************************************/
400 :
401 0 : static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
402 : const char *alias_name,
403 : struct samr_AliasInfoAll *info,
404 : uint32_t level,
405 : uint32_t *entries_read,
406 : uint8_t **buffer)
407 : {
408 0 : struct LOCALGROUP_INFO_0 g0;
409 0 : struct LOCALGROUP_INFO_1 g1;
410 0 : struct LOCALGROUP_INFO_1002 g1002;
411 :
412 0 : switch (level) {
413 0 : case 0:
414 0 : g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
415 0 : W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
416 :
417 0 : ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
418 : (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
419 :
420 0 : break;
421 0 : case 1:
422 0 : g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
423 0 : g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
424 0 : W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
425 :
426 0 : ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
427 : (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
428 :
429 0 : break;
430 0 : case 1002:
431 0 : g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
432 :
433 0 : ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
434 : (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
435 :
436 0 : break;
437 0 : default:
438 0 : return WERR_INVALID_LEVEL;
439 : }
440 :
441 0 : return WERR_OK;
442 : }
443 :
444 : /****************************************************************
445 : ****************************************************************/
446 :
447 0 : WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
448 : struct NetLocalGroupGetInfo *r)
449 : {
450 0 : struct rpc_pipe_client *pipe_cli = NULL;
451 0 : NTSTATUS status, result;
452 0 : WERROR werr;
453 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
454 0 : struct dom_sid2 *domain_sid = NULL;
455 0 : union samr_AliasInfo *alias_info = NULL;
456 0 : uint32_t entries_read = 0;
457 0 : struct dcerpc_binding_handle *b = NULL;
458 :
459 0 : if (!r->in.group_name) {
460 0 : return WERR_INVALID_PARAMETER;
461 : }
462 :
463 0 : switch (r->in.level) {
464 0 : case 0:
465 : case 1:
466 : case 1002:
467 0 : break;
468 0 : default:
469 0 : return WERR_INVALID_LEVEL;
470 : }
471 :
472 0 : ZERO_STRUCT(connect_handle);
473 0 : ZERO_STRUCT(builtin_handle);
474 0 : ZERO_STRUCT(domain_handle);
475 0 : ZERO_STRUCT(alias_handle);
476 :
477 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
478 : &ndr_table_samr,
479 : &pipe_cli);
480 0 : if (!W_ERROR_IS_OK(werr)) {
481 0 : goto done;
482 : }
483 :
484 0 : b = pipe_cli->binding_handle;
485 :
486 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
487 : SAMR_ACCESS_LOOKUP_DOMAIN |
488 : SAMR_ACCESS_ENUM_DOMAINS,
489 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
490 : &connect_handle,
491 : &builtin_handle);
492 0 : if (!W_ERROR_IS_OK(werr)) {
493 0 : goto done;
494 : }
495 :
496 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
497 : &builtin_handle,
498 : r->in.group_name,
499 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
500 : &alias_handle);
501 :
502 0 : if (ctx->disable_policy_handle_cache) {
503 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
504 : }
505 :
506 0 : if (NT_STATUS_IS_OK(status)) {
507 0 : goto query_alias;
508 : }
509 :
510 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
511 : SAMR_ACCESS_ENUM_DOMAINS |
512 : SAMR_ACCESS_LOOKUP_DOMAIN,
513 : SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
514 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
515 : &connect_handle,
516 : &domain_handle,
517 : &domain_sid);
518 0 : if (!W_ERROR_IS_OK(werr)) {
519 0 : goto done;
520 : }
521 :
522 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
523 : &domain_handle,
524 : r->in.group_name,
525 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
526 : &alias_handle);
527 :
528 0 : if (ctx->disable_policy_handle_cache) {
529 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
530 : }
531 :
532 0 : if (!NT_STATUS_IS_OK(status)) {
533 0 : werr = ntstatus_to_werror(status);
534 0 : goto done;
535 : }
536 :
537 0 : query_alias:
538 0 : status = dcerpc_samr_QueryAliasInfo(b, talloc_tos(),
539 : &alias_handle,
540 : ALIASINFOALL,
541 : &alias_info,
542 : &result);
543 0 : if (any_nt_status_not_ok(status, result, &status)) {
544 0 : werr = ntstatus_to_werror(status);
545 0 : goto done;
546 : }
547 :
548 0 : werr = map_alias_info_to_buffer(ctx,
549 : r->in.group_name,
550 0 : &alias_info->all,
551 : r->in.level, &entries_read,
552 : r->out.buffer);
553 :
554 0 : done:
555 0 : if (is_valid_policy_hnd(&alias_handle)) {
556 0 : dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
557 : }
558 :
559 0 : if (ctx->disable_policy_handle_cache) {
560 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
561 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
562 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
563 : }
564 :
565 0 : return werr;
566 : }
567 :
568 : /****************************************************************
569 : ****************************************************************/
570 :
571 0 : WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
572 : struct NetLocalGroupGetInfo *r)
573 : {
574 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
575 : }
576 :
577 : /****************************************************************
578 : ****************************************************************/
579 :
580 0 : static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
581 : uint32_t level,
582 : uint8_t *buffer,
583 : enum samr_AliasInfoEnum *alias_level,
584 : union samr_AliasInfo **alias_info)
585 : {
586 0 : struct LOCALGROUP_INFO_0 *info0;
587 0 : struct LOCALGROUP_INFO_1 *info1;
588 0 : struct LOCALGROUP_INFO_1002 *info1002;
589 0 : union samr_AliasInfo *info = NULL;
590 :
591 0 : info = talloc_zero(mem_ctx, union samr_AliasInfo);
592 0 : W_ERROR_HAVE_NO_MEMORY(info);
593 :
594 0 : switch (level) {
595 0 : case 0:
596 0 : info0 = (struct LOCALGROUP_INFO_0 *)buffer;
597 0 : init_lsa_String(&info->name, info0->lgrpi0_name);
598 0 : *alias_level = ALIASINFONAME;
599 0 : break;
600 0 : case 1:
601 0 : info1 = (struct LOCALGROUP_INFO_1 *)buffer;
602 : /* group name will be ignored */
603 0 : init_lsa_String(&info->description, info1->lgrpi1_comment);
604 0 : *alias_level = ALIASINFODESCRIPTION;
605 0 : break;
606 0 : case 1002:
607 0 : info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
608 0 : init_lsa_String(&info->description, info1002->lgrpi1002_comment);
609 0 : *alias_level = ALIASINFODESCRIPTION;
610 0 : break;
611 : }
612 :
613 0 : *alias_info = info;
614 :
615 0 : return WERR_OK;
616 : }
617 :
618 : /****************************************************************
619 : ****************************************************************/
620 :
621 0 : WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
622 : struct NetLocalGroupSetInfo *r)
623 : {
624 0 : struct rpc_pipe_client *pipe_cli = NULL;
625 0 : NTSTATUS status, result;
626 0 : WERROR werr;
627 0 : struct lsa_String lsa_account_name;
628 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
629 0 : struct dom_sid2 *domain_sid = NULL;
630 0 : enum samr_AliasInfoEnum alias_level = 0;
631 0 : union samr_AliasInfo *alias_info = NULL;
632 0 : struct dcerpc_binding_handle *b = NULL;
633 :
634 0 : if (!r->in.group_name) {
635 0 : return WERR_INVALID_PARAMETER;
636 : }
637 :
638 0 : switch (r->in.level) {
639 0 : case 0:
640 : case 1:
641 : case 1002:
642 0 : break;
643 0 : default:
644 0 : return WERR_INVALID_LEVEL;
645 : }
646 :
647 0 : ZERO_STRUCT(connect_handle);
648 0 : ZERO_STRUCT(builtin_handle);
649 0 : ZERO_STRUCT(domain_handle);
650 0 : ZERO_STRUCT(alias_handle);
651 :
652 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
653 : &ndr_table_samr,
654 : &pipe_cli);
655 0 : if (!W_ERROR_IS_OK(werr)) {
656 0 : goto done;
657 : }
658 :
659 0 : b = pipe_cli->binding_handle;
660 :
661 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
662 : SAMR_ACCESS_LOOKUP_DOMAIN |
663 : SAMR_ACCESS_ENUM_DOMAINS,
664 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
665 : &connect_handle,
666 : &builtin_handle);
667 0 : if (!W_ERROR_IS_OK(werr)) {
668 0 : goto done;
669 : }
670 :
671 0 : init_lsa_String(&lsa_account_name, r->in.group_name);
672 :
673 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
674 : &builtin_handle,
675 : r->in.group_name,
676 : SAMR_ALIAS_ACCESS_SET_INFO,
677 : &alias_handle);
678 :
679 0 : if (ctx->disable_policy_handle_cache) {
680 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
681 : }
682 :
683 0 : if (NT_STATUS_IS_OK(status)) {
684 0 : goto set_alias;
685 : }
686 :
687 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
688 : SAMR_ACCESS_ENUM_DOMAINS |
689 : SAMR_ACCESS_LOOKUP_DOMAIN,
690 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
691 : &connect_handle,
692 : &domain_handle,
693 : &domain_sid);
694 0 : if (!W_ERROR_IS_OK(werr)) {
695 0 : goto done;
696 : }
697 :
698 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
699 : &domain_handle,
700 : r->in.group_name,
701 : SAMR_ALIAS_ACCESS_SET_INFO,
702 : &alias_handle);
703 0 : if (!NT_STATUS_IS_OK(status)) {
704 0 : werr = ntstatus_to_werror(status);
705 0 : goto done;
706 : }
707 :
708 0 : if (ctx->disable_policy_handle_cache) {
709 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
710 : }
711 :
712 0 : set_alias:
713 :
714 0 : werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
715 : &alias_level, &alias_info);
716 0 : if (!W_ERROR_IS_OK(werr)) {
717 0 : goto done;
718 : }
719 :
720 0 : status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
721 : &alias_handle,
722 : alias_level,
723 : alias_info,
724 : &result);
725 0 : if (any_nt_status_not_ok(status, result, &status)) {
726 0 : werr = ntstatus_to_werror(status);
727 0 : goto done;
728 : }
729 :
730 0 : werr = WERR_OK;
731 :
732 0 : done:
733 0 : if (is_valid_policy_hnd(&alias_handle)) {
734 0 : dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
735 : }
736 :
737 0 : if (ctx->disable_policy_handle_cache) {
738 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
739 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
740 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
741 : }
742 :
743 0 : return werr;
744 : }
745 :
746 : /****************************************************************
747 : ****************************************************************/
748 :
749 0 : WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
750 : struct NetLocalGroupSetInfo *r)
751 : {
752 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
753 : }
754 :
755 : /****************************************************************
756 : ****************************************************************/
757 :
758 0 : WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
759 : struct NetLocalGroupEnum *r)
760 : {
761 0 : struct rpc_pipe_client *pipe_cli = NULL;
762 0 : NTSTATUS status, result;
763 0 : WERROR werr;
764 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
765 0 : struct dom_sid2 *domain_sid = NULL;
766 0 : uint32_t entries_read = 0;
767 0 : union samr_DomainInfo *domain_info = NULL;
768 0 : union samr_DomainInfo *builtin_info = NULL;
769 0 : struct samr_SamArray *domain_sam_array = NULL;
770 0 : struct samr_SamArray *builtin_sam_array = NULL;
771 0 : int i;
772 0 : struct dcerpc_binding_handle *b = NULL;
773 :
774 0 : if (!r->out.buffer) {
775 0 : return WERR_INVALID_PARAMETER;
776 : }
777 :
778 0 : switch (r->in.level) {
779 0 : case 0:
780 : case 1:
781 0 : break;
782 0 : default:
783 0 : return WERR_INVALID_LEVEL;
784 : }
785 :
786 0 : if (r->out.total_entries) {
787 0 : *r->out.total_entries = 0;
788 : }
789 0 : if (r->out.entries_read) {
790 0 : *r->out.entries_read = 0;
791 : }
792 :
793 0 : ZERO_STRUCT(connect_handle);
794 0 : ZERO_STRUCT(builtin_handle);
795 0 : ZERO_STRUCT(domain_handle);
796 0 : ZERO_STRUCT(alias_handle);
797 :
798 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
799 : &ndr_table_samr,
800 : &pipe_cli);
801 0 : if (!W_ERROR_IS_OK(werr)) {
802 0 : goto done;
803 : }
804 :
805 0 : b = pipe_cli->binding_handle;
806 :
807 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
808 : SAMR_ACCESS_LOOKUP_DOMAIN |
809 : SAMR_ACCESS_ENUM_DOMAINS,
810 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
811 : SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
812 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
813 : &connect_handle,
814 : &builtin_handle);
815 0 : if (!W_ERROR_IS_OK(werr)) {
816 0 : goto done;
817 : }
818 :
819 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
820 : SAMR_ACCESS_LOOKUP_DOMAIN |
821 : SAMR_ACCESS_ENUM_DOMAINS,
822 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
823 : SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
824 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
825 : &connect_handle,
826 : &domain_handle,
827 : &domain_sid);
828 0 : if (!W_ERROR_IS_OK(werr)) {
829 0 : goto done;
830 : }
831 :
832 0 : status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
833 : &builtin_handle,
834 : 2,
835 : &builtin_info,
836 : &result);
837 0 : if (any_nt_status_not_ok(status, result, &status)) {
838 0 : werr = ntstatus_to_werror(status);
839 0 : goto done;
840 : }
841 :
842 0 : if (r->out.total_entries) {
843 0 : *r->out.total_entries += builtin_info->general.num_aliases;
844 : }
845 :
846 0 : status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
847 : &domain_handle,
848 : 2,
849 : &domain_info,
850 : &result);
851 0 : if (any_nt_status_not_ok(status, result, &status)) {
852 0 : werr = ntstatus_to_werror(status);
853 0 : goto done;
854 : }
855 :
856 0 : if (r->out.total_entries) {
857 0 : *r->out.total_entries += domain_info->general.num_aliases;
858 : }
859 :
860 0 : status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
861 : &builtin_handle,
862 : r->in.resume_handle,
863 : &builtin_sam_array,
864 : r->in.prefmaxlen,
865 : &entries_read,
866 : &result);
867 0 : if (any_nt_status_not_ok(status, result, &status)) {
868 0 : werr = ntstatus_to_werror(status);
869 0 : goto done;
870 : }
871 :
872 0 : for (i=0; i<builtin_sam_array->count; i++) {
873 0 : union samr_AliasInfo *alias_info = NULL;
874 :
875 0 : if (r->in.level == 1) {
876 :
877 0 : status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
878 : &builtin_handle,
879 0 : builtin_sam_array->entries[i].idx,
880 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
881 : ALIASINFOALL,
882 : &alias_info);
883 0 : if (!NT_STATUS_IS_OK(status)) {
884 0 : werr = ntstatus_to_werror(status);
885 0 : goto done;
886 : }
887 : }
888 :
889 0 : werr = map_alias_info_to_buffer(ctx,
890 0 : builtin_sam_array->entries[i].name.string,
891 0 : alias_info ? &alias_info->all : NULL,
892 : r->in.level,
893 : r->out.entries_read,
894 : r->out.buffer);
895 : }
896 :
897 0 : status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
898 : &domain_handle,
899 : r->in.resume_handle,
900 : &domain_sam_array,
901 : r->in.prefmaxlen,
902 : &entries_read,
903 : &result);
904 0 : if (any_nt_status_not_ok(status, result, &status)) {
905 0 : werr = ntstatus_to_werror(status);
906 0 : goto done;
907 : }
908 :
909 0 : for (i=0; i<domain_sam_array->count; i++) {
910 :
911 0 : union samr_AliasInfo *alias_info = NULL;
912 :
913 0 : if (r->in.level == 1) {
914 0 : status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
915 : &domain_handle,
916 0 : domain_sam_array->entries[i].idx,
917 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
918 : ALIASINFOALL,
919 : &alias_info);
920 0 : if (!NT_STATUS_IS_OK(status)) {
921 0 : werr = ntstatus_to_werror(status);
922 0 : goto done;
923 : }
924 : }
925 :
926 0 : werr = map_alias_info_to_buffer(ctx,
927 0 : domain_sam_array->entries[i].name.string,
928 0 : alias_info ? &alias_info->all : NULL,
929 : r->in.level,
930 : r->out.entries_read,
931 : r->out.buffer);
932 : }
933 :
934 0 : done:
935 0 : if (ctx->disable_policy_handle_cache) {
936 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
937 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
938 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
939 : }
940 :
941 0 : return werr;
942 : }
943 :
944 : /****************************************************************
945 : ****************************************************************/
946 :
947 0 : WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
948 : struct NetLocalGroupEnum *r)
949 : {
950 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
951 : }
952 :
953 : /****************************************************************
954 : ****************************************************************/
955 :
956 0 : static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
957 : struct rpc_pipe_client *lsa_pipe,
958 : const char *name,
959 : struct dom_sid *sid)
960 : {
961 0 : NTSTATUS status, result;
962 0 : struct policy_handle lsa_handle;
963 0 : struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
964 :
965 0 : struct lsa_RefDomainList *domains = NULL;
966 0 : struct lsa_TransSidArray3 sids;
967 0 : uint32_t count = 0;
968 :
969 0 : struct lsa_String names;
970 0 : uint32_t num_names = 1;
971 0 : union lsa_revision_info out_revision_info = {
972 : .info1 = {
973 : .revision = 0,
974 : },
975 : };
976 0 : uint32_t out_version = 0;
977 :
978 0 : if (!sid || !name) {
979 0 : return NT_STATUS_INVALID_PARAMETER;
980 : }
981 :
982 0 : ZERO_STRUCT(sids);
983 :
984 0 : init_lsa_String(&names, name);
985 :
986 0 : status = dcerpc_lsa_open_policy_fallback(
987 : b,
988 : mem_ctx,
989 0 : lsa_pipe->srv_name_slash,
990 : false,
991 : SEC_STD_READ_CONTROL |
992 : LSA_POLICY_VIEW_LOCAL_INFORMATION |
993 : LSA_POLICY_LOOKUP_NAMES,
994 : &out_version,
995 : &out_revision_info,
996 : &lsa_handle,
997 : &result);
998 0 : if (any_nt_status_not_ok(status, result, &status)) {
999 0 : return status;
1000 : }
1001 :
1002 0 : status = dcerpc_lsa_LookupNames3(b, mem_ctx,
1003 : &lsa_handle,
1004 : num_names,
1005 : &names,
1006 : &domains,
1007 : &sids,
1008 : LSA_LOOKUP_NAMES_ALL, /* sure ? */
1009 : &count,
1010 : 0, 0,
1011 : &result);
1012 0 : NT_STATUS_NOT_OK_RETURN(status);
1013 0 : NT_STATUS_NOT_OK_RETURN(result);
1014 :
1015 0 : if (count != 1 || sids.count != 1) {
1016 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
1017 : }
1018 :
1019 0 : sid_copy(sid, sids.sids[0].sid);
1020 :
1021 0 : return NT_STATUS_OK;
1022 : }
1023 :
1024 : /****************************************************************
1025 : ****************************************************************/
1026 :
1027 0 : static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
1028 : struct NetLocalGroupAddMembers *add,
1029 : struct NetLocalGroupDelMembers *del,
1030 : struct NetLocalGroupSetMembers *set)
1031 : {
1032 0 : struct NetLocalGroupAddMembers *r = NULL;
1033 :
1034 0 : struct rpc_pipe_client *pipe_cli = NULL;
1035 0 : struct rpc_pipe_client *lsa_pipe = NULL;
1036 0 : NTSTATUS status, result;
1037 0 : WERROR werr;
1038 0 : struct lsa_String lsa_account_name;
1039 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1040 0 : struct dom_sid2 *domain_sid = NULL;
1041 0 : struct dom_sid *member_sids = NULL;
1042 0 : int i = 0, k = 0;
1043 :
1044 0 : struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1045 0 : struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1046 :
1047 0 : struct dom_sid *add_sids = NULL;
1048 0 : struct dom_sid *del_sids = NULL;
1049 0 : uint32_t num_add_sids = 0;
1050 0 : uint32_t num_del_sids = 0;
1051 0 : struct dcerpc_binding_handle *b = NULL;
1052 :
1053 0 : if ((!add && !del && !set) || (add && del && set)) {
1054 0 : return WERR_INVALID_PARAMETER;
1055 : }
1056 :
1057 0 : if (add) {
1058 0 : r = add;
1059 : }
1060 :
1061 0 : if (del) {
1062 0 : r = (struct NetLocalGroupAddMembers *)del;
1063 : }
1064 :
1065 0 : if (set) {
1066 0 : r = (struct NetLocalGroupAddMembers *)set;
1067 : }
1068 :
1069 0 : if (r==NULL || r->in.group_name == NULL) {
1070 0 : return WERR_INVALID_PARAMETER;
1071 : }
1072 :
1073 0 : switch (r->in.level) {
1074 0 : case 0:
1075 : case 3:
1076 0 : break;
1077 0 : default:
1078 0 : return WERR_INVALID_LEVEL;
1079 : }
1080 :
1081 0 : if (r->in.total_entries == 0 || !r->in.buffer) {
1082 0 : return WERR_INVALID_PARAMETER;
1083 : }
1084 :
1085 0 : ZERO_STRUCT(connect_handle);
1086 0 : ZERO_STRUCT(builtin_handle);
1087 0 : ZERO_STRUCT(domain_handle);
1088 0 : ZERO_STRUCT(alias_handle);
1089 :
1090 0 : member_sids = talloc_zero_array(ctx, struct dom_sid,
1091 : r->in.total_entries);
1092 0 : W_ERROR_HAVE_NO_MEMORY(member_sids);
1093 :
1094 0 : switch (r->in.level) {
1095 0 : case 0:
1096 0 : info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1097 0 : for (i=0; i < r->in.total_entries; i++) {
1098 0 : sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1099 : }
1100 0 : break;
1101 0 : case 3:
1102 0 : info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1103 0 : break;
1104 0 : default:
1105 0 : break;
1106 : }
1107 :
1108 0 : if (r->in.level == 3) {
1109 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1110 : &ndr_table_lsarpc,
1111 : &lsa_pipe);
1112 0 : if (!W_ERROR_IS_OK(werr)) {
1113 0 : goto done;
1114 : }
1115 :
1116 0 : for (i=0; i < r->in.total_entries; i++) {
1117 0 : status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1118 0 : info3[i].lgrmi3_domainandname,
1119 0 : &member_sids[i]);
1120 0 : if (!NT_STATUS_IS_OK(status)) {
1121 0 : werr = ntstatus_to_werror(status);
1122 0 : goto done;
1123 : }
1124 : }
1125 0 : TALLOC_FREE(lsa_pipe);
1126 : }
1127 :
1128 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1129 : &ndr_table_samr,
1130 : &pipe_cli);
1131 0 : if (!W_ERROR_IS_OK(werr)) {
1132 0 : goto done;
1133 : }
1134 :
1135 0 : b = pipe_cli->binding_handle;
1136 :
1137 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1138 : SAMR_ACCESS_LOOKUP_DOMAIN |
1139 : SAMR_ACCESS_ENUM_DOMAINS,
1140 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1141 : &connect_handle,
1142 : &builtin_handle);
1143 0 : if (!W_ERROR_IS_OK(werr)) {
1144 0 : goto done;
1145 : }
1146 :
1147 0 : init_lsa_String(&lsa_account_name, r->in.group_name);
1148 :
1149 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1150 : &builtin_handle,
1151 : r->in.group_name,
1152 : SAMR_ALIAS_ACCESS_ADD_MEMBER |
1153 : SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1154 : SAMR_ALIAS_ACCESS_GET_MEMBERS |
1155 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1156 : &alias_handle);
1157 :
1158 0 : if (ctx->disable_policy_handle_cache) {
1159 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1160 : }
1161 :
1162 0 : if (NT_STATUS_IS_OK(status)) {
1163 0 : goto modify_membership;
1164 : }
1165 :
1166 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1167 : SAMR_ACCESS_ENUM_DOMAINS |
1168 : SAMR_ACCESS_LOOKUP_DOMAIN,
1169 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1170 : &connect_handle,
1171 : &domain_handle,
1172 : &domain_sid);
1173 0 : if (!W_ERROR_IS_OK(werr)) {
1174 0 : goto done;
1175 : }
1176 :
1177 0 : status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1178 : &domain_handle,
1179 : r->in.group_name,
1180 : SAMR_ALIAS_ACCESS_ADD_MEMBER |
1181 : SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1182 : SAMR_ALIAS_ACCESS_GET_MEMBERS |
1183 : SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1184 : &alias_handle);
1185 0 : if (!NT_STATUS_IS_OK(status)) {
1186 0 : werr = ntstatus_to_werror(status);
1187 0 : goto done;
1188 : }
1189 :
1190 0 : if (ctx->disable_policy_handle_cache) {
1191 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1192 : }
1193 :
1194 0 : modify_membership:
1195 :
1196 0 : if (add) {
1197 0 : for (i=0; i < r->in.total_entries; i++) {
1198 0 : status = add_sid_to_array_unique(ctx, &member_sids[i],
1199 : &add_sids,
1200 : &num_add_sids);
1201 0 : if (!NT_STATUS_IS_OK(status)) {
1202 0 : werr = ntstatus_to_werror(status);
1203 0 : goto done;
1204 : }
1205 : }
1206 : }
1207 :
1208 0 : if (del) {
1209 0 : for (i=0; i < r->in.total_entries; i++) {
1210 0 : status = add_sid_to_array_unique(ctx, &member_sids[i],
1211 : &del_sids,
1212 : &num_del_sids);
1213 0 : if (!NT_STATUS_IS_OK(status)) {
1214 0 : werr = ntstatus_to_werror(status);
1215 0 : goto done;
1216 : }
1217 : }
1218 : }
1219 :
1220 0 : if (set) {
1221 :
1222 0 : struct lsa_SidArray current_sids;
1223 :
1224 0 : status = dcerpc_samr_GetMembersInAlias(b, talloc_tos(),
1225 : &alias_handle,
1226 : ¤t_sids,
1227 : &result);
1228 0 : if (any_nt_status_not_ok(status, result, &status)) {
1229 0 : werr = ntstatus_to_werror(status);
1230 0 : goto done;
1231 : }
1232 :
1233 : /* add list */
1234 :
1235 0 : for (i=0; i < r->in.total_entries; i++) {
1236 0 : bool already_member = false;
1237 0 : for (k=0; k < current_sids.num_sids; k++) {
1238 0 : if (dom_sid_equal(&member_sids[i],
1239 0 : current_sids.sids[k].sid)) {
1240 0 : already_member = true;
1241 0 : break;
1242 : }
1243 : }
1244 0 : if (!already_member) {
1245 0 : status = add_sid_to_array_unique(ctx,
1246 0 : &member_sids[i],
1247 : &add_sids, &num_add_sids);
1248 0 : if (!NT_STATUS_IS_OK(status)) {
1249 0 : werr = ntstatus_to_werror(status);
1250 0 : goto done;
1251 : }
1252 : }
1253 : }
1254 :
1255 : /* del list */
1256 :
1257 0 : for (k=0; k < current_sids.num_sids; k++) {
1258 0 : bool keep_member = false;
1259 0 : for (i=0; i < r->in.total_entries; i++) {
1260 0 : if (dom_sid_equal(&member_sids[i],
1261 0 : current_sids.sids[k].sid)) {
1262 0 : keep_member = true;
1263 0 : break;
1264 : }
1265 : }
1266 0 : if (!keep_member) {
1267 0 : status = add_sid_to_array_unique(ctx,
1268 0 : current_sids.sids[k].sid,
1269 : &del_sids, &num_del_sids);
1270 0 : if (!NT_STATUS_IS_OK(status)) {
1271 0 : werr = ntstatus_to_werror(status);
1272 0 : goto done;
1273 : }
1274 : }
1275 : }
1276 : }
1277 :
1278 : /* add list */
1279 :
1280 0 : for (i=0; i < num_add_sids; i++) {
1281 0 : status = dcerpc_samr_AddAliasMember(b, talloc_tos(),
1282 : &alias_handle,
1283 0 : &add_sids[i],
1284 : &result);
1285 0 : if (any_nt_status_not_ok(status, result, &status)) {
1286 0 : werr = ntstatus_to_werror(status);
1287 0 : goto done;
1288 : }
1289 : }
1290 :
1291 : /* del list */
1292 :
1293 0 : for (i=0; i < num_del_sids; i++) {
1294 0 : status = dcerpc_samr_DeleteAliasMember(b, talloc_tos(),
1295 : &alias_handle,
1296 0 : &del_sids[i],
1297 : &result);
1298 0 : if (any_nt_status_not_ok(status, result, &status)) {
1299 0 : werr = ntstatus_to_werror(status);
1300 0 : goto done;
1301 : }
1302 : }
1303 :
1304 0 : werr = WERR_OK;
1305 :
1306 0 : done:
1307 0 : if (b && is_valid_policy_hnd(&alias_handle)) {
1308 0 : dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
1309 : }
1310 :
1311 0 : if (ctx->disable_policy_handle_cache) {
1312 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1313 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1314 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1315 : }
1316 :
1317 0 : return werr;
1318 : }
1319 :
1320 : /****************************************************************
1321 : ****************************************************************/
1322 :
1323 0 : WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1324 : struct NetLocalGroupAddMembers *r)
1325 : {
1326 0 : return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1327 : }
1328 :
1329 : /****************************************************************
1330 : ****************************************************************/
1331 :
1332 0 : WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1333 : struct NetLocalGroupAddMembers *r)
1334 : {
1335 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1336 : }
1337 :
1338 : /****************************************************************
1339 : ****************************************************************/
1340 :
1341 0 : WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1342 : struct NetLocalGroupDelMembers *r)
1343 : {
1344 0 : return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1345 : }
1346 :
1347 : /****************************************************************
1348 : ****************************************************************/
1349 :
1350 0 : WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1351 : struct NetLocalGroupDelMembers *r)
1352 : {
1353 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1354 : }
1355 :
1356 : /****************************************************************
1357 : ****************************************************************/
1358 :
1359 0 : WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1360 : struct NetLocalGroupGetMembers *r)
1361 : {
1362 0 : return WERR_NOT_SUPPORTED;
1363 : }
1364 :
1365 : /****************************************************************
1366 : ****************************************************************/
1367 :
1368 0 : WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1369 : struct NetLocalGroupGetMembers *r)
1370 : {
1371 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1372 : }
1373 :
1374 : /****************************************************************
1375 : ****************************************************************/
1376 :
1377 0 : WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1378 : struct NetLocalGroupSetMembers *r)
1379 : {
1380 0 : return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1381 : }
1382 :
1383 : /****************************************************************
1384 : ****************************************************************/
1385 :
1386 0 : WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1387 : struct NetLocalGroupSetMembers *r)
1388 : {
1389 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);
1390 : }
|