~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/lib/netapi/localgroup.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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
                                                       &current_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,
 
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,
 
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,
 
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,
 
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,
 
1290
                                 struct NetLocalGroupGetMembers *r)
 
1291
{
 
1292
        return WERR_NOT_SUPPORTED;
 
1293
}
 
1294
 
 
1295
/****************************************************************
 
1296
****************************************************************/
 
1297
 
 
1298
WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
 
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,
 
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,
 
1317
                                 struct NetLocalGroupSetMembers *r)
 
1318
{
 
1319
        LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);
 
1320
}