2 Unix SMB/CIFS implementation.
4 Async helpers for blocking functions
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Gerald Carter 2006
9 The helpers always consist of three functions:
11 * A request setup function that takes the necessary parameters together
12 with a continuation function that is to be called upon completion
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.
18 * A worker function that is called inside the appropriate child process.
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 2 of the License, or
23 (at your option) any later version.
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.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
39 #define DBGC_CLASS DBGC_WINBIND
41 struct do_async_state
{
43 struct winbindd_request request
;
44 struct winbindd_response response
;
45 void (*cont
)(TALLOC_CTX
*mem_ctx
,
47 struct winbindd_response
*response
,
48 void *c
, void *private_data
);
49 void *c
, *private_data
;
52 static void do_async_recv(void *private_data
, BOOL success
)
54 struct do_async_state
*state
=
55 talloc_get_type_abort(private_data
, struct do_async_state
);
57 state
->cont(state
->mem_ctx
, success
, &state
->response
,
58 state
->c
, state
->private_data
);
61 static void do_async(TALLOC_CTX
*mem_ctx
, struct winbindd_child
*child
,
62 const struct winbindd_request
*request
,
63 void (*cont
)(TALLOC_CTX
*mem_ctx
, BOOL success
,
64 struct winbindd_response
*response
,
65 void *c
, void *private_data
),
66 void *c
, void *private_data
)
68 struct do_async_state
*state
;
70 state
= TALLOC_ZERO_P(mem_ctx
, struct do_async_state
);
72 DEBUG(0, ("talloc failed\n"));
73 cont(mem_ctx
, False
, NULL
, c
, private_data
);
77 state
->mem_ctx
= mem_ctx
;
78 state
->request
= *request
;
79 state
->request
.length
= sizeof(state
->request
);
82 state
->private_data
= private_data
;
84 async_request(mem_ctx
, child
, &state
->request
,
85 &state
->response
, do_async_recv
, state
);
88 void do_async_domain(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
89 const struct winbindd_request
*request
,
90 void (*cont
)(TALLOC_CTX
*mem_ctx
, BOOL success
,
91 struct winbindd_response
*response
,
92 void *c
, void *private_data
),
93 void *c
, void *private_data
)
95 struct do_async_state
*state
;
97 state
= TALLOC_ZERO_P(mem_ctx
, struct do_async_state
);
99 DEBUG(0, ("talloc failed\n"));
100 cont(mem_ctx
, False
, NULL
, c
, private_data
);
104 state
->mem_ctx
= mem_ctx
;
105 state
->request
= *request
;
106 state
->request
.length
= sizeof(state
->request
);
109 state
->private_data
= private_data
;
111 async_domain_request(mem_ctx
, domain
, &state
->request
,
112 &state
->response
, do_async_recv
, state
);
115 static void winbindd_set_mapping_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
116 struct winbindd_response
*response
,
117 void *c
, void *private_data
)
119 void (*cont
)(void *priv
, BOOL succ
) = (void (*)(void *, BOOL
))c
;
122 DEBUG(5, ("Could not trigger idmap_set_mapping\n"));
123 cont(private_data
, False
);
127 if (response
->result
!= WINBINDD_OK
) {
128 DEBUG(5, ("idmap_set_mapping returned an error\n"));
129 cont(private_data
, False
);
133 cont(private_data
, True
);
136 void winbindd_set_mapping_async(TALLOC_CTX
*mem_ctx
, const struct id_map
*map
,
137 void (*cont
)(void *private_data
, BOOL success
),
140 struct winbindd_request request
;
141 ZERO_STRUCT(request
);
142 request
.cmd
= WINBINDD_DUAL_SET_MAPPING
;
143 request
.data
.dual_idmapset
.id
= map
->xid
.id
;
144 request
.data
.dual_idmapset
.type
= map
->xid
.type
;
145 sid_to_string(request
.data
.dual_idmapset
.sid
, map
->sid
);
147 do_async(mem_ctx
, idmap_child(), &request
, winbindd_set_mapping_recv
,
148 (void *)cont
, private_data
);
151 enum winbindd_result
winbindd_dual_set_mapping(struct winbindd_domain
*domain
,
152 struct winbindd_cli_state
*state
)
158 DEBUG(3, ("[%5lu]: dual_idmapset\n", (unsigned long)state
->pid
));
160 if (!string_to_sid(&sid
, state
->request
.data
.dual_idmapset
.sid
))
161 return WINBINDD_ERROR
;
164 map
.xid
.id
= state
->request
.data
.dual_idmapset
.id
;
165 map
.xid
.type
= state
->request
.data
.dual_idmapset
.type
;
166 map
.status
= ID_MAPPED
;
168 result
= idmap_set_mapping(&map
);
169 return NT_STATUS_IS_OK(result
) ? WINBINDD_OK
: WINBINDD_ERROR
;
172 static void winbindd_set_hwm_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
173 struct winbindd_response
*response
,
174 void *c
, void *private_data
)
176 void (*cont
)(void *priv
, BOOL succ
) = (void (*)(void *, BOOL
))c
;
179 DEBUG(5, ("Could not trigger idmap_set_hwm\n"));
180 cont(private_data
, False
);
184 if (response
->result
!= WINBINDD_OK
) {
185 DEBUG(5, ("idmap_set_hwm returned an error\n"));
186 cont(private_data
, False
);
190 cont(private_data
, True
);
193 void winbindd_set_hwm_async(TALLOC_CTX
*mem_ctx
, const struct unixid
*xid
,
194 void (*cont
)(void *private_data
, BOOL success
),
197 struct winbindd_request request
;
198 ZERO_STRUCT(request
);
199 request
.cmd
= WINBINDD_DUAL_SET_HWM
;
200 request
.data
.dual_idmapset
.id
= xid
->id
;
201 request
.data
.dual_idmapset
.type
= xid
->type
;
203 do_async(mem_ctx
, idmap_child(), &request
, winbindd_set_hwm_recv
,
204 (void *)cont
, private_data
);
207 enum winbindd_result
winbindd_dual_set_hwm(struct winbindd_domain
*domain
,
208 struct winbindd_cli_state
*state
)
213 DEBUG(3, ("[%5lu]: dual_set_hwm\n", (unsigned long)state
->pid
));
215 xid
.id
= state
->request
.data
.dual_idmapset
.id
;
216 xid
.type
= state
->request
.data
.dual_idmapset
.type
;
220 result
= idmap_set_uid_hwm(&xid
);
223 result
= idmap_set_gid_hwm(&xid
);
226 return WINBINDD_ERROR
;
228 return NT_STATUS_IS_OK(result
) ? WINBINDD_OK
: WINBINDD_ERROR
;
231 static void winbindd_sids2xids_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
232 struct winbindd_response
*response
,
233 void *c
, void *private_data
)
235 void (*cont
)(void *priv
, BOOL succ
, void *, int) =
236 (void (*)(void *, BOOL
, void *, int))c
;
239 DEBUG(5, ("Could not trigger sids2xids\n"));
240 cont(private_data
, False
, NULL
, 0);
244 if (response
->result
!= WINBINDD_OK
) {
245 DEBUG(5, ("sids2xids returned an error\n"));
246 cont(private_data
, False
, NULL
, 0);
250 cont(private_data
, True
, response
->extra_data
.data
, response
->length
- sizeof(response
));
253 void winbindd_sids2xids_async(TALLOC_CTX
*mem_ctx
, void *sids
, int size
,
254 void (*cont
)(void *private_data
, BOOL success
, void *data
, int len
),
257 struct winbindd_request request
;
258 ZERO_STRUCT(request
);
259 request
.cmd
= WINBINDD_DUAL_SIDS2XIDS
;
260 request
.extra_data
.data
= (char *)sids
;
261 request
.extra_len
= size
;
262 do_async(mem_ctx
, idmap_child(), &request
, winbindd_sids2xids_recv
,
263 (void *)cont
, private_data
);
266 enum winbindd_result
winbindd_dual_sids2xids(struct winbindd_domain
*domain
,
267 struct winbindd_cli_state
*state
)
275 DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state
->pid
));
277 if (state
->request
.extra_len
== 0) {
278 DEBUG(0, ("Invalid buffer size!\n"));
279 return WINBINDD_ERROR
;
282 sids
= (DOM_SID
*)state
->request
.extra_data
.data
;
283 num
= state
->request
.extra_len
/ sizeof(DOM_SID
);
285 ids
= TALLOC_ZERO_ARRAY(state
->mem_ctx
, struct id_map
*, num
+ 1);
287 DEBUG(0, ("Out of memory!\n"));
288 return WINBINDD_ERROR
;
290 for (i
= 0; i
< num
; i
++) {
291 ids
[i
] = TALLOC_P(ids
, struct id_map
);
293 DEBUG(0, ("Out of memory!\n"));
295 return WINBINDD_ERROR
;
297 ids
[i
]->sid
= &sids
[i
];
300 result
= idmap_sids_to_unixids(ids
);
302 if (NT_STATUS_IS_OK(result
)) {
304 xids
= SMB_MALLOC_ARRAY(struct unixid
, num
);
306 DEBUG(0, ("Out of memory!\n"));
308 return WINBINDD_ERROR
;
311 for (i
= 0; i
< num
; i
++) {
312 if (ids
[i
]->status
== ID_MAPPED
) {
313 xids
[i
].type
= ids
[i
]->xid
.type
;
314 xids
[i
].id
= ids
[i
]->xid
.id
;
320 state
->response
.length
= sizeof(state
->response
) + (sizeof(struct unixid
) * num
);
321 state
->response
.extra_data
.data
= xids
;
324 DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result
)));
326 return WINBINDD_ERROR
;
333 static void winbindd_sid2uid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
334 struct winbindd_response
*response
,
335 void *c
, void *private_data
)
337 void (*cont
)(void *priv
, BOOL succ
, uid_t uid
) =
338 (void (*)(void *, BOOL
, uid_t
))c
;
341 DEBUG(5, ("Could not trigger sid2uid\n"));
342 cont(private_data
, False
, 0);
346 if (response
->result
!= WINBINDD_OK
) {
347 DEBUG(5, ("sid2uid returned an error\n"));
348 cont(private_data
, False
, 0);
352 cont(private_data
, True
, response
->data
.uid
);
355 void winbindd_sid2uid_async(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sid
,
356 void (*cont
)(void *private_data
, BOOL success
, uid_t uid
),
359 struct winbindd_request request
;
360 ZERO_STRUCT(request
);
361 request
.cmd
= WINBINDD_DUAL_SID2UID
;
362 sid_to_string(request
.data
.dual_sid2id
.sid
, sid
);
363 do_async(mem_ctx
, idmap_child(), &request
, winbindd_sid2uid_recv
,
364 (void *)cont
, private_data
);
367 enum winbindd_result
winbindd_dual_sid2uid(struct winbindd_domain
*domain
,
368 struct winbindd_cli_state
*state
)
373 DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state
->pid
,
374 state
->request
.data
.dual_sid2id
.sid
));
376 if (!string_to_sid(&sid
, state
->request
.data
.dual_sid2id
.sid
)) {
377 DEBUG(1, ("Could not get convert sid %s from string\n",
378 state
->request
.data
.dual_sid2id
.sid
));
379 return WINBINDD_ERROR
;
382 /* Find uid for this sid and return it, possibly ask the slow remote idmap */
384 result
= idmap_sid_to_uid(&sid
, &(state
->response
.data
.uid
));
386 return NT_STATUS_IS_OK(result
) ? WINBINDD_OK
: WINBINDD_ERROR
;
390 static void uid2name_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
391 struct winbindd_response
*response
,
392 void *c
, void *private_data
);
394 void winbindd_uid2name_async(TALLOC_CTX
*mem_ctx
, uid_t uid
,
395 void (*cont
)(void *private_data
, BOOL success
,
399 struct winbindd_request request
;
400 ZERO_STRUCT(request
);
401 request
.cmd
= WINBINDD_DUAL_UID2NAME
;
402 request
.data
.uid
= uid
;
403 do_async(mem_ctx
, idmap_child(), &request
, uid2name_recv
,
404 (void *)cont
, private_data
);
406 #endif /* not used */
408 enum winbindd_result
winbindd_dual_uid2name(struct winbindd_domain
*domain
,
409 struct winbindd_cli_state
*state
)
413 DEBUG(3, ("[%5lu]: uid2name %lu\n", (unsigned long)state
->pid
,
414 (unsigned long)state
->request
.data
.uid
));
416 pw
= getpwuid(state
->request
.data
.uid
);
418 DEBUG(5, ("User %lu not found\n",
419 (unsigned long)state
->request
.data
.uid
));
420 return WINBINDD_ERROR
;
423 fstrcpy(state
->response
.data
.name
.name
, pw
->pw_name
);
428 static void uid2name_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
429 struct winbindd_response
*response
,
430 void *c
, void *private_data
)
432 void (*cont
)(void *priv
, BOOL succ
, const char *name
) =
433 (void (*)(void *, BOOL
, const char *))c
;
436 DEBUG(5, ("Could not trigger uid2name\n"));
437 cont(private_data
, False
, NULL
);
441 if (response
->result
!= WINBINDD_OK
) {
442 DEBUG(5, ("uid2name returned an error\n"));
443 cont(private_data
, False
, NULL
);
447 cont(private_data
, True
, response
->data
.name
.name
);
450 static void name2uid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
451 struct winbindd_response
*response
,
452 void *c
, void *private_data
);
454 static void winbindd_name2uid_async(TALLOC_CTX
*mem_ctx
, const char *name
,
455 void (*cont
)(void *private_data
, BOOL success
,
459 struct winbindd_request request
;
460 ZERO_STRUCT(request
);
461 request
.cmd
= WINBINDD_DUAL_NAME2UID
;
462 fstrcpy(request
.data
.username
, name
);
463 do_async(mem_ctx
, idmap_child(), &request
, name2uid_recv
,
464 (void *)cont
, private_data
);
466 #endif /* not used */
468 enum winbindd_result
winbindd_dual_name2uid(struct winbindd_domain
*domain
,
469 struct winbindd_cli_state
*state
)
473 /* Ensure null termination */
474 state
->request
.data
.username
475 [sizeof(state
->request
.data
.username
)-1] = '\0';
477 DEBUG(3, ("[%5lu]: name2uid %s\n", (unsigned long)state
->pid
,
478 state
->request
.data
.username
));
480 pw
= getpwnam(state
->request
.data
.username
);
482 return WINBINDD_ERROR
;
485 state
->response
.data
.uid
= pw
->pw_uid
;
490 static void name2uid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
491 struct winbindd_response
*response
,
492 void *c
, void *private_data
)
494 void (*cont
)(void *priv
, BOOL succ
, uid_t uid
) =
495 (void (*)(void *, BOOL
, uid_t
))c
;
498 DEBUG(5, ("Could not trigger name2uid\n"));
499 cont(private_data
, False
, 0);
503 if (response
->result
!= WINBINDD_OK
) {
504 DEBUG(5, ("name2uid returned an error\n"));
505 cont(private_data
, False
, 0);
509 cont(private_data
, True
, response
->data
.uid
);
511 #endif /* not used */
513 static void winbindd_sid2gid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
514 struct winbindd_response
*response
,
515 void *c
, void *private_data
)
517 void (*cont
)(void *priv
, BOOL succ
, gid_t gid
) =
518 (void (*)(void *, BOOL
, gid_t
))c
;
521 DEBUG(5, ("Could not trigger sid2gid\n"));
522 cont(private_data
, False
, 0);
526 if (response
->result
!= WINBINDD_OK
) {
527 DEBUG(5, ("sid2gid returned an error\n"));
528 cont(private_data
, False
, 0);
532 cont(private_data
, True
, response
->data
.gid
);
535 void winbindd_sid2gid_async(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sid
,
536 void (*cont
)(void *private_data
, BOOL success
, gid_t gid
),
539 struct winbindd_request request
;
540 ZERO_STRUCT(request
);
541 request
.cmd
= WINBINDD_DUAL_SID2GID
;
542 sid_to_string(request
.data
.dual_sid2id
.sid
, sid
);
544 DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
545 request
.data
.dual_sid2id
.sid
));
547 do_async(mem_ctx
, idmap_child(), &request
, winbindd_sid2gid_recv
,
548 (void *)cont
, private_data
);
551 enum winbindd_result
winbindd_dual_sid2gid(struct winbindd_domain
*domain
,
552 struct winbindd_cli_state
*state
)
557 DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state
->pid
,
558 state
->request
.data
.dual_sid2id
.sid
));
560 if (!string_to_sid(&sid
, state
->request
.data
.dual_sid2id
.sid
)) {
561 DEBUG(1, ("Could not get convert sid %s from string\n",
562 state
->request
.data
.dual_sid2id
.sid
));
563 return WINBINDD_ERROR
;
566 /* Find gid for this sid and return it, possibly ask the slow remote idmap */
568 result
= idmap_sid_to_gid(&sid
, &state
->response
.data
.gid
);
570 DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", NT_STATUS_V(result
), sid_string_static(&sid
), state
->response
.data
.gid
));
572 return NT_STATUS_IS_OK(result
) ? WINBINDD_OK
: WINBINDD_ERROR
;
575 static void gid2name_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
576 struct winbindd_response
*response
,
577 void *c
, void *private_data
)
579 void (*cont
)(void *priv
, BOOL succ
, const char *name
) =
580 (void (*)(void *, BOOL
, const char *))c
;
583 DEBUG(5, ("Could not trigger gid2name\n"));
584 cont(private_data
, False
, NULL
);
588 if (response
->result
!= WINBINDD_OK
) {
589 DEBUG(5, ("gid2name returned an error\n"));
590 cont(private_data
, False
, NULL
);
594 cont(private_data
, True
, response
->data
.name
.name
);
597 void winbindd_gid2name_async(TALLOC_CTX
*mem_ctx
, gid_t gid
,
598 void (*cont
)(void *private_data
, BOOL success
,
602 struct winbindd_request request
;
603 ZERO_STRUCT(request
);
604 request
.cmd
= WINBINDD_DUAL_GID2NAME
;
605 request
.data
.gid
= gid
;
606 do_async(mem_ctx
, idmap_child(), &request
, gid2name_recv
,
607 (void *)cont
, private_data
);
610 enum winbindd_result
winbindd_dual_gid2name(struct winbindd_domain
*domain
,
611 struct winbindd_cli_state
*state
)
615 DEBUG(3, ("[%5lu]: gid2name %lu\n", (unsigned long)state
->pid
,
616 (unsigned long)state
->request
.data
.gid
));
618 gr
= getgrgid(state
->request
.data
.gid
);
620 return WINBINDD_ERROR
;
622 fstrcpy(state
->response
.data
.name
.name
, gr
->gr_name
);
627 static void name2gid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
628 struct winbindd_response
*response
,
629 void *c
, void *private_data
);
631 static void winbindd_name2gid_async(TALLOC_CTX
*mem_ctx
, const char *name
,
632 void (*cont
)(void *private_data
, BOOL success
,
636 struct winbindd_request request
;
637 ZERO_STRUCT(request
);
638 request
.cmd
= WINBINDD_DUAL_NAME2GID
;
639 fstrcpy(request
.data
.groupname
, name
);
640 do_async(mem_ctx
, idmap_child(), &request
, name2gid_recv
,
641 (void *)cont
, private_data
);
643 #endif /* not used */
645 enum winbindd_result
winbindd_dual_name2gid(struct winbindd_domain
*domain
,
646 struct winbindd_cli_state
*state
)
650 /* Ensure null termination */
651 state
->request
.data
.groupname
652 [sizeof(state
->request
.data
.groupname
)-1] = '\0';
654 DEBUG(3, ("[%5lu]: name2gid %s\n", (unsigned long)state
->pid
,
655 state
->request
.data
.groupname
));
657 gr
= getgrnam(state
->request
.data
.groupname
);
659 return WINBINDD_ERROR
;
662 state
->response
.data
.gid
= gr
->gr_gid
;
667 static void name2gid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
668 struct winbindd_response
*response
,
669 void *c
, void *private_data
)
671 void (*cont
)(void *priv
, BOOL succ
, gid_t gid
) =
672 (void (*)(void *, BOOL
, gid_t
))c
;
675 DEBUG(5, ("Could not trigger name2gid\n"));
676 cont(private_data
, False
, 0);
680 if (response
->result
!= WINBINDD_OK
) {
681 DEBUG(5, ("name2gid returned an error\n"));
682 cont(private_data
, False
, 0);
686 cont(private_data
, True
, response
->data
.gid
);
688 #endif /* not used */
690 static void lookupsid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
691 struct winbindd_response
*response
,
692 void *c
, void *private_data
)
694 void (*cont
)(void *priv
, BOOL succ
, const char *dom_name
,
695 const char *name
, enum lsa_SidType type
) =
696 (void (*)(void *, BOOL
, const char *, const char *,
700 DEBUG(5, ("Could not trigger lookupsid\n"));
701 cont(private_data
, False
, NULL
, NULL
, SID_NAME_UNKNOWN
);
705 if (response
->result
!= WINBINDD_OK
) {
706 DEBUG(5, ("lookupsid returned an error\n"));
707 cont(private_data
, False
, NULL
, NULL
, SID_NAME_UNKNOWN
);
711 cont(private_data
, True
, response
->data
.name
.dom_name
,
712 response
->data
.name
.name
,
713 (enum lsa_SidType
)response
->data
.name
.type
);
716 void winbindd_lookupsid_async(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sid
,
717 void (*cont
)(void *private_data
, BOOL success
,
718 const char *dom_name
,
720 enum lsa_SidType type
),
723 struct winbindd_domain
*domain
;
724 struct winbindd_request request
;
726 domain
= find_lookup_domain_from_sid(sid
);
727 if (domain
== NULL
) {
728 DEBUG(5, ("Could not find domain for sid %s\n",
729 sid_string_static(sid
)));
730 cont(private_data
, False
, NULL
, NULL
, SID_NAME_UNKNOWN
);
734 ZERO_STRUCT(request
);
735 request
.cmd
= WINBINDD_LOOKUPSID
;
736 fstrcpy(request
.data
.sid
, sid_string_static(sid
));
738 do_async_domain(mem_ctx
, domain
, &request
, lookupsid_recv
,
739 (void *)cont
, private_data
);
742 enum winbindd_result
winbindd_dual_lookupsid(struct winbindd_domain
*domain
,
743 struct winbindd_cli_state
*state
)
745 enum lsa_SidType type
;
750 /* Ensure null termination */
751 state
->request
.data
.sid
[sizeof(state
->request
.data
.sid
)-1]='\0';
753 DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state
->pid
,
754 state
->request
.data
.sid
));
756 /* Lookup sid from PDC using lsa_lookup_sids() */
758 if (!string_to_sid(&sid
, state
->request
.data
.sid
)) {
759 DEBUG(5, ("%s not a SID\n", state
->request
.data
.sid
));
760 return WINBINDD_ERROR
;
765 if (!winbindd_lookup_name_by_sid(state
->mem_ctx
, &sid
, &dom_name
, &name
,
767 TALLOC_FREE(dom_name
);
769 return WINBINDD_ERROR
;
772 fstrcpy(state
->response
.data
.name
.dom_name
, dom_name
);
773 fstrcpy(state
->response
.data
.name
.name
, name
);
774 state
->response
.data
.name
.type
= type
;
776 TALLOC_FREE(dom_name
);
781 /********************************************************************
782 This is the second callback after contacting the forest root
783 ********************************************************************/
785 struct lookupname_state
{
788 void *caller_private_data
;
791 static void lookupname_recv2(TALLOC_CTX
*mem_ctx
, BOOL success
,
792 struct winbindd_response
*response
,
793 void *c
, void *private_data
)
795 void (*cont
)(void *priv
, BOOL succ
, const DOM_SID
*sid
,
796 enum lsa_SidType type
) =
797 (void (*)(void *, BOOL
, const DOM_SID
*, enum lsa_SidType
))c
;
799 struct lookupname_state
*s
= talloc_get_type_abort(private_data
, struct lookupname_state
);
802 DEBUG(5, ("Could not trigger lookup_name\n"));
803 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
807 if (response
->result
!= WINBINDD_OK
) {
808 DEBUG(5, ("lookup_name returned an error\n"));
809 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
813 if (!string_to_sid(&sid
, response
->data
.sid
.sid
)) {
814 DEBUG(0, ("Could not convert string %s to sid\n",
815 response
->data
.sid
.sid
));
816 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
820 cont(s
->caller_private_data
, True
, &sid
,
821 (enum lsa_SidType
)response
->data
.sid
.type
);
824 /********************************************************************
825 This is the first callback after contacting our own domain
826 ********************************************************************/
828 static void lookupname_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
829 struct winbindd_response
*response
,
830 void *c
, void *private_data
)
832 void (*cont
)(void *priv
, BOOL succ
, const DOM_SID
*sid
,
833 enum lsa_SidType type
) =
834 (void (*)(void *, BOOL
, const DOM_SID
*, enum lsa_SidType
))c
;
836 struct lookupname_state
*s
= talloc_get_type_abort(private_data
, struct lookupname_state
);
839 DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
840 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
844 if (response
->result
!= WINBINDD_OK
) {
845 /* Try again using the forest root */
846 struct winbindd_domain
*root_domain
= find_root_domain();
847 struct winbindd_request request
;
849 if ( !root_domain
) {
850 DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
851 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
855 ZERO_STRUCT(request
);
856 request
.cmd
= WINBINDD_LOOKUPNAME
;
857 fstrcpy(request
.data
.name
.dom_name
, s
->dom_name
);
858 fstrcpy(request
.data
.name
.name
, s
->name
);
860 do_async_domain(mem_ctx
, root_domain
, &request
, lookupname_recv2
,
866 if (!string_to_sid(&sid
, response
->data
.sid
.sid
)) {
867 DEBUG(0, ("Could not convert string %s to sid\n",
868 response
->data
.sid
.sid
));
869 cont(s
->caller_private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
873 cont(s
->caller_private_data
, True
, &sid
,
874 (enum lsa_SidType
)response
->data
.sid
.type
);
877 /********************************************************************
878 The lookup name call first contacts a DC in its own domain
879 and fallbacks to contact a DC in the forest in our domain doesn't
881 ********************************************************************/
883 void winbindd_lookupname_async(TALLOC_CTX
*mem_ctx
,
884 const char *dom_name
, const char *name
,
885 void (*cont
)(void *private_data
, BOOL success
,
887 enum lsa_SidType type
),
890 struct winbindd_request request
;
891 struct winbindd_domain
*domain
;
892 struct lookupname_state
*s
;
894 if ( (domain
= find_lookup_domain_from_name(dom_name
)) == NULL
) {
895 DEBUG(5, ("Could not find domain for name %s\n", dom_name
));
896 cont(private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
900 ZERO_STRUCT(request
);
901 request
.cmd
= WINBINDD_LOOKUPNAME
;
902 fstrcpy(request
.data
.name
.dom_name
, dom_name
);
903 fstrcpy(request
.data
.name
.name
, name
);
905 if ( (s
= TALLOC_ZERO_P(mem_ctx
, struct lookupname_state
)) == NULL
) {
906 DEBUG(0, ("winbindd_lookupname_async: talloc failed\n"));
907 cont(private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
911 s
->dom_name
= talloc_strdup( s
, dom_name
);
912 s
->name
= talloc_strdup( s
, name
);
913 if (!s
->dom_name
|| !s
->name
) {
914 cont(private_data
, False
, NULL
, SID_NAME_UNKNOWN
);
918 s
->caller_private_data
= private_data
;
920 do_async_domain(mem_ctx
, domain
, &request
, lookupname_recv
,
924 enum winbindd_result
winbindd_dual_lookupname(struct winbindd_domain
*domain
,
925 struct winbindd_cli_state
*state
)
927 enum lsa_SidType type
;
928 char *name_domain
, *name_user
;
932 /* Ensure null termination */
933 state
->request
.data
.name
.dom_name
[sizeof(state
->request
.data
.name
.dom_name
)-1]='\0';
935 /* Ensure null termination */
936 state
->request
.data
.name
.name
[sizeof(state
->request
.data
.name
.name
)-1]='\0';
938 /* cope with the name being a fully qualified name */
939 p
= strstr(state
->request
.data
.name
.name
, lp_winbind_separator());
942 name_domain
= state
->request
.data
.name
.name
;
945 name_domain
= state
->request
.data
.name
.dom_name
;
946 name_user
= state
->request
.data
.name
.name
;
949 DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state
->pid
,
950 name_domain
, lp_winbind_separator(), name_user
));
952 /* Lookup name from DC using lsa_lookup_names() */
953 if (!winbindd_lookup_sid_by_name(state
->mem_ctx
, domain
, name_domain
,
954 name_user
, &sid
, &type
)) {
955 return WINBINDD_ERROR
;
958 sid_to_string(state
->response
.data
.sid
.sid
, &sid
);
959 state
->response
.data
.sid
.type
= type
;
964 BOOL
print_sidlist(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sids
,
965 size_t num_sids
, char **result
, ssize_t
*len
)
972 for (i
=0; i
<num_sids
; i
++) {
973 sprintf_append(mem_ctx
, result
, len
, &buflen
,
974 "%s\n", sid_string_static(&sids
[i
]));
977 if ((num_sids
!= 0) && (*result
== NULL
)) {
984 static BOOL
parse_sidlist(TALLOC_CTX
*mem_ctx
, char *sidstr
,
985 DOM_SID
**sids
, size_t *num_sids
)
993 while (p
[0] != '\0') {
997 DEBUG(0, ("Got invalid sidstr: %s\n", p
));
1002 if (!string_to_sid(&sid
, p
)) {
1003 DEBUG(0, ("Could not parse sid %s\n", p
));
1006 if (!add_sid_to_array(mem_ctx
, &sid
, sids
, num_sids
)) {
1014 static BOOL
parse_ridlist(TALLOC_CTX
*mem_ctx
, char *ridstr
,
1015 uint32
**rids
, size_t *num_rids
)
1023 while (p
[0] != '\0') {
1026 rid
= strtoul(p
, &q
, 10);
1028 DEBUG(0, ("Got invalid ridstr: %s\n", p
));
1032 ADD_TO_ARRAY(mem_ctx
, uint32
, rid
, rids
, num_rids
);
1037 enum winbindd_result
winbindd_dual_lookuprids(struct winbindd_domain
*domain
,
1038 struct winbindd_cli_state
*state
)
1040 uint32
*rids
= NULL
;
1041 size_t i
, buflen
, num_rids
= 0;
1046 enum lsa_SidType
*types
;
1050 DEBUG(10, ("Looking up RIDs for domain %s (%s)\n",
1051 state
->request
.domain_name
,
1052 state
->request
.data
.sid
));
1054 if (!parse_ridlist(state
->mem_ctx
, state
->request
.extra_data
.data
,
1055 &rids
, &num_rids
)) {
1056 DEBUG(5, ("Could not parse ridlist\n"));
1057 return WINBINDD_ERROR
;
1060 if (!string_to_sid(&domain_sid
, state
->request
.data
.sid
)) {
1061 DEBUG(5, ("Could not parse domain sid %s\n",
1062 state
->request
.data
.sid
));
1063 return WINBINDD_ERROR
;
1066 status
= domain
->methods
->rids_to_names(domain
, state
->mem_ctx
,
1067 &domain_sid
, rids
, num_rids
,
1071 if (!NT_STATUS_IS_OK(status
) &&
1072 !NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
1073 return WINBINDD_ERROR
;
1080 for (i
=0; i
<num_rids
; i
++) {
1081 sprintf_append(state
->mem_ctx
, &result
, &len
, &buflen
,
1082 "%d %s\n", types
[i
], names
[i
]);
1085 fstrcpy(state
->response
.data
.domain_name
, domain_name
);
1087 if (result
!= NULL
) {
1088 state
->response
.extra_data
.data
= SMB_STRDUP(result
);
1089 if (!state
->response
.extra_data
.data
) {
1090 return WINBINDD_ERROR
;
1092 state
->response
.length
+= len
+1;
1098 static void getsidaliases_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
1099 struct winbindd_response
*response
,
1100 void *c
, void *private_data
)
1102 void (*cont
)(void *priv
, BOOL succ
,
1103 DOM_SID
*aliases
, size_t num_aliases
) =
1104 (void (*)(void *, BOOL
, DOM_SID
*, size_t))c
;
1106 DOM_SID
*sids
= NULL
;
1107 size_t num_sids
= 0;
1110 DEBUG(5, ("Could not trigger getsidaliases\n"));
1111 cont(private_data
, success
, NULL
, 0);
1115 if (response
->result
!= WINBINDD_OK
) {
1116 DEBUG(5, ("getsidaliases returned an error\n"));
1117 cont(private_data
, False
, NULL
, 0);
1121 aliases_str
= (char *)response
->extra_data
.data
;
1123 if (aliases_str
== NULL
) {
1124 DEBUG(10, ("getsidaliases return 0 SIDs\n"));
1125 cont(private_data
, True
, NULL
, 0);
1129 if (!parse_sidlist(mem_ctx
, aliases_str
, &sids
, &num_sids
)) {
1130 DEBUG(0, ("Could not parse sids\n"));
1131 cont(private_data
, False
, NULL
, 0);
1135 SAFE_FREE(response
->extra_data
.data
);
1137 cont(private_data
, True
, sids
, num_sids
);
1140 void winbindd_getsidaliases_async(struct winbindd_domain
*domain
,
1141 TALLOC_CTX
*mem_ctx
,
1142 const DOM_SID
*sids
, size_t num_sids
,
1143 void (*cont
)(void *private_data
,
1145 const DOM_SID
*aliases
,
1146 size_t num_aliases
),
1149 struct winbindd_request request
;
1150 char *sidstr
= NULL
;
1153 if (num_sids
== 0) {
1154 cont(private_data
, True
, NULL
, 0);
1158 if (!print_sidlist(mem_ctx
, sids
, num_sids
, &sidstr
, &len
)) {
1159 cont(private_data
, False
, NULL
, 0);
1163 ZERO_STRUCT(request
);
1164 request
.cmd
= WINBINDD_DUAL_GETSIDALIASES
;
1165 request
.extra_len
= len
;
1166 request
.extra_data
.data
= sidstr
;
1168 do_async_domain(mem_ctx
, domain
, &request
, getsidaliases_recv
,
1169 (void *)cont
, private_data
);
1172 enum winbindd_result
winbindd_dual_getsidaliases(struct winbindd_domain
*domain
,
1173 struct winbindd_cli_state
*state
)
1175 DOM_SID
*sids
= NULL
;
1176 size_t num_sids
= 0;
1177 char *sidstr
= NULL
;
1184 DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state
->pid
));
1186 sidstr
= state
->request
.extra_data
.data
;
1187 if (sidstr
== NULL
) {
1188 sidstr
= talloc_strdup(state
->mem_ctx
, "\n"); /* No SID */
1190 DEBUG(0, ("Out of memory\n"));
1191 return WINBINDD_ERROR
;
1195 DEBUG(10, ("Sidlist: %s\n", sidstr
));
1197 if (!parse_sidlist(state
->mem_ctx
, sidstr
, &sids
, &num_sids
)) {
1198 DEBUG(0, ("Could not parse SID list: %s\n", sidstr
));
1199 return WINBINDD_ERROR
;
1205 result
= domain
->methods
->lookup_useraliases(domain
,
1211 if (!NT_STATUS_IS_OK(result
)) {
1212 DEBUG(3, ("Could not lookup_useraliases: %s\n",
1213 nt_errstr(result
)));
1214 return WINBINDD_ERROR
;
1221 DEBUG(10, ("Got %d aliases\n", num_aliases
));
1223 for (i
=0; i
<num_aliases
; i
++) {
1225 DEBUGADD(10, (" rid %d\n", alias_rids
[i
]));
1226 sid_copy(&sid
, &domain
->sid
);
1227 sid_append_rid(&sid
, alias_rids
[i
]);
1228 if (!add_sid_to_array(state
->mem_ctx
, &sid
, &sids
, &num_sids
)) {
1229 return WINBINDD_ERROR
;
1234 if (!print_sidlist(state
->mem_ctx
, sids
, num_sids
, &sidstr
, &len
)) {
1235 DEBUG(0, ("Could not print_sidlist\n"));
1236 state
->response
.extra_data
.data
= NULL
;
1237 return WINBINDD_ERROR
;
1240 state
->response
.extra_data
.data
= NULL
;
1243 state
->response
.extra_data
.data
= SMB_STRDUP(sidstr
);
1244 if (!state
->response
.extra_data
.data
) {
1245 DEBUG(0, ("Out of memory\n"));
1246 return WINBINDD_ERROR
;
1248 DEBUG(10, ("aliases_list: %s\n",
1249 (char *)state
->response
.extra_data
.data
));
1250 state
->response
.length
+= len
+1;
1256 struct gettoken_state
{
1257 TALLOC_CTX
*mem_ctx
;
1259 struct winbindd_domain
*alias_domain
;
1260 struct winbindd_domain
*local_alias_domain
;
1261 struct winbindd_domain
*builtin_domain
;
1264 void (*cont
)(void *private_data
, BOOL success
, DOM_SID
*sids
, size_t num_sids
);
1268 static void gettoken_recvdomgroups(TALLOC_CTX
*mem_ctx
, BOOL success
,
1269 struct winbindd_response
*response
,
1270 void *c
, void *private_data
);
1271 static void gettoken_recvaliases(void *private_data
, BOOL success
,
1272 const DOM_SID
*aliases
,
1273 size_t num_aliases
);
1276 void winbindd_gettoken_async(TALLOC_CTX
*mem_ctx
, const DOM_SID
*user_sid
,
1277 void (*cont
)(void *private_data
, BOOL success
,
1278 DOM_SID
*sids
, size_t num_sids
),
1281 struct winbindd_domain
*domain
;
1282 struct winbindd_request request
;
1283 struct gettoken_state
*state
;
1285 state
= TALLOC_ZERO_P(mem_ctx
, struct gettoken_state
);
1286 if (state
== NULL
) {
1287 DEBUG(0, ("talloc failed\n"));
1288 cont(private_data
, False
, NULL
, 0);
1292 state
->mem_ctx
= mem_ctx
;
1293 sid_copy(&state
->user_sid
, user_sid
);
1294 state
->alias_domain
= find_our_domain();
1295 state
->local_alias_domain
= find_domain_from_name( get_global_sam_name() );
1296 state
->builtin_domain
= find_builtin_domain();
1298 state
->private_data
= private_data
;
1300 domain
= find_domain_from_sid_noinit(user_sid
);
1301 if (domain
== NULL
) {
1302 DEBUG(5, ("Could not find domain from SID %s\n",
1303 sid_string_static(user_sid
)));
1304 cont(private_data
, False
, NULL
, 0);
1308 ZERO_STRUCT(request
);
1309 request
.cmd
= WINBINDD_GETUSERDOMGROUPS
;
1310 fstrcpy(request
.data
.sid
, sid_string_static(user_sid
));
1312 do_async_domain(mem_ctx
, domain
, &request
, gettoken_recvdomgroups
,
1316 static void gettoken_recvdomgroups(TALLOC_CTX
*mem_ctx
, BOOL success
,
1317 struct winbindd_response
*response
,
1318 void *c
, void *private_data
)
1320 struct gettoken_state
*state
=
1321 talloc_get_type_abort(private_data
, struct gettoken_state
);
1325 DEBUG(10, ("Could not get domain groups\n"));
1326 state
->cont(state
->private_data
, False
, NULL
, 0);
1330 sids_str
= (char *)response
->extra_data
.data
;
1332 if (sids_str
== NULL
) {
1333 /* This could be normal if we are dealing with a
1334 local user and local groups */
1336 if ( !sid_check_is_in_our_domain( &state
->user_sid
) ) {
1337 DEBUG(10, ("Received no domain groups\n"));
1338 state
->cont(state
->private_data
, True
, NULL
, 0);
1344 state
->num_sids
= 0;
1346 if (!add_sid_to_array(mem_ctx
, &state
->user_sid
, &state
->sids
,
1347 &state
->num_sids
)) {
1348 DEBUG(0, ("Out of memory\n"));
1349 state
->cont(state
->private_data
, False
, NULL
, 0);
1353 if (sids_str
&& !parse_sidlist(mem_ctx
, sids_str
, &state
->sids
,
1354 &state
->num_sids
)) {
1355 DEBUG(0, ("Could not parse sids\n"));
1356 state
->cont(state
->private_data
, False
, NULL
, 0);
1360 SAFE_FREE(response
->extra_data
.data
);
1362 if (state
->alias_domain
== NULL
) {
1363 DEBUG(10, ("Don't expand domain local groups\n"));
1364 state
->cont(state
->private_data
, True
, state
->sids
,
1369 winbindd_getsidaliases_async(state
->alias_domain
, mem_ctx
,
1370 state
->sids
, state
->num_sids
,
1371 gettoken_recvaliases
, state
);
1374 static void gettoken_recvaliases(void *private_data
, BOOL success
,
1375 const DOM_SID
*aliases
,
1378 struct gettoken_state
*state
= (struct gettoken_state
*)private_data
;
1382 DEBUG(10, ("Could not receive domain local groups\n"));
1383 state
->cont(state
->private_data
, False
, NULL
, 0);
1387 for (i
=0; i
<num_aliases
; i
++) {
1388 if (!add_sid_to_array(state
->mem_ctx
, &aliases
[i
],
1389 &state
->sids
, &state
->num_sids
)) {
1390 DEBUG(0, ("Out of memory\n"));
1391 state
->cont(state
->private_data
, False
, NULL
, 0);
1396 if (state
->local_alias_domain
!= NULL
) {
1397 struct winbindd_domain
*local_domain
= state
->local_alias_domain
;
1398 DEBUG(10, ("Expanding our own local groups\n"));
1399 state
->local_alias_domain
= NULL
;
1400 winbindd_getsidaliases_async(local_domain
, state
->mem_ctx
,
1401 state
->sids
, state
->num_sids
,
1402 gettoken_recvaliases
, state
);
1406 if (state
->builtin_domain
!= NULL
) {
1407 struct winbindd_domain
*builtin_domain
= state
->builtin_domain
;
1408 DEBUG(10, ("Expanding our own BUILTIN groups\n"));
1409 state
->builtin_domain
= NULL
;
1410 winbindd_getsidaliases_async(builtin_domain
, state
->mem_ctx
,
1411 state
->sids
, state
->num_sids
,
1412 gettoken_recvaliases
, state
);
1416 state
->cont(state
->private_data
, True
, state
->sids
, state
->num_sids
);
1419 static void query_user_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
1420 struct winbindd_response
*response
,
1421 void *c
, void *private_data
)
1423 void (*cont
)(void *priv
, BOOL succ
, const char *acct_name
,
1424 const char *full_name
, const char *homedir
,
1425 const char *shell
, uint32 gid
, uint32 group_rid
) =
1426 (void (*)(void *, BOOL
, const char *, const char *,
1427 const char *, const char *, uint32
, uint32
))c
;
1430 DEBUG(5, ("Could not trigger query_user\n"));
1431 cont(private_data
, False
, NULL
, NULL
, NULL
, NULL
, -1, -1);
1435 if (response
->result
!= WINBINDD_OK
) {
1436 DEBUG(5, ("query_user returned an error\n"));
1437 cont(private_data
, False
, NULL
, NULL
, NULL
, NULL
, -1, -1);
1441 cont(private_data
, True
, response
->data
.user_info
.acct_name
,
1442 response
->data
.user_info
.full_name
,
1443 response
->data
.user_info
.homedir
,
1444 response
->data
.user_info
.shell
,
1445 response
->data
.user_info
.primary_gid
,
1446 response
->data
.user_info
.group_rid
);
1449 void query_user_async(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1451 void (*cont
)(void *private_data
, BOOL success
,
1452 const char *acct_name
,
1453 const char *full_name
,
1454 const char *homedir
,
1460 struct winbindd_request request
;
1461 ZERO_STRUCT(request
);
1462 request
.cmd
= WINBINDD_DUAL_USERINFO
;
1463 sid_to_string(request
.data
.sid
, sid
);
1464 do_async_domain(mem_ctx
, domain
, &request
, query_user_recv
,
1465 (void *)cont
, private_data
);
1468 /* The following uid2sid/gid2sid functions has been contributed by
1469 * Keith Reynolds <Keith.Reynolds@centrify.com> */
1471 static void winbindd_uid2sid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
1472 struct winbindd_response
*response
,
1473 void *c
, void *private_data
)
1475 void (*cont
)(void *priv
, BOOL succ
, const char *sid
) =
1476 (void (*)(void *, BOOL
, const char *))c
;
1479 DEBUG(5, ("Could not trigger uid2sid\n"));
1480 cont(private_data
, False
, NULL
);
1484 if (response
->result
!= WINBINDD_OK
) {
1485 DEBUG(5, ("uid2sid returned an error\n"));
1486 cont(private_data
, False
, NULL
);
1490 cont(private_data
, True
, response
->data
.sid
.sid
);
1493 void winbindd_uid2sid_async(TALLOC_CTX
*mem_ctx
, uid_t uid
,
1494 void (*cont
)(void *private_data
, BOOL success
, const char *sid
),
1497 struct winbindd_request request
;
1499 ZERO_STRUCT(request
);
1500 request
.cmd
= WINBINDD_DUAL_UID2SID
;
1501 request
.data
.uid
= uid
;
1502 do_async(mem_ctx
, idmap_child(), &request
, winbindd_uid2sid_recv
,
1503 (void *)cont
, private_data
);
1506 enum winbindd_result
winbindd_dual_uid2sid(struct winbindd_domain
*domain
,
1507 struct winbindd_cli_state
*state
)
1512 DEBUG(3,("[%5lu]: uid to sid %lu\n",
1513 (unsigned long)state
->pid
,
1514 (unsigned long) state
->request
.data
.uid
));
1516 /* Find sid for this uid and return it, possibly ask the slow remote idmap */
1517 result
= idmap_uid_to_sid(&sid
, state
->request
.data
.uid
);
1519 if (NT_STATUS_IS_OK(result
)) {
1520 sid_to_string(state
->response
.data
.sid
.sid
, &sid
);
1521 state
->response
.data
.sid
.type
= SID_NAME_USER
;
1525 return WINBINDD_ERROR
;
1528 static void winbindd_gid2sid_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
1529 struct winbindd_response
*response
,
1530 void *c
, void *private_data
)
1532 void (*cont
)(void *priv
, BOOL succ
, const char *sid
) =
1533 (void (*)(void *, BOOL
, const char *))c
;
1536 DEBUG(5, ("Could not trigger gid2sid\n"));
1537 cont(private_data
, False
, NULL
);
1541 if (response
->result
!= WINBINDD_OK
) {
1542 DEBUG(5, ("gid2sid returned an error\n"));
1543 cont(private_data
, False
, NULL
);
1547 cont(private_data
, True
, response
->data
.sid
.sid
);
1550 void winbindd_gid2sid_async(TALLOC_CTX
*mem_ctx
, gid_t gid
,
1551 void (*cont
)(void *private_data
, BOOL success
, const char *sid
),
1554 struct winbindd_request request
;
1556 ZERO_STRUCT(request
);
1557 request
.cmd
= WINBINDD_DUAL_GID2SID
;
1558 request
.data
.gid
= gid
;
1559 do_async(mem_ctx
, idmap_child(), &request
, winbindd_gid2sid_recv
,
1560 (void *)cont
, private_data
);
1563 enum winbindd_result
winbindd_dual_gid2sid(struct winbindd_domain
*domain
,
1564 struct winbindd_cli_state
*state
)
1569 DEBUG(3,("[%5lu]: gid %lu to sid\n",
1570 (unsigned long)state
->pid
,
1571 (unsigned long) state
->request
.data
.gid
));
1573 /* Find sid for this gid and return it, possibly ask the slow remote idmap */
1574 result
= idmap_gid_to_sid(&sid
, state
->request
.data
.gid
);
1576 if (NT_STATUS_IS_OK(result
)) {
1577 sid_to_string(state
->response
.data
.sid
.sid
, &sid
);
1578 DEBUG(10, ("[%5lu]: retrieved sid: %s\n",
1579 (unsigned long)state
->pid
,
1580 state
->response
.data
.sid
.sid
));
1581 state
->response
.data
.sid
.type
= SID_NAME_DOM_GRP
;
1585 return WINBINDD_ERROR
;
1588 static void winbindd_dump_id_maps_recv(TALLOC_CTX
*mem_ctx
, BOOL success
,
1589 struct winbindd_response
*response
,
1590 void *c
, void *private_data
)
1592 void (*cont
)(void *priv
, BOOL succ
) =
1593 (void (*)(void *, BOOL
))c
;
1596 DEBUG(5, ("Could not trigger a map dump\n"));
1597 cont(private_data
, False
);
1601 if (response
->result
!= WINBINDD_OK
) {
1602 DEBUG(5, ("idmap dump maps returned an error\n"));
1603 cont(private_data
, False
);
1607 cont(private_data
, True
);
1610 void winbindd_dump_maps_async(TALLOC_CTX
*mem_ctx
, void *data
, int size
,
1611 void (*cont
)(void *private_data
, BOOL success
),
1614 struct winbindd_request request
;
1615 ZERO_STRUCT(request
);
1616 request
.cmd
= WINBINDD_DUAL_DUMP_MAPS
;
1617 request
.extra_data
.data
= (char *)data
;
1618 request
.extra_len
= size
;
1619 do_async(mem_ctx
, idmap_child(), &request
, winbindd_dump_id_maps_recv
,
1620 (void *)cont
, private_data
);
1623 enum winbindd_result
winbindd_dual_dump_maps(struct winbindd_domain
*domain
,
1624 struct winbindd_cli_state
*state
)
1626 DEBUG(3, ("[%5lu]: dual dump maps\n", (unsigned long)state
->pid
));
1628 idmap_dump_maps((char *)state
->request
.extra_data
.data
);