Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : async implementation of WINBINDD_ALLOCATE_GID 4 : Copyright (C) Volker Lendecke 2009 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 : #include "winbindd.h" 22 : #include "librpc/gen_ndr/ndr_winbind_c.h" 23 : 24 : struct winbindd_allocate_gid_state { 25 : struct tevent_context *ev; 26 : uint64_t gid; 27 : }; 28 : 29 : static void winbindd_allocate_gid_initialized(struct tevent_req *subreq); 30 : static void winbindd_allocate_gid_done(struct tevent_req *subreq); 31 : 32 429 : struct tevent_req *winbindd_allocate_gid_send(TALLOC_CTX *mem_ctx, 33 : struct tevent_context *ev, 34 : struct winbindd_cli_state *cli, 35 : struct winbindd_request *request) 36 : { 37 0 : struct tevent_req *req, *subreq; 38 0 : struct winbindd_allocate_gid_state *state; 39 : 40 429 : req = tevent_req_create(mem_ctx, &state, 41 : struct winbindd_allocate_gid_state); 42 429 : if (req == NULL) { 43 0 : return NULL; 44 : } 45 429 : state->ev = ev; 46 : 47 429 : DEBUG(3, ("allocate_gid\n")); 48 : 49 429 : subreq = wb_parent_idmap_setup_send(state, ev); 50 429 : if (tevent_req_nomem(subreq, req)) { 51 0 : return tevent_req_post(req, ev); 52 : } 53 429 : tevent_req_set_callback( 54 : subreq, winbindd_allocate_gid_initialized, req); 55 429 : return req; 56 : } 57 : 58 429 : static void winbindd_allocate_gid_initialized(struct tevent_req *subreq) 59 : { 60 429 : struct tevent_req *req = tevent_req_callback_data( 61 : subreq, struct tevent_req); 62 429 : struct winbindd_allocate_gid_state *state = tevent_req_data( 63 : req, struct winbindd_allocate_gid_state); 64 0 : NTSTATUS status; 65 429 : const struct wb_parent_idmap_config *cfg = NULL; 66 429 : struct dcerpc_binding_handle *child_binding_handle = NULL; 67 : 68 429 : status = wb_parent_idmap_setup_recv(subreq, &cfg); 69 429 : TALLOC_FREE(subreq); 70 429 : if (tevent_req_nterror(req, status)) { 71 0 : return; 72 : } 73 429 : if (cfg->num_doms == 0) { 74 : /* 75 : * idmap_tdb also returns UNSUCCESSFUL if a range is full 76 : */ 77 0 : tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 78 0 : return; 79 : } 80 : 81 429 : child_binding_handle = idmap_child_handle(); 82 : 83 429 : subreq = dcerpc_wbint_AllocateGid_send( 84 : state, state->ev, child_binding_handle, &state->gid); 85 429 : if (tevent_req_nomem(subreq, req)) { 86 0 : return; 87 : } 88 429 : tevent_req_set_callback(subreq, winbindd_allocate_gid_done, req); 89 : } 90 : 91 429 : static void winbindd_allocate_gid_done(struct tevent_req *subreq) 92 : { 93 429 : struct tevent_req *req = tevent_req_callback_data( 94 : subreq, struct tevent_req); 95 429 : struct winbindd_allocate_gid_state *state = tevent_req_data( 96 : req, struct winbindd_allocate_gid_state); 97 0 : NTSTATUS status, result; 98 : 99 429 : status = dcerpc_wbint_AllocateGid_recv(subreq, state, &result); 100 429 : TALLOC_FREE(subreq); 101 429 : if (any_nt_status_not_ok(status, result, &status)) { 102 0 : tevent_req_nterror(req, status); 103 0 : return; 104 : } 105 429 : tevent_req_done(req); 106 : } 107 : 108 429 : NTSTATUS winbindd_allocate_gid_recv(struct tevent_req *req, 109 : struct winbindd_response *response) 110 : { 111 429 : struct winbindd_allocate_gid_state *state = tevent_req_data( 112 : req, struct winbindd_allocate_gid_state); 113 0 : NTSTATUS status; 114 : 115 429 : if (tevent_req_is_nterror(req, &status)) { 116 0 : DEBUG(5, ("Could not allocate gid: %s\n", nt_errstr(status))); 117 0 : return status; 118 : } 119 429 : response->data.gid = state->gid; 120 429 : return NT_STATUS_OK; 121 : }