2
* Unix SMB/CIFS implementation.
3
* NetApi LocalGroup Support
4
* Copyright (C) Guenther Deschner 2008
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.
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.
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/>.
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"
27
static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
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)
36
struct lsa_String lsa_account_name;
37
struct samr_Ids user_rids, name_types;
39
init_lsa_String(&lsa_account_name, group_name);
41
status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
47
if (!NT_STATUS_IS_OK(status)) {
51
switch (name_types.ids[0]) {
53
case SID_NAME_WKN_GRP:
56
return NT_STATUS_INVALID_SID;
59
return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
66
/****************************************************************
67
****************************************************************/
69
static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
70
struct rpc_pipe_client *pipe_cli,
71
struct policy_handle *handle,
73
uint32_t access_rights,
74
enum samr_AliasInfoEnum level,
75
union samr_AliasInfo **alias_info)
78
struct policy_handle alias_handle;
79
union samr_AliasInfo *_alias_info = NULL;
81
ZERO_STRUCT(alias_handle);
83
status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
88
if (!NT_STATUS_IS_OK(status)) {
92
status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
96
if (!NT_STATUS_IS_OK(status)) {
100
*alias_info = _alias_info;
103
if (is_valid_policy_hnd(&alias_handle)) {
104
rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
110
/****************************************************************
111
****************************************************************/
113
WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
114
struct NetLocalGroupAdd *r)
116
struct rpc_pipe_client *pipe_cli = NULL;
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;
124
struct LOCALGROUP_INFO_0 *info0 = NULL;
125
struct LOCALGROUP_INFO_1 *info1 = NULL;
127
const char *alias_name = NULL;
130
return WERR_INVALID_PARAM;
133
switch (r->in.level) {
135
info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
136
alias_name = info0->lgrpi0_name;
139
info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
140
alias_name = info1->lgrpi1_name;
143
werr = WERR_UNKNOWN_LEVEL;
147
ZERO_STRUCT(connect_handle);
148
ZERO_STRUCT(builtin_handle);
149
ZERO_STRUCT(domain_handle);
150
ZERO_STRUCT(alias_handle);
152
werr = libnetapi_open_pipe(ctx, r->in.server_name,
153
&ndr_table_samr.syntax_id,
155
if (!W_ERROR_IS_OK(werr)) {
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,
165
if (!W_ERROR_IS_OK(werr)) {
169
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
172
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
174
if (ctx->disable_policy_handle_cache) {
175
libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
178
if (NT_STATUS_IS_OK(status)) {
179
werr = WERR_ALIAS_EXISTS;
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,
191
if (!W_ERROR_IS_OK(werr)) {
195
init_lsa_String(&lsa_account_name, alias_name);
197
status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
201
SAMR_ALIAS_ACCESS_SET_INFO,
204
if (!NT_STATUS_IS_OK(status)) {
205
werr = ntstatus_to_werror(status);
209
if (r->in.level == 1 && info1->lgrpi1_comment) {
211
union samr_AliasInfo alias_info;
213
init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
215
status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
217
ALIASINFODESCRIPTION,
219
if (!NT_STATUS_IS_OK(status)) {
220
werr = ntstatus_to_werror(status);
228
if (is_valid_policy_hnd(&alias_handle)) {
229
rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
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);
241
/****************************************************************
242
****************************************************************/
244
WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
245
struct NetLocalGroupAdd *r)
247
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
250
/****************************************************************
251
****************************************************************/
254
WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
255
struct NetLocalGroupDel *r)
257
struct rpc_pipe_client *pipe_cli = NULL;
260
struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
261
struct dom_sid2 *domain_sid = NULL;
263
if (!r->in.group_name) {
264
return WERR_INVALID_PARAM;
267
ZERO_STRUCT(connect_handle);
268
ZERO_STRUCT(builtin_handle);
269
ZERO_STRUCT(domain_handle);
270
ZERO_STRUCT(alias_handle);
272
werr = libnetapi_open_pipe(ctx, r->in.server_name,
273
&ndr_table_samr.syntax_id,
275
if (!W_ERROR_IS_OK(werr)) {
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,
285
if (!W_ERROR_IS_OK(werr)) {
289
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
295
if (ctx->disable_policy_handle_cache) {
296
libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
299
if (NT_STATUS_IS_OK(status)) {
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,
311
if (!W_ERROR_IS_OK(werr)) {
315
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
321
if (ctx->disable_policy_handle_cache) {
322
libnetapi_samr_close_domain_handle(ctx, &domain_handle);
325
if (!NT_STATUS_IS_OK(status)) {
326
werr = ntstatus_to_werror(status);
332
status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
334
if (!NT_STATUS_IS_OK(status)) {
335
werr = ntstatus_to_werror(status);
339
ZERO_STRUCT(alias_handle);
344
if (is_valid_policy_hnd(&alias_handle)) {
345
rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
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);
357
/****************************************************************
358
****************************************************************/
360
WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
361
struct NetLocalGroupDel *r)
363
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
366
/****************************************************************
367
****************************************************************/
369
static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
370
const char *alias_name,
371
struct samr_AliasInfoAll *info,
373
uint32_t *entries_read,
376
struct LOCALGROUP_INFO_0 g0;
377
struct LOCALGROUP_INFO_1 g1;
378
struct LOCALGROUP_INFO_1002 g1002;
382
g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
383
W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
385
ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
386
(struct LOCALGROUP_INFO_0 **)buffer, entries_read);
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);
394
ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
395
(struct LOCALGROUP_INFO_1 **)buffer, entries_read);
399
g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
401
ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
402
(struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
406
return WERR_UNKNOWN_LEVEL;
412
/****************************************************************
413
****************************************************************/
415
WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
416
struct NetLocalGroupGetInfo *r)
418
struct rpc_pipe_client *pipe_cli = NULL;
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;
426
if (!r->in.group_name) {
427
return WERR_INVALID_PARAM;
430
switch (r->in.level) {
436
return WERR_UNKNOWN_LEVEL;
439
ZERO_STRUCT(connect_handle);
440
ZERO_STRUCT(builtin_handle);
441
ZERO_STRUCT(domain_handle);
442
ZERO_STRUCT(alias_handle);
444
werr = libnetapi_open_pipe(ctx, r->in.server_name,
445
&ndr_table_samr.syntax_id,
447
if (!W_ERROR_IS_OK(werr)) {
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,
457
if (!W_ERROR_IS_OK(werr)) {
461
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
464
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
467
if (ctx->disable_policy_handle_cache) {
468
libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
471
if (NT_STATUS_IS_OK(status)) {
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,
483
if (!W_ERROR_IS_OK(werr)) {
487
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
490
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
493
if (ctx->disable_policy_handle_cache) {
494
libnetapi_samr_close_domain_handle(ctx, &domain_handle);
497
if (!NT_STATUS_IS_OK(status)) {
498
werr = ntstatus_to_werror(status);
503
status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
507
if (!NT_STATUS_IS_OK(status)) {
508
werr = ntstatus_to_werror(status);
512
werr = map_alias_info_to_buffer(ctx,
515
r->in.level, &entries_read,
519
if (is_valid_policy_hnd(&alias_handle)) {
520
rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
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);
532
/****************************************************************
533
****************************************************************/
535
WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
536
struct NetLocalGroupGetInfo *r)
538
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
541
/****************************************************************
542
****************************************************************/
544
static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
547
enum samr_AliasInfoEnum *alias_level,
548
union samr_AliasInfo **alias_info)
550
struct LOCALGROUP_INFO_0 *info0;
551
struct LOCALGROUP_INFO_1 *info1;
552
struct LOCALGROUP_INFO_1002 *info1002;
553
union samr_AliasInfo *info = NULL;
555
info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
556
W_ERROR_HAVE_NO_MEMORY(info);
560
info0 = (struct LOCALGROUP_INFO_0 *)buffer;
561
init_lsa_String(&info->name, info0->lgrpi0_name);
562
*alias_level = ALIASINFONAME;
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;
571
info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
572
init_lsa_String(&info->description, info1002->lgrpi1002_comment);
573
*alias_level = ALIASINFODESCRIPTION;
582
/****************************************************************
583
****************************************************************/
585
WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
586
struct NetLocalGroupSetInfo *r)
588
struct rpc_pipe_client *pipe_cli = NULL;
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;
597
if (!r->in.group_name) {
598
return WERR_INVALID_PARAM;
601
switch (r->in.level) {
607
return WERR_UNKNOWN_LEVEL;
610
ZERO_STRUCT(connect_handle);
611
ZERO_STRUCT(builtin_handle);
612
ZERO_STRUCT(domain_handle);
613
ZERO_STRUCT(alias_handle);
615
werr = libnetapi_open_pipe(ctx, r->in.server_name,
616
&ndr_table_samr.syntax_id,
618
if (!W_ERROR_IS_OK(werr)) {
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,
628
if (!W_ERROR_IS_OK(werr)) {
632
init_lsa_String(&lsa_account_name, r->in.group_name);
634
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
637
SAMR_ALIAS_ACCESS_SET_INFO,
640
if (ctx->disable_policy_handle_cache) {
641
libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
644
if (NT_STATUS_IS_OK(status)) {
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,
655
if (!W_ERROR_IS_OK(werr)) {
659
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
662
SAMR_ALIAS_ACCESS_SET_INFO,
664
if (!NT_STATUS_IS_OK(status)) {
665
werr = ntstatus_to_werror(status);
669
if (ctx->disable_policy_handle_cache) {
670
libnetapi_samr_close_domain_handle(ctx, &domain_handle);
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)) {
681
status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
685
if (!NT_STATUS_IS_OK(status)) {
686
werr = ntstatus_to_werror(status);
693
if (is_valid_policy_hnd(&alias_handle)) {
694
rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
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);
706
/****************************************************************
707
****************************************************************/
709
WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
710
struct NetLocalGroupSetInfo *r)
712
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
715
/****************************************************************
716
****************************************************************/
718
WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
719
struct NetLocalGroupEnum *r)
721
struct rpc_pipe_client *pipe_cli = NULL;
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;
733
if (!r->out.buffer) {
734
return WERR_INVALID_PARAM;
737
switch (r->in.level) {
742
return WERR_UNKNOWN_LEVEL;
745
if (r->out.total_entries) {
746
*r->out.total_entries = 0;
748
if (r->out.entries_read) {
749
*r->out.entries_read = 0;
752
ZERO_STRUCT(connect_handle);
753
ZERO_STRUCT(builtin_handle);
754
ZERO_STRUCT(domain_handle);
755
ZERO_STRUCT(alias_handle);
757
werr = libnetapi_open_pipe(ctx, r->in.server_name,
758
&ndr_table_samr.syntax_id,
760
if (!W_ERROR_IS_OK(werr)) {
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,
772
if (!W_ERROR_IS_OK(werr)) {
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,
785
if (!W_ERROR_IS_OK(werr)) {
789
status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
793
if (!NT_STATUS_IS_OK(status)) {
794
werr = ntstatus_to_werror(status);
798
if (r->out.total_entries) {
799
*r->out.total_entries += builtin_info->general.num_aliases;
802
status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
806
if (!NT_STATUS_IS_OK(status)) {
807
werr = ntstatus_to_werror(status);
811
if (r->out.total_entries) {
812
*r->out.total_entries += domain_info->general.num_aliases;
815
status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
821
if (!NT_STATUS_IS_OK(status)) {
822
werr = ntstatus_to_werror(status);
826
for (i=0; i<builtin_sam_array->count; i++) {
827
union samr_AliasInfo *alias_info = NULL;
829
if (r->in.level == 1) {
831
status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
833
builtin_sam_array->entries[i].idx,
834
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
837
if (!NT_STATUS_IS_OK(status)) {
838
werr = ntstatus_to_werror(status);
843
werr = map_alias_info_to_buffer(ctx,
844
builtin_sam_array->entries[i].name.string,
845
alias_info ? &alias_info->all : NULL,
851
status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
857
if (!NT_STATUS_IS_OK(status)) {
858
werr = ntstatus_to_werror(status);
862
for (i=0; i<domain_sam_array->count; i++) {
864
union samr_AliasInfo *alias_info = NULL;
866
if (r->in.level == 1) {
867
status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
869
domain_sam_array->entries[i].idx,
870
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
873
if (!NT_STATUS_IS_OK(status)) {
874
werr = ntstatus_to_werror(status);
879
werr = map_alias_info_to_buffer(ctx,
880
domain_sam_array->entries[i].name.string,
881
alias_info ? &alias_info->all : NULL,
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);
897
/****************************************************************
898
****************************************************************/
900
WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
901
struct NetLocalGroupEnum *r)
903
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
906
/****************************************************************
907
****************************************************************/
909
static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
910
struct rpc_pipe_client *lsa_pipe,
915
struct policy_handle lsa_handle;
917
struct lsa_RefDomainList *domains = NULL;
918
struct lsa_TransSidArray3 sids;
921
struct lsa_String names;
922
uint32_t num_names = 1;
925
return NT_STATUS_INVALID_PARAMETER;
930
init_lsa_String(&names, name);
932
status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
934
STD_RIGHT_READ_CONTROL_ACCESS |
935
LSA_POLICY_VIEW_LOCAL_INFORMATION |
936
LSA_POLICY_LOOKUP_NAMES,
938
NT_STATUS_NOT_OK_RETURN(status);
940
status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
946
LSA_LOOKUP_NAMES_ALL, /* sure ? */
949
NT_STATUS_NOT_OK_RETURN(status);
951
if (count != 1 || sids.count != 1) {
952
return NT_STATUS_NONE_MAPPED;
955
sid_copy(sid, sids.sids[0].sid);
960
/****************************************************************
961
****************************************************************/
963
static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
964
struct NetLocalGroupAddMembers *add,
965
struct NetLocalGroupDelMembers *del,
966
struct NetLocalGroupSetMembers *set)
968
struct NetLocalGroupAddMembers *r = NULL;
970
struct rpc_pipe_client *pipe_cli = NULL;
971
struct rpc_pipe_client *lsa_pipe = NULL;
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;
980
struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
981
struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
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;
988
if ((!add && !del && !set) || (add && del && set)) {
989
return WERR_INVALID_PARAM;
997
r = (struct NetLocalGroupAddMembers *)del;
1001
r = (struct NetLocalGroupAddMembers *)set;
1004
if (!r->in.group_name) {
1005
return WERR_INVALID_PARAM;
1008
switch (r->in.level) {
1013
return WERR_UNKNOWN_LEVEL;
1016
if (r->in.total_entries == 0 || !r->in.buffer) {
1017
return WERR_INVALID_PARAM;
1020
ZERO_STRUCT(connect_handle);
1021
ZERO_STRUCT(builtin_handle);
1022
ZERO_STRUCT(domain_handle);
1023
ZERO_STRUCT(alias_handle);
1025
member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1026
r->in.total_entries);
1027
W_ERROR_HAVE_NO_MEMORY(member_sids);
1029
switch (r->in.level) {
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);
1037
info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1043
if (r->in.level == 3) {
1044
werr = libnetapi_open_pipe(ctx, r->in.server_name,
1045
&ndr_table_lsarpc.syntax_id,
1047
if (!W_ERROR_IS_OK(werr)) {
1051
for (i=0; i < r->in.total_entries; i++) {
1052
status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1053
info3[i].lgrmi3_domainandname,
1055
if (!NT_STATUS_IS_OK(status)) {
1056
werr = ntstatus_to_werror(status);
1060
TALLOC_FREE(lsa_pipe);
1063
werr = libnetapi_open_pipe(ctx, r->in.server_name,
1064
&ndr_table_samr.syntax_id,
1066
if (!W_ERROR_IS_OK(werr)) {
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,
1076
if (!W_ERROR_IS_OK(werr)) {
1080
init_lsa_String(&lsa_account_name, r->in.group_name);
1082
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1085
SAMR_ALIAS_ACCESS_ADD_MEMBER |
1086
SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1087
SAMR_ALIAS_ACCESS_GET_MEMBERS |
1088
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1091
if (ctx->disable_policy_handle_cache) {
1092
libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1095
if (NT_STATUS_IS_OK(status)) {
1096
goto modify_membership;
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,
1106
if (!W_ERROR_IS_OK(werr)) {
1110
status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1113
SAMR_ALIAS_ACCESS_ADD_MEMBER |
1114
SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1115
SAMR_ALIAS_ACCESS_GET_MEMBERS |
1116
SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1118
if (!NT_STATUS_IS_OK(status)) {
1119
werr = ntstatus_to_werror(status);
1123
if (ctx->disable_policy_handle_cache) {
1124
libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1130
for (i=0; i < r->in.total_entries; i++) {
1131
status = add_sid_to_array_unique(ctx, &member_sids[i],
1134
if (!NT_STATUS_IS_OK(status)) {
1135
werr = ntstatus_to_werror(status);
1142
for (i=0; i < r->in.total_entries; i++) {
1143
status = add_sid_to_array_unique(ctx, &member_sids[i],
1146
if (!NT_STATUS_IS_OK(status)) {
1147
werr = ntstatus_to_werror(status);
1155
struct lsa_SidArray current_sids;
1157
status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1160
if (!NT_STATUS_IS_OK(status)) {
1161
werr = ntstatus_to_werror(status);
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;
1176
if (!already_member) {
1177
status = add_sid_to_array_unique(ctx,
1179
&add_sids, &num_add_sids);
1180
if (!NT_STATUS_IS_OK(status)) {
1181
werr = ntstatus_to_werror(status);
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)) {
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);
1212
for (i=0; i < num_add_sids; i++) {
1213
status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1216
if (!NT_STATUS_IS_OK(status)) {
1217
werr = ntstatus_to_werror(status);
1224
for (i=0; i < num_del_sids; i++) {
1225
status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1228
if (!NT_STATUS_IS_OK(status)) {
1229
werr = ntstatus_to_werror(status);
1237
if (is_valid_policy_hnd(&alias_handle)) {
1238
rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
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);
1250
/****************************************************************
1251
****************************************************************/
1253
WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1254
struct NetLocalGroupAddMembers *r)
1256
return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1259
/****************************************************************
1260
****************************************************************/
1262
WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1263
struct NetLocalGroupAddMembers *r)
1265
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1268
/****************************************************************
1269
****************************************************************/
1271
WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1272
struct NetLocalGroupDelMembers *r)
1274
return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1277
/****************************************************************
1278
****************************************************************/
1280
WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1281
struct NetLocalGroupDelMembers *r)
1283
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1286
/****************************************************************
1287
****************************************************************/
1289
WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1290
struct NetLocalGroupGetMembers *r)
1292
return WERR_NOT_SUPPORTED;
1295
/****************************************************************
1296
****************************************************************/
1298
WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1299
struct NetLocalGroupGetMembers *r)
1301
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1304
/****************************************************************
1305
****************************************************************/
1307
WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1308
struct NetLocalGroupSetMembers *r)
1310
return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1313
/****************************************************************
1314
****************************************************************/
1316
WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1317
struct NetLocalGroupSetMembers *r)
1319
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);