s3: Remove unused query_user_async
[samba.git] / source3 / winbindd / winbindd_async.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Async helpers for blocking functions
5
6    Copyright (C) Volker Lendecke 2005
7    Copyright (C) Gerald Carter 2006
8
9    The helpers always consist of three functions: 
10
11    * A request setup function that takes the necessary parameters together
12      with a continuation function that is to be called upon completion
13
14    * A private continuation function that is internal only. This is to be
15      called by the lower-level functions in do_async(). Its only task is to
16      properly call the continuation function named above.
17
18    * A worker function that is called inside the appropriate child process.
19
20    This program is free software; you can redistribute it and/or modify
21    it under the terms of the GNU General Public License as published by
22    the Free Software Foundation; either version 3 of the License, or
23    (at your option) any later version.
24
25    This program is distributed in the hope that it will be useful,
26    but WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28    GNU General Public License for more details.
29
30    You should have received a copy of the GNU General Public License
31    along with this program.  If not, see <http://www.gnu.org/licenses/>.
32 */
33
34 #include "includes.h"
35 #include "winbindd.h"
36
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_WINBIND
39
40 struct do_async_state {
41         TALLOC_CTX *mem_ctx;
42         struct winbindd_request request;
43         struct winbindd_response response;
44         void (*cont)(TALLOC_CTX *mem_ctx,
45                      bool success,
46                      struct winbindd_response *response,
47                      void *c, void *private_data);
48         void *c, *private_data;
49 };
50
51 static void do_async_recv(void *private_data, bool success)
52 {
53         struct do_async_state *state =
54                 talloc_get_type_abort(private_data, struct do_async_state);
55
56         state->cont(state->mem_ctx, success, &state->response,
57                     state->c, state->private_data);
58 }
59
60 void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
61               const struct winbindd_request *request,
62               void (*cont)(TALLOC_CTX *mem_ctx, bool success,
63                            struct winbindd_response *response,
64                            void *c, void *private_data),
65               void *c, void *private_data)
66 {
67         struct do_async_state *state;
68
69         state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
70         if (state == NULL) {
71                 DEBUG(0, ("talloc failed\n"));
72                 cont(mem_ctx, False, NULL, c, private_data);
73                 return;
74         }
75
76         state->mem_ctx = mem_ctx;
77         state->request = *request;
78         state->request.length = sizeof(state->request);
79         state->cont = cont;
80         state->c = c;
81         state->private_data = private_data;
82
83         async_request(mem_ctx, child, &state->request,
84                       &state->response, do_async_recv, state);
85 }
86
87 static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
88                             const struct winbindd_request *request,
89                             void (*cont)(TALLOC_CTX *mem_ctx, bool success,
90                                          struct winbindd_response *response,
91                                          void *c, void *private_data),
92                             void *c, void *private_data)
93 {
94         struct do_async_state *state;
95
96         state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
97         if (state == NULL) {
98                 DEBUG(0, ("talloc failed\n"));
99                 cont(mem_ctx, False, NULL, c, private_data);
100                 return;
101         }
102
103         state->mem_ctx = mem_ctx;
104         state->request = *request;
105         state->request.length = sizeof(state->request);
106         state->cont = cont;
107         state->c = c;
108         state->private_data = private_data;
109
110         async_domain_request(mem_ctx, domain, &state->request,
111                              &state->response, do_async_recv, state);
112 }
113
114 enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
115                                              struct winbindd_cli_state *state)
116 {
117         enum lsa_SidType type;
118         DOM_SID sid;
119         char *name;
120         char *dom_name;
121
122         /* Ensure null termination */
123         state->request->data.sid[sizeof(state->request->data.sid)-1]='\0';
124
125         DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, 
126                   state->request->data.sid));
127
128         /* Lookup sid from PDC using lsa_lookup_sids() */
129
130         if (!string_to_sid(&sid, state->request->data.sid)) {
131                 DEBUG(5, ("%s not a SID\n", state->request->data.sid));
132                 return WINBINDD_ERROR;
133         }
134
135         /* Lookup the sid */
136
137         if (!winbindd_lookup_name_by_sid(state->mem_ctx, domain, &sid, 
138                                          &dom_name, &name, &type)) 
139         {
140                 TALLOC_FREE(dom_name);
141                 TALLOC_FREE(name);
142                 return WINBINDD_ERROR;
143         }
144
145         fstrcpy(state->response->data.name.dom_name, dom_name);
146         fstrcpy(state->response->data.name.name, name);
147         state->response->data.name.type = type;
148
149         TALLOC_FREE(dom_name);
150         TALLOC_FREE(name);
151         return WINBINDD_OK;
152 }
153
154 enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
155                                               struct winbindd_cli_state *state)
156 {
157         enum lsa_SidType type;
158         char *name_domain, *name_user;
159         DOM_SID sid;
160         char *p;
161
162         /* Ensure null termination */
163         state->request->data.name.dom_name[sizeof(state->request->data.name.dom_name)-1]='\0';
164
165         /* Ensure null termination */
166         state->request->data.name.name[sizeof(state->request->data.name.name)-1]='\0';
167
168         /* cope with the name being a fully qualified name */
169         p = strstr(state->request->data.name.name, lp_winbind_separator());
170         if (p) {
171                 *p = 0;
172                 name_domain = state->request->data.name.name;
173                 name_user = p+1;
174         } else {
175                 name_domain = state->request->data.name.dom_name;
176                 name_user = state->request->data.name.name;
177         }
178
179         DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
180                   name_domain, lp_winbind_separator(), name_user));
181
182         /* Lookup name from DC using lsa_lookup_names() */
183         if (!winbindd_lookup_sid_by_name(state->mem_ctx, state->request->original_cmd, domain, name_domain,
184                                          name_user, &sid, &type)) {
185                 return WINBINDD_ERROR;
186         }
187
188         sid_to_fstring(state->response->data.sid.sid, &sid);
189         state->response->data.sid.type = type;
190
191         return WINBINDD_OK;
192 }
193
194 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
195                    size_t num_sids, char **result, ssize_t *len)
196 {
197         size_t i;
198         size_t buflen = 0;
199
200         *len = 0;
201         *result = NULL;
202         for (i=0; i<num_sids; i++) {
203                 fstring tmp;
204                 sprintf_append(mem_ctx, result, len, &buflen,
205                                "%s\n", sid_to_fstring(tmp, &sids[i]));
206         }
207
208         if ((num_sids != 0) && (*result == NULL)) {
209                 return False;
210         }
211
212         return True;
213 }
214
215 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
216                    DOM_SID **sids, size_t *num_sids)
217 {
218         const char *p, *q;
219
220         p = sidstr;
221         if (p == NULL)
222                 return False;
223
224         while (p[0] != '\0') {
225                 fstring tmp;
226                 size_t sidlen;
227                 DOM_SID sid;
228                 q = strchr(p, '\n');
229                 if (q == NULL) {
230                         DEBUG(0, ("Got invalid sidstr: %s\n", p));
231                         return False;
232                 }
233                 sidlen = PTR_DIFF(q, p);
234                 if (sidlen >= sizeof(tmp)-1) {
235                         return false;
236                 }
237                 memcpy(tmp, p, sidlen);
238                 tmp[sidlen] = '\0';
239                 q += 1;
240                 if (!string_to_sid(&sid, tmp)) {
241                         DEBUG(0, ("Could not parse sid %s\n", p));
242                         return False;
243                 }
244                 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
245                                                       num_sids)))
246                 {
247                         return False;
248                 }
249                 p = q;
250         }
251         return True;
252 }
253
254 enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain,
255                                         struct winbindd_cli_state *state)
256 {
257         return WINBINDD_OK;
258 }