netapi: use libnetapi_samr_lookup_and_open_alias().
[tprouty/samba.git] / source3 / lib / netapi / localgroup.c
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 WERROR libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
28                                                    struct rpc_pipe_client *pipe_cli,
29                                                    struct policy_handle *domain_handle,
30                                                    struct lsa_String *lsa_account_name,
31                                                    uint32_t access_rights,
32                                                    struct policy_handle *alias_handle)
33 {
34         NTSTATUS status;
35         WERROR werr;
36         struct samr_Ids user_rids, name_types;
37
38         status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
39                                          domain_handle,
40                                          1,
41                                          lsa_account_name,
42                                          &user_rids,
43                                          &name_types);
44         if (!NT_STATUS_IS_OK(status)) {
45                 werr = ntstatus_to_werror(status);
46                 goto done;
47         }
48
49         switch (name_types.ids[0]) {
50                 case SID_NAME_ALIAS:
51                 case SID_NAME_WKN_GRP:
52                         break;
53                 default:
54                         return WERR_INVALID_DATATYPE;
55         }
56
57         status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
58                                        domain_handle,
59                                        access_rights,
60                                        user_rids.ids[0],
61                                        alias_handle);
62         if (NT_STATUS_IS_OK(status)) {
63                 werr = ntstatus_to_werror(status);
64                 goto done;
65         }
66
67         werr = WERR_OK;
68
69  done:
70         return werr;
71 }
72
73 /****************************************************************
74 ****************************************************************/
75
76 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
77                           struct NetLocalGroupAdd *r)
78 {
79         struct cli_state *cli = NULL;
80         struct rpc_pipe_client *pipe_cli = NULL;
81         NTSTATUS status;
82         WERROR werr;
83         struct lsa_String lsa_account_name;
84         struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
85         struct dom_sid2 *domain_sid = NULL;
86         uint32_t rid;
87
88         struct LOCALGROUP_INFO_0 *info0;
89         struct LOCALGROUP_INFO_1 *info1;
90
91         const char *alias_name = NULL;
92
93         if (!r->in.buf) {
94                 return WERR_INVALID_PARAM;
95         }
96
97         switch (r->in.level) {
98                 case 0:
99                         info0 = (struct LOCALGROUP_INFO_0 *)r->in.buf;
100                         alias_name = info0->lgrpi0_name;
101                         break;
102                 case 1:
103                         info1 = (struct LOCALGROUP_INFO_1 *)r->in.buf;
104                         alias_name = info1->lgrpi1_name;
105                         break;
106                 default:
107                         werr = WERR_UNKNOWN_LEVEL;
108                         goto done;
109         }
110
111         ZERO_STRUCT(connect_handle);
112         ZERO_STRUCT(builtin_handle);
113         ZERO_STRUCT(domain_handle);
114         ZERO_STRUCT(alias_handle);
115
116         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
117         if (!W_ERROR_IS_OK(werr)) {
118                 goto done;
119         }
120
121         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
122         if (!W_ERROR_IS_OK(werr)) {
123                 goto done;
124         }
125
126         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
127                                                   SAMR_ACCESS_OPEN_DOMAIN |
128                                                   SAMR_ACCESS_ENUM_DOMAINS,
129                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
130                                                   &connect_handle,
131                                                   &builtin_handle);
132         if (!W_ERROR_IS_OK(werr)) {
133                 goto done;
134         }
135
136         init_lsa_String(&lsa_account_name, alias_name);
137
138         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
139                                                     &builtin_handle,
140                                                     &lsa_account_name,
141                                                     SAMR_ALIAS_ACCESS_LOOKUP_INFO,
142                                                     &alias_handle);
143
144         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
145
146         if (W_ERROR_IS_OK(werr)) {
147                 werr = WERR_ALIAS_EXISTS;
148                 goto done;
149         }
150
151         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
152                                           SAMR_ACCESS_ENUM_DOMAINS |
153                                           SAMR_ACCESS_OPEN_DOMAIN,
154                                           SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
155                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
156                                           &connect_handle,
157                                           &domain_handle,
158                                           &domain_sid);
159         if (!W_ERROR_IS_OK(werr)) {
160                 goto done;
161         }
162
163         status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
164                                             &domain_handle,
165                                             &lsa_account_name,
166                                             SEC_STD_DELETE |
167                                             SAMR_ALIAS_ACCESS_SET_INFO,
168                                             &alias_handle,
169                                             &rid);
170         if (!NT_STATUS_IS_OK(status)) {
171                 werr = ntstatus_to_werror(status);
172                 goto done;
173         }
174
175         if (r->in.level == 1) {
176
177                 union samr_AliasInfo alias_info;
178
179                 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
180
181                 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
182                                                   &alias_handle,
183                                                   ALIASINFODESCRIPTION,
184                                                   &alias_info);
185                 if (!NT_STATUS_IS_OK(status)) {
186                         werr = ntstatus_to_werror(status);
187                         goto done;
188                 }
189         }
190
191         werr = WERR_OK;
192
193  done:
194         if (!cli) {
195                 return werr;
196         }
197
198         if (is_valid_policy_hnd(&alias_handle)) {
199                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
200         }
201         if (is_valid_policy_hnd(&domain_handle)) {
202                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
203         }
204         if (is_valid_policy_hnd(&builtin_handle)) {
205                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
206         }
207         if (is_valid_policy_hnd(&connect_handle)) {
208                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
209         }
210
211         return werr;
212 }
213
214 /****************************************************************
215 ****************************************************************/
216
217 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
218                           struct NetLocalGroupAdd *r)
219 {
220         return NetLocalGroupAdd_r(ctx, r);
221 }
222
223 /****************************************************************
224 ****************************************************************/
225
226
227 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
228                           struct NetLocalGroupDel *r)
229 {
230         struct cli_state *cli = NULL;
231         struct rpc_pipe_client *pipe_cli = NULL;
232         NTSTATUS status;
233         WERROR werr;
234         struct lsa_String lsa_account_name;
235         struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
236         struct dom_sid2 *domain_sid = NULL;
237
238         if (!r->in.group_name) {
239                 return WERR_INVALID_PARAM;
240         }
241
242         ZERO_STRUCT(connect_handle);
243         ZERO_STRUCT(builtin_handle);
244         ZERO_STRUCT(domain_handle);
245         ZERO_STRUCT(alias_handle);
246
247         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
248         if (!W_ERROR_IS_OK(werr)) {
249                 goto done;
250         }
251
252         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
253         if (!W_ERROR_IS_OK(werr)) {
254                 goto done;
255         }
256
257         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
258                                                   SAMR_ACCESS_OPEN_DOMAIN |
259                                                   SAMR_ACCESS_ENUM_DOMAINS,
260                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
261                                                   &connect_handle,
262                                                   &builtin_handle);
263         if (!W_ERROR_IS_OK(werr)) {
264                 goto done;
265         }
266
267         init_lsa_String(&lsa_account_name, r->in.group_name);
268
269         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
270                                                     &builtin_handle,
271                                                     &lsa_account_name,
272                                                     SEC_STD_DELETE,
273                                                     &alias_handle);
274
275         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
276
277         if (W_ERROR_IS_OK(werr)) {
278                 goto delete_alias;
279         }
280
281         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
282                                           SAMR_ACCESS_ENUM_DOMAINS |
283                                           SAMR_ACCESS_OPEN_DOMAIN,
284                                           SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
285                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
286                                           &connect_handle,
287                                           &domain_handle,
288                                           &domain_sid);
289         if (!W_ERROR_IS_OK(werr)) {
290                 goto done;
291         }
292
293         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
294                                                     &domain_handle,
295                                                     &lsa_account_name,
296                                                     SEC_STD_DELETE,
297                                                     &alias_handle);
298
299         rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
300
301         if (!W_ERROR_IS_OK(werr)) {
302                 goto done;
303         }
304
305
306  delete_alias:
307         status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
308                                             &alias_handle);
309         if (!NT_STATUS_IS_OK(status)) {
310                 werr = ntstatus_to_werror(status);
311                 goto done;
312         }
313
314         ZERO_STRUCT(alias_handle);
315
316         werr = WERR_OK;
317
318  done:
319         if (!cli) {
320                 return werr;
321         }
322
323         if (is_valid_policy_hnd(&alias_handle)) {
324                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
325         }
326         if (is_valid_policy_hnd(&domain_handle)) {
327                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
328         }
329         if (is_valid_policy_hnd(&builtin_handle)) {
330                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
331         }
332         if (is_valid_policy_hnd(&connect_handle)) {
333                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
334         }
335
336         return werr;
337 }
338
339 /****************************************************************
340 ****************************************************************/
341
342 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
343                           struct NetLocalGroupDel *r)
344 {
345         return NetLocalGroupDel_r(ctx, r);
346 }
347
348 /****************************************************************
349 ****************************************************************/
350
351 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
352                                        struct samr_AliasInfoAll *info,
353                                        uint32_t level,
354                                        uint8_t **buffer)
355 {
356         struct LOCALGROUP_INFO_0 g0;
357         struct LOCALGROUP_INFO_1 g1;
358         struct LOCALGROUP_INFO_1002 g1002;
359
360         switch (level) {
361                 case 0:
362                         g0.lgrpi0_name          = info->name.string;
363
364                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g0, sizeof(g0));
365
366                         break;
367                 case 1:
368                         g1.lgrpi1_name          = info->name.string;
369                         g1.lgrpi1_comment       = info->description.string;
370
371                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1, sizeof(g1));
372
373                         break;
374                 case 1002:
375                         g1002.lgrpi1002_comment = info->description.string;
376
377                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1002, sizeof(g1002));
378
379                         break;
380                 default:
381                         return WERR_UNKNOWN_LEVEL;
382         }
383
384         W_ERROR_HAVE_NO_MEMORY(*buffer);
385
386         return WERR_OK;
387 }
388
389 /****************************************************************
390 ****************************************************************/
391
392 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
393                               struct NetLocalGroupGetInfo *r)
394 {
395         struct cli_state *cli = NULL;
396         struct rpc_pipe_client *pipe_cli = NULL;
397         NTSTATUS status;
398         WERROR werr;
399         struct lsa_String lsa_account_name;
400         struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
401         struct dom_sid2 *domain_sid = NULL;
402         union samr_AliasInfo *alias_info = NULL;
403
404         if (!r->in.group_name) {
405                 return WERR_INVALID_PARAM;
406         }
407
408         switch (r->in.level) {
409                 case 0:
410                 case 1:
411                 case 1002:
412                         break;
413                 default:
414                         return WERR_UNKNOWN_LEVEL;
415         }
416
417         ZERO_STRUCT(connect_handle);
418         ZERO_STRUCT(builtin_handle);
419         ZERO_STRUCT(domain_handle);
420         ZERO_STRUCT(alias_handle);
421
422         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
423         if (!W_ERROR_IS_OK(werr)) {
424                 goto done;
425         }
426
427         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
428         if (!W_ERROR_IS_OK(werr)) {
429                 goto done;
430         }
431
432         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
433                                                   SAMR_ACCESS_OPEN_DOMAIN |
434                                                   SAMR_ACCESS_ENUM_DOMAINS,
435                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
436                                                   &connect_handle,
437                                                   &builtin_handle);
438         if (!W_ERROR_IS_OK(werr)) {
439                 goto done;
440         }
441
442         init_lsa_String(&lsa_account_name, r->in.group_name);
443
444         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
445                                                     &builtin_handle,
446                                                     &lsa_account_name,
447                                                     SAMR_ALIAS_ACCESS_LOOKUP_INFO,
448                                                     &alias_handle);
449
450         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
451
452         if (W_ERROR_IS_OK(werr)) {
453                 goto query_alias;
454         }
455
456         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
457                                           SAMR_ACCESS_ENUM_DOMAINS |
458                                           SAMR_ACCESS_OPEN_DOMAIN,
459                                           SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
460                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
461                                           &connect_handle,
462                                           &domain_handle,
463                                           &domain_sid);
464         if (!W_ERROR_IS_OK(werr)) {
465                 goto done;
466         }
467
468         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
469                                                     &domain_handle,
470                                                     &lsa_account_name,
471                                                     SAMR_ALIAS_ACCESS_LOOKUP_INFO,
472                                                     &alias_handle);
473
474         rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
475
476         if (!W_ERROR_IS_OK(werr)) {
477                 goto done;
478         }
479
480  query_alias:
481         status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
482                                             &alias_handle,
483                                             ALIASINFOALL,
484                                             &alias_info);
485         if (!NT_STATUS_IS_OK(status)) {
486                 werr = ntstatus_to_werror(status);
487                 goto done;
488         }
489
490         werr = map_alias_info_to_buffer(ctx, &alias_info->all,
491                                         r->in.level, r->out.buf);
492
493  done:
494         if (!cli) {
495                 return werr;
496         }
497
498         if (is_valid_policy_hnd(&alias_handle)) {
499                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
500         }
501         if (is_valid_policy_hnd(&domain_handle)) {
502                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
503         }
504         if (is_valid_policy_hnd(&builtin_handle)) {
505                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
506         }
507         if (is_valid_policy_hnd(&connect_handle)) {
508                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
509         }
510
511         return werr;
512 }
513
514 /****************************************************************
515 ****************************************************************/
516
517 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
518                               struct NetLocalGroupGetInfo *r)
519 {
520         return NetLocalGroupGetInfo_r(ctx, r);
521 }
522
523 /****************************************************************
524 ****************************************************************/
525
526 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
527                                        uint32_t level,
528                                        uint8_t *buffer,
529                                        enum samr_AliasInfoEnum *alias_level,
530                                        union samr_AliasInfo **alias_info)
531 {
532         struct LOCALGROUP_INFO_0 *info0;
533         struct LOCALGROUP_INFO_1 *info1;
534         struct LOCALGROUP_INFO_1002 *info1002;
535         union samr_AliasInfo *info = NULL;
536
537         info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
538         W_ERROR_HAVE_NO_MEMORY(info);
539
540         switch (level) {
541                 case 0:
542                         info0 = (struct LOCALGROUP_INFO_0 *)buffer;
543                         init_lsa_String(&info->name, info0->lgrpi0_name);
544                         *alias_level = ALIASINFONAME;
545                         break;
546                 case 1:
547                         info1 = (struct LOCALGROUP_INFO_1 *)buffer;
548                         /* group name will be ignored */
549                         init_lsa_String(&info->description, info1->lgrpi1_comment);
550                         *alias_level = ALIASINFODESCRIPTION;
551                         break;
552                 case 1002:
553                         info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
554                         init_lsa_String(&info->description, info1002->lgrpi1002_comment);
555                         *alias_level = ALIASINFODESCRIPTION;
556                         break;
557         }
558
559         *alias_info = info;
560
561         return WERR_OK;
562 }
563
564 /****************************************************************
565 ****************************************************************/
566
567 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
568                               struct NetLocalGroupSetInfo *r)
569 {
570         struct cli_state *cli = NULL;
571         struct rpc_pipe_client *pipe_cli = NULL;
572         NTSTATUS status;
573         WERROR werr;
574         struct lsa_String lsa_account_name;
575         struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
576         struct dom_sid2 *domain_sid = NULL;
577         enum samr_AliasInfoEnum alias_level;
578         union samr_AliasInfo *alias_info = NULL;
579
580         if (!r->in.group_name) {
581                 return WERR_INVALID_PARAM;
582         }
583
584         switch (r->in.level) {
585                 case 0:
586                 case 1:
587                 case 1002:
588                         break;
589                 default:
590                         return WERR_UNKNOWN_LEVEL;
591         }
592
593         ZERO_STRUCT(connect_handle);
594         ZERO_STRUCT(builtin_handle);
595         ZERO_STRUCT(domain_handle);
596         ZERO_STRUCT(alias_handle);
597
598         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
599         if (!W_ERROR_IS_OK(werr)) {
600                 goto done;
601         }
602
603         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
604         if (!W_ERROR_IS_OK(werr)) {
605                 goto done;
606         }
607
608         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
609                                                   SAMR_ACCESS_OPEN_DOMAIN |
610                                                   SAMR_ACCESS_ENUM_DOMAINS,
611                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
612                                                   &connect_handle,
613                                                   &builtin_handle);
614         if (!W_ERROR_IS_OK(werr)) {
615                 goto done;
616         }
617
618         init_lsa_String(&lsa_account_name, r->in.group_name);
619
620         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
621                                                     &builtin_handle,
622                                                     &lsa_account_name,
623                                                     SAMR_ALIAS_ACCESS_SET_INFO,
624                                                     &alias_handle);
625
626         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
627
628         if (W_ERROR_IS_OK(werr)) {
629                 goto set_alias;
630         }
631
632         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
633                                           SAMR_ACCESS_ENUM_DOMAINS |
634                                           SAMR_ACCESS_OPEN_DOMAIN,
635                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
636                                           &connect_handle,
637                                           &domain_handle,
638                                           &domain_sid);
639         if (!W_ERROR_IS_OK(werr)) {
640                 goto done;
641         }
642
643         werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
644                                                     &domain_handle,
645                                                     &lsa_account_name,
646                                                     SAMR_ALIAS_ACCESS_SET_INFO,
647                                                     &alias_handle);
648         if (!W_ERROR_IS_OK(werr)) {
649                 goto done;
650         }
651
652         rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
653
654  set_alias:
655
656         werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buf,
657                                         &alias_level, &alias_info);
658         if (!W_ERROR_IS_OK(werr)) {
659                 goto done;
660         }
661
662         status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
663                                           &alias_handle,
664                                           alias_level,
665                                           alias_info);
666         if (!NT_STATUS_IS_OK(status)) {
667                 werr = ntstatus_to_werror(status);
668                 goto done;
669         }
670
671         werr = WERR_OK;
672
673  done:
674         if (!cli) {
675                 return werr;
676         }
677
678         if (is_valid_policy_hnd(&alias_handle)) {
679                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
680         }
681         if (is_valid_policy_hnd(&domain_handle)) {
682                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
683         }
684         if (is_valid_policy_hnd(&builtin_handle)) {
685                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
686         }
687         if (is_valid_policy_hnd(&connect_handle)) {
688                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
689         }
690
691         return werr;
692 }
693
694 /****************************************************************
695 ****************************************************************/
696
697 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
698                               struct NetLocalGroupSetInfo *r)
699 {
700         return NetLocalGroupSetInfo_r(ctx, r);
701 }