s4:lsa Functions to set Domain Trust Information
[sfrench/samba-autobuild/.git] / source3 / winbindd / wb_lookupname.c
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
24 struct 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
33 static void wb_lookupname_done(struct tevent_req *subreq);
34 static void wb_lookupname_root_done(struct tevent_req *subreq);
35
36 struct 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
81 static 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
121 static 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
142 NTSTATUS 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 }