netapi: add NetLocalGroupGetInfo() skeleton.
[nivanova/samba-autobuild/.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 /****************************************************************
28 ****************************************************************/
29
30 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
31                           struct NetLocalGroupAdd *r)
32 {
33         struct cli_state *cli = NULL;
34         struct rpc_pipe_client *pipe_cli = NULL;
35         NTSTATUS status;
36         WERROR werr;
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;
41         uint32_t rid;
42
43         struct LOCALGROUP_INFO_0 *info0;
44         struct LOCALGROUP_INFO_1 *info1;
45
46         const char *alias_name = NULL;
47
48         if (!r->in.buf) {
49                 return WERR_INVALID_PARAM;
50         }
51
52         switch (r->in.level) {
53                 case 0:
54                         info0 = (struct LOCALGROUP_INFO_0 *)r->in.buf;
55                         alias_name = info0->lgrpi0_name;
56                         break;
57                 case 1:
58                         info1 = (struct LOCALGROUP_INFO_1 *)r->in.buf;
59                         alias_name = info1->lgrpi1_name;
60                         break;
61                 default:
62                         werr = WERR_UNKNOWN_LEVEL;
63                         goto done;
64         }
65
66         ZERO_STRUCT(connect_handle);
67         ZERO_STRUCT(builtin_handle);
68         ZERO_STRUCT(domain_handle);
69         ZERO_STRUCT(alias_handle);
70
71         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
72         if (!W_ERROR_IS_OK(werr)) {
73                 goto done;
74         }
75
76         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
77         if (!W_ERROR_IS_OK(werr)) {
78                 goto done;
79         }
80
81         status = rpccli_try_samr_connects(pipe_cli, ctx,
82                                           SAMR_ACCESS_OPEN_DOMAIN |
83                                           SAMR_ACCESS_ENUM_DOMAINS,
84                                           &connect_handle);
85         if (!NT_STATUS_IS_OK(status)) {
86                 werr = ntstatus_to_werror(status);
87                 goto done;
88         }
89
90         status = rpccli_samr_OpenDomain(pipe_cli, ctx,
91                                         &connect_handle,
92                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
93                                         CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
94                                         &builtin_handle);
95         if (!NT_STATUS_IS_OK(status)) {
96                 werr = ntstatus_to_werror(status);
97                 goto done;
98         }
99
100         init_lsa_String(&lsa_account_name, alias_name);
101
102         status = rpccli_samr_LookupNames(pipe_cli, ctx,
103                                          &builtin_handle,
104                                          1,
105                                          &lsa_account_name,
106                                          &user_rids,
107                                          &name_types);
108         if (NT_STATUS_IS_OK(status)) {
109                 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
110                                                &builtin_handle,
111                                                SAMR_ALIAS_ACCESS_LOOKUP_INFO,
112                                                user_rids.ids[0],
113                                                &alias_handle);
114                 if (NT_STATUS_IS_OK(status)) {
115                         werr = WERR_ALIAS_EXISTS;
116                         goto done;
117                 }
118
119         }
120
121         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
122
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,
128                                             &connect_handle,
129                                             &domain_handle,
130                                             &domain_sid);
131         if (!NT_STATUS_IS_OK(status)) {
132                 werr = ntstatus_to_werror(status);
133                 goto done;
134         }
135
136         status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
137                                             &domain_handle,
138                                             &lsa_account_name,
139                                             SEC_STD_DELETE |
140                                             SAMR_ALIAS_ACCESS_SET_INFO,
141                                             &alias_handle,
142                                             &rid);
143         if (!NT_STATUS_IS_OK(status)) {
144                 werr = ntstatus_to_werror(status);
145                 goto done;
146         }
147
148         if (r->in.level == 1) {
149
150                 union samr_AliasInfo alias_info;
151
152                 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
153
154                 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
155                                                   &alias_handle,
156                                                   ALIASINFODESCRIPTION,
157                                                   &alias_info);
158                 if (!NT_STATUS_IS_OK(status)) {
159                         werr = ntstatus_to_werror(status);
160                         goto done;
161                 }
162         }
163
164         werr = WERR_OK;
165
166  done:
167         if (!cli) {
168                 return werr;
169         }
170
171         if (is_valid_policy_hnd(&alias_handle)) {
172                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
173         }
174         if (is_valid_policy_hnd(&domain_handle)) {
175                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
176         }
177         if (is_valid_policy_hnd(&builtin_handle)) {
178                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
179         }
180         if (is_valid_policy_hnd(&connect_handle)) {
181                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
182         }
183
184         return werr;
185 }
186
187 /****************************************************************
188 ****************************************************************/
189
190 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
191                           struct NetLocalGroupAdd *r)
192 {
193         return NetLocalGroupAdd_r(ctx, r);
194 }
195
196 /****************************************************************
197 ****************************************************************/
198
199
200 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
201                           struct NetLocalGroupDel *r)
202 {
203         struct cli_state *cli = NULL;
204         struct rpc_pipe_client *pipe_cli = NULL;
205         NTSTATUS status;
206         WERROR werr;
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;
211
212         if (!r->in.group_name) {
213                 return WERR_INVALID_PARAM;
214         }
215
216         ZERO_STRUCT(connect_handle);
217         ZERO_STRUCT(builtin_handle);
218         ZERO_STRUCT(domain_handle);
219         ZERO_STRUCT(alias_handle);
220
221         werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
222         if (!W_ERROR_IS_OK(werr)) {
223                 goto done;
224         }
225
226         werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
227         if (!W_ERROR_IS_OK(werr)) {
228                 goto done;
229         }
230
231         status = rpccli_try_samr_connects(pipe_cli, ctx,
232                                           SAMR_ACCESS_OPEN_DOMAIN |
233                                           SAMR_ACCESS_ENUM_DOMAINS,
234                                           &connect_handle);
235         if (!NT_STATUS_IS_OK(status)) {
236                 werr = ntstatus_to_werror(status);
237                 goto done;
238         }
239
240         status = rpccli_samr_OpenDomain(pipe_cli, ctx,
241                                         &connect_handle,
242                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
243                                         CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
244                                         &builtin_handle);
245         if (!NT_STATUS_IS_OK(status)) {
246                 werr = ntstatus_to_werror(status);
247                 goto done;
248         }
249
250         init_lsa_String(&lsa_account_name, r->in.group_name);
251
252         status = rpccli_samr_LookupNames(pipe_cli, ctx,
253                                          &builtin_handle,
254                                          1,
255                                          &lsa_account_name,
256                                          &user_rids,
257                                          &name_types);
258         if (NT_STATUS_IS_OK(status)) {
259                 status = rpccli_samr_OpenAlias(pipe_cli, ctx,
260                                                &builtin_handle,
261                                                SEC_STD_DELETE,
262                                                user_rids.ids[0],
263                                                &alias_handle);
264                 if (NT_STATUS_IS_OK(status)) {
265                         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
266                         goto delete_alias;
267                 }
268         }
269
270         rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
271
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,
277                                             &connect_handle,
278                                             &domain_handle,
279                                             &domain_sid);
280         if (!NT_STATUS_IS_OK(status)) {
281                 werr = ntstatus_to_werror(status);
282                 goto done;
283         }
284
285         status = rpccli_samr_LookupNames(pipe_cli, ctx,
286                                          &domain_handle,
287                                          1,
288                                          &lsa_account_name,
289                                          &user_rids,
290                                          &name_types);
291         if (!NT_STATUS_IS_OK(status)) {
292                 werr = ntstatus_to_werror(status);
293                 goto done;
294         }
295
296         status = rpccli_samr_OpenAlias(pipe_cli, ctx,
297                                        &domain_handle,
298                                        SEC_STD_DELETE,
299                                        user_rids.ids[0],
300                                        &alias_handle);
301         if (!NT_STATUS_IS_OK(status)) {
302                 werr = ntstatus_to_werror(status);
303                 goto done;
304         }
305
306         rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
307
308  delete_alias:
309         status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
310                                             &alias_handle);
311         if (!NT_STATUS_IS_OK(status)) {
312                 werr = ntstatus_to_werror(status);
313                 goto done;
314         }
315
316         ZERO_STRUCT(alias_handle);
317
318         werr = WERR_OK;
319
320  done:
321         if (!cli) {
322                 return werr;
323         }
324
325         if (is_valid_policy_hnd(&alias_handle)) {
326                 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
327         }
328         if (is_valid_policy_hnd(&domain_handle)) {
329                 rpccli_samr_Close(pipe_cli, ctx, &domain_handle);
330         }
331         if (is_valid_policy_hnd(&builtin_handle)) {
332                 rpccli_samr_Close(pipe_cli, ctx, &builtin_handle);
333         }
334         if (is_valid_policy_hnd(&connect_handle)) {
335                 rpccli_samr_Close(pipe_cli, ctx, &connect_handle);
336         }
337
338         return werr;
339 }
340
341 /****************************************************************
342 ****************************************************************/
343
344 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
345                           struct NetLocalGroupDel *r)
346 {
347         return NetLocalGroupDel_r(ctx, r);
348 }
349
350 /****************************************************************
351 ****************************************************************/
352
353
354 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
355                               struct NetLocalGroupGetInfo *r)
356 {
357         return WERR_NOT_SUPPORTED;
358 }
359
360 /****************************************************************
361 ****************************************************************/
362
363 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
364                               struct NetLocalGroupGetInfo *r)
365 {
366         return WERR_NOT_SUPPORTED;
367 }