r25367: Add initial implementation of internal group add function.
[ira/wip.git] / source / libnet / groupman.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Rafal Szczesniak 2007
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 /*
21   a composite function for manipulating (add/edit/del) groups via samr pipe
22 */
23
24 #include "includes.h"
25 #include "libcli/composite/composite.h"
26 #include "libnet/composite.h"
27 #include "libnet/groupman.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29
30
31 struct groupadd_state {
32         struct dcerpc_pipe *pipe;
33         struct policy_handle domain_handle;
34         struct samr_CreateDomainGroup creategroup;
35         struct policy_handle group_handle;
36         uint32_t group_rid;
37         
38         void (*monitor_fn)(struct monitor_msg*);
39 };
40
41
42 static void continue_groupadd_created(struct rpc_request *req);
43
44
45 struct composite_context* libnet_rpc_groupadd_send(struct dcerpc_pipe *p,
46                                                    struct libnet_rpc_groupadd *io,
47                                                    void (*monitor)(struct monitor_msg*))
48 {
49         struct composite_context *c;
50         struct groupadd_state *s;
51         struct rpc_request *create_req;
52
53         if (!p || !io) return NULL;
54
55         c = composite_create(p, dcerpc_event_context(p));
56         if (c == NULL) return NULL;
57
58         s = talloc_zero(c, struct groupadd_state);
59         if (composite_nomem(s, c)) return c;
60
61         c->private_data = s;
62
63         s->domain_handle = io->in.domain_handle;
64         s->pipe          = p;
65         s->monitor_fn    = monitor;
66
67         s->creategroup.in.domain_handle  = &s->domain_handle;
68
69         s->creategroup.in.name           = talloc_zero(c, struct lsa_String);
70         if (composite_nomem(s->creategroup.in.name, c)) return c;
71
72         s->creategroup.in.name->string   = talloc_strdup(c, io->in.groupname);
73         if (composite_nomem(s->creategroup.in.name->string, c)) return c;
74         
75         s->creategroup.in.access_mask    = 0;
76         
77         s->creategroup.out.group_handle  = &s->group_handle;
78         s->creategroup.out.rid           = &s->group_rid;
79         
80         create_req = dcerpc_samr_CreateDomainGroup_send(s->pipe, c, &s->creategroup);
81         if (composite_nomem(create_req, c)) return c;
82
83         composite_continue_rpc(c, create_req, continue_groupadd_created, c);
84         return c;
85 }
86
87
88 NTSTATUS libnet_rpc_groupadd_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
89                                   struct libnet_rpc_groupadd *io)
90 {
91         NTSTATUS status;
92         struct groupadd_state *s;
93         
94         status = composite_wait(c);
95         if (NT_STATUS_IS_OK(status)) {
96                 s = talloc_get_type(c, struct groupadd_state);
97         }
98
99         return status;
100 }
101
102
103 static void continue_groupadd_created(struct rpc_request *req)
104 {
105         struct composite_context *c;
106         struct groupadd_state *s;
107
108         c = talloc_get_type(req->async.private_data, struct composite_context);
109         s = talloc_get_type(c->private_data, struct groupadd_state);
110
111         c->status = dcerpc_ndr_request_recv(req);
112         if (!composite_is_ok(c)) return;
113
114         c->status = s->creategroup.out.result;
115         if (!composite_is_ok(c)) return;
116         
117         if (s->monitor_fn) {
118                 struct monitor_msg msg;
119                 
120                 msg.type      = mon_SamrCreateUser;
121                 msg.data      = NULL;
122                 msg.data_size = 0;
123                 
124                 s->monitor_fn(&msg);
125         }
126
127         composite_done(c);
128 }
129
130
131 NTSTATUS libnet_rpc_groupadd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
132                              struct libnet_rpc_groupadd *io)
133 {
134         struct composite_context *c;
135
136         c = libnet_rpc_groupadd_send(p, io, NULL);
137         return libnet_rpc_groupadd_recv(c, mem_ctx, io);
138 }