source: vendor/3.6.23/source3/lib/netapi/localgroup.c

Last change on this file was 860, checked in by Silvan Scherrer, 11 years ago

Samba 3.6: updated vendor to latest version

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