1/* 2 Unix SMB/CIFS implementation. 3 async gid2sid 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/cli_wbint.h" 23 24struct wb_gid2sid_state { 25 struct tevent_context *ev; 26 char *dom_name; 27 struct dom_sid sid; 28}; 29 30static void wb_gid2sid_done(struct tevent_req *subreq); 31 32struct tevent_req *wb_gid2sid_send(TALLOC_CTX *mem_ctx, 33 struct tevent_context *ev, 34 gid_t gid) 35{ 36 struct tevent_req *req, *subreq; 37 struct wb_gid2sid_state *state; 38 struct winbindd_domain *domain; 39 struct winbindd_child *child; 40 bool expired; 41 42 req = tevent_req_create(mem_ctx, &state, struct wb_gid2sid_state); 43 if (req == NULL) { 44 return NULL; 45 } 46 47 if (winbindd_use_idmap_cache() 48 && idmap_cache_find_gid2sid(gid, &state->sid, &expired)) { 49 50 DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", 51 (int)gid, expired ? " (expired)": "")); 52 53 if (!expired || idmap_is_offline()) { 54 if (is_null_sid(&state->sid)) { 55 tevent_req_nterror(req, 56 NT_STATUS_NONE_MAPPED); 57 } else { 58 tevent_req_done(req); 59 } 60 return tevent_req_post(req, ev); 61 } 62 } 63 64 state->dom_name = NULL; 65 66 for (domain = domain_list(); domain != NULL; domain = domain->next) { 67 if (domain->have_idmap_config 68 && (gid >= domain->id_range_low) 69 && (gid <= domain->id_range_high)) { 70 state->dom_name = domain->name; 71 break; 72 } 73 } 74 75 child = idmap_child(); 76 77 subreq = rpccli_wbint_Gid2Sid_send( 78 state, ev, child->rpccli, state->dom_name, 79 gid, &state->sid); 80 if (tevent_req_nomem(subreq, req)) { 81 return tevent_req_post(req, ev); 82 } 83 tevent_req_set_callback(subreq, wb_gid2sid_done, req); 84 return req; 85} 86 87static void wb_gid2sid_done(struct tevent_req *subreq) 88{ 89 struct tevent_req *req = tevent_req_callback_data( 90 subreq, struct tevent_req); 91 struct wb_gid2sid_state *state = tevent_req_data( 92 req, struct wb_gid2sid_state); 93 NTSTATUS status, result; 94 95 status = rpccli_wbint_Gid2Sid_recv(subreq, state, &result); 96 TALLOC_FREE(subreq); 97 if (!NT_STATUS_IS_OK(status)) { 98 tevent_req_nterror(req, status); 99 return; 100 } 101 if (!NT_STATUS_IS_OK(result)) { 102 tevent_req_nterror(req, result); 103 return; 104 } 105 tevent_req_done(req); 106} 107 108NTSTATUS wb_gid2sid_recv(struct tevent_req *req, struct dom_sid *sid) 109{ 110 struct wb_gid2sid_state *state = tevent_req_data( 111 req, struct wb_gid2sid_state); 112 NTSTATUS status; 113 114 if (tevent_req_is_nterror(req, &status)) { 115 return status; 116 } 117 sid_copy(sid, &state->sid); 118 return NT_STATUS_OK; 119} 120