Line data Source code
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/libnet.h" 27 : #include "librpc/gen_ndr/ndr_samr_c.h" 28 : 29 : 30 : struct groupadd_state { 31 : struct dcerpc_binding_handle *binding_handle; 32 : struct policy_handle domain_handle; 33 : struct samr_CreateDomainGroup creategroup; 34 : struct policy_handle group_handle; 35 : uint32_t group_rid; 36 : 37 : void (*monitor_fn)(struct monitor_msg*); 38 : }; 39 : 40 : 41 : static void continue_groupadd_created(struct tevent_req *subreq); 42 : 43 : 44 2 : struct composite_context* libnet_rpc_groupadd_send(TALLOC_CTX *mem_ctx, 45 : struct tevent_context *ev, 46 : struct dcerpc_binding_handle *b, 47 : struct libnet_rpc_groupadd *io, 48 : void (*monitor)(struct monitor_msg*)) 49 : { 50 2 : struct composite_context *c; 51 2 : struct groupadd_state *s; 52 2 : struct tevent_req *subreq; 53 : 54 2 : if (!b || !io) return NULL; 55 : 56 2 : c = composite_create(mem_ctx, ev); 57 2 : if (c == NULL) return NULL; 58 : 59 2 : s = talloc_zero(c, struct groupadd_state); 60 2 : if (composite_nomem(s, c)) return c; 61 : 62 2 : c->private_data = s; 63 : 64 2 : s->domain_handle = io->in.domain_handle; 65 2 : s->binding_handle= b; 66 2 : s->monitor_fn = monitor; 67 : 68 2 : s->creategroup.in.domain_handle = &s->domain_handle; 69 : 70 2 : s->creategroup.in.name = talloc_zero(c, struct lsa_String); 71 2 : if (composite_nomem(s->creategroup.in.name, c)) return c; 72 : 73 2 : s->creategroup.in.name->string = talloc_strdup(c, io->in.groupname); 74 2 : if (composite_nomem(s->creategroup.in.name->string, c)) return c; 75 : 76 2 : s->creategroup.in.access_mask = 0; 77 : 78 2 : s->creategroup.out.group_handle = &s->group_handle; 79 2 : s->creategroup.out.rid = &s->group_rid; 80 : 81 2 : subreq = dcerpc_samr_CreateDomainGroup_r_send(s, c->event_ctx, 82 : s->binding_handle, 83 : &s->creategroup); 84 2 : if (composite_nomem(subreq, c)) return c; 85 : 86 2 : tevent_req_set_callback(subreq, continue_groupadd_created, c); 87 2 : return c; 88 : } 89 : 90 : 91 2 : NTSTATUS libnet_rpc_groupadd_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, 92 : struct libnet_rpc_groupadd *io) 93 : { 94 2 : NTSTATUS status; 95 2 : struct groupadd_state *s; 96 : 97 2 : status = composite_wait(c); 98 2 : if (NT_STATUS_IS_OK(status) && io) { 99 2 : s = talloc_get_type(c->private_data, struct groupadd_state); 100 2 : io->out.group_handle = s->group_handle; 101 : } 102 : 103 2 : talloc_free(c); 104 2 : return status; 105 : } 106 : 107 : 108 2 : static void continue_groupadd_created(struct tevent_req *subreq) 109 : { 110 2 : struct composite_context *c; 111 2 : struct groupadd_state *s; 112 : 113 2 : c = tevent_req_callback_data(subreq, struct composite_context); 114 2 : s = talloc_get_type(c->private_data, struct groupadd_state); 115 : 116 2 : c->status = dcerpc_samr_CreateDomainGroup_r_recv(subreq, s); 117 2 : TALLOC_FREE(subreq); 118 2 : if (!composite_is_ok(c)) return; 119 : 120 2 : c->status = s->creategroup.out.result; 121 2 : if (!NT_STATUS_IS_OK(c->status)) { 122 0 : composite_error(c, c->status); 123 0 : return; 124 : } 125 : 126 2 : composite_done(c); 127 : } 128 : 129 : 130 1 : NTSTATUS libnet_rpc_groupadd(struct tevent_context *ev, 131 : struct dcerpc_binding_handle *b, 132 : TALLOC_CTX *mem_ctx, 133 : struct libnet_rpc_groupadd *io) 134 : { 135 1 : struct composite_context *c; 136 : 137 1 : c = libnet_rpc_groupadd_send(mem_ctx, ev, b, io, NULL); 138 1 : return libnet_rpc_groupadd_recv(c, mem_ctx, io); 139 : }