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