1/* 2 Unix SMB/CIFS implementation. 3 async lookupname 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_lookupname_state { 25 struct tevent_context *ev; 26 const char *dom_name; 27 const char *name; 28 uint32_t flags; 29 struct dom_sid sid; 30 enum lsa_SidType type; 31}; 32 33static void wb_lookupname_done(struct tevent_req *subreq); 34static void wb_lookupname_root_done(struct tevent_req *subreq); 35 36struct tevent_req *wb_lookupname_send(TALLOC_CTX *mem_ctx, 37 struct tevent_context *ev, 38 const char *dom_name, const char *name, 39 uint32_t flags) 40{ 41 struct tevent_req *req, *subreq; 42 struct wb_lookupname_state *state; 43 struct winbindd_domain *domain; 44 45 req = tevent_req_create(mem_ctx, &state, struct wb_lookupname_state); 46 if (req == NULL) { 47 return NULL; 48 } 49 state->ev = ev; 50 state->flags = flags; 51 52 /* 53 * Uppercase domain and name so that we become cache-friendly 54 */ 55 state->dom_name = talloc_strdup_upper(state, dom_name); 56 if (tevent_req_nomem(state->dom_name, req)) { 57 return tevent_req_post(req, ev); 58 } 59 state->name = talloc_strdup_upper(state, name); 60 if (tevent_req_nomem(state->name, req)) { 61 return tevent_req_post(req, ev); 62 } 63 64 domain = find_lookup_domain_from_name(state->dom_name); 65 if (domain == NULL) { 66 DEBUG(5, ("Could not find domain for %s\n", state->dom_name)); 67 tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); 68 return tevent_req_post(req, ev); 69 } 70 71 subreq = rpccli_wbint_LookupName_send( 72 state, ev, domain->child.rpccli, state->dom_name, state->name, 73 flags, &state->type, &state->sid); 74 if (tevent_req_nomem(subreq, req)) { 75 return tevent_req_post(req, ev); 76 } 77 tevent_req_set_callback(subreq, wb_lookupname_done, req); 78 return req; 79} 80 81static void wb_lookupname_done(struct tevent_req *subreq) 82{ 83 struct tevent_req *req = tevent_req_callback_data( 84 subreq, struct tevent_req); 85 struct wb_lookupname_state *state = tevent_req_data( 86 req, struct wb_lookupname_state); 87 struct winbindd_domain *root_domain; 88 NTSTATUS status, result; 89 90 status = rpccli_wbint_LookupName_recv(subreq, state, &result); 91 TALLOC_FREE(subreq); 92 if (!NT_STATUS_IS_OK(status)) { 93 tevent_req_nterror(req, status); 94 return; 95 } 96 if (NT_STATUS_IS_OK(result)) { 97 tevent_req_done(req); 98 return; 99 } 100 101 /* 102 * "our" DC did not find it, lets retry with the forest root 103 * domain 104 */ 105 106 root_domain = find_root_domain(); 107 if (root_domain == NULL) { 108 tevent_req_nterror(req, result); 109 return; 110 } 111 112 subreq = rpccli_wbint_LookupName_send( 113 state, state->ev, root_domain->child.rpccli, state->dom_name, 114 state->name, state->flags, &state->type, &state->sid); 115 if (tevent_req_nomem(subreq, req)) { 116 return; 117 } 118 tevent_req_set_callback(subreq, wb_lookupname_root_done, req); 119} 120 121static void wb_lookupname_root_done(struct tevent_req *subreq) 122{ 123 struct tevent_req *req = tevent_req_callback_data( 124 subreq, struct tevent_req); 125 struct wb_lookupname_state *state = tevent_req_data( 126 req, struct wb_lookupname_state); 127 NTSTATUS status, result; 128 129 status = rpccli_wbint_LookupName_recv(subreq, state, &result); 130 TALLOC_FREE(subreq); 131 if (!NT_STATUS_IS_OK(status)) { 132 tevent_req_nterror(req, status); 133 return; 134 } 135 if (!NT_STATUS_IS_OK(result)) { 136 tevent_req_nterror(req, result); 137 return; 138 } 139 tevent_req_done(req); 140} 141 142NTSTATUS wb_lookupname_recv(struct tevent_req *req, struct dom_sid *sid, 143 enum lsa_SidType *type) 144{ 145 struct wb_lookupname_state *state = tevent_req_data( 146 req, struct wb_lookupname_state); 147 NTSTATUS status; 148 149 if (tevent_req_is_nterror(req, &status)) { 150 return status; 151 } 152 sid_copy(sid, &state->sid); 153 *type = state->type; 154 return NT_STATUS_OK; 155} 156