2 * Unix SMB/CIFS implementation.
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 NetGroupAdd_r(struct libnetapi_ctx *ctx,
31 struct NetGroupAdd *r)
33 struct cli_state *cli = NULL;
34 struct rpc_pipe_client *pipe_cli = NULL;
37 uint32_t resume_handle = 0;
38 uint32_t num_entries = 0;
39 POLICY_HND connect_handle, domain_handle, group_handle;
40 struct samr_SamArray *sam = NULL;
41 const char *domain_name = NULL;
42 struct lsa_String lsa_domain_name, lsa_group_name;
43 struct dom_sid2 *domain_sid = NULL;
45 bool domain_found = true;
47 struct GROUP_INFO_0 *info0;
48 struct GROUP_INFO_1 *info1;
49 struct GROUP_INFO_2 *info2;
50 struct GROUP_INFO_3 *info3;
51 union samr_GroupInfo info;
53 ZERO_STRUCT(connect_handle);
54 ZERO_STRUCT(domain_handle);
55 ZERO_STRUCT(group_handle);
58 return WERR_INVALID_PARAM;
61 switch (r->in.level) {
63 info0 = (struct GROUP_INFO_0 *)r->in.buf;
66 info1 = (struct GROUP_INFO_1 *)r->in.buf;
69 info2 = (struct GROUP_INFO_2 *)r->in.buf;
72 info3 = (struct GROUP_INFO_3 *)r->in.buf;
75 werr = WERR_UNKNOWN_LEVEL;
79 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
80 if (!W_ERROR_IS_OK(werr)) {
84 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
85 if (!W_ERROR_IS_OK(werr)) {
89 status = rpccli_try_samr_connects(pipe_cli, ctx,
90 SAMR_ACCESS_ENUM_DOMAINS |
91 SAMR_ACCESS_OPEN_DOMAIN,
93 if (!NT_STATUS_IS_OK(status)) {
94 werr = ntstatus_to_werror(status);
98 status = rpccli_samr_EnumDomains(pipe_cli, ctx,
104 if (!NT_STATUS_IS_OK(status)) {
105 werr = ntstatus_to_werror(status);
109 for (i=0; i<num_entries; i++) {
111 domain_name = sam->entries[i].name.string;
113 if (strequal(domain_name, builtin_domain_name())) {
122 werr = WERR_NO_SUCH_DOMAIN;
126 init_lsa_String(&lsa_domain_name, domain_name);
128 status = rpccli_samr_LookupDomain(pipe_cli, ctx,
132 if (!NT_STATUS_IS_OK(status)) {
133 werr = ntstatus_to_werror(status);
137 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
139 SAMR_DOMAIN_ACCESS_CREATE_GROUP |
140 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
143 if (!NT_STATUS_IS_OK(status)) {
144 werr = ntstatus_to_werror(status);
148 switch (r->in.level) {
150 init_lsa_String(&lsa_group_name, info0->grpi0_name);
153 init_lsa_String(&lsa_group_name, info1->grpi1_name);
156 init_lsa_String(&lsa_group_name, info2->grpi2_name);
159 init_lsa_String(&lsa_group_name, info3->grpi3_name);
163 status = rpccli_samr_CreateDomainGroup(pipe_cli, ctx,
167 SAMR_GROUP_ACCESS_SET_INFO,
171 if (!NT_STATUS_IS_OK(status)) {
172 werr = ntstatus_to_werror(status);
176 switch (r->in.level) {
178 if (info1->grpi1_comment) {
179 init_lsa_String(&info.description,
180 info1->grpi1_comment);
182 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
184 GROUPINFODESCRIPTION,
189 if (info2->grpi2_comment) {
190 init_lsa_String(&info.description,
191 info2->grpi2_comment);
193 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
195 GROUPINFODESCRIPTION,
197 if (!NT_STATUS_IS_OK(status)) {
198 werr = ntstatus_to_werror(status);
203 if (info2->grpi2_attributes != 0) {
204 info.attributes.attributes = info2->grpi2_attributes;
205 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
213 if (info3->grpi3_comment) {
214 init_lsa_String(&info.description,
215 info3->grpi3_comment);
217 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
219 GROUPINFODESCRIPTION,
221 if (!NT_STATUS_IS_OK(status)) {
222 werr = ntstatus_to_werror(status);
227 if (info3->grpi3_attributes != 0) {
228 info.attributes.attributes = info3->grpi3_attributes;
229 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
239 if (!NT_STATUS_IS_OK(status)) {
240 werr = ntstatus_to_werror(status);
248 rpccli_samr_DeleteDomainGroup(pipe_cli, ctx,
256 if (is_valid_policy_hnd(&group_handle)) {
257 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
259 if (is_valid_policy_hnd(&domain_handle)) {
260 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
262 if (is_valid_policy_hnd(&connect_handle)) {
263 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
269 /****************************************************************
270 ****************************************************************/
272 WERROR NetGroupAdd_l(struct libnetapi_ctx *ctx,
273 struct NetGroupAdd *r)
275 return NetGroupAdd_r(ctx, r);
278 /****************************************************************
279 ****************************************************************/
281 WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
282 struct NetGroupDel *r)
284 struct cli_state *cli = NULL;
285 struct rpc_pipe_client *pipe_cli = NULL;
288 uint32_t resume_handle = 0;
289 uint32_t num_entries = 0;
290 POLICY_HND connect_handle, domain_handle, group_handle;
291 struct samr_SamArray *sam = NULL;
292 const char *domain_name = NULL;
293 struct lsa_String lsa_domain_name, lsa_group_name;
294 struct dom_sid2 *domain_sid = NULL;
295 bool domain_found = true;
298 struct samr_Ids rids;
299 struct samr_Ids types;
300 union samr_GroupInfo *info = NULL;
301 struct samr_RidTypeArray *rid_array = NULL;
303 ZERO_STRUCT(connect_handle);
304 ZERO_STRUCT(domain_handle);
305 ZERO_STRUCT(group_handle);
307 if (!r->in.group_name) {
308 return WERR_INVALID_PARAM;
311 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
312 if (!W_ERROR_IS_OK(werr)) {
316 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
317 if (!W_ERROR_IS_OK(werr)) {
321 status = rpccli_try_samr_connects(pipe_cli, ctx,
322 SAMR_ACCESS_ENUM_DOMAINS |
323 SAMR_ACCESS_OPEN_DOMAIN,
325 if (!NT_STATUS_IS_OK(status)) {
326 werr = ntstatus_to_werror(status);
330 status = rpccli_samr_EnumDomains(pipe_cli, ctx,
336 if (!NT_STATUS_IS_OK(status)) {
337 werr = ntstatus_to_werror(status);
341 for (i=0; i<num_entries; i++) {
343 domain_name = sam->entries[i].name.string;
345 if (strequal(domain_name, builtin_domain_name())) {
354 werr = WERR_NO_SUCH_DOMAIN;
358 init_lsa_String(&lsa_domain_name, domain_name);
360 status = rpccli_samr_LookupDomain(pipe_cli, ctx,
364 if (!NT_STATUS_IS_OK(status)) {
365 werr = ntstatus_to_werror(status);
369 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
371 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
374 if (!NT_STATUS_IS_OK(status)) {
375 werr = ntstatus_to_werror(status);
379 init_lsa_String(&lsa_group_name, r->in.group_name);
381 status = rpccli_samr_LookupNames(pipe_cli, ctx,
387 if (!NT_STATUS_IS_OK(status)) {
388 werr = ntstatus_to_werror(status);
392 if (types.ids[0] != SID_NAME_DOM_GRP) {
393 werr = WERR_INVALID_DATATYPE;
397 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
400 SAMR_GROUP_ACCESS_GET_MEMBERS |
401 SAMR_GROUP_ACCESS_REMOVE_MEMBER |
402 SAMR_GROUP_ACCESS_ADD_MEMBER |
403 SAMR_GROUP_ACCESS_LOOKUP_INFO,
406 if (!NT_STATUS_IS_OK(status)) {
407 werr = ntstatus_to_werror(status);
411 status = rpccli_samr_QueryGroupInfo(pipe_cli, ctx,
415 if (!NT_STATUS_IS_OK(status)) {
416 werr = ntstatus_to_werror(status);
420 if (!(info->attributes.attributes & SE_GROUP_ENABLED)) {
421 werr = WERR_ACCESS_DENIED;
425 status = rpccli_samr_QueryGroupMember(pipe_cli, ctx,
428 if (!NT_STATUS_IS_OK(status)) {
429 werr = ntstatus_to_werror(status);
434 struct lsa_Strings names;
435 struct samr_Ids member_types;
437 status = rpccli_samr_LookupRids(pipe_cli, ctx,
443 if (!NT_STATUS_IS_OK(status)) {
444 werr = ntstatus_to_werror(status);
449 for (i=0; i < rid_array->count; i++) {
451 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
454 if (!NT_STATUS_IS_OK(status)) {
455 werr = ntstatus_to_werror(status);
460 status = rpccli_samr_DeleteDomainGroup(pipe_cli, ctx,
462 if (!NT_STATUS_IS_OK(status)) {
463 werr = ntstatus_to_werror(status);
467 ZERO_STRUCT(group_handle);
476 if (is_valid_policy_hnd(&group_handle)) {
477 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
479 if (is_valid_policy_hnd(&domain_handle)) {
480 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
482 if (is_valid_policy_hnd(&connect_handle)) {
483 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
489 /****************************************************************
490 ****************************************************************/
492 WERROR NetGroupDel_l(struct libnetapi_ctx *ctx,
493 struct NetGroupDel *r)
495 return NetGroupDel_r(ctx, r);