Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : async implementation of WINBINDD_ALLOCATE_UID 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_uid_state { 25 : struct tevent_context *ev; 26 : uint64_t uid; 27 : }; 28 : 29 : static void winbindd_allocate_uid_initialized(struct tevent_req *subreq); 30 : static void winbindd_allocate_uid_done(struct tevent_req *subreq); 31 : 32 6 : struct tevent_req *winbindd_allocate_uid_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_uid_state *state; 39 : 40 6 : req = tevent_req_create(mem_ctx, &state, 41 : struct winbindd_allocate_uid_state); 42 6 : if (req == NULL) { 43 0 : return NULL; 44 : } 45 6 : state->ev = ev; 46 : 47 6 : DEBUG(3, ("allocate_uid\n")); 48 : 49 6 : subreq = wb_parent_idmap_setup_send(state, ev); 50 6 : if (tevent_req_nomem(subreq, req)) { 51 0 : return tevent_req_post(req, ev); 52 : } 53 6 : tevent_req_set_callback(subreq, winbindd_allocate_uid_initialized, req); 54 6 : return req; 55 : } 56 : 57 6 : static void winbindd_allocate_uid_initialized(struct tevent_req *subreq) 58 : { 59 6 : struct tevent_req *req = tevent_req_callback_data( 60 : subreq, struct tevent_req); 61 6 : struct dcerpc_binding_handle *child_binding_handle = NULL; 62 6 : struct winbindd_allocate_uid_state *state = tevent_req_data( 63 : req, struct winbindd_allocate_uid_state); 64 6 : const struct wb_parent_idmap_config *cfg = NULL; 65 0 : NTSTATUS status; 66 : 67 6 : status = wb_parent_idmap_setup_recv(subreq, &cfg); 68 6 : TALLOC_FREE(subreq); 69 6 : if (tevent_req_nterror(req, status)) { 70 0 : return; 71 : } 72 6 : if (cfg->num_doms == 0) { 73 : /* 74 : * idmap_tdb also returns UNSUCCESSFUL if a range is full 75 : */ 76 0 : tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 77 0 : return; 78 : } 79 : 80 6 : child_binding_handle = idmap_child_handle(); 81 : 82 6 : subreq = dcerpc_wbint_AllocateUid_send(state, 83 : state->ev, 84 : child_binding_handle, 85 : &state->uid); 86 6 : if (tevent_req_nomem(subreq, req)) { 87 0 : return; 88 : } 89 6 : tevent_req_set_callback(subreq, winbindd_allocate_uid_done, req); 90 : } 91 : 92 6 : static void winbindd_allocate_uid_done(struct tevent_req *subreq) 93 : { 94 6 : struct tevent_req *req = tevent_req_callback_data( 95 : subreq, struct tevent_req); 96 6 : struct winbindd_allocate_uid_state *state = tevent_req_data( 97 : req, struct winbindd_allocate_uid_state); 98 0 : NTSTATUS status, result; 99 : 100 6 : status = dcerpc_wbint_AllocateUid_recv(subreq, state, &result); 101 6 : TALLOC_FREE(subreq); 102 6 : if (any_nt_status_not_ok(status, result, &status)) { 103 0 : tevent_req_nterror(req, status); 104 0 : return; 105 : } 106 6 : tevent_req_done(req); 107 : } 108 : 109 6 : NTSTATUS winbindd_allocate_uid_recv(struct tevent_req *req, 110 : struct winbindd_response *response) 111 : { 112 6 : struct winbindd_allocate_uid_state *state = tevent_req_data( 113 : req, struct winbindd_allocate_uid_state); 114 0 : NTSTATUS status; 115 : 116 6 : if (tevent_req_is_nterror(req, &status)) { 117 0 : DEBUG(5, ("Could not allocate uid: %s\n", nt_errstr(status))); 118 0 : return status; 119 : } 120 6 : response->data.uid = state->uid; 121 6 : return NT_STATUS_OK; 122 : }