2 * Unix SMB/CIFS implementation.
3 * NetApi LocalGroup Support
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
27 static 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
)
36 struct samr_Ids user_rids
, name_types
;
38 status
= rpccli_samr_LookupNames(pipe_cli
, mem_ctx
,
44 if (!NT_STATUS_IS_OK(status
)) {
45 werr
= ntstatus_to_werror(status
);
49 switch (name_types
.ids
[0]) {
51 case SID_NAME_WKN_GRP
:
54 return WERR_INVALID_DATATYPE
;
57 status
= rpccli_samr_OpenAlias(pipe_cli
, mem_ctx
,
62 if (NT_STATUS_IS_OK(status
)) {
63 werr
= ntstatus_to_werror(status
);
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
;
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
;
88 struct LOCALGROUP_INFO_0
*info0
;
89 struct LOCALGROUP_INFO_1
*info1
;
91 const char *alias_name
= NULL
;
94 return WERR_INVALID_PARAM
;
97 switch (r
->in
.level
) {
99 info0
= (struct LOCALGROUP_INFO_0
*)r
->in
.buf
;
100 alias_name
= info0
->lgrpi0_name
;
103 info1
= (struct LOCALGROUP_INFO_1
*)r
->in
.buf
;
104 alias_name
= info1
->lgrpi1_name
;
107 werr
= WERR_UNKNOWN_LEVEL
;
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
)) {
121 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
122 if (!W_ERROR_IS_OK(werr
)) {
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
,
132 if (!W_ERROR_IS_OK(werr
)) {
136 init_lsa_String(&lsa_account_name
, alias_name
);
138 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
141 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
144 rpccli_samr_Close(pipe_cli
, ctx
, &builtin_handle
);
146 if (W_ERROR_IS_OK(werr
)) {
147 werr
= WERR_ALIAS_EXISTS
;
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
,
159 if (!W_ERROR_IS_OK(werr
)) {
163 status
= rpccli_samr_CreateDomAlias(pipe_cli
, ctx
,
167 SAMR_ALIAS_ACCESS_SET_INFO
,
170 if (!NT_STATUS_IS_OK(status
)) {
171 werr
= ntstatus_to_werror(status
);
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
,
183 ALIASINFODESCRIPTION
,
185 if (!NT_STATUS_IS_OK(status
)) {
186 werr
= ntstatus_to_werror(status
);
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
);
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
;
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
)) {
252 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
253 if (!W_ERROR_IS_OK(werr
)) {
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
,
263 if (!W_ERROR_IS_OK(werr
)) {
267 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
269 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
275 rpccli_samr_Close(pipe_cli
, ctx
, &builtin_handle
);
277 if (W_ERROR_IS_OK(werr
)) {
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
,
289 if (!W_ERROR_IS_OK(werr
)) {
293 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
299 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
301 if (!W_ERROR_IS_OK(werr
)) {
307 status
= rpccli_samr_DeleteDomAlias(pipe_cli
, ctx
,
309 if (!NT_STATUS_IS_OK(status
)) {
310 werr
= ntstatus_to_werror(status
);
314 ZERO_STRUCT(alias_handle
);
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
);
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
,
356 struct LOCALGROUP_INFO_0 g0
;
357 struct LOCALGROUP_INFO_1 g1
;
358 struct LOCALGROUP_INFO_1002 g1002
;
362 g0
.lgrpi0_name
= info
->name
.string
;
364 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &g0
, sizeof(g0
));
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
));
375 g1002
.lgrpi1002_comment
= info
->description
.string
;
377 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &g1002
, sizeof(g1002
));
381 return WERR_UNKNOWN_LEVEL
;
384 W_ERROR_HAVE_NO_MEMORY(*buffer
);
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
;
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
) {
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
)) {
427 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
428 if (!W_ERROR_IS_OK(werr
)) {
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
,
438 if (!W_ERROR_IS_OK(werr
)) {
442 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
444 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
447 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
450 rpccli_samr_Close(pipe_cli
, ctx
, &builtin_handle
);
452 if (W_ERROR_IS_OK(werr
)) {
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
,
464 if (!W_ERROR_IS_OK(werr
)) {
468 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
471 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
474 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
476 if (!W_ERROR_IS_OK(werr
)) {
481 status
= rpccli_samr_QueryAliasInfo(pipe_cli
, ctx
,
485 if (!NT_STATUS_IS_OK(status
)) {
486 werr
= ntstatus_to_werror(status
);
490 werr
= map_alias_info_to_buffer(ctx
, &alias_info
->all
,
491 r
->in
.level
, r
->out
.buf
);
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
);
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
,
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
);
542 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
543 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
544 *alias_level
= ALIASINFONAME
;
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
;
553 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
554 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
555 *alias_level
= ALIASINFODESCRIPTION
;
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
;
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
) {
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
)) {
603 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
604 if (!W_ERROR_IS_OK(werr
)) {
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
,
614 if (!W_ERROR_IS_OK(werr
)) {
618 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
620 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
623 SAMR_ALIAS_ACCESS_SET_INFO
,
626 rpccli_samr_Close(pipe_cli
, ctx
, &builtin_handle
);
628 if (W_ERROR_IS_OK(werr
)) {
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
,
639 if (!W_ERROR_IS_OK(werr
)) {
643 werr
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
646 SAMR_ALIAS_ACCESS_SET_INFO
,
648 if (!W_ERROR_IS_OK(werr
)) {
652 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
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
)) {
662 status
= rpccli_samr_SetAliasInfo(pipe_cli
, ctx
,
666 if (!NT_STATUS_IS_OK(status
)) {
667 werr
= ntstatus_to_werror(status
);
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
);
694 /****************************************************************
695 ****************************************************************/
697 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
698 struct NetLocalGroupSetInfo
*r
)
700 return NetLocalGroupSetInfo_r(ctx
, r
);