00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "includes.h"
00036 #include "winbindd.h"
00037
00038 #undef DBGC_CLASS
00039 #define DBGC_CLASS DBGC_WINBIND
00040
00041 struct do_async_state {
00042 TALLOC_CTX *mem_ctx;
00043 struct winbindd_request request;
00044 struct winbindd_response response;
00045 void (*cont)(TALLOC_CTX *mem_ctx,
00046 BOOL success,
00047 struct winbindd_response *response,
00048 void *c, void *private_data);
00049 void *c, *private_data;
00050 };
00051
00052 static void do_async_recv(void *private_data, BOOL success)
00053 {
00054 struct do_async_state *state =
00055 talloc_get_type_abort(private_data, struct do_async_state);
00056
00057 state->cont(state->mem_ctx, success, &state->response,
00058 state->c, state->private_data);
00059 }
00060
00061 static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
00062 const struct winbindd_request *request,
00063 void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
00064 struct winbindd_response *response,
00065 void *c, void *private_data),
00066 void *c, void *private_data)
00067 {
00068 struct do_async_state *state;
00069
00070 state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
00071 if (state == NULL) {
00072 DEBUG(0, ("talloc failed\n"));
00073 cont(mem_ctx, False, NULL, c, private_data);
00074 return;
00075 }
00076
00077 state->mem_ctx = mem_ctx;
00078 state->request = *request;
00079 state->request.length = sizeof(state->request);
00080 state->cont = cont;
00081 state->c = c;
00082 state->private_data = private_data;
00083
00084 async_request(mem_ctx, child, &state->request,
00085 &state->response, do_async_recv, state);
00086 }
00087
00088 void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
00089 const struct winbindd_request *request,
00090 void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
00091 struct winbindd_response *response,
00092 void *c, void *private_data),
00093 void *c, void *private_data)
00094 {
00095 struct do_async_state *state;
00096
00097 state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
00098 if (state == NULL) {
00099 DEBUG(0, ("talloc failed\n"));
00100 cont(mem_ctx, False, NULL, c, private_data);
00101 return;
00102 }
00103
00104 state->mem_ctx = mem_ctx;
00105 state->request = *request;
00106 state->request.length = sizeof(state->request);
00107 state->cont = cont;
00108 state->c = c;
00109 state->private_data = private_data;
00110
00111 async_domain_request(mem_ctx, domain, &state->request,
00112 &state->response, do_async_recv, state);
00113 }
00114
00115 static void winbindd_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success,
00116 struct winbindd_response *response,
00117 void *c, void *private_data)
00118 {
00119 void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
00120
00121 if (!success) {
00122 DEBUG(5, ("Could not trigger idmap_set_mapping\n"));
00123 cont(private_data, False);
00124 return;
00125 }
00126
00127 if (response->result != WINBINDD_OK) {
00128 DEBUG(5, ("idmap_set_mapping returned an error\n"));
00129 cont(private_data, False);
00130 return;
00131 }
00132
00133 cont(private_data, True);
00134 }
00135
00136 void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
00137 void (*cont)(void *private_data, BOOL success),
00138 void *private_data)
00139 {
00140 struct winbindd_request request;
00141 ZERO_STRUCT(request);
00142 request.cmd = WINBINDD_DUAL_SET_MAPPING;
00143 request.data.dual_idmapset.id = map->xid.id;
00144 request.data.dual_idmapset.type = map->xid.type;
00145 sid_to_string(request.data.dual_idmapset.sid, map->sid);
00146
00147 do_async(mem_ctx, idmap_child(), &request, winbindd_set_mapping_recv,
00148 (void *)cont, private_data);
00149 }
00150
00151 enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
00152 struct winbindd_cli_state *state)
00153 {
00154 struct id_map map;
00155 DOM_SID sid;
00156 NTSTATUS result;
00157
00158 DEBUG(3, ("[%5lu]: dual_idmapset\n", (unsigned long)state->pid));
00159
00160 if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
00161 return WINBINDD_ERROR;
00162
00163 map.sid = &sid;
00164 map.xid.id = state->request.data.dual_idmapset.id;
00165 map.xid.type = state->request.data.dual_idmapset.type;
00166 map.status = ID_MAPPED;
00167
00168 result = idmap_set_mapping(&map);
00169 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
00170 }
00171
00172 static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, BOOL success,
00173 struct winbindd_response *response,
00174 void *c, void *private_data)
00175 {
00176 void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
00177
00178 if (!success) {
00179 DEBUG(5, ("Could not trigger idmap_set_hwm\n"));
00180 cont(private_data, False);
00181 return;
00182 }
00183
00184 if (response->result != WINBINDD_OK) {
00185 DEBUG(5, ("idmap_set_hwm returned an error\n"));
00186 cont(private_data, False);
00187 return;
00188 }
00189
00190 cont(private_data, True);
00191 }
00192
00193 void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
00194 void (*cont)(void *private_data, BOOL success),
00195 void *private_data)
00196 {
00197 struct winbindd_request request;
00198 ZERO_STRUCT(request);
00199 request.cmd = WINBINDD_DUAL_SET_HWM;
00200 request.data.dual_idmapset.id = xid->id;
00201 request.data.dual_idmapset.type = xid->type;
00202
00203 do_async(mem_ctx, idmap_child(), &request, winbindd_set_hwm_recv,
00204 (void *)cont, private_data);
00205 }
00206
00207 enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain,
00208 struct winbindd_cli_state *state)
00209 {
00210 struct unixid xid;
00211 NTSTATUS result;
00212
00213 DEBUG(3, ("[%5lu]: dual_set_hwm\n", (unsigned long)state->pid));
00214
00215 xid.id = state->request.data.dual_idmapset.id;
00216 xid.type = state->request.data.dual_idmapset.type;
00217
00218 switch (xid.type) {
00219 case ID_TYPE_UID:
00220 result = idmap_set_uid_hwm(&xid);
00221 break;
00222 case ID_TYPE_GID:
00223 result = idmap_set_gid_hwm(&xid);
00224 break;
00225 default:
00226 return WINBINDD_ERROR;
00227 }
00228 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
00229 }
00230
00231 static void winbindd_sids2xids_recv(TALLOC_CTX *mem_ctx, BOOL success,
00232 struct winbindd_response *response,
00233 void *c, void *private_data)
00234 {
00235 void (*cont)(void *priv, BOOL succ, void *, int) =
00236 (void (*)(void *, BOOL, void *, int))c;
00237
00238 if (!success) {
00239 DEBUG(5, ("Could not trigger sids2xids\n"));
00240 cont(private_data, False, NULL, 0);
00241 return;
00242 }
00243
00244 if (response->result != WINBINDD_OK) {
00245 DEBUG(5, ("sids2xids returned an error\n"));
00246 cont(private_data, False, NULL, 0);
00247 return;
00248 }
00249
00250 cont(private_data, True, response->extra_data.data, response->length - sizeof(response));
00251 }
00252
00253 void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size,
00254 void (*cont)(void *private_data, BOOL success, void *data, int len),
00255 void *private_data)
00256 {
00257 struct winbindd_request request;
00258 ZERO_STRUCT(request);
00259 request.cmd = WINBINDD_DUAL_SIDS2XIDS;
00260 request.extra_data.data = (char *)sids;
00261 request.extra_len = size;
00262 do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv,
00263 (void *)cont, private_data);
00264 }
00265
00266 enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain,
00267 struct winbindd_cli_state *state)
00268 {
00269 DOM_SID *sids;
00270 struct unixid *xids;
00271 struct id_map **ids;
00272 NTSTATUS result;
00273 int num, i;
00274
00275 DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid));
00276
00277 if (state->request.extra_len == 0) {
00278 DEBUG(0, ("Invalid buffer size!\n"));
00279 return WINBINDD_ERROR;
00280 }
00281
00282 sids = (DOM_SID *)state->request.extra_data.data;
00283 num = state->request.extra_len / sizeof(DOM_SID);
00284
00285 ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1);
00286 if ( ! ids) {
00287 DEBUG(0, ("Out of memory!\n"));
00288 return WINBINDD_ERROR;
00289 }
00290 for (i = 0; i < num; i++) {
00291 ids[i] = TALLOC_P(ids, struct id_map);
00292 if ( ! ids[i]) {
00293 DEBUG(0, ("Out of memory!\n"));
00294 talloc_free(ids);
00295 return WINBINDD_ERROR;
00296 }
00297 ids[i]->sid = &sids[i];
00298 }
00299
00300 result = idmap_sids_to_unixids(ids);
00301
00302 if (NT_STATUS_IS_OK(result)) {
00303
00304 xids = SMB_MALLOC_ARRAY(struct unixid, num);
00305 if ( ! xids) {
00306 DEBUG(0, ("Out of memory!\n"));
00307 talloc_free(ids);
00308 return WINBINDD_ERROR;
00309 }
00310
00311 for (i = 0; i < num; i++) {
00312 if (ids[i]->status == ID_MAPPED) {
00313 xids[i].type = ids[i]->xid.type;
00314 xids[i].id = ids[i]->xid.id;
00315 } else {
00316 xids[i].type = -1;
00317 }
00318 }
00319
00320 state->response.length = sizeof(state->response) + (sizeof(struct unixid) * num);
00321 state->response.extra_data.data = xids;
00322
00323 } else {
00324 DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result)));
00325 talloc_free(ids);
00326 return WINBINDD_ERROR;
00327 }
00328
00329 talloc_free(ids);
00330 return WINBINDD_OK;
00331 }
00332
00333 static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00334 struct winbindd_response *response,
00335 void *c, void *private_data)
00336 {
00337 void (*cont)(void *priv, BOOL succ, uid_t uid) =
00338 (void (*)(void *, BOOL, uid_t))c;
00339
00340 if (!success) {
00341 DEBUG(5, ("Could not trigger sid2uid\n"));
00342 cont(private_data, False, 0);
00343 return;
00344 }
00345
00346 if (response->result != WINBINDD_OK) {
00347 DEBUG(5, ("sid2uid returned an error\n"));
00348 cont(private_data, False, 0);
00349 return;
00350 }
00351
00352 cont(private_data, True, response->data.uid);
00353 }
00354
00355 void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00356 void (*cont)(void *private_data, BOOL success, uid_t uid),
00357 void *private_data)
00358 {
00359 struct winbindd_request request;
00360 ZERO_STRUCT(request);
00361 request.cmd = WINBINDD_DUAL_SID2UID;
00362 sid_to_string(request.data.dual_sid2id.sid, sid);
00363 do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv,
00364 (void *)cont, private_data);
00365 }
00366
00367 enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
00368 struct winbindd_cli_state *state)
00369 {
00370 DOM_SID sid;
00371 NTSTATUS result;
00372
00373 DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
00374 state->request.data.dual_sid2id.sid));
00375
00376 if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
00377 DEBUG(1, ("Could not get convert sid %s from string\n",
00378 state->request.data.dual_sid2id.sid));
00379 return WINBINDD_ERROR;
00380 }
00381
00382
00383
00384 result = idmap_sid_to_uid(&sid, &(state->response.data.uid));
00385
00386 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
00387 }
00388
00389 #if 0
00390 static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
00391 struct winbindd_response *response,
00392 void *c, void *private_data);
00393
00394 void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid,
00395 void (*cont)(void *private_data, BOOL success,
00396 const char *name),
00397 void *private_data)
00398 {
00399 struct winbindd_request request;
00400 ZERO_STRUCT(request);
00401 request.cmd = WINBINDD_DUAL_UID2NAME;
00402 request.data.uid = uid;
00403 do_async(mem_ctx, idmap_child(), &request, uid2name_recv,
00404 (void *)cont, private_data);
00405 }
00406 #endif
00407
00408 enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain,
00409 struct winbindd_cli_state *state)
00410 {
00411 struct passwd *pw;
00412
00413 DEBUG(3, ("[%5lu]: uid2name %lu\n", (unsigned long)state->pid,
00414 (unsigned long)state->request.data.uid));
00415
00416 pw = getpwuid(state->request.data.uid);
00417 if (pw == NULL) {
00418 DEBUG(5, ("User %lu not found\n",
00419 (unsigned long)state->request.data.uid));
00420 return WINBINDD_ERROR;
00421 }
00422
00423 fstrcpy(state->response.data.name.name, pw->pw_name);
00424 return WINBINDD_OK;
00425 }
00426
00427 #if 0
00428 static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
00429 struct winbindd_response *response,
00430 void *c, void *private_data)
00431 {
00432 void (*cont)(void *priv, BOOL succ, const char *name) =
00433 (void (*)(void *, BOOL, const char *))c;
00434
00435 if (!success) {
00436 DEBUG(5, ("Could not trigger uid2name\n"));
00437 cont(private_data, False, NULL);
00438 return;
00439 }
00440
00441 if (response->result != WINBINDD_OK) {
00442 DEBUG(5, ("uid2name returned an error\n"));
00443 cont(private_data, False, NULL);
00444 return;
00445 }
00446
00447 cont(private_data, True, response->data.name.name);
00448 }
00449
00450 static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00451 struct winbindd_response *response,
00452 void *c, void *private_data);
00453
00454 static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name,
00455 void (*cont)(void *private_data, BOOL success,
00456 uid_t uid),
00457 void *private_data)
00458 {
00459 struct winbindd_request request;
00460 ZERO_STRUCT(request);
00461 request.cmd = WINBINDD_DUAL_NAME2UID;
00462 fstrcpy(request.data.username, name);
00463 do_async(mem_ctx, idmap_child(), &request, name2uid_recv,
00464 (void *)cont, private_data);
00465 }
00466 #endif
00467
00468 enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain,
00469 struct winbindd_cli_state *state)
00470 {
00471 struct passwd *pw;
00472
00473
00474 state->request.data.username
00475 [sizeof(state->request.data.username)-1] = '\0';
00476
00477 DEBUG(3, ("[%5lu]: name2uid %s\n", (unsigned long)state->pid,
00478 state->request.data.username));
00479
00480 pw = getpwnam(state->request.data.username);
00481 if (pw == NULL) {
00482 return WINBINDD_ERROR;
00483 }
00484
00485 state->response.data.uid = pw->pw_uid;
00486 return WINBINDD_OK;
00487 }
00488
00489 #if 0
00490 static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00491 struct winbindd_response *response,
00492 void *c, void *private_data)
00493 {
00494 void (*cont)(void *priv, BOOL succ, uid_t uid) =
00495 (void (*)(void *, BOOL, uid_t))c;
00496
00497 if (!success) {
00498 DEBUG(5, ("Could not trigger name2uid\n"));
00499 cont(private_data, False, 0);
00500 return;
00501 }
00502
00503 if (response->result != WINBINDD_OK) {
00504 DEBUG(5, ("name2uid returned an error\n"));
00505 cont(private_data, False, 0);
00506 return;
00507 }
00508
00509 cont(private_data, True, response->data.uid);
00510 }
00511 #endif
00512
00513 static void winbindd_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00514 struct winbindd_response *response,
00515 void *c, void *private_data)
00516 {
00517 void (*cont)(void *priv, BOOL succ, gid_t gid) =
00518 (void (*)(void *, BOOL, gid_t))c;
00519
00520 if (!success) {
00521 DEBUG(5, ("Could not trigger sid2gid\n"));
00522 cont(private_data, False, 0);
00523 return;
00524 }
00525
00526 if (response->result != WINBINDD_OK) {
00527 DEBUG(5, ("sid2gid returned an error\n"));
00528 cont(private_data, False, 0);
00529 return;
00530 }
00531
00532 cont(private_data, True, response->data.gid);
00533 }
00534
00535 void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00536 void (*cont)(void *private_data, BOOL success, gid_t gid),
00537 void *private_data)
00538 {
00539 struct winbindd_request request;
00540 ZERO_STRUCT(request);
00541 request.cmd = WINBINDD_DUAL_SID2GID;
00542 sid_to_string(request.data.dual_sid2id.sid, sid);
00543
00544 DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
00545 request.data.dual_sid2id.sid));
00546
00547 do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,
00548 (void *)cont, private_data);
00549 }
00550
00551 enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
00552 struct winbindd_cli_state *state)
00553 {
00554 DOM_SID sid;
00555 NTSTATUS result;
00556
00557 DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
00558 state->request.data.dual_sid2id.sid));
00559
00560 if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
00561 DEBUG(1, ("Could not get convert sid %s from string\n",
00562 state->request.data.dual_sid2id.sid));
00563 return WINBINDD_ERROR;
00564 }
00565
00566
00567
00568 result = idmap_sid_to_gid(&sid, &state->response.data.gid);
00569
00570 DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", NT_STATUS_V(result), sid_string_static(&sid), state->response.data.gid));
00571
00572 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
00573 }
00574
00575 static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
00576 struct winbindd_response *response,
00577 void *c, void *private_data)
00578 {
00579 void (*cont)(void *priv, BOOL succ, const char *name) =
00580 (void (*)(void *, BOOL, const char *))c;
00581
00582 if (!success) {
00583 DEBUG(5, ("Could not trigger gid2name\n"));
00584 cont(private_data, False, NULL);
00585 return;
00586 }
00587
00588 if (response->result != WINBINDD_OK) {
00589 DEBUG(5, ("gid2name returned an error\n"));
00590 cont(private_data, False, NULL);
00591 return;
00592 }
00593
00594 cont(private_data, True, response->data.name.name);
00595 }
00596
00597 void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid,
00598 void (*cont)(void *private_data, BOOL success,
00599 const char *name),
00600 void *private_data)
00601 {
00602 struct winbindd_request request;
00603 ZERO_STRUCT(request);
00604 request.cmd = WINBINDD_DUAL_GID2NAME;
00605 request.data.gid = gid;
00606 do_async(mem_ctx, idmap_child(), &request, gid2name_recv,
00607 (void *)cont, private_data);
00608 }
00609
00610 enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain,
00611 struct winbindd_cli_state *state)
00612 {
00613 struct group *gr;
00614
00615 DEBUG(3, ("[%5lu]: gid2name %lu\n", (unsigned long)state->pid,
00616 (unsigned long)state->request.data.gid));
00617
00618 gr = getgrgid(state->request.data.gid);
00619 if (gr == NULL)
00620 return WINBINDD_ERROR;
00621
00622 fstrcpy(state->response.data.name.name, gr->gr_name);
00623 return WINBINDD_OK;
00624 }
00625
00626 #if 0
00627 static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00628 struct winbindd_response *response,
00629 void *c, void *private_data);
00630
00631 static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name,
00632 void (*cont)(void *private_data, BOOL success,
00633 gid_t gid),
00634 void *private_data)
00635 {
00636 struct winbindd_request request;
00637 ZERO_STRUCT(request);
00638 request.cmd = WINBINDD_DUAL_NAME2GID;
00639 fstrcpy(request.data.groupname, name);
00640 do_async(mem_ctx, idmap_child(), &request, name2gid_recv,
00641 (void *)cont, private_data);
00642 }
00643 #endif
00644
00645 enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain,
00646 struct winbindd_cli_state *state)
00647 {
00648 struct group *gr;
00649
00650
00651 state->request.data.groupname
00652 [sizeof(state->request.data.groupname)-1] = '\0';
00653
00654 DEBUG(3, ("[%5lu]: name2gid %s\n", (unsigned long)state->pid,
00655 state->request.data.groupname));
00656
00657 gr = getgrnam(state->request.data.groupname);
00658 if (gr == NULL) {
00659 return WINBINDD_ERROR;
00660 }
00661
00662 state->response.data.gid = gr->gr_gid;
00663 return WINBINDD_OK;
00664 }
00665
00666 #if 0
00667 static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00668 struct winbindd_response *response,
00669 void *c, void *private_data)
00670 {
00671 void (*cont)(void *priv, BOOL succ, gid_t gid) =
00672 (void (*)(void *, BOOL, gid_t))c;
00673
00674 if (!success) {
00675 DEBUG(5, ("Could not trigger name2gid\n"));
00676 cont(private_data, False, 0);
00677 return;
00678 }
00679
00680 if (response->result != WINBINDD_OK) {
00681 DEBUG(5, ("name2gid returned an error\n"));
00682 cont(private_data, False, 0);
00683 return;
00684 }
00685
00686 cont(private_data, True, response->data.gid);
00687 }
00688 #endif
00689
00690 static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success,
00691 struct winbindd_response *response,
00692 void *c, void *private_data)
00693 {
00694 void (*cont)(void *priv, BOOL succ, const char *dom_name,
00695 const char *name, enum lsa_SidType type) =
00696 (void (*)(void *, BOOL, const char *, const char *,
00697 enum lsa_SidType))c;
00698
00699 if (!success) {
00700 DEBUG(5, ("Could not trigger lookupsid\n"));
00701 cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
00702 return;
00703 }
00704
00705 if (response->result != WINBINDD_OK) {
00706 DEBUG(5, ("lookupsid returned an error\n"));
00707 cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
00708 return;
00709 }
00710
00711 cont(private_data, True, response->data.name.dom_name,
00712 response->data.name.name,
00713 (enum lsa_SidType)response->data.name.type);
00714 }
00715
00716 void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00717 void (*cont)(void *private_data, BOOL success,
00718 const char *dom_name,
00719 const char *name,
00720 enum lsa_SidType type),
00721 void *private_data)
00722 {
00723 struct winbindd_domain *domain;
00724 struct winbindd_request request;
00725
00726 domain = find_lookup_domain_from_sid(sid);
00727 if (domain == NULL) {
00728 DEBUG(5, ("Could not find domain for sid %s\n",
00729 sid_string_static(sid)));
00730 cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
00731 return;
00732 }
00733
00734 ZERO_STRUCT(request);
00735 request.cmd = WINBINDD_LOOKUPSID;
00736 fstrcpy(request.data.sid, sid_string_static(sid));
00737
00738 do_async_domain(mem_ctx, domain, &request, lookupsid_recv,
00739 (void *)cont, private_data);
00740 }
00741
00742 enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
00743 struct winbindd_cli_state *state)
00744 {
00745 enum lsa_SidType type;
00746 DOM_SID sid;
00747 char *name;
00748 char *dom_name;
00749
00750
00751 state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
00752
00753 DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
00754 state->request.data.sid));
00755
00756
00757
00758 if (!string_to_sid(&sid, state->request.data.sid)) {
00759 DEBUG(5, ("%s not a SID\n", state->request.data.sid));
00760 return WINBINDD_ERROR;
00761 }
00762
00763
00764
00765 if (!winbindd_lookup_name_by_sid(state->mem_ctx, &sid, &dom_name, &name,
00766 &type)) {
00767 TALLOC_FREE(dom_name);
00768 TALLOC_FREE(name);
00769 return WINBINDD_ERROR;
00770 }
00771
00772 fstrcpy(state->response.data.name.dom_name, dom_name);
00773 fstrcpy(state->response.data.name.name, name);
00774 state->response.data.name.type = type;
00775
00776 TALLOC_FREE(dom_name);
00777 TALLOC_FREE(name);
00778 return WINBINDD_OK;
00779 }
00780
00781
00782
00783
00784
00785 struct lookupname_state {
00786 char *dom_name;
00787 char *name;
00788 void *caller_private_data;
00789 };
00790
00791 static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
00792 struct winbindd_response *response,
00793 void *c, void *private_data)
00794 {
00795 void (*cont)(void *priv, BOOL succ, const DOM_SID *sid,
00796 enum lsa_SidType type) =
00797 (void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
00798 DOM_SID sid;
00799 struct lookupname_state *s = talloc_get_type_abort(private_data, struct lookupname_state);
00800
00801 if (!success) {
00802 DEBUG(5, ("Could not trigger lookup_name\n"));
00803 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00804 return;
00805 }
00806
00807 if (response->result != WINBINDD_OK) {
00808 DEBUG(5, ("lookup_name returned an error\n"));
00809 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00810 return;
00811 }
00812
00813 if (!string_to_sid(&sid, response->data.sid.sid)) {
00814 DEBUG(0, ("Could not convert string %s to sid\n",
00815 response->data.sid.sid));
00816 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00817 return;
00818 }
00819
00820 cont(s->caller_private_data, True, &sid,
00821 (enum lsa_SidType)response->data.sid.type);
00822 }
00823
00824
00825
00826
00827
00828 static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
00829 struct winbindd_response *response,
00830 void *c, void *private_data)
00831 {
00832 void (*cont)(void *priv, BOOL succ, const DOM_SID *sid,
00833 enum lsa_SidType type) =
00834 (void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
00835 DOM_SID sid;
00836 struct lookupname_state *s = talloc_get_type_abort(private_data, struct lookupname_state);
00837
00838 if (!success) {
00839 DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
00840 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00841 return;
00842 }
00843
00844 if (response->result != WINBINDD_OK) {
00845
00846 struct winbindd_domain *root_domain = find_root_domain();
00847 struct winbindd_request request;
00848
00849 if ( !root_domain ) {
00850 DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
00851 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00852 return;
00853 }
00854
00855 ZERO_STRUCT(request);
00856 request.cmd = WINBINDD_LOOKUPNAME;
00857 fstrcpy(request.data.name.dom_name, s->dom_name);
00858 fstrcpy(request.data.name.name, s->name);
00859
00860 do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
00861 (void *)cont, s);
00862
00863 return;
00864 }
00865
00866 if (!string_to_sid(&sid, response->data.sid.sid)) {
00867 DEBUG(0, ("Could not convert string %s to sid\n",
00868 response->data.sid.sid));
00869 cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
00870 return;
00871 }
00872
00873 cont(s->caller_private_data, True, &sid,
00874 (enum lsa_SidType)response->data.sid.type);
00875 }
00876
00877
00878
00879
00880
00881
00882
00883 void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
00884 const char *dom_name, const char *name,
00885 void (*cont)(void *private_data, BOOL success,
00886 const DOM_SID *sid,
00887 enum lsa_SidType type),
00888 void *private_data)
00889 {
00890 struct winbindd_request request;
00891 struct winbindd_domain *domain;
00892 struct lookupname_state *s;
00893
00894 if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
00895 DEBUG(5, ("Could not find domain for name %s\n", dom_name));
00896 cont(private_data, False, NULL, SID_NAME_UNKNOWN);
00897 return;
00898 }
00899
00900 ZERO_STRUCT(request);
00901 request.cmd = WINBINDD_LOOKUPNAME;
00902 fstrcpy(request.data.name.dom_name, dom_name);
00903 fstrcpy(request.data.name.name, name);
00904
00905 if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupname_state)) == NULL ) {
00906 DEBUG(0, ("winbindd_lookupname_async: talloc failed\n"));
00907 cont(private_data, False, NULL, SID_NAME_UNKNOWN);
00908 return;
00909 }
00910
00911 s->dom_name = talloc_strdup( s, dom_name );
00912 s->name = talloc_strdup( s, name );
00913 if (!s->dom_name || !s->name) {
00914 cont(private_data, False, NULL, SID_NAME_UNKNOWN);
00915 return;
00916 }
00917
00918 s->caller_private_data = private_data;
00919
00920 do_async_domain(mem_ctx, domain, &request, lookupname_recv,
00921 (void *)cont, s);
00922 }
00923
00924 enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
00925 struct winbindd_cli_state *state)
00926 {
00927 enum lsa_SidType type;
00928 char *name_domain, *name_user;
00929 DOM_SID sid;
00930 char *p;
00931
00932
00933 state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
00934
00935
00936 state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
00937
00938
00939 p = strstr(state->request.data.name.name, lp_winbind_separator());
00940 if (p) {
00941 *p = 0;
00942 name_domain = state->request.data.name.name;
00943 name_user = p+1;
00944 } else {
00945 name_domain = state->request.data.name.dom_name;
00946 name_user = state->request.data.name.name;
00947 }
00948
00949 DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
00950 name_domain, lp_winbind_separator(), name_user));
00951
00952
00953 if (!winbindd_lookup_sid_by_name(state->mem_ctx, domain, name_domain,
00954 name_user, &sid, &type)) {
00955 return WINBINDD_ERROR;
00956 }
00957
00958 sid_to_string(state->response.data.sid.sid, &sid);
00959 state->response.data.sid.type = type;
00960
00961 return WINBINDD_OK;
00962 }
00963
00964 BOOL print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
00965 size_t num_sids, char **result, ssize_t *len)
00966 {
00967 size_t i;
00968 size_t buflen = 0;
00969
00970 *len = 0;
00971 *result = NULL;
00972 for (i=0; i<num_sids; i++) {
00973 sprintf_append(mem_ctx, result, len, &buflen,
00974 "%s\n", sid_string_static(&sids[i]));
00975 }
00976
00977 if ((num_sids != 0) && (*result == NULL)) {
00978 return False;
00979 }
00980
00981 return True;
00982 }
00983
00984 static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
00985 DOM_SID **sids, size_t *num_sids)
00986 {
00987 char *p, *q;
00988
00989 p = sidstr;
00990 if (p == NULL)
00991 return False;
00992
00993 while (p[0] != '\0') {
00994 DOM_SID sid;
00995 q = strchr(p, '\n');
00996 if (q == NULL) {
00997 DEBUG(0, ("Got invalid sidstr: %s\n", p));
00998 return False;
00999 }
01000 *q = '\0';
01001 q += 1;
01002 if (!string_to_sid(&sid, p)) {
01003 DEBUG(0, ("Could not parse sid %s\n", p));
01004 return False;
01005 }
01006 if (!add_sid_to_array(mem_ctx, &sid, sids, num_sids)) {
01007 return False;
01008 }
01009 p = q;
01010 }
01011 return True;
01012 }
01013
01014 static BOOL parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr,
01015 uint32 **rids, size_t *num_rids)
01016 {
01017 char *p;
01018
01019 p = ridstr;
01020 if (p == NULL)
01021 return False;
01022
01023 while (p[0] != '\0') {
01024 uint32 rid;
01025 char *q;
01026 rid = strtoul(p, &q, 10);
01027 if (*q != '\n') {
01028 DEBUG(0, ("Got invalid ridstr: %s\n", p));
01029 return False;
01030 }
01031 p = q+1;
01032 ADD_TO_ARRAY(mem_ctx, uint32, rid, rids, num_rids);
01033 }
01034 return True;
01035 }
01036
01037 enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain,
01038 struct winbindd_cli_state *state)
01039 {
01040 uint32 *rids = NULL;
01041 size_t i, buflen, num_rids = 0;
01042 ssize_t len;
01043 DOM_SID domain_sid;
01044 char *domain_name;
01045 char **names;
01046 enum lsa_SidType *types;
01047 NTSTATUS status;
01048 char *result;
01049
01050 DEBUG(10, ("Looking up RIDs for domain %s (%s)\n",
01051 state->request.domain_name,
01052 state->request.data.sid));
01053
01054 if (!parse_ridlist(state->mem_ctx, state->request.extra_data.data,
01055 &rids, &num_rids)) {
01056 DEBUG(5, ("Could not parse ridlist\n"));
01057 return WINBINDD_ERROR;
01058 }
01059
01060 if (!string_to_sid(&domain_sid, state->request.data.sid)) {
01061 DEBUG(5, ("Could not parse domain sid %s\n",
01062 state->request.data.sid));
01063 return WINBINDD_ERROR;
01064 }
01065
01066 status = domain->methods->rids_to_names(domain, state->mem_ctx,
01067 &domain_sid, rids, num_rids,
01068 &domain_name,
01069 &names, &types);
01070
01071 if (!NT_STATUS_IS_OK(status) &&
01072 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
01073 return WINBINDD_ERROR;
01074 }
01075
01076 len = 0;
01077 buflen = 0;
01078 result = NULL;
01079
01080 for (i=0; i<num_rids; i++) {
01081 sprintf_append(state->mem_ctx, &result, &len, &buflen,
01082 "%d %s\n", types[i], names[i]);
01083 }
01084
01085 fstrcpy(state->response.data.domain_name, domain_name);
01086
01087 if (result != NULL) {
01088 state->response.extra_data.data = SMB_STRDUP(result);
01089 if (!state->response.extra_data.data) {
01090 return WINBINDD_ERROR;
01091 }
01092 state->response.length += len+1;
01093 }
01094
01095 return WINBINDD_OK;
01096 }
01097
01098 static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success,
01099 struct winbindd_response *response,
01100 void *c, void *private_data)
01101 {
01102 void (*cont)(void *priv, BOOL succ,
01103 DOM_SID *aliases, size_t num_aliases) =
01104 (void (*)(void *, BOOL, DOM_SID *, size_t))c;
01105 char *aliases_str;
01106 DOM_SID *sids = NULL;
01107 size_t num_sids = 0;
01108
01109 if (!success) {
01110 DEBUG(5, ("Could not trigger getsidaliases\n"));
01111 cont(private_data, success, NULL, 0);
01112 return;
01113 }
01114
01115 if (response->result != WINBINDD_OK) {
01116 DEBUG(5, ("getsidaliases returned an error\n"));
01117 cont(private_data, False, NULL, 0);
01118 return;
01119 }
01120
01121 aliases_str = (char *)response->extra_data.data;
01122
01123 if (aliases_str == NULL) {
01124 DEBUG(10, ("getsidaliases return 0 SIDs\n"));
01125 cont(private_data, True, NULL, 0);
01126 return;
01127 }
01128
01129 if (!parse_sidlist(mem_ctx, aliases_str, &sids, &num_sids)) {
01130 DEBUG(0, ("Could not parse sids\n"));
01131 cont(private_data, False, NULL, 0);
01132 return;
01133 }
01134
01135 SAFE_FREE(response->extra_data.data);
01136
01137 cont(private_data, True, sids, num_sids);
01138 }
01139
01140 void winbindd_getsidaliases_async(struct winbindd_domain *domain,
01141 TALLOC_CTX *mem_ctx,
01142 const DOM_SID *sids, size_t num_sids,
01143 void (*cont)(void *private_data,
01144 BOOL success,
01145 const DOM_SID *aliases,
01146 size_t num_aliases),
01147 void *private_data)
01148 {
01149 struct winbindd_request request;
01150 char *sidstr = NULL;
01151 ssize_t len;
01152
01153 if (num_sids == 0) {
01154 cont(private_data, True, NULL, 0);
01155 return;
01156 }
01157
01158 if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr, &len)) {
01159 cont(private_data, False, NULL, 0);
01160 return;
01161 }
01162
01163 ZERO_STRUCT(request);
01164 request.cmd = WINBINDD_DUAL_GETSIDALIASES;
01165 request.extra_len = len;
01166 request.extra_data.data = sidstr;
01167
01168 do_async_domain(mem_ctx, domain, &request, getsidaliases_recv,
01169 (void *)cont, private_data);
01170 }
01171
01172 enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
01173 struct winbindd_cli_state *state)
01174 {
01175 DOM_SID *sids = NULL;
01176 size_t num_sids = 0;
01177 char *sidstr = NULL;
01178 ssize_t len;
01179 size_t i;
01180 uint32 num_aliases;
01181 uint32 *alias_rids;
01182 NTSTATUS result;
01183
01184 DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
01185
01186 sidstr = state->request.extra_data.data;
01187 if (sidstr == NULL) {
01188 sidstr = talloc_strdup(state->mem_ctx, "\n");
01189 if (!sidstr) {
01190 DEBUG(0, ("Out of memory\n"));
01191 return WINBINDD_ERROR;
01192 }
01193 }
01194
01195 DEBUG(10, ("Sidlist: %s\n", sidstr));
01196
01197 if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) {
01198 DEBUG(0, ("Could not parse SID list: %s\n", sidstr));
01199 return WINBINDD_ERROR;
01200 }
01201
01202 num_aliases = 0;
01203 alias_rids = NULL;
01204
01205 result = domain->methods->lookup_useraliases(domain,
01206 state->mem_ctx,
01207 num_sids, sids,
01208 &num_aliases,
01209 &alias_rids);
01210
01211 if (!NT_STATUS_IS_OK(result)) {
01212 DEBUG(3, ("Could not lookup_useraliases: %s\n",
01213 nt_errstr(result)));
01214 return WINBINDD_ERROR;
01215 }
01216
01217 num_sids = 0;
01218 sids = NULL;
01219 sidstr = NULL;
01220
01221 DEBUG(10, ("Got %d aliases\n", num_aliases));
01222
01223 for (i=0; i<num_aliases; i++) {
01224 DOM_SID sid;
01225 DEBUGADD(10, (" rid %d\n", alias_rids[i]));
01226 sid_copy(&sid, &domain->sid);
01227 sid_append_rid(&sid, alias_rids[i]);
01228 if (!add_sid_to_array(state->mem_ctx, &sid, &sids, &num_sids)) {
01229 return WINBINDD_ERROR;
01230 }
01231 }
01232
01233
01234 if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) {
01235 DEBUG(0, ("Could not print_sidlist\n"));
01236 state->response.extra_data.data = NULL;
01237 return WINBINDD_ERROR;
01238 }
01239
01240 state->response.extra_data.data = NULL;
01241
01242 if (sidstr) {
01243 state->response.extra_data.data = SMB_STRDUP(sidstr);
01244 if (!state->response.extra_data.data) {
01245 DEBUG(0, ("Out of memory\n"));
01246 return WINBINDD_ERROR;
01247 }
01248 DEBUG(10, ("aliases_list: %s\n",
01249 (char *)state->response.extra_data.data));
01250 state->response.length += len+1;
01251 }
01252
01253 return WINBINDD_OK;
01254 }
01255
01256 struct gettoken_state {
01257 TALLOC_CTX *mem_ctx;
01258 DOM_SID user_sid;
01259 struct winbindd_domain *alias_domain;
01260 struct winbindd_domain *local_alias_domain;
01261 struct winbindd_domain *builtin_domain;
01262 DOM_SID *sids;
01263 size_t num_sids;
01264 void (*cont)(void *private_data, BOOL success, DOM_SID *sids, size_t num_sids);
01265 void *private_data;
01266 };
01267
01268 static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success,
01269 struct winbindd_response *response,
01270 void *c, void *private_data);
01271 static void gettoken_recvaliases(void *private_data, BOOL success,
01272 const DOM_SID *aliases,
01273 size_t num_aliases);
01274
01275
01276 void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid,
01277 void (*cont)(void *private_data, BOOL success,
01278 DOM_SID *sids, size_t num_sids),
01279 void *private_data)
01280 {
01281 struct winbindd_domain *domain;
01282 struct winbindd_request request;
01283 struct gettoken_state *state;
01284
01285 state = TALLOC_ZERO_P(mem_ctx, struct gettoken_state);
01286 if (state == NULL) {
01287 DEBUG(0, ("talloc failed\n"));
01288 cont(private_data, False, NULL, 0);
01289 return;
01290 }
01291
01292 state->mem_ctx = mem_ctx;
01293 sid_copy(&state->user_sid, user_sid);
01294 state->alias_domain = find_our_domain();
01295 state->local_alias_domain = find_domain_from_name( get_global_sam_name() );
01296 state->builtin_domain = find_builtin_domain();
01297 state->cont = cont;
01298 state->private_data = private_data;
01299
01300 domain = find_domain_from_sid_noinit(user_sid);
01301 if (domain == NULL) {
01302 DEBUG(5, ("Could not find domain from SID %s\n",
01303 sid_string_static(user_sid)));
01304 cont(private_data, False, NULL, 0);
01305 return;
01306 }
01307
01308 ZERO_STRUCT(request);
01309 request.cmd = WINBINDD_GETUSERDOMGROUPS;
01310 fstrcpy(request.data.sid, sid_string_static(user_sid));
01311
01312 do_async_domain(mem_ctx, domain, &request, gettoken_recvdomgroups,
01313 NULL, state);
01314 }
01315
01316 static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success,
01317 struct winbindd_response *response,
01318 void *c, void *private_data)
01319 {
01320 struct gettoken_state *state =
01321 talloc_get_type_abort(private_data, struct gettoken_state);
01322 char *sids_str;
01323
01324 if (!success) {
01325 DEBUG(10, ("Could not get domain groups\n"));
01326 state->cont(state->private_data, False, NULL, 0);
01327 return;
01328 }
01329
01330 sids_str = (char *)response->extra_data.data;
01331
01332 if (sids_str == NULL) {
01333
01334
01335
01336 if ( !sid_check_is_in_our_domain( &state->user_sid ) ) {
01337 DEBUG(10, ("Received no domain groups\n"));
01338 state->cont(state->private_data, True, NULL, 0);
01339 return;
01340 }
01341 }
01342
01343 state->sids = NULL;
01344 state->num_sids = 0;
01345
01346 if (!add_sid_to_array(mem_ctx, &state->user_sid, &state->sids,
01347 &state->num_sids)) {
01348 DEBUG(0, ("Out of memory\n"));
01349 state->cont(state->private_data, False, NULL, 0);
01350 return;
01351 }
01352
01353 if (sids_str && !parse_sidlist(mem_ctx, sids_str, &state->sids,
01354 &state->num_sids)) {
01355 DEBUG(0, ("Could not parse sids\n"));
01356 state->cont(state->private_data, False, NULL, 0);
01357 return;
01358 }
01359
01360 SAFE_FREE(response->extra_data.data);
01361
01362 if (state->alias_domain == NULL) {
01363 DEBUG(10, ("Don't expand domain local groups\n"));
01364 state->cont(state->private_data, True, state->sids,
01365 state->num_sids);
01366 return;
01367 }
01368
01369 winbindd_getsidaliases_async(state->alias_domain, mem_ctx,
01370 state->sids, state->num_sids,
01371 gettoken_recvaliases, state);
01372 }
01373
01374 static void gettoken_recvaliases(void *private_data, BOOL success,
01375 const DOM_SID *aliases,
01376 size_t num_aliases)
01377 {
01378 struct gettoken_state *state = (struct gettoken_state *)private_data;
01379 size_t i;
01380
01381 if (!success) {
01382 DEBUG(10, ("Could not receive domain local groups\n"));
01383 state->cont(state->private_data, False, NULL, 0);
01384 return;
01385 }
01386
01387 for (i=0; i<num_aliases; i++) {
01388 if (!add_sid_to_array(state->mem_ctx, &aliases[i],
01389 &state->sids, &state->num_sids)) {
01390 DEBUG(0, ("Out of memory\n"));
01391 state->cont(state->private_data, False, NULL, 0);
01392 return;
01393 }
01394 }
01395
01396 if (state->local_alias_domain != NULL) {
01397 struct winbindd_domain *local_domain = state->local_alias_domain;
01398 DEBUG(10, ("Expanding our own local groups\n"));
01399 state->local_alias_domain = NULL;
01400 winbindd_getsidaliases_async(local_domain, state->mem_ctx,
01401 state->sids, state->num_sids,
01402 gettoken_recvaliases, state);
01403 return;
01404 }
01405
01406 if (state->builtin_domain != NULL) {
01407 struct winbindd_domain *builtin_domain = state->builtin_domain;
01408 DEBUG(10, ("Expanding our own BUILTIN groups\n"));
01409 state->builtin_domain = NULL;
01410 winbindd_getsidaliases_async(builtin_domain, state->mem_ctx,
01411 state->sids, state->num_sids,
01412 gettoken_recvaliases, state);
01413 return;
01414 }
01415
01416 state->cont(state->private_data, True, state->sids, state->num_sids);
01417 }
01418
01419 static void query_user_recv(TALLOC_CTX *mem_ctx, BOOL success,
01420 struct winbindd_response *response,
01421 void *c, void *private_data)
01422 {
01423 void (*cont)(void *priv, BOOL succ, const char *acct_name,
01424 const char *full_name, const char *homedir,
01425 const char *shell, uint32 gid, uint32 group_rid) =
01426 (void (*)(void *, BOOL, const char *, const char *,
01427 const char *, const char *, uint32, uint32))c;
01428
01429 if (!success) {
01430 DEBUG(5, ("Could not trigger query_user\n"));
01431 cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1);
01432 return;
01433 }
01434
01435 if (response->result != WINBINDD_OK) {
01436 DEBUG(5, ("query_user returned an error\n"));
01437 cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1);
01438 return;
01439 }
01440
01441 cont(private_data, True, response->data.user_info.acct_name,
01442 response->data.user_info.full_name,
01443 response->data.user_info.homedir,
01444 response->data.user_info.shell,
01445 response->data.user_info.primary_gid,
01446 response->data.user_info.group_rid);
01447 }
01448
01449 void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
01450 const DOM_SID *sid,
01451 void (*cont)(void *private_data, BOOL success,
01452 const char *acct_name,
01453 const char *full_name,
01454 const char *homedir,
01455 const char *shell,
01456 gid_t gid,
01457 uint32 group_rid),
01458 void *private_data)
01459 {
01460 struct winbindd_request request;
01461 ZERO_STRUCT(request);
01462 request.cmd = WINBINDD_DUAL_USERINFO;
01463 sid_to_string(request.data.sid, sid);
01464 do_async_domain(mem_ctx, domain, &request, query_user_recv,
01465 (void *)cont, private_data);
01466 }
01467
01468
01469
01470
01471 static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
01472 struct winbindd_response *response,
01473 void *c, void *private_data)
01474 {
01475 void (*cont)(void *priv, BOOL succ, const char *sid) =
01476 (void (*)(void *, BOOL, const char *))c;
01477
01478 if (!success) {
01479 DEBUG(5, ("Could not trigger uid2sid\n"));
01480 cont(private_data, False, NULL);
01481 return;
01482 }
01483
01484 if (response->result != WINBINDD_OK) {
01485 DEBUG(5, ("uid2sid returned an error\n"));
01486 cont(private_data, False, NULL);
01487 return;
01488 }
01489
01490 cont(private_data, True, response->data.sid.sid);
01491 }
01492
01493 void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
01494 void (*cont)(void *private_data, BOOL success, const char *sid),
01495 void *private_data)
01496 {
01497 struct winbindd_request request;
01498
01499 ZERO_STRUCT(request);
01500 request.cmd = WINBINDD_DUAL_UID2SID;
01501 request.data.uid = uid;
01502 do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv,
01503 (void *)cont, private_data);
01504 }
01505
01506 enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
01507 struct winbindd_cli_state *state)
01508 {
01509 DOM_SID sid;
01510 NTSTATUS result;
01511
01512 DEBUG(3,("[%5lu]: uid to sid %lu\n",
01513 (unsigned long)state->pid,
01514 (unsigned long) state->request.data.uid));
01515
01516
01517 result = idmap_uid_to_sid(&sid, state->request.data.uid);
01518
01519 if (NT_STATUS_IS_OK(result)) {
01520 sid_to_string(state->response.data.sid.sid, &sid);
01521 state->response.data.sid.type = SID_NAME_USER;
01522 return WINBINDD_OK;
01523 }
01524
01525 return WINBINDD_ERROR;
01526 }
01527
01528 static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
01529 struct winbindd_response *response,
01530 void *c, void *private_data)
01531 {
01532 void (*cont)(void *priv, BOOL succ, const char *sid) =
01533 (void (*)(void *, BOOL, const char *))c;
01534
01535 if (!success) {
01536 DEBUG(5, ("Could not trigger gid2sid\n"));
01537 cont(private_data, False, NULL);
01538 return;
01539 }
01540
01541 if (response->result != WINBINDD_OK) {
01542 DEBUG(5, ("gid2sid returned an error\n"));
01543 cont(private_data, False, NULL);
01544 return;
01545 }
01546
01547 cont(private_data, True, response->data.sid.sid);
01548 }
01549
01550 void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
01551 void (*cont)(void *private_data, BOOL success, const char *sid),
01552 void *private_data)
01553 {
01554 struct winbindd_request request;
01555
01556 ZERO_STRUCT(request);
01557 request.cmd = WINBINDD_DUAL_GID2SID;
01558 request.data.gid = gid;
01559 do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv,
01560 (void *)cont, private_data);
01561 }
01562
01563 enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
01564 struct winbindd_cli_state *state)
01565 {
01566 DOM_SID sid;
01567 NTSTATUS result;
01568
01569 DEBUG(3,("[%5lu]: gid %lu to sid\n",
01570 (unsigned long)state->pid,
01571 (unsigned long) state->request.data.gid));
01572
01573
01574 result = idmap_gid_to_sid(&sid, state->request.data.gid);
01575
01576 if (NT_STATUS_IS_OK(result)) {
01577 sid_to_string(state->response.data.sid.sid, &sid);
01578 DEBUG(10, ("[%5lu]: retrieved sid: %s\n",
01579 (unsigned long)state->pid,
01580 state->response.data.sid.sid));
01581 state->response.data.sid.type = SID_NAME_DOM_GRP;
01582 return WINBINDD_OK;
01583 }
01584
01585 return WINBINDD_ERROR;
01586 }
01587
01588 static void winbindd_dump_id_maps_recv(TALLOC_CTX *mem_ctx, BOOL success,
01589 struct winbindd_response *response,
01590 void *c, void *private_data)
01591 {
01592 void (*cont)(void *priv, BOOL succ) =
01593 (void (*)(void *, BOOL))c;
01594
01595 if (!success) {
01596 DEBUG(5, ("Could not trigger a map dump\n"));
01597 cont(private_data, False);
01598 return;
01599 }
01600
01601 if (response->result != WINBINDD_OK) {
01602 DEBUG(5, ("idmap dump maps returned an error\n"));
01603 cont(private_data, False);
01604 return;
01605 }
01606
01607 cont(private_data, True);
01608 }
01609
01610 void winbindd_dump_maps_async(TALLOC_CTX *mem_ctx, void *data, int size,
01611 void (*cont)(void *private_data, BOOL success),
01612 void *private_data)
01613 {
01614 struct winbindd_request request;
01615 ZERO_STRUCT(request);
01616 request.cmd = WINBINDD_DUAL_DUMP_MAPS;
01617 request.extra_data.data = (char *)data;
01618 request.extra_len = size;
01619 do_async(mem_ctx, idmap_child(), &request, winbindd_dump_id_maps_recv,
01620 (void *)cont, private_data);
01621 }
01622
01623 enum winbindd_result winbindd_dual_dump_maps(struct winbindd_domain *domain,
01624 struct winbindd_cli_state *state)
01625 {
01626 DEBUG(3, ("[%5lu]: dual dump maps\n", (unsigned long)state->pid));
01627
01628 idmap_dump_maps((char *)state->request.extra_data.data);
01629
01630 return WINBINDD_OK;
01631 }
01632