netapi: use libnetapi_samr_lookup_and_open_alias().
[Samba.git] / source / lib / netapi / localgroup.c
blobde15dcf699f8a4b9d11c2cb07821953fc0ac793f
1 /*
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/>.
20 #include "includes.h"
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 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)
34 NTSTATUS status;
35 WERROR werr;
36 struct samr_Ids user_rids, name_types;
38 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
39 domain_handle,
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;
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;
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;
67 werr = WERR_OK;
69 done:
70 return werr;
73 /****************************************************************
74 ****************************************************************/
76 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
77 struct NetLocalGroupAdd *r)
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;
88 struct LOCALGROUP_INFO_0 *info0;
89 struct LOCALGROUP_INFO_1 *info1;
91 const char *alias_name = NULL;
93 if (!r->in.buf) {
94 return WERR_INVALID_PARAM;
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;
111 ZERO_STRUCT(connect_handle);
112 ZERO_STRUCT(builtin_handle);
113 ZERO_STRUCT(domain_handle);
114 ZERO_STRUCT(alias_handle);
116 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
117 if (!W_ERROR_IS_OK(werr)) {
118 goto done;
121 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
122 if (!W_ERROR_IS_OK(werr)) {
123 goto done;
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;
136 init_lsa_String(&lsa_account_name, alias_name);
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);
144 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
146 if (W_ERROR_IS_OK(werr)) {
147 werr = WERR_ALIAS_EXISTS;
148 goto done;
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;
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;
175 if (r->in.level == 1) {
177 union samr_AliasInfo alias_info;
179 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
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;
191 werr = WERR_OK;
193 done:
194 if (!cli) {
195 return werr;
198 if (is_valid_policy_hnd(&alias_handle)) {
199 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
201 if (is_valid_policy_hnd(&domain_handle)) {
202 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
204 if (is_valid_policy_hnd(&builtin_handle)) {
205 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
207 if (is_valid_policy_hnd(&connect_handle)) {
208 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
211 return werr;
214 /****************************************************************
215 ****************************************************************/
217 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
218 struct NetLocalGroupAdd *r)
220 return NetLocalGroupAdd_r(ctx, r);
223 /****************************************************************
224 ****************************************************************/
227 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
228 struct NetLocalGroupDel *r)
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;
238 if (!r->in.group_name) {
239 return WERR_INVALID_PARAM;
242 ZERO_STRUCT(connect_handle);
243 ZERO_STRUCT(builtin_handle);
244 ZERO_STRUCT(domain_handle);
245 ZERO_STRUCT(alias_handle);
247 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
248 if (!W_ERROR_IS_OK(werr)) {
249 goto done;
252 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
253 if (!W_ERROR_IS_OK(werr)) {
254 goto done;
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;
267 init_lsa_String(&lsa_account_name, r->in.group_name);
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);
275 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
277 if (W_ERROR_IS_OK(werr)) {
278 goto delete_alias;
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;
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);
299 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
301 if (!W_ERROR_IS_OK(werr)) {
302 goto done;
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;
314 ZERO_STRUCT(alias_handle);
316 werr = WERR_OK;
318 done:
319 if (!cli) {
320 return werr;
323 if (is_valid_policy_hnd(&alias_handle)) {
324 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
326 if (is_valid_policy_hnd(&domain_handle)) {
327 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
329 if (is_valid_policy_hnd(&builtin_handle)) {
330 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
332 if (is_valid_policy_hnd(&connect_handle)) {
333 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
336 return werr;
339 /****************************************************************
340 ****************************************************************/
342 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
343 struct NetLocalGroupDel *r)
345 return NetLocalGroupDel_r(ctx, r);
348 /****************************************************************
349 ****************************************************************/
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)
356 struct LOCALGROUP_INFO_0 g0;
357 struct LOCALGROUP_INFO_1 g1;
358 struct LOCALGROUP_INFO_1002 g1002;
360 switch (level) {
361 case 0:
362 g0.lgrpi0_name = info->name.string;
364 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g0, sizeof(g0));
366 break;
367 case 1:
368 g1.lgrpi1_name = info->name.string;
369 g1.lgrpi1_comment = info->description.string;
371 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1, sizeof(g1));
373 break;
374 case 1002:
375 g1002.lgrpi1002_comment = info->description.string;
377 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1002, sizeof(g1002));
379 break;
380 default:
381 return WERR_UNKNOWN_LEVEL;
384 W_ERROR_HAVE_NO_MEMORY(*buffer);
386 return WERR_OK;
389 /****************************************************************
390 ****************************************************************/
392 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
393 struct NetLocalGroupGetInfo *r)
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;
404 if (!r->in.group_name) {
405 return WERR_INVALID_PARAM;
408 switch (r->in.level) {
409 case 0:
410 case 1:
411 case 1002:
412 break;
413 default:
414 return WERR_UNKNOWN_LEVEL;
417 ZERO_STRUCT(connect_handle);
418 ZERO_STRUCT(builtin_handle);
419 ZERO_STRUCT(domain_handle);
420 ZERO_STRUCT(alias_handle);
422 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
423 if (!W_ERROR_IS_OK(werr)) {
424 goto done;
427 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
428 if (!W_ERROR_IS_OK(werr)) {
429 goto done;
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;
442 init_lsa_String(&lsa_account_name, r->in.group_name);
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);
450 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
452 if (W_ERROR_IS_OK(werr)) {
453 goto query_alias;
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;
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);
474 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
476 if (!W_ERROR_IS_OK(werr)) {
477 goto done;
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;
490 werr = map_alias_info_to_buffer(ctx, &alias_info->all,
491 r->in.level, r->out.buf);
493 done:
494 if (!cli) {
495 return werr;
498 if (is_valid_policy_hnd(&alias_handle)) {
499 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
501 if (is_valid_policy_hnd(&domain_handle)) {
502 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
504 if (is_valid_policy_hnd(&builtin_handle)) {
505 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
507 if (is_valid_policy_hnd(&connect_handle)) {
508 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
511 return werr;
514 /****************************************************************
515 ****************************************************************/
517 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
518 struct NetLocalGroupGetInfo *r)
520 return NetLocalGroupGetInfo_r(ctx, r);
523 /****************************************************************
524 ****************************************************************/
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)
532 struct LOCALGROUP_INFO_0 *info0;
533 struct LOCALGROUP_INFO_1 *info1;
534 struct LOCALGROUP_INFO_1002 *info1002;
535 union samr_AliasInfo *info = NULL;
537 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
538 W_ERROR_HAVE_NO_MEMORY(info);
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;
559 *alias_info = info;
561 return WERR_OK;
564 /****************************************************************
565 ****************************************************************/
567 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
568 struct NetLocalGroupSetInfo *r)
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;
580 if (!r->in.group_name) {
581 return WERR_INVALID_PARAM;
584 switch (r->in.level) {
585 case 0:
586 case 1:
587 case 1002:
588 break;
589 default:
590 return WERR_UNKNOWN_LEVEL;
593 ZERO_STRUCT(connect_handle);
594 ZERO_STRUCT(builtin_handle);
595 ZERO_STRUCT(domain_handle);
596 ZERO_STRUCT(alias_handle);
598 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
599 if (!W_ERROR_IS_OK(werr)) {
600 goto done;
603 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
604 if (!W_ERROR_IS_OK(werr)) {
605 goto done;
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;
618 init_lsa_String(&lsa_account_name, r->in.group_name);
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);
626 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
628 if (W_ERROR_IS_OK(werr)) {
629 goto set_alias;
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;
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;
652 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
654 set_alias:
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;
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;
671 werr = WERR_OK;
673 done:
674 if (!cli) {
675 return werr;
678 if (is_valid_policy_hnd(&alias_handle)) {
679 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
681 if (is_valid_policy_hnd(&domain_handle)) {
682 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
684 if (is_valid_policy_hnd(&builtin_handle)) {
685 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
687 if (is_valid_policy_hnd(&connect_handle)) {
688 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
691 return werr;
694 /****************************************************************
695 ****************************************************************/
697 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
698 struct NetLocalGroupSetInfo *r)
700 return NetLocalGroupSetInfo_r(ctx, r);