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 /****************************************************************
28 ****************************************************************/
30 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
31 struct NetLocalGroupAdd *r)
33 struct cli_state *cli = NULL;
34 struct rpc_pipe_client *pipe_cli = NULL;
37 struct lsa_String lsa_account_name;
38 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
39 struct samr_Ids user_rids, name_types;
40 struct dom_sid2 *domain_sid = NULL;
43 struct LOCALGROUP_INFO_0 *info0;
44 struct LOCALGROUP_INFO_1 *info1;
46 const char *alias_name = NULL;
49 return WERR_INVALID_PARAM;
52 switch (r->in.level) {
54 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buf;
55 alias_name = info0->lgrpi0_name;
58 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buf;
59 alias_name = info1->lgrpi1_name;
62 werr = WERR_UNKNOWN_LEVEL;
66 ZERO_STRUCT(connect_handle);
67 ZERO_STRUCT(builtin_handle);
68 ZERO_STRUCT(domain_handle);
69 ZERO_STRUCT(alias_handle);
71 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
72 if (!W_ERROR_IS_OK(werr)) {
76 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
77 if (!W_ERROR_IS_OK(werr)) {
81 status = rpccli_try_samr_connects(pipe_cli, ctx,
82 SAMR_ACCESS_OPEN_DOMAIN |
83 SAMR_ACCESS_ENUM_DOMAINS,
85 if (!NT_STATUS_IS_OK(status)) {
86 werr = ntstatus_to_werror(status);
90 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
92 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
93 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
95 if (!NT_STATUS_IS_OK(status)) {
96 werr = ntstatus_to_werror(status);
100 init_lsa_String(&lsa_account_name, alias_name);
102 status = rpccli_samr_LookupNames(pipe_cli, ctx,
108 if (NT_STATUS_IS_OK(status)) {
109 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
111 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
114 if (NT_STATUS_IS_OK(status)) {
115 werr = WERR_ALIAS_EXISTS;
121 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
123 status = libnetapi_samr_open_domain(ctx, pipe_cli,
124 SAMR_ACCESS_ENUM_DOMAINS |
125 SAMR_ACCESS_OPEN_DOMAIN,
126 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
127 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
131 if (!NT_STATUS_IS_OK(status)) {
132 werr = ntstatus_to_werror(status);
136 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
140 SAMR_ALIAS_ACCESS_SET_INFO,
143 if (!NT_STATUS_IS_OK(status)) {
144 werr = ntstatus_to_werror(status);
148 if (r->in.level == 1) {
150 union samr_AliasInfo alias_info;
152 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
154 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
156 ALIASINFODESCRIPTION,
158 if (!NT_STATUS_IS_OK(status)) {
159 werr = ntstatus_to_werror(status);
171 if (is_valid_policy_hnd(&alias_handle)) {
172 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
174 if (is_valid_policy_hnd(&domain_handle)) {
175 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
177 if (is_valid_policy_hnd(&builtin_handle)) {
178 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
180 if (is_valid_policy_hnd(&connect_handle)) {
181 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
187 /****************************************************************
188 ****************************************************************/
190 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
191 struct NetLocalGroupAdd *r)
193 return NetLocalGroupAdd_r(ctx, r);
196 /****************************************************************
197 ****************************************************************/
200 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
201 struct NetLocalGroupDel *r)
203 struct cli_state *cli = NULL;
204 struct rpc_pipe_client *pipe_cli = NULL;
207 struct lsa_String lsa_account_name;
208 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
209 struct samr_Ids user_rids, name_types;
210 struct dom_sid2 *domain_sid = NULL;
212 if (!r->in.group_name) {
213 return WERR_INVALID_PARAM;
216 ZERO_STRUCT(connect_handle);
217 ZERO_STRUCT(builtin_handle);
218 ZERO_STRUCT(domain_handle);
219 ZERO_STRUCT(alias_handle);
221 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
222 if (!W_ERROR_IS_OK(werr)) {
226 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
227 if (!W_ERROR_IS_OK(werr)) {
231 status = rpccli_try_samr_connects(pipe_cli, ctx,
232 SAMR_ACCESS_OPEN_DOMAIN |
233 SAMR_ACCESS_ENUM_DOMAINS,
235 if (!NT_STATUS_IS_OK(status)) {
236 werr = ntstatus_to_werror(status);
240 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
242 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
243 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
245 if (!NT_STATUS_IS_OK(status)) {
246 werr = ntstatus_to_werror(status);
250 init_lsa_String(&lsa_account_name, r->in.group_name);
252 status = rpccli_samr_LookupNames(pipe_cli, ctx,
258 if (NT_STATUS_IS_OK(status)) {
259 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
264 if (NT_STATUS_IS_OK(status)) {
265 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
270 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
272 status = libnetapi_samr_open_domain(ctx, pipe_cli,
273 SAMR_ACCESS_ENUM_DOMAINS |
274 SAMR_ACCESS_OPEN_DOMAIN,
275 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
276 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
280 if (!NT_STATUS_IS_OK(status)) {
281 werr = ntstatus_to_werror(status);
285 status = rpccli_samr_LookupNames(pipe_cli, ctx,
291 if (!NT_STATUS_IS_OK(status)) {
292 werr = ntstatus_to_werror(status);
296 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
301 if (!NT_STATUS_IS_OK(status)) {
302 werr = ntstatus_to_werror(status);
306 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
309 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
311 if (!NT_STATUS_IS_OK(status)) {
312 werr = ntstatus_to_werror(status);
316 ZERO_STRUCT(alias_handle);
325 if (is_valid_policy_hnd(&alias_handle)) {
326 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
328 if (is_valid_policy_hnd(&domain_handle)) {
329 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
331 if (is_valid_policy_hnd(&builtin_handle)) {
332 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
334 if (is_valid_policy_hnd(&connect_handle)) {
335 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
341 /****************************************************************
342 ****************************************************************/
344 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
345 struct NetLocalGroupDel *r)
347 return NetLocalGroupDel_r(ctx, r);
350 /****************************************************************
351 ****************************************************************/
353 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
354 struct samr_AliasInfoAll *info,
358 struct LOCALGROUP_INFO_0 g0;
359 struct LOCALGROUP_INFO_1 g1;
360 struct LOCALGROUP_INFO_1002 g1002;
364 g0.lgrpi0_name = info->name.string;
366 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g0, sizeof(g0));
370 g1.lgrpi1_name = info->name.string;
371 g1.lgrpi1_comment = info->description.string;
373 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1, sizeof(g1));
377 g1002.lgrpi1002_comment = info->description.string;
379 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &g1002, sizeof(g1002));
383 return WERR_UNKNOWN_LEVEL;
386 W_ERROR_HAVE_NO_MEMORY(*buffer);
391 /****************************************************************
392 ****************************************************************/
394 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
395 struct NetLocalGroupGetInfo *r)
397 struct cli_state *cli = NULL;
398 struct rpc_pipe_client *pipe_cli = NULL;
401 struct lsa_String lsa_account_name;
402 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
403 struct samr_Ids user_rids, name_types;
404 struct dom_sid2 *domain_sid = NULL;
405 union samr_AliasInfo *alias_info = NULL;
407 if (!r->in.group_name) {
408 return WERR_INVALID_PARAM;
411 switch (r->in.level) {
417 return WERR_UNKNOWN_LEVEL;
420 ZERO_STRUCT(connect_handle);
421 ZERO_STRUCT(builtin_handle);
422 ZERO_STRUCT(domain_handle);
423 ZERO_STRUCT(alias_handle);
425 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
426 if (!W_ERROR_IS_OK(werr)) {
430 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
431 if (!W_ERROR_IS_OK(werr)) {
435 status = rpccli_try_samr_connects(pipe_cli, ctx,
436 SAMR_ACCESS_OPEN_DOMAIN |
437 SAMR_ACCESS_ENUM_DOMAINS,
439 if (!NT_STATUS_IS_OK(status)) {
440 werr = ntstatus_to_werror(status);
444 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
446 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
447 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
449 if (!NT_STATUS_IS_OK(status)) {
450 werr = ntstatus_to_werror(status);
454 init_lsa_String(&lsa_account_name, r->in.group_name);
456 status = rpccli_samr_LookupNames(pipe_cli, ctx,
462 if (NT_STATUS_IS_OK(status)) {
463 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
465 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
468 if (NT_STATUS_IS_OK(status)) {
469 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
474 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
476 status = libnetapi_samr_open_domain(ctx, pipe_cli,
477 SAMR_ACCESS_ENUM_DOMAINS |
478 SAMR_ACCESS_OPEN_DOMAIN,
479 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
480 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
484 if (!NT_STATUS_IS_OK(status)) {
485 werr = ntstatus_to_werror(status);
489 status = rpccli_samr_LookupNames(pipe_cli, ctx,
495 if (!NT_STATUS_IS_OK(status)) {
496 werr = ntstatus_to_werror(status);
500 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
502 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
505 if (!NT_STATUS_IS_OK(status)) {
506 werr = ntstatus_to_werror(status);
510 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
513 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
517 if (!NT_STATUS_IS_OK(status)) {
518 werr = ntstatus_to_werror(status);
522 werr = map_alias_info_to_buffer(ctx, &alias_info->all,
523 r->in.level, r->out.buf);
530 if (is_valid_policy_hnd(&alias_handle)) {
531 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
533 if (is_valid_policy_hnd(&domain_handle)) {
534 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
536 if (is_valid_policy_hnd(&builtin_handle)) {
537 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
539 if (is_valid_policy_hnd(&connect_handle)) {
540 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
546 /****************************************************************
547 ****************************************************************/
549 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
550 struct NetLocalGroupGetInfo *r)
552 return NetLocalGroupGetInfo_r(ctx, r);