6
Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "util/util.h"
23
#include "db/sysdb_private.h"
24
#include "util/nss_sha512crypt.h"
27
static int add_string(struct ldb_message *msg, int flags,
28
const char *attr, const char *value)
32
ret = ldb_msg_add_empty(msg, attr, flags, NULL);
33
if (ret == LDB_SUCCESS) {
34
ret = ldb_msg_add_string(msg, attr, value);
35
if (ret == LDB_SUCCESS) return EOK;
40
static int add_ulong(struct ldb_message *msg, int flags,
41
const char *attr, unsigned long value)
45
ret = ldb_msg_add_empty(msg, attr, flags, NULL);
46
if (ret == LDB_SUCCESS) {
47
ret = ldb_msg_add_fmt(msg, attr, "%lu", value);
48
if (ret == LDB_SUCCESS) return EOK;
53
static uint32_t get_attr_as_uint32(struct ldb_message *msg, const char *attr)
55
const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr);
63
l = strtoll((const char *)v->data, NULL, 0);
68
if (l < 0 || l > ((uint32_t)(-1))) {
75
#define ERROR_OUT(v, r, l) do { v = r; goto l; } while(0);
77
/* =LDB-Request-(tevent_req-style)======================================== */
79
struct sldb_request_state {
80
struct tevent_context *ev;
81
struct ldb_context *ldbctx;
82
struct ldb_request *ldbreq;
83
struct ldb_reply *ldbreply;
86
static void sldb_request_wakeup(struct tevent_req *subreq);
87
static int sldb_request_callback(struct ldb_request *ldbreq,
88
struct ldb_reply *ldbreply);
90
static struct tevent_req *sldb_request_send(TALLOC_CTX *mem_ctx,
91
struct tevent_context *ev,
92
struct ldb_context *ldbctx,
93
struct ldb_request *ldbreq)
95
struct tevent_req *req, *subreq;
96
struct sldb_request_state *state;
97
struct timeval tv = { 0, 0 };
99
req = tevent_req_create(mem_ctx, &state, struct sldb_request_state);
100
if (!req) return NULL;
103
state->ldbctx = ldbctx;
104
state->ldbreq = ldbreq;
105
state->ldbreply = NULL;
107
subreq = tevent_wakeup_send(state, ev, tv);
109
DEBUG(1, ("Failed to add critical timer to run next ldb operation!\n"));
113
tevent_req_set_callback(subreq, sldb_request_wakeup, req);
118
static void sldb_request_wakeup(struct tevent_req *subreq)
120
struct tevent_req *req = tevent_req_callback_data(subreq,
122
struct sldb_request_state *state = tevent_req_data(req,
123
struct sldb_request_state);
126
if (!tevent_wakeup_recv(subreq)) return;
127
talloc_zfree(subreq);
129
state->ldbreq->callback = sldb_request_callback;
130
state->ldbreq->context = req;
132
ret = ldb_request(state->ldbctx, state->ldbreq);
133
if (ret != LDB_SUCCESS) {
134
int err = sysdb_error_to_errno(ret);
135
DEBUG(6, ("Error: %d (%s)\n", err, strerror(err)));
136
tevent_req_error(req, err);
140
static int sldb_request_callback(struct ldb_request *ldbreq,
141
struct ldb_reply *ldbreply)
143
struct tevent_req *req = talloc_get_type(ldbreq->context,
145
struct sldb_request_state *state = tevent_req_data(req,
146
struct sldb_request_state);
150
DEBUG(6, ("Error: Missing ldbreply"));
151
ERROR_OUT(err, EIO, fail);
154
state->ldbreply = talloc_steal(state, ldbreply);
156
if (ldbreply->error != LDB_SUCCESS) {
157
DEBUG(6, ("LDB Error: %d (%s)\n",
158
ldbreply->error, ldb_errstring(state->ldbctx)));
159
ERROR_OUT(err, sysdb_error_to_errno(ldbreply->error), fail);
162
if (ldbreply->type == LDB_REPLY_DONE) {
163
tevent_req_done(req);
167
tevent_req_notify_callback(req);
171
tevent_req_error(req, err);
175
static int sldb_request_recv(struct tevent_req *req,
177
struct ldb_reply **ldbreply)
179
struct sldb_request_state *state = tevent_req_data(req,
180
struct sldb_request_state);
181
enum tevent_req_state tstate;
184
if (state->ldbreply) {
185
*ldbreply = talloc_move(mem_ctx, &state->ldbreply);
188
if (tevent_req_is_error(req, &tstate, &err)) {
190
case TEVENT_REQ_USER_ERROR:
192
case TEVENT_REQ_IN_PROGRESS:
202
/* =Standard-Sysdb-Operations-utility-functions=========================== */
204
struct sysdb_op_state {
205
struct tevent_context *ev;
206
struct sysdb_handle *handle;
208
bool ignore_not_found;
210
struct ldb_reply *ldbreply;
212
struct ldb_message **msgs;
215
static void sysdb_op_default_done(struct tevent_req *subreq)
217
struct tevent_req *req = tevent_req_callback_data(subreq,
219
struct sysdb_op_state *state = tevent_req_data(req,
220
struct sysdb_op_state);
223
ret = sldb_request_recv(subreq, state, &state->ldbreply);
224
talloc_zfree(subreq);
226
if (state->ignore_not_found && ret == ENOENT) {
229
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
230
tevent_req_error(req, ret);
234
if (state->ldbreply->type != LDB_REPLY_DONE) {
235
DEBUG(6, ("Error: %d (%s)\n", EIO, strerror(EIO)));
236
tevent_req_error(req, EIO);
241
tevent_req_done(req);
244
static int sysdb_op_default_recv(struct tevent_req *req)
246
TEVENT_REQ_RETURN_ON_ERROR(req);
252
/* =Remove-Entry-From-Sysdb=============================================== */
254
struct tevent_req *sysdb_delete_entry_send(TALLOC_CTX *mem_ctx,
255
struct tevent_context *ev,
256
struct sysdb_handle *handle,
258
bool ignore_not_found)
260
struct tevent_req *req, *subreq;
261
struct sysdb_op_state *state;
262
struct ldb_request *ldbreq;
265
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
266
if (!req) return NULL;
269
state->handle = handle;
270
state->ignore_not_found = ignore_not_found;
271
state->ldbreply = NULL;
273
ret = ldb_build_del_req(&ldbreq, handle->ctx->ldb, state, dn,
274
NULL, NULL, NULL, NULL);
276
if (ret != LDB_SUCCESS) {
277
DEBUG(1, ("LDB Error: %s(%d)\nError Message: [%s]\n",
278
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
279
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
282
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
284
ERROR_OUT(ret, ENOMEM, fail);
286
tevent_req_set_callback(subreq, sysdb_op_default_done, req);
291
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
292
tevent_req_error(req, ret);
293
tevent_req_post(req, ev);
297
int sysdb_delete_entry_recv(struct tevent_req *req)
299
return sysdb_op_default_recv(req);
303
/* =Remove-Subentries-From-Sysdb=============================================== */
305
struct sysdb_delete_recursive_state {
306
struct tevent_context *ev;
307
struct sysdb_handle *handle;
309
bool ignore_not_found;
311
struct ldb_reply *ldbreply;
313
struct ldb_message **msgs;
317
static void sysdb_delete_search_done(struct tevent_req *subreq);
318
static void sysdb_delete_recursive_prepare_op(struct tevent_req *req);
319
static void sysdb_delete_recursive_op_done(struct tevent_req *req);
321
struct tevent_req *sysdb_delete_recursive_send(TALLOC_CTX *mem_ctx,
322
struct tevent_context *ev,
323
struct sysdb_handle *handle,
325
bool ignore_not_found)
327
struct tevent_req *req, *subreq;
328
struct sysdb_delete_recursive_state *state;
330
const char **no_attrs;
332
req = tevent_req_create(mem_ctx, &state,
333
struct sysdb_delete_recursive_state);
334
if (!req) return NULL;
337
state->handle = handle;
338
state->ignore_not_found = ignore_not_found;
339
state->ldbreply = NULL;
340
state->msgs_count = 0;
342
state->current_item = 0;
344
no_attrs = talloc_array(state, const char *, 1);
345
if (no_attrs == NULL) {
346
ERROR_OUT(ret, ENOMEM, fail);
350
subreq = sysdb_search_entry_send(state, ev, handle, dn, LDB_SCOPE_SUBTREE,
351
"(distinguishedName=*)", no_attrs);
354
ERROR_OUT(ret, ENOMEM, fail);
356
tevent_req_set_callback(subreq, sysdb_delete_search_done, req);
361
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
362
tevent_req_error(req, ret);
363
tevent_req_post(req, ev);
367
static void sysdb_delete_search_done(struct tevent_req *subreq)
369
struct tevent_req *req = tevent_req_callback_data(subreq,
371
struct sysdb_delete_recursive_state *state = tevent_req_data(req,
372
struct sysdb_delete_recursive_state);
375
ret = sysdb_search_entry_recv(subreq, state, &state->msgs_count,
377
talloc_zfree(subreq);
379
if (state->ignore_not_found && ret == ENOENT) {
380
tevent_req_done(req);
383
DEBUG(6, ("Search error: %d (%s)\n", ret, strerror(ret)));
384
tevent_req_error(req, ret);
387
DEBUG(9, ("Found [%d] items to delete.\n", state->msgs_count));
389
qsort(state->msgs, state->msgs_count, sizeof(struct ldb_message *),
390
compare_ldb_dn_comp_num);
392
state->current_item = 0;
393
sysdb_delete_recursive_prepare_op(req);
396
static void sysdb_delete_recursive_prepare_op(struct tevent_req *req)
398
struct sysdb_delete_recursive_state *state = tevent_req_data(req,
399
struct sysdb_delete_recursive_state);
400
struct tevent_req *subreq;
402
struct ldb_request *ldbreq;
404
if (state->current_item < state->msgs_count) {
405
DEBUG(9 ,("Trying to delete [%s].\n",
406
ldb_dn_canonical_string(state,
407
state->msgs[state->current_item]->dn)));
408
ret = ldb_build_del_req(&ldbreq, state->handle->ctx->ldb, state,
409
state->msgs[state->current_item]->dn, NULL,
411
if (ret != LDB_SUCCESS) {
412
DEBUG(1, ("LDB Error: %s(%d)\nError Message: [%s]\n",
413
ldb_strerror(ret), ret,
414
ldb_errstring(state->handle->ctx->ldb)));
415
ret = sysdb_error_to_errno(ret);
419
subreq = sldb_request_send(state, state->ev, state->handle->ctx->ldb,
426
state->current_item++;
427
tevent_req_set_callback(subreq, sysdb_delete_recursive_op_done, req);
431
tevent_req_done(req);
435
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
436
tevent_req_error(req, ret);
439
static void sysdb_delete_recursive_op_done(struct tevent_req *subreq)
441
struct tevent_req *req = tevent_req_callback_data(subreq,
445
ret = sysdb_op_default_recv(subreq);
446
talloc_zfree(subreq);
448
DEBUG(6, ("Delete error: %d (%s)\n", ret, strerror(ret)));
449
tevent_req_error(req, ret);
453
sysdb_delete_recursive_prepare_op(req);
456
int sysdb_delete_recursive_recv(struct tevent_req *req)
458
return sysdb_op_default_recv(req);
462
/* =Search-Entry========================================================== */
464
static void sysdb_search_entry_done(struct tevent_req *subreq);
466
struct tevent_req *sysdb_search_entry_send(TALLOC_CTX *mem_ctx,
467
struct tevent_context *ev,
468
struct sysdb_handle *handle,
469
struct ldb_dn *base_dn,
474
struct tevent_req *req, *subreq;
475
struct sysdb_op_state *state;
476
struct ldb_request *ldbreq;
479
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
480
if (!req) return NULL;
483
state->handle = handle;
484
state->ignore_not_found = false;
485
state->ldbreply = NULL;
486
state->msgs_count = 0;
489
ret = ldb_build_search_req(&ldbreq, handle->ctx->ldb, state,
490
base_dn, scope, filter, attrs,
491
NULL, NULL, NULL, NULL);
492
if (ret != LDB_SUCCESS) {
493
DEBUG(1, ("Failed to build search request: %s(%d)[%s]\n",
494
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
495
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
498
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
500
ERROR_OUT(ret, ENOMEM, fail);
502
tevent_req_set_callback(subreq, sysdb_search_entry_done, req);
507
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
508
tevent_req_error(req, ret);
509
tevent_req_post(req, ev);
513
static void sysdb_search_entry_done(struct tevent_req *subreq)
515
struct tevent_req *req = tevent_req_callback_data(subreq,
517
struct sysdb_op_state *state = tevent_req_data(req,
518
struct sysdb_op_state);
519
struct ldb_reply *ldbreply;
520
struct ldb_message **dummy;
523
ret = sldb_request_recv(subreq, state, &ldbreply);
525
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
526
tevent_req_error(req, ret);
530
switch (ldbreply->type) {
531
case LDB_REPLY_ENTRY:
532
dummy = talloc_realloc(state, state->msgs,
533
struct ldb_message *,
534
state->msgs_count + 2);
536
tevent_req_error(req, ENOMEM);
541
state->msgs[state->msgs_count + 1] = NULL;
543
state->msgs[state->msgs_count] = talloc_steal(state->msgs,
547
talloc_zfree(ldbreply);
551
talloc_zfree(subreq);
552
talloc_zfree(ldbreply);
553
if (state->msgs_count == 0) {
554
DEBUG(6, ("Error: Entry not Found!\n"));
555
tevent_req_error(req, ENOENT);
558
return tevent_req_done(req);
561
/* unexpected stuff */
562
talloc_zfree(ldbreply);
563
DEBUG(6, ("Error: Unknown error!\n"));
564
tevent_req_error(req, EIO);
569
int sysdb_search_entry_recv(struct tevent_req *req,
572
struct ldb_message ***msgs)
574
struct sysdb_op_state *state = tevent_req_data(req,
575
struct sysdb_op_state);
577
TEVENT_REQ_RETURN_ON_ERROR(req);
579
*msgs_count = state->msgs_count;
580
*msgs = talloc_move(mem_ctx, &state->msgs);
586
/* =Search-User-by-[UID/NAME]============================================= */
588
struct sysdb_search_user_state {
589
struct tevent_context *ev;
590
struct sysdb_handle *handle;
592
struct ldb_dn *basedn;
598
struct ldb_message **msgs;
601
static void sysdb_search_user_cont(struct tevent_req *subreq);
602
static void sysdb_search_user_done(struct tevent_req *subreq);
604
struct tevent_req *sysdb_search_user_by_name_send(TALLOC_CTX *mem_ctx,
605
struct tevent_context *ev,
606
struct sysdb_ctx *sysdb,
607
struct sysdb_handle *handle,
608
struct sss_domain_info *domain,
612
struct tevent_req *req, *subreq;
613
struct sysdb_search_user_state *state;
614
static const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL };
617
if (!sysdb && !handle) return NULL;
619
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_user_state);
620
if (!req) return NULL;
623
state->handle = handle;
624
state->msgs_count = 0;
627
state->attrs = attrs ? attrs : def_attrs;
628
state->filter = NULL;
629
state->scope = LDB_SCOPE_BASE;
631
if (!sysdb) sysdb = handle->ctx;
633
state->basedn = sysdb_user_dn(sysdb, state, domain->name, name);
634
if (!state->basedn) {
635
ERROR_OUT(ret, ENOMEM, fail);
639
subreq = sysdb_operation_send(state, state->ev, sysdb);
641
ERROR_OUT(ret, ENOMEM, fail);
643
tevent_req_set_callback(subreq, sysdb_search_user_cont, req);
646
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
647
state->basedn, state->scope,
648
state->filter, state->attrs);
650
ERROR_OUT(ret, ENOMEM, fail);
652
tevent_req_set_callback(subreq, sysdb_search_user_done, req);
658
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
659
tevent_req_error(req, ret);
660
tevent_req_post(req, ev);
664
struct tevent_req *sysdb_search_user_by_uid_send(TALLOC_CTX *mem_ctx,
665
struct tevent_context *ev,
666
struct sysdb_ctx *sysdb,
667
struct sysdb_handle *handle,
668
struct sss_domain_info *domain,
672
struct tevent_req *req, *subreq;
673
struct sysdb_search_user_state *state;
674
static const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL };
677
if (!sysdb && !handle) return NULL;
679
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_user_state);
680
if (!req) return NULL;
683
state->handle = handle;
684
state->msgs_count = 0;
686
state->attrs = attrs ? attrs : def_attrs;
688
if (!sysdb) sysdb = handle->ctx;
690
state->basedn = ldb_dn_new_fmt(state, sysdb->ldb,
691
SYSDB_TMPL_USER_BASE, domain->name);
692
if (!state->basedn) {
693
ERROR_OUT(ret, ENOMEM, fail);
696
state->filter = talloc_asprintf(state, SYSDB_PWUID_FILTER,
698
if (!state->filter) {
699
ERROR_OUT(ret, ENOMEM, fail);
702
state->scope = LDB_SCOPE_ONELEVEL;
705
subreq = sysdb_operation_send(state, state->ev, sysdb);
707
ERROR_OUT(ret, ENOMEM, fail);
709
tevent_req_set_callback(subreq, sysdb_search_user_cont, req);
712
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
713
state->basedn, state->scope,
714
state->filter, state->attrs);
716
ERROR_OUT(ret, ENOMEM, fail);
718
tevent_req_set_callback(subreq, sysdb_search_user_done, req);
724
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
725
tevent_req_error(req, ret);
726
tevent_req_post(req, ev);
730
static void sysdb_search_user_cont(struct tevent_req *subreq)
732
struct tevent_req *req = tevent_req_callback_data(subreq,
734
struct sysdb_search_user_state *state = tevent_req_data(req,
735
struct sysdb_search_user_state);
738
ret = sysdb_operation_recv(subreq, state, &state->handle);
739
talloc_zfree(subreq);
741
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
742
tevent_req_error(req, ret);
746
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
747
state->basedn, state->scope,
748
state->filter, state->attrs);
750
DEBUG(6, ("Error: Out of memory\n"));
751
tevent_req_error(req, ENOMEM);
754
tevent_req_set_callback(subreq, sysdb_search_user_done, req);
757
static void sysdb_search_user_done(struct tevent_req *subreq)
759
struct tevent_req *req = tevent_req_callback_data(subreq,
761
struct sysdb_search_user_state *state = tevent_req_data(req,
762
struct sysdb_search_user_state);
765
ret = sysdb_search_entry_recv(subreq, state, &state->msgs_count,
767
talloc_zfree(subreq);
769
tevent_req_error(req, ret);
773
tevent_req_done(req);
776
int sysdb_search_user_recv(struct tevent_req *req,
778
struct ldb_message **msg)
780
struct sysdb_search_user_state *state = tevent_req_data(req,
781
struct sysdb_search_user_state);
783
TEVENT_REQ_RETURN_ON_ERROR(req);
785
if (state->msgs_count > 1) {
786
DEBUG(1, ("More than one result found.\n"));
790
*msg = talloc_move(mem_ctx, &state->msgs[0]);
796
/* =Search-Group-by-[GID/NAME]============================================ */
798
struct sysdb_search_group_state {
799
struct tevent_context *ev;
800
struct sysdb_handle *handle;
802
struct ldb_dn *basedn;
808
struct ldb_message **msgs;
811
static void sysdb_search_group_cont(struct tevent_req *subreq);
812
static void sysdb_search_group_done(struct tevent_req *subreq);
814
struct tevent_req *sysdb_search_group_by_name_send(TALLOC_CTX *mem_ctx,
815
struct tevent_context *ev,
816
struct sysdb_ctx *sysdb,
817
struct sysdb_handle *handle,
818
struct sss_domain_info *domain,
822
struct tevent_req *req, *subreq;
823
struct sysdb_search_group_state *state;
824
static const char *def_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL };
827
if (!sysdb && !handle) return NULL;
829
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_group_state);
830
if (!req) return NULL;
833
state->handle = handle;
834
state->msgs_count = 0;
837
state->attrs = attrs ? attrs : def_attrs;
838
state->filter = NULL;
839
state->scope = LDB_SCOPE_BASE;
841
if (!sysdb) sysdb = handle->ctx;
843
state->basedn = sysdb_group_dn(sysdb, state, domain->name, name);
844
if (!state->basedn) {
845
ERROR_OUT(ret, ENOMEM, fail);
849
subreq = sysdb_operation_send(state, state->ev, sysdb);
851
ERROR_OUT(ret, ENOMEM, fail);
853
tevent_req_set_callback(subreq, sysdb_search_group_cont, req);
856
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
857
state->basedn, state->scope,
858
state->filter, state->attrs);
860
ERROR_OUT(ret, ENOMEM, fail);
862
tevent_req_set_callback(subreq, sysdb_search_group_done, req);
868
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
869
tevent_req_error(req, ret);
870
tevent_req_post(req, ev);
874
struct tevent_req *sysdb_search_group_by_gid_send(TALLOC_CTX *mem_ctx,
875
struct tevent_context *ev,
876
struct sysdb_ctx *sysdb,
877
struct sysdb_handle *handle,
878
struct sss_domain_info *domain,
882
struct tevent_req *req, *subreq;
883
struct sysdb_search_group_state *state;
884
static const char *def_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL };
887
if (!sysdb && !handle) return NULL;
889
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_group_state);
890
if (!req) return NULL;
893
state->handle = handle;
894
state->msgs_count = 0;
896
state->attrs = attrs ? attrs : def_attrs;
898
if (!sysdb) sysdb = handle->ctx;
900
state->basedn = ldb_dn_new_fmt(state, sysdb->ldb,
901
SYSDB_TMPL_GROUP_BASE, domain->name);
902
if (!state->basedn) {
903
ERROR_OUT(ret, ENOMEM, fail);
906
state->filter = talloc_asprintf(state, SYSDB_GRGID_FILTER,
908
if (!state->filter) {
909
ERROR_OUT(ret, ENOMEM, fail);
912
state->scope = LDB_SCOPE_ONELEVEL;
915
subreq = sysdb_operation_send(state, state->ev, sysdb);
917
ERROR_OUT(ret, ENOMEM, fail);
919
tevent_req_set_callback(subreq, sysdb_search_group_cont, req);
922
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
923
state->basedn, state->scope,
924
state->filter, state->attrs);
926
ERROR_OUT(ret, ENOMEM, fail);
928
tevent_req_set_callback(subreq, sysdb_search_group_done, req);
934
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
935
tevent_req_error(req, ret);
936
tevent_req_post(req, ev);
940
static void sysdb_search_group_cont(struct tevent_req *subreq)
942
struct tevent_req *req = tevent_req_callback_data(subreq,
944
struct sysdb_search_group_state *state = tevent_req_data(req,
945
struct sysdb_search_group_state);
948
ret = sysdb_operation_recv(subreq, state, &state->handle);
949
talloc_zfree(subreq);
951
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
952
tevent_req_error(req, ret);
956
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
957
state->basedn, state->scope,
958
state->filter, state->attrs);
960
DEBUG(6, ("Error: Out of memory\n"));
961
tevent_req_error(req, ENOMEM);
964
tevent_req_set_callback(subreq, sysdb_search_group_done, req);
967
static void sysdb_search_group_done(struct tevent_req *subreq)
969
struct tevent_req *req = tevent_req_callback_data(subreq,
971
struct sysdb_search_group_state *state = tevent_req_data(req,
972
struct sysdb_search_group_state);
975
ret = sysdb_search_entry_recv(subreq, state, &state->msgs_count,
977
talloc_zfree(subreq);
979
tevent_req_error(req, ret);
983
tevent_req_done(req);
986
int sysdb_search_group_recv(struct tevent_req *req,
988
struct ldb_message **msg)
990
struct sysdb_search_group_state *state = tevent_req_data(req,
991
struct sysdb_search_group_state);
993
TEVENT_REQ_RETURN_ON_ERROR(req);
995
if (state->msgs_count > 1) {
996
DEBUG(1, ("More than one result found.\n"));
1000
*msg = talloc_move(mem_ctx, &state->msgs[0]);
1006
/* =Replace-Attributes-On-Entry=========================================== */
1008
struct tevent_req *sysdb_set_entry_attr_send(TALLOC_CTX *mem_ctx,
1009
struct tevent_context *ev,
1010
struct sysdb_handle *handle,
1011
struct ldb_dn *entry_dn,
1012
struct sysdb_attrs *attrs,
1015
struct tevent_req *req, *subreq;
1016
struct sysdb_op_state *state;
1017
struct ldb_request *ldbreq;
1018
struct ldb_message *msg;
1021
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
1022
if (!req) return NULL;
1025
state->handle = handle;
1026
state->ignore_not_found = false;
1027
state->ldbreply = NULL;
1030
ERROR_OUT(ret, EINVAL, fail);
1033
if (attrs->num == 0) {
1034
ERROR_OUT(ret, EINVAL, fail);
1037
msg = ldb_msg_new(state);
1039
ERROR_OUT(ret, ENOMEM, fail);
1044
msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num);
1045
if (!msg->elements) {
1046
ERROR_OUT(ret, ENOMEM, fail);
1049
for (i = 0; i < attrs->num; i++) {
1050
msg->elements[i] = attrs->a[i];
1051
msg->elements[i].flags = mod_op;
1054
msg->num_elements = attrs->num;
1056
ret = ldb_build_mod_req(&ldbreq, handle->ctx->ldb, state, msg,
1057
NULL, NULL, NULL, NULL);
1058
if (ret != LDB_SUCCESS) {
1059
DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
1060
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
1061
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
1064
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
1066
ERROR_OUT(ret, ENOMEM, fail);
1068
tevent_req_set_callback(subreq, sysdb_op_default_done, req);
1073
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1074
tevent_req_error(req, ret);
1075
tevent_req_post(req, ev);
1079
int sysdb_set_entry_attr_recv(struct tevent_req *req)
1081
return sysdb_op_default_recv(req);
1085
/* =Replace-Attributes-On-User============================================ */
1087
static void sysdb_set_user_attr_done(struct tevent_req *subreq);
1089
struct tevent_req *sysdb_set_user_attr_send(TALLOC_CTX *mem_ctx,
1090
struct tevent_context *ev,
1091
struct sysdb_handle *handle,
1092
struct sss_domain_info *domain,
1094
struct sysdb_attrs *attrs,
1097
struct tevent_req *req, *subreq;
1098
struct sysdb_op_state *state;
1102
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
1103
if (!req) return NULL;
1106
state->handle = handle;
1107
state->ignore_not_found = false;
1108
state->ldbreply = NULL;
1110
dn = sysdb_user_dn(handle->ctx, state, domain->name, name);
1112
ERROR_OUT(ret, ENOMEM, fail);
1115
subreq = sysdb_set_entry_attr_send(state, ev, handle, dn, attrs, mod_op);
1117
ERROR_OUT(ret, ENOMEM, fail);
1119
tevent_req_set_callback(subreq, sysdb_set_user_attr_done, req);
1124
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1125
tevent_req_error(req, ret);
1126
tevent_req_post(req, ev);
1130
static void sysdb_set_user_attr_done(struct tevent_req *subreq)
1132
struct tevent_req *req = tevent_req_callback_data(subreq,
1136
ret = sysdb_set_entry_attr_recv(subreq);
1137
talloc_zfree(subreq);
1139
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1140
tevent_req_error(req, ret);
1144
tevent_req_done(req);
1147
int sysdb_set_user_attr_recv(struct tevent_req *req)
1149
return sysdb_op_default_recv(req);
1153
/* =Replace-Attributes-On-Group=========================================== */
1155
static void sysdb_set_group_attr_done(struct tevent_req *subreq);
1157
struct tevent_req *sysdb_set_group_attr_send(TALLOC_CTX *mem_ctx,
1158
struct tevent_context *ev,
1159
struct sysdb_handle *handle,
1160
struct sss_domain_info *domain,
1162
struct sysdb_attrs *attrs,
1165
struct tevent_req *req, *subreq;
1166
struct sysdb_op_state *state;
1170
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
1171
if (!req) return NULL;
1174
state->handle = handle;
1175
state->ignore_not_found = false;
1176
state->ldbreply = NULL;
1178
dn = sysdb_group_dn(handle->ctx, state, domain->name, name);
1180
ERROR_OUT(ret, ENOMEM, fail);
1183
subreq = sysdb_set_entry_attr_send(state, ev, handle, dn, attrs, mod_op);
1185
ERROR_OUT(ret, ENOMEM, fail);
1187
tevent_req_set_callback(subreq, sysdb_set_group_attr_done, req);
1192
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1193
tevent_req_error(req, ret);
1194
tevent_req_post(req, ev);
1198
static void sysdb_set_group_attr_done(struct tevent_req *subreq)
1200
struct tevent_req *req = tevent_req_callback_data(subreq,
1204
ret = sysdb_set_entry_attr_recv(subreq);
1205
talloc_zfree(subreq);
1207
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1208
tevent_req_error(req, ret);
1212
tevent_req_done(req);
1215
int sysdb_set_group_attr_recv(struct tevent_req *req)
1217
return sysdb_op_default_recv(req);
1221
/* =Get-New-ID============================================================ */
1223
struct sysdb_get_new_id_state {
1224
struct tevent_context *ev;
1225
struct sysdb_handle *handle;
1226
struct sss_domain_info *domain;
1228
struct ldb_dn *base_dn;
1229
struct ldb_message *base;
1231
struct ldb_message **v_msgs;
1237
static void sysdb_get_new_id_base(struct tevent_req *subreq);
1238
static void sysdb_get_new_id_verify(struct tevent_req *subreq);
1239
static void sysdb_get_new_id_done(struct tevent_req *subreq);
1241
struct tevent_req *sysdb_get_new_id_send(TALLOC_CTX *mem_ctx,
1242
struct tevent_context *ev,
1243
struct sysdb_handle *handle,
1244
struct sss_domain_info *domain)
1246
struct tevent_req *req, *subreq;
1247
struct sysdb_get_new_id_state *state;
1248
static const char *attrs[] = { SYSDB_NEXTID, NULL };
1249
struct ldb_request *ldbreq;
1252
req = tevent_req_create(mem_ctx, &state, struct sysdb_get_new_id_state);
1253
if (!req) return NULL;
1256
state->handle = handle;
1257
state->domain = domain;
1259
state->v_msgs = NULL;
1263
state->base_dn = sysdb_domain_dn(handle->ctx, state, domain->name);
1264
if (!state->base_dn) {
1265
ERROR_OUT(ret, ENOMEM, fail);
1268
ret = ldb_build_search_req(&ldbreq, handle->ctx->ldb, state,
1269
state->base_dn, LDB_SCOPE_BASE,
1270
SYSDB_NEXTID_FILTER, attrs,
1271
NULL, NULL, NULL, NULL);
1272
if (ret != LDB_SUCCESS) {
1273
DEBUG(1, ("Failed to build search request: %s(%d)[%s]\n",
1274
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
1275
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
1278
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
1280
ERROR_OUT(ret, ENOMEM, fail);
1282
tevent_req_set_callback(subreq, sysdb_get_new_id_base, req);
1287
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1288
tevent_req_error(req, ret);
1289
tevent_req_post(req, ev);
1293
static void sysdb_get_new_id_base(struct tevent_req *subreq)
1295
struct tevent_req *req = tevent_req_callback_data(subreq,
1297
struct sysdb_get_new_id_state *state = tevent_req_data(req,
1298
struct sysdb_get_new_id_state);
1299
static const char *attrs[] = { SYSDB_UIDNUM, SYSDB_GIDNUM, NULL };
1300
struct ldb_reply *ldbreply;
1301
struct ldb_request *ldbreq;
1305
ret = sldb_request_recv(subreq, state, &ldbreply);
1307
talloc_zfree(subreq);
1308
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1309
tevent_req_error(req, ret);
1313
switch (ldbreply->type) {
1314
case LDB_REPLY_ENTRY:
1316
DEBUG(1, ("More than one reply for a base search ?! "
1317
"DB seems corrupted, aborting."));
1318
tevent_req_error(req, EFAULT);
1322
state->base = talloc_move(state, &ldbreply->message);
1324
DEBUG(6, ("Error: Out of memory!\n"));
1325
tevent_req_error(req, ENOMEM);
1329
/* just return, wait for a LDB_REPLY_DONE entry */
1330
talloc_zfree(ldbreply);
1333
case LDB_REPLY_DONE:
1337
/* unexpected stuff */
1338
DEBUG(6, ("Error: Unknown error\n"));
1339
tevent_req_error(req, EIO);
1340
talloc_zfree(ldbreply);
1344
talloc_zfree(subreq);
1347
state->new_id = get_attr_as_uint32(state->base, SYSDB_NEXTID);
1348
if (state->new_id == (uint32_t)(-1)) {
1349
DEBUG(1, ("Invalid Next ID in domain %s\n", state->domain->name));
1350
tevent_req_error(req, ERANGE);
1354
if (state->new_id < state->domain->id_min) {
1355
state->new_id = state->domain->id_min;
1358
if ((state->domain->id_max != 0) &&
1359
(state->new_id > state->domain->id_max)) {
1360
DEBUG(0, ("Failed to allocate new id, out of range (%u/%u)\n",
1361
state->new_id, state->domain->id_max));
1362
tevent_req_error(req, ERANGE);
1367
/* looks like the domain is not initialized yet, use min_id */
1368
state->new_id = state->domain->id_min;
1371
/* verify the id is actually really free.
1372
* search all entries with id >= new_id and < max_id */
1373
if (state->domain->id_max) {
1374
filter = talloc_asprintf(state,
1375
"(|(&(%s>=%u)(%s<=%u))(&(%s>=%u)(%s<=%u)))",
1376
SYSDB_UIDNUM, state->new_id,
1377
SYSDB_UIDNUM, state->domain->id_max,
1378
SYSDB_GIDNUM, state->new_id,
1379
SYSDB_GIDNUM, state->domain->id_max);
1382
filter = talloc_asprintf(state,
1383
"(|(%s>=%u)(%s>=%u))",
1384
SYSDB_UIDNUM, state->new_id,
1385
SYSDB_GIDNUM, state->new_id);
1388
DEBUG(6, ("Error: Out of memory\n"));
1389
tevent_req_error(req, ENOMEM);
1393
ret = ldb_build_search_req(&ldbreq, state->handle->ctx->ldb, state,
1394
state->base_dn, LDB_SCOPE_SUBTREE,
1396
NULL, NULL, NULL, NULL);
1397
if (ret != LDB_SUCCESS) {
1398
DEBUG(1, ("Failed to build search request: %s(%d)[%s]\n",
1399
ldb_strerror(ret), ret,
1400
ldb_errstring(state->handle->ctx->ldb)));
1401
tevent_req_error(req, sysdb_error_to_errno(ret));
1405
subreq = sldb_request_send(state, state->ev,
1406
state->handle->ctx->ldb, ldbreq);
1408
DEBUG(6, ("Error: Out of memory\n"));
1409
tevent_req_error(req, ENOMEM);
1412
tevent_req_set_callback(subreq, sysdb_get_new_id_verify, req);
1417
static void sysdb_get_new_id_verify(struct tevent_req *subreq)
1419
struct tevent_req *req = tevent_req_callback_data(subreq,
1421
struct sysdb_get_new_id_state *state = tevent_req_data(req,
1422
struct sysdb_get_new_id_state);
1423
struct ldb_reply *ldbreply;
1424
struct ldb_request *ldbreq;
1425
struct ldb_message *msg;
1428
ret = sldb_request_recv(subreq, state, &ldbreply);
1430
talloc_zfree(subreq);
1431
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1432
tevent_req_error(req, ret);
1436
switch (ldbreply->type) {
1437
case LDB_REPLY_ENTRY:
1438
state->v_msgs = talloc_realloc(state, state->v_msgs,
1439
struct ldb_message *,
1440
state->v_count + 2);
1441
if (!state->v_msgs) {
1442
DEBUG(6, ("Error: Out of memory\n"));
1443
tevent_req_error(req, ENOMEM);
1447
state->v_msgs[state->v_count] = talloc_move(state, &ldbreply->message);
1448
if (!state->v_msgs[state->v_count]) {
1449
DEBUG(6, ("Error: Out of memory\n"));
1450
tevent_req_error(req, ENOMEM);
1455
/* just return, wait for a LDB_REPLY_DONE entry */
1456
talloc_zfree(ldbreply);
1459
case LDB_REPLY_DONE:
1463
/* unexpected stuff */
1464
DEBUG(6, ("Error: Unknown error\n"));
1465
tevent_req_error(req, EIO);
1466
talloc_zfree(ldbreply);
1470
talloc_zfree(subreq);
1472
/* if anything was found, find the maximum and increment past it */
1473
if (state->v_count) {
1476
for (i = 0; i < state->v_count; i++) {
1477
id = get_attr_as_uint32(state->v_msgs[i], SYSDB_UIDNUM);
1478
if (id != (uint32_t)(-1)) {
1479
if (id > state->new_id) state->new_id = id;
1481
id = get_attr_as_uint32(state->v_msgs[i], SYSDB_GIDNUM);
1482
if (id != (uint32_t)(-1)) {
1483
if (id > state->new_id) state->new_id = id;
1489
/* check again we are not falling out of range */
1490
if ((state->domain->id_max != 0) &&
1491
(state->new_id > state->domain->id_max)) {
1492
DEBUG(0, ("Failed to allocate new id, out of range (%u/%u)\n",
1493
state->new_id, state->domain->id_max));
1494
tevent_req_error(req, ERANGE);
1498
talloc_zfree(state->v_msgs);
1502
/* finally store the new next id */
1503
msg = ldb_msg_new(state);
1505
DEBUG(6, ("Error: Out of memory\n"));
1506
tevent_req_error(req, ENOMEM);
1509
msg->dn = state->base_dn;
1511
ret = add_ulong(msg, LDB_FLAG_MOD_REPLACE,
1512
SYSDB_NEXTID, state->new_id + 1);
1514
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1515
tevent_req_error(req, ret);
1519
ret = ldb_build_mod_req(&ldbreq, state->handle->ctx->ldb, state, msg,
1520
NULL, NULL, NULL, NULL);
1521
if (ret != LDB_SUCCESS) {
1522
DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
1523
ldb_strerror(ret), ret,
1524
ldb_errstring(state->handle->ctx->ldb)));
1525
tevent_req_error(req, ret);
1529
subreq = sldb_request_send(state, state->ev,
1530
state->handle->ctx->ldb, ldbreq);
1532
DEBUG(6, ("Error: Out of memory\n"));
1533
tevent_req_error(req, ENOMEM);
1536
tevent_req_set_callback(subreq, sysdb_get_new_id_done, req);
1539
static void sysdb_get_new_id_done(struct tevent_req *subreq)
1541
struct tevent_req *req = tevent_req_callback_data(subreq,
1543
struct sysdb_get_new_id_state *state = tevent_req_data(req,
1544
struct sysdb_get_new_id_state);
1545
struct ldb_reply *ldbreply;
1548
ret = sldb_request_recv(subreq, state, &ldbreply);
1549
talloc_zfree(subreq);
1551
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1552
tevent_req_error(req, ret);
1556
if (ldbreply->type != LDB_REPLY_DONE) {
1557
DEBUG(6, ("Error: %d (%s)\n", EIO, strerror(EIO)));
1558
tevent_req_error(req, EIO);
1562
tevent_req_done(req);
1565
int sysdb_get_new_id_recv(struct tevent_req *req, uint32_t *id)
1567
struct sysdb_get_new_id_state *state = tevent_req_data(req,
1568
struct sysdb_get_new_id_state);
1570
TEVENT_REQ_RETURN_ON_ERROR(req);
1572
*id = state->new_id;
1578
/* =Add-Basic-User-NO-CHECKS============================================== */
1580
struct tevent_req *sysdb_add_basic_user_send(TALLOC_CTX *mem_ctx,
1581
struct tevent_context *ev,
1582
struct sysdb_handle *handle,
1583
struct sss_domain_info *domain,
1585
uid_t uid, gid_t gid,
1587
const char *homedir,
1590
struct tevent_req *req, *subreq;
1591
struct sysdb_op_state *state;
1592
struct ldb_request *ldbreq;
1593
struct ldb_message *msg;
1596
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
1597
if (!req) return NULL;
1600
state->handle = handle;
1601
state->ignore_not_found = false;
1602
state->ldbreply = NULL;
1604
msg = ldb_msg_new(state);
1606
ERROR_OUT(ret, ENOMEM, fail);
1610
msg->dn = sysdb_user_dn(handle->ctx, msg, domain->name, name);
1612
ERROR_OUT(ret, ENOMEM, fail);
1615
ret = add_string(msg, LDB_FLAG_MOD_ADD, "objectClass", SYSDB_USER_CLASS);
1618
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name);
1621
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_UIDNUM, (unsigned long)uid);
1624
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid);
1627
/* We set gecos to be the same as fullname on user creation,
1628
* But we will not enforce coherency after that, it's up to
1629
* admins to decide if they want to keep it in sync if they change
1631
if (gecos && *gecos) {
1632
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_FULLNAME, gecos);
1634
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_GECOS, gecos);
1638
if (homedir && *homedir) {
1639
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_HOMEDIR, homedir);
1643
if (shell && *shell) {
1644
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_SHELL, shell);
1649
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
1650
(unsigned long)time(NULL));
1654
ret = ldb_build_add_req(&ldbreq, handle->ctx->ldb, state, msg,
1655
NULL, NULL, NULL, NULL);
1656
if (ret != LDB_SUCCESS) {
1657
DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
1658
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
1659
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
1662
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
1664
ERROR_OUT(ret, ENOMEM, fail);
1666
tevent_req_set_callback(subreq, sysdb_op_default_done, req);
1671
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1672
tevent_req_error(req, ret);
1673
tevent_req_post(req, ev);
1677
int sysdb_add_basic_user_recv(struct tevent_req *req)
1679
return sysdb_op_default_recv(req);
1683
/* =Add-User-Function===================================================== */
1685
struct sysdb_add_user_state {
1686
struct tevent_context *ev;
1687
struct sysdb_handle *handle;
1688
struct sss_domain_info *domain;
1694
const char *homedir;
1696
struct sysdb_attrs *attrs;
1701
static void sysdb_add_user_group_check(struct tevent_req *subreq);
1702
static void sysdb_add_user_uid_check(struct tevent_req *subreq);
1703
static void sysdb_add_user_basic_done(struct tevent_req *subreq);
1704
static void sysdb_add_user_get_id_done(struct tevent_req *subreq);
1705
static void sysdb_add_user_set_id_done(struct tevent_req *subreq);
1706
static void sysdb_add_user_set_attrs(struct tevent_req *req);
1707
static void sysdb_add_user_set_attrs_done(struct tevent_req *subreq);
1709
struct tevent_req *sysdb_add_user_send(TALLOC_CTX *mem_ctx,
1710
struct tevent_context *ev,
1711
struct sysdb_handle *handle,
1712
struct sss_domain_info *domain,
1714
uid_t uid, gid_t gid,
1716
const char *homedir,
1718
struct sysdb_attrs *attrs,
1721
struct tevent_req *req, *subreq;
1722
struct sysdb_add_user_state *state;
1725
req = tevent_req_create(mem_ctx, &state, struct sysdb_add_user_state);
1726
if (!req) return NULL;
1729
state->handle = handle;
1730
state->domain = domain;
1734
state->gecos = gecos;
1735
state->homedir = homedir;
1736
state->shell = shell;
1737
state->attrs = attrs;
1738
state->cache_timeout = cache_timeout;
1740
if (handle->ctx->mpg) {
1742
DEBUG(0, ("Cannot add user with arbitrary GID in MPG domain!\n"));
1743
ERROR_OUT(ret, EINVAL, fail);
1745
state->gid = state->uid;
1748
if (domain->id_max != 0 && uid != 0 &&
1749
(uid < domain->id_min || uid > domain->id_max)) {
1750
DEBUG(2, ("Supplied uid [%d] is not in the allowed range [%d-%d].\n",
1751
uid, domain->id_min, domain->id_max));
1752
ERROR_OUT(ret, ERANGE, fail);
1755
if (domain->id_max != 0 && gid != 0 &&
1756
(gid < domain->id_min || gid > domain->id_max)) {
1757
DEBUG(2, ("Supplied gid [%d] is not in the allowed range [%d-%d].\n",
1758
gid, domain->id_min, domain->id_max));
1759
ERROR_OUT(ret, ERANGE, fail);
1762
if (handle->ctx->mpg) {
1763
/* In MPG domains you can't have groups with the same name as users,
1764
* search if a group with the same name exists.
1765
* Don't worry about users, if we try to add a user with the same
1766
* name the operation will fail */
1768
subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
1769
domain, name, NULL);
1771
ERROR_OUT(ret, ENOMEM, fail);
1773
tevent_req_set_callback(subreq, sysdb_add_user_group_check, req);
1777
/* check no other user with the same uid exist */
1778
if (state->uid != 0) {
1779
subreq = sysdb_search_user_by_uid_send(state, ev, NULL, handle,
1782
ERROR_OUT(ret, ENOMEM, fail);
1784
tevent_req_set_callback(subreq, sysdb_add_user_uid_check, req);
1788
/* try to add the user */
1789
subreq = sysdb_add_basic_user_send(state, ev, handle,
1790
domain, name, uid, gid,
1791
gecos, homedir, shell);
1793
ERROR_OUT(ret, ENOMEM, fail);
1795
tevent_req_set_callback(subreq, sysdb_add_user_basic_done, req);
1799
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1800
tevent_req_error(req, ret);
1801
tevent_req_post(req, ev);
1805
static void sysdb_add_user_group_check(struct tevent_req *subreq)
1807
struct tevent_req *req = tevent_req_callback_data(subreq,
1809
struct sysdb_add_user_state *state = tevent_req_data(req,
1810
struct sysdb_add_user_state);
1811
struct ldb_message *msg;
1814
/* We can succeed only if we get an ENOENT error, which means no groups
1815
* with the same name exist.
1816
* If any other error is returned fail as well. */
1817
ret = sysdb_search_group_recv(subreq, state, &msg);
1818
talloc_zfree(subreq);
1819
if (ret != ENOENT) {
1820
if (ret == EOK) ret = EEXIST;
1821
tevent_req_error(req, ret);
1825
/* check no other user with the same uid exist */
1826
if (state->uid != 0) {
1827
subreq = sysdb_search_user_by_uid_send(state, state->ev,
1828
NULL, state->handle,
1829
state->domain, state->uid,
1832
DEBUG(6, ("Error: Out of memory\n"));
1833
tevent_req_error(req, ENOMEM);
1836
tevent_req_set_callback(subreq, sysdb_add_user_uid_check, req);
1840
/* try to add the user */
1841
subreq = sysdb_add_basic_user_send(state, state->ev, state->handle,
1842
state->domain, state->name,
1843
state->uid, state->gid,
1848
DEBUG(6, ("Error: Out of memory\n"));
1849
tevent_req_error(req, ENOMEM);
1852
tevent_req_set_callback(subreq, sysdb_add_user_basic_done, req);
1855
static void sysdb_add_user_uid_check(struct tevent_req *subreq)
1857
struct tevent_req *req = tevent_req_callback_data(subreq,
1859
struct sysdb_add_user_state *state = tevent_req_data(req,
1860
struct sysdb_add_user_state);
1861
struct ldb_message *msg;
1864
/* We can succeed only if we get an ENOENT error, which means no user
1865
* with the same uid exist.
1866
* If any other error is returned fail as well. */
1867
ret = sysdb_search_user_recv(subreq, state, &msg);
1868
talloc_zfree(subreq);
1869
if (ret != ENOENT) {
1870
if (ret == EOK) ret = EEXIST;
1871
tevent_req_error(req, ret);
1875
/* try to add the user */
1876
subreq = sysdb_add_basic_user_send(state, state->ev, state->handle,
1877
state->domain, state->name,
1878
state->uid, state->gid,
1883
DEBUG(6, ("Error: Out of memory\n"));
1884
tevent_req_error(req, ENOMEM);
1887
tevent_req_set_callback(subreq, sysdb_add_user_basic_done, req);
1890
static void sysdb_add_user_basic_done(struct tevent_req *subreq)
1892
struct tevent_req *req = tevent_req_callback_data(subreq,
1894
struct sysdb_add_user_state *state = tevent_req_data(req,
1895
struct sysdb_add_user_state);
1898
ret = sysdb_add_basic_user_recv(subreq);
1899
talloc_zfree(subreq);
1901
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1902
tevent_req_error(req, ret);
1906
if (state->uid == 0) {
1907
subreq = sysdb_get_new_id_send(state,
1908
state->ev, state->handle,
1911
DEBUG(6, ("Error: Out of memory\n"));
1912
tevent_req_error(req, ENOMEM);
1915
tevent_req_set_callback(subreq, sysdb_add_user_get_id_done, req);
1919
sysdb_add_user_set_attrs(req);
1922
static void sysdb_add_user_get_id_done(struct tevent_req *subreq)
1924
struct tevent_req *req = tevent_req_callback_data(subreq,
1926
struct sysdb_add_user_state *state = tevent_req_data(req,
1927
struct sysdb_add_user_state);
1928
struct sysdb_attrs *id_attrs;
1932
ret = sysdb_get_new_id_recv(subreq, &id);
1933
talloc_zfree(subreq);
1935
tevent_req_error(req, ret);
1939
if (state->uid == 0) {
1940
id_attrs = sysdb_new_attrs(state);
1942
DEBUG(6, ("Error: Out of memory\n"));
1943
tevent_req_error(req, ENOMEM);
1946
ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_UIDNUM, id);
1948
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1949
tevent_req_error(req, ret);
1952
if (state->handle->ctx->mpg) {
1953
ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_GIDNUM, id);
1955
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
1956
tevent_req_error(req, ret);
1961
subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
1962
state->domain, state->name,
1963
id_attrs, SYSDB_MOD_REP);
1965
DEBUG(6, ("Error: Out of memory\n"));
1966
tevent_req_error(req, ENOMEM);
1969
tevent_req_set_callback(subreq, sysdb_add_user_set_id_done, req);
1973
sysdb_add_user_set_attrs(req);
1976
static void sysdb_add_user_set_id_done(struct tevent_req *subreq)
1978
struct tevent_req *req = tevent_req_callback_data(subreq,
1980
struct sysdb_add_user_state *state = tevent_req_data(req,
1981
struct sysdb_add_user_state);
1984
ret = sysdb_set_user_attr_recv(subreq);
1985
talloc_zfree(subreq);
1987
tevent_req_error(req, ret);
1994
tevent_req_done(req);
1997
static void sysdb_add_user_set_attrs(struct tevent_req *req)
1999
struct sysdb_add_user_state *state = tevent_req_data(req,
2000
struct sysdb_add_user_state);
2001
struct tevent_req *subreq;
2002
time_t now = time(NULL);
2005
if (!state->attrs) {
2006
state->attrs = sysdb_new_attrs(state);
2007
if (!state->attrs) {
2008
DEBUG(6, ("Error: Out of memory\n"));
2009
tevent_req_error(req, ENOMEM);
2014
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
2016
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2017
tevent_req_error(req, ret);
2021
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
2022
((state->cache_timeout) ?
2023
(now + state->cache_timeout) : 0));
2025
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2026
tevent_req_error(req, ret);
2030
subreq = sysdb_set_user_attr_send(state, state->ev,
2031
state->handle, state->domain,
2032
state->name, state->attrs,
2035
DEBUG(6, ("Error: Out of memory\n"));
2036
tevent_req_error(req, ENOMEM);
2039
tevent_req_set_callback(subreq, sysdb_add_user_set_attrs_done, req);
2042
static void sysdb_add_user_set_attrs_done(struct tevent_req *subreq)
2044
struct tevent_req *req = tevent_req_callback_data(subreq,
2048
ret = sysdb_set_user_attr_recv(subreq);
2049
talloc_zfree(subreq);
2051
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2052
tevent_req_error(req, ret);
2056
tevent_req_done(req);
2059
int sysdb_add_user_recv(struct tevent_req *req)
2061
return sysdb_op_default_recv(req);
2065
/* =Add-Basic-Group-NO-CHECKS============================================= */
2067
struct tevent_req *sysdb_add_basic_group_send(TALLOC_CTX *mem_ctx,
2068
struct tevent_context *ev,
2069
struct sysdb_handle *handle,
2070
struct sss_domain_info *domain,
2071
const char *name, gid_t gid)
2073
struct tevent_req *req, *subreq;
2074
struct sysdb_op_state *state;
2075
struct ldb_request *ldbreq;
2076
struct ldb_message *msg;
2079
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
2080
if (!req) return NULL;
2083
state->handle = handle;
2084
state->ignore_not_found = false;
2085
state->ldbreply = NULL;
2087
msg = ldb_msg_new(state);
2089
ERROR_OUT(ret, ENOMEM, fail);
2093
msg->dn = sysdb_group_dn(handle->ctx, msg, domain->name, name);
2095
ERROR_OUT(ret, ENOMEM, fail);
2098
ret = add_string(msg, LDB_FLAG_MOD_ADD, "objectClass", SYSDB_GROUP_CLASS);
2101
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name);
2104
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid);
2108
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
2109
(unsigned long)time(NULL));
2113
ret = ldb_build_add_req(&ldbreq, handle->ctx->ldb, state, msg,
2114
NULL, NULL, NULL, NULL);
2115
if (ret != LDB_SUCCESS) {
2116
DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
2117
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
2118
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
2121
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
2123
ERROR_OUT(ret, ENOMEM, fail);
2125
tevent_req_set_callback(subreq, sysdb_op_default_done, req);
2130
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2131
tevent_req_error(req, ret);
2132
tevent_req_post(req, ev);
2136
int sysdb_add_basic_group_recv(struct tevent_req *req)
2138
return sysdb_op_default_recv(req);
2142
/* =Add-Group-Function==================================================== */
2144
struct sysdb_add_group_state {
2145
struct tevent_context *ev;
2146
struct sysdb_handle *handle;
2147
struct sss_domain_info *domain;
2151
struct sysdb_attrs *attrs;
2156
static void sysdb_add_group_user_check(struct tevent_req *subreq);
2157
static void sysdb_add_group_gid_check(struct tevent_req *subreq);
2158
static void sysdb_add_group_basic_done(struct tevent_req *subreq);
2159
static void sysdb_add_group_get_id_done(struct tevent_req *subreq);
2160
static void sysdb_add_group_set_attrs(struct tevent_req *req);
2161
static void sysdb_add_group_set_attrs_done(struct tevent_req *subreq);
2163
struct tevent_req *sysdb_add_group_send(TALLOC_CTX *mem_ctx,
2164
struct tevent_context *ev,
2165
struct sysdb_handle *handle,
2166
struct sss_domain_info *domain,
2167
const char *name, gid_t gid,
2168
struct sysdb_attrs *attrs,
2171
struct tevent_req *req, *subreq;
2172
struct sysdb_add_group_state *state;
2175
req = tevent_req_create(mem_ctx, &state, struct sysdb_add_group_state);
2176
if (!req) return NULL;
2179
state->handle = handle;
2180
state->domain = domain;
2183
state->attrs = attrs;
2184
state->cache_timeout = cache_timeout;
2186
if (domain->id_max != 0 && gid != 0 &&
2187
(gid < domain->id_min || gid > domain->id_max)) {
2188
DEBUG(2, ("Supplied gid [%d] is not in the allowed range [%d-%d].\n",
2189
gid, domain->id_min, domain->id_max));
2190
ERROR_OUT(ret, ERANGE, fail);
2193
if (handle->ctx->mpg) {
2194
/* In MPG domains you can't have groups with the same name as users,
2195
* search if a group with the same name exists.
2196
* Don't worry about users, if we try to add a user with the same
2197
* name the operation will fail */
2199
subreq = sysdb_search_user_by_name_send(state, ev, NULL, handle,
2200
domain, name, NULL);
2202
ERROR_OUT(ret, ENOMEM, fail);
2204
tevent_req_set_callback(subreq, sysdb_add_group_user_check, req);
2208
/* check no other groups with the same gid exist */
2209
if (state->gid != 0) {
2210
subreq = sysdb_search_group_by_gid_send(state, ev, NULL, handle,
2213
ERROR_OUT(ret, ENOMEM, fail);
2215
tevent_req_set_callback(subreq, sysdb_add_group_gid_check, req);
2219
/* try to add the group */
2220
subreq = sysdb_add_basic_group_send(state, ev, handle,
2223
ERROR_OUT(ret, ENOMEM, fail);
2225
tevent_req_set_callback(subreq, sysdb_add_group_basic_done, req);
2229
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2230
tevent_req_error(req, ret);
2231
tevent_req_post(req, ev);
2235
static void sysdb_add_group_user_check(struct tevent_req *subreq)
2237
struct tevent_req *req = tevent_req_callback_data(subreq,
2239
struct sysdb_add_group_state *state = tevent_req_data(req,
2240
struct sysdb_add_group_state);
2241
struct ldb_message *msg;
2244
/* We can succeed only if we get an ENOENT error, which means no users
2245
* with the same name exist.
2246
* If any other error is returned fail as well. */
2247
ret = sysdb_search_user_recv(subreq, state, &msg);
2248
talloc_zfree(subreq);
2249
if (ret != ENOENT) {
2250
if (ret == EOK) ret = EEXIST;
2251
tevent_req_error(req, ret);
2255
/* check no other group with the same gid exist */
2256
if (state->gid != 0) {
2257
subreq = sysdb_search_group_by_gid_send(state, state->ev,
2258
NULL, state->handle,
2259
state->domain, state->gid,
2262
DEBUG(6, ("Error: Out of memory\n"));
2263
tevent_req_error(req, ENOMEM);
2266
tevent_req_set_callback(subreq, sysdb_add_group_gid_check, req);
2270
/* try to add the group */
2271
subreq = sysdb_add_basic_group_send(state, state->ev,
2272
state->handle, state->domain,
2273
state->name, state->gid);
2275
DEBUG(6, ("Error: Out of memory\n"));
2276
tevent_req_error(req, ENOMEM);
2279
tevent_req_set_callback(subreq, sysdb_add_group_basic_done, req);
2282
static void sysdb_add_group_gid_check(struct tevent_req *subreq)
2284
struct tevent_req *req = tevent_req_callback_data(subreq,
2286
struct sysdb_add_group_state *state = tevent_req_data(req,
2287
struct sysdb_add_group_state);
2288
struct ldb_message *msg;
2291
/* We can succeed only if we get an ENOENT error, which means no group
2292
* with the same gid exist.
2293
* If any other error is returned fail as well. */
2294
ret = sysdb_search_group_recv(subreq, state, &msg);
2295
talloc_zfree(subreq);
2296
if (ret != ENOENT) {
2297
if (ret == EOK) ret = EEXIST;
2298
tevent_req_error(req, ret);
2302
/* try to add the group */
2303
subreq = sysdb_add_basic_group_send(state, state->ev,
2304
state->handle, state->domain,
2305
state->name, state->gid);
2307
DEBUG(6, ("Error: Out of memory\n"));
2308
tevent_req_error(req, ENOMEM);
2311
tevent_req_set_callback(subreq, sysdb_add_group_basic_done, req);
2314
static void sysdb_add_group_basic_done(struct tevent_req *subreq)
2316
struct tevent_req *req = tevent_req_callback_data(subreq,
2318
struct sysdb_add_group_state *state = tevent_req_data(req,
2319
struct sysdb_add_group_state);
2322
ret = sysdb_add_basic_group_recv(subreq);
2323
talloc_zfree(subreq);
2325
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2326
tevent_req_error(req, ret);
2330
if (state->gid == 0) {
2331
subreq = sysdb_get_new_id_send(state,
2332
state->ev, state->handle,
2335
DEBUG(6, ("Error: Out of memory\n"));
2336
tevent_req_error(req, ENOMEM);
2339
tevent_req_set_callback(subreq, sysdb_add_group_get_id_done, req);
2343
sysdb_add_group_set_attrs(req);
2346
static void sysdb_add_group_get_id_done(struct tevent_req *subreq)
2348
struct tevent_req *req = tevent_req_callback_data(subreq,
2350
struct sysdb_add_group_state *state = tevent_req_data(req,
2351
struct sysdb_add_group_state);
2355
ret = sysdb_get_new_id_recv(subreq, &id);
2356
talloc_zfree(subreq);
2358
tevent_req_error(req, ret);
2362
if (state->gid == 0) {
2363
if (!state->attrs) {
2364
state->attrs = sysdb_new_attrs(state);
2365
if (!state->attrs) {
2366
DEBUG(6, ("Error: Out of memory\n"));
2367
tevent_req_error(req, ENOMEM);
2372
ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, id);
2374
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2375
tevent_req_error(req, ret);
2380
sysdb_add_group_set_attrs(req);
2383
static void sysdb_add_group_set_attrs(struct tevent_req *req)
2385
struct sysdb_add_group_state *state = tevent_req_data(req,
2386
struct sysdb_add_group_state);
2387
struct tevent_req *subreq;
2388
time_t now = time(NULL);
2391
if (!state->attrs) {
2392
state->attrs = sysdb_new_attrs(state);
2393
if (!state->attrs) {
2394
DEBUG(6, ("Error: Out of memory\n"));
2395
tevent_req_error(req, ENOMEM);
2400
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
2402
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2403
tevent_req_error(req, ret);
2407
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
2408
((state->cache_timeout) ?
2409
(now + state->cache_timeout) : 0));
2411
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2412
tevent_req_error(req, ret);
2416
subreq = sysdb_set_group_attr_send(state, state->ev,
2417
state->handle, state->domain,
2418
state->name, state->attrs,
2421
DEBUG(6, ("Error: Out of memory\n"));
2422
tevent_req_error(req, ENOMEM);
2425
tevent_req_set_callback(subreq, sysdb_add_group_set_attrs_done, req);
2428
static void sysdb_add_group_set_attrs_done(struct tevent_req *subreq)
2430
struct tevent_req *req = tevent_req_callback_data(subreq,
2434
ret = sysdb_set_group_attr_recv(subreq);
2435
talloc_zfree(subreq);
2437
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2438
tevent_req_error(req, ret);
2442
tevent_req_done(req);
2445
int sysdb_add_group_recv(struct tevent_req *req)
2447
return sysdb_op_default_recv(req);
2451
/* =Add-Or-Remove-Group-Memeber=========================================== */
2453
/* mod_op must be either SYSDB_MOD_ADD or SYSDB_MOD_DEL */
2454
struct tevent_req *sysdb_mod_group_member_send(TALLOC_CTX *mem_ctx,
2455
struct tevent_context *ev,
2456
struct sysdb_handle *handle,
2457
struct ldb_dn *member_dn,
2458
struct ldb_dn *group_dn,
2461
struct tevent_req *req, *subreq;
2462
struct sysdb_op_state *state;
2463
struct ldb_request *ldbreq;
2464
struct ldb_message *msg;
2468
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
2469
if (!req) return NULL;
2472
state->handle = handle;
2473
state->ignore_not_found = false;
2474
state->ldbreply = NULL;
2476
msg = ldb_msg_new(state);
2478
ERROR_OUT(ret, ENOMEM, fail);
2482
ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, mod_op, NULL);
2483
if (ret != LDB_SUCCESS) {
2484
ERROR_OUT(ret, ENOMEM, fail);
2487
dn = ldb_dn_get_linearized(member_dn);
2489
ERROR_OUT(ret, EINVAL, fail);
2492
ret = ldb_msg_add_fmt(msg, SYSDB_MEMBER, "%s", dn);
2493
if (ret != LDB_SUCCESS) {
2494
ERROR_OUT(ret, EINVAL, fail);
2497
ret = ldb_build_mod_req(&ldbreq, handle->ctx->ldb, state, msg,
2498
NULL, NULL, NULL, NULL);
2499
if (ret != LDB_SUCCESS) {
2500
DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
2501
ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
2502
ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
2505
subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
2507
ERROR_OUT(ret, ENOMEM, fail);
2509
tevent_req_set_callback(subreq, sysdb_op_default_done, req);
2514
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2515
tevent_req_error(req, ret);
2516
tevent_req_post(req, ev);
2520
int sysdb_mod_group_member_recv(struct tevent_req *req)
2522
return sysdb_op_default_recv(req);
2526
/* =Store-Users-(Native/Legacy)-(replaces-existing-data)================== */
2528
/* if one of the basic attributes is empty ("") as opposed to NULL,
2529
* this will just remove it */
2531
struct sysdb_store_user_state {
2532
struct tevent_context *ev;
2533
struct sysdb_handle *handle;
2534
struct sss_domain_info *domain;
2540
const char *homedir;
2542
struct sysdb_attrs *attrs;
2544
uint64_t cache_timeout;
2547
static void sysdb_store_user_check(struct tevent_req *subreq);
2548
static void sysdb_store_user_add_done(struct tevent_req *subreq);
2549
static void sysdb_store_user_attr_done(struct tevent_req *subreq);
2551
struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
2552
struct tevent_context *ev,
2553
struct sysdb_handle *handle,
2554
struct sss_domain_info *domain,
2557
uid_t uid, gid_t gid,
2559
const char *homedir,
2561
struct sysdb_attrs *attrs,
2562
uint64_t cache_timeout)
2564
struct tevent_req *req, *subreq;
2565
struct sysdb_store_user_state *state;
2568
req = tevent_req_create(mem_ctx, &state, struct sysdb_store_user_state);
2569
if (!req) return NULL;
2572
state->handle = handle;
2573
state->domain = domain;
2577
state->gecos = gecos;
2578
state->homedir = homedir;
2579
state->shell = shell;
2580
state->attrs = attrs;
2581
state->cache_timeout = cache_timeout;
2583
if (pwd && (domain->legacy_passwords || !*pwd)) {
2584
ret = sysdb_attrs_add_string(state->attrs, SYSDB_PWD, pwd);
2588
subreq = sysdb_search_user_by_name_send(state, ev, NULL, handle,
2589
domain, name, NULL);
2591
ERROR_OUT(ret, ENOMEM, fail);
2593
tevent_req_set_callback(subreq, sysdb_store_user_check, req);
2598
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2599
tevent_req_error(req, ret);
2600
tevent_req_post(req, ev);
2604
static void sysdb_store_user_check(struct tevent_req *subreq)
2606
struct tevent_req *req = tevent_req_callback_data(subreq,
2608
struct sysdb_store_user_state *state = tevent_req_data(req,
2609
struct sysdb_store_user_state);
2610
struct ldb_message *msg;
2611
time_t now = time(NULL);
2614
ret = sysdb_search_user_recv(subreq, state, &msg);
2615
talloc_zfree(subreq);
2616
if (ret && ret != ENOENT) {
2617
tevent_req_error(req, ret);
2621
if (ret == ENOENT) {
2622
/* users doesn't exist, turn into adding a user */
2623
subreq = sysdb_add_user_send(state, state->ev, state->handle,
2624
state->domain, state->name,
2625
state->uid, state->gid,
2626
state->gecos, state->homedir,
2627
state->shell, state->attrs,
2628
state->cache_timeout);
2630
DEBUG(6, ("Error: Out of memory\n"));
2631
tevent_req_error(req, ENOMEM);
2634
tevent_req_set_callback(subreq, sysdb_store_user_add_done, req);
2638
/* the user exists, let's just replace attributes when set */
2639
if (!state->attrs) {
2640
state->attrs = sysdb_new_attrs(state);
2641
if (!state->attrs) {
2642
DEBUG(6, ("Error: Out of memory\n"));
2643
tevent_req_error(req, ENOMEM);
2649
ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_UIDNUM, state->uid);
2651
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2652
tevent_req_error(req, ret);
2658
ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, state->gid);
2660
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2661
tevent_req_error(req, ret);
2666
if (state->uid && !state->gid && state->handle->ctx->mpg) {
2667
ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, state->uid);
2669
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2670
tevent_req_error(req, ret);
2676
ret = sysdb_attrs_add_string(state->attrs, SYSDB_GECOS, state->gecos);
2678
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2679
tevent_req_error(req, ret);
2684
if (state->homedir) {
2685
ret = sysdb_attrs_add_string(state->attrs,
2686
SYSDB_HOMEDIR, state->homedir);
2688
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2689
tevent_req_error(req, ret);
2695
ret = sysdb_attrs_add_string(state->attrs, SYSDB_SHELL, state->shell);
2697
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2698
tevent_req_error(req, ret);
2703
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
2705
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2706
tevent_req_error(req, ret);
2710
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
2711
((state->cache_timeout) ?
2712
(now + state->cache_timeout) : 0));
2714
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2715
tevent_req_error(req, ret);
2719
subreq = sysdb_set_user_attr_send(state, state->ev,
2720
state->handle, state->domain,
2721
state->name, state->attrs,
2724
DEBUG(6, ("Error: Out of memory\n"));
2725
tevent_req_error(req, ENOMEM);
2728
tevent_req_set_callback(subreq, sysdb_store_user_attr_done, req);
2731
static void sysdb_store_user_add_done(struct tevent_req *subreq)
2733
struct tevent_req *req = tevent_req_callback_data(subreq,
2737
ret = sysdb_add_user_recv(subreq);
2738
talloc_zfree(subreq);
2740
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2741
tevent_req_error(req, ret);
2745
tevent_req_done(req);
2748
static void sysdb_store_user_attr_done(struct tevent_req *subreq)
2750
struct tevent_req *req = tevent_req_callback_data(subreq,
2754
ret = sysdb_set_user_attr_recv(subreq);
2755
talloc_zfree(subreq);
2757
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2758
tevent_req_error(req, ret);
2762
tevent_req_done(req);
2765
int sysdb_store_user_recv(struct tevent_req *req)
2767
return sysdb_op_default_recv(req);
2770
/* =Store-Group-(Native/Legacy)-(replaces-existing-data)================== */
2772
/* this function does not check that all user members are actually present */
2774
struct sysdb_store_group_state {
2775
struct tevent_context *ev;
2776
struct sysdb_handle *handle;
2777
struct sss_domain_info *domain;
2782
struct sysdb_attrs *attrs;
2784
uint64_t cache_timeout;
2787
static void sysdb_store_group_check(struct tevent_req *subreq);
2788
static void sysdb_store_group_add_done(struct tevent_req *subreq);
2789
static void sysdb_store_group_attr_done(struct tevent_req *subreq);
2791
struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
2792
struct tevent_context *ev,
2793
struct sysdb_handle *handle,
2794
struct sss_domain_info *domain,
2797
struct sysdb_attrs *attrs,
2798
uint64_t cache_timeout)
2800
struct tevent_req *req, *subreq;
2801
struct sysdb_store_group_state *state;
2802
static const char *src_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM,
2803
SYSDB_ORIG_MODSTAMP, NULL };
2806
req = tevent_req_create(mem_ctx, &state, struct sysdb_store_group_state);
2807
if (!req) return NULL;
2810
state->handle = handle;
2811
state->domain = domain;
2814
state->attrs = attrs;
2815
state->cache_timeout = cache_timeout;
2817
subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
2818
domain, name, src_attrs);
2820
ERROR_OUT(ret, ENOMEM, fail);
2822
tevent_req_set_callback(subreq, sysdb_store_group_check, req);
2827
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2828
tevent_req_error(req, ret);
2829
tevent_req_post(req, ev);
2833
static void sysdb_store_group_check(struct tevent_req *subreq)
2835
struct tevent_req *req = tevent_req_callback_data(subreq,
2837
struct sysdb_store_group_state *state = tevent_req_data(req,
2838
struct sysdb_store_group_state);
2839
struct ldb_message *msg;
2840
time_t now = time(NULL);
2841
bool new_group = false;
2844
ret = sysdb_search_group_recv(subreq, state, &msg);
2845
talloc_zfree(subreq);
2846
if (ret && ret != ENOENT) {
2847
tevent_req_error(req, ret);
2850
if (ret == ENOENT) {
2854
/* FIXME: use the remote modification timestamp to know if the
2855
* group needs any update */
2858
/* group doesn't exist, turn into adding a group */
2859
subreq = sysdb_add_group_send(state, state->ev, state->handle,
2860
state->domain, state->name,
2861
state->gid, state->attrs,
2862
state->cache_timeout);
2864
DEBUG(6, ("Error: Out of memory\n"));
2865
tevent_req_error(req, ENOMEM);
2868
tevent_req_set_callback(subreq, sysdb_store_group_add_done, req);
2873
/* the group exists, let's just replace attributes when set */
2875
if (!state->attrs) {
2876
state->attrs = sysdb_new_attrs(state);
2877
if (!state->attrs) {
2878
DEBUG(6, ("Error: Out of memory\n"));
2879
tevent_req_error(req, ENOMEM);
2885
ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, state->gid);
2887
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2888
tevent_req_error(req, ret);
2893
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
2895
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2896
tevent_req_error(req, ret);
2900
ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
2901
((state->cache_timeout) ?
2902
(now + state->cache_timeout) : 0));
2904
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2905
tevent_req_error(req, ret);
2909
subreq = sysdb_set_group_attr_send(state, state->ev,
2910
state->handle, state->domain,
2911
state->name, state->attrs,
2914
DEBUG(6, ("Error: Out of memory\n"));
2915
tevent_req_error(req, ENOMEM);
2918
tevent_req_set_callback(subreq, sysdb_store_group_attr_done, req);
2921
static void sysdb_store_group_add_done(struct tevent_req *subreq)
2923
struct tevent_req *req = tevent_req_callback_data(subreq,
2927
ret = sysdb_add_group_recv(subreq);
2928
talloc_zfree(subreq);
2930
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2931
tevent_req_error(req, ret);
2935
tevent_req_done(req);
2938
static void sysdb_store_group_attr_done(struct tevent_req *subreq)
2940
struct tevent_req *req = tevent_req_callback_data(subreq,
2944
ret = sysdb_set_group_attr_recv(subreq);
2945
talloc_zfree(subreq);
2947
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
2948
tevent_req_error(req, ret);
2952
tevent_req_done(req);
2955
int sysdb_store_group_recv(struct tevent_req *req)
2957
return sysdb_op_default_recv(req);
2961
/* =Add-User-to-Group(Native/Legacy)====================================== */
2963
static void sysdb_add_group_member_done(struct tevent_req *subreq);
2965
struct tevent_req *sysdb_add_group_member_send(TALLOC_CTX *mem_ctx,
2966
struct tevent_context *ev,
2967
struct sysdb_handle *handle,
2968
struct sss_domain_info *domain,
2972
struct tevent_req *req, *subreq;
2973
struct sysdb_op_state *state;
2974
struct ldb_dn *group_dn, *user_dn;
2977
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
2978
if (!req) return NULL;
2981
state->handle = handle;
2982
state->ignore_not_found = false;
2983
state->ldbreply = NULL;
2985
group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group);
2987
ERROR_OUT(ret, ENOMEM, fail);
2990
user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user);
2992
ERROR_OUT(ret, ENOMEM, fail);
2995
subreq = sysdb_mod_group_member_send(state, ev, handle,
2999
ERROR_OUT(ret, ENOMEM, fail);
3001
tevent_req_set_callback(subreq, sysdb_add_group_member_done, req);
3006
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3007
tevent_req_error(req, ret);
3008
tevent_req_post(req, ev);
3012
static void sysdb_add_group_member_done(struct tevent_req *subreq)
3014
struct tevent_req *req = tevent_req_callback_data(subreq,
3018
ret = sysdb_mod_group_member_recv(subreq);
3019
talloc_zfree(subreq);
3021
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3022
tevent_req_error(req, ret);
3026
tevent_req_done(req);
3029
int sysdb_add_group_member_recv(struct tevent_req *req)
3031
return sysdb_op_default_recv(req);
3035
/* =Remove-member-from-Group(Native/Legacy)=============================== */
3037
static void sysdb_remove_group_member_done(struct tevent_req *subreq);
3039
struct tevent_req *sysdb_remove_group_member_send(TALLOC_CTX *mem_ctx,
3040
struct tevent_context *ev,
3041
struct sysdb_handle *handle,
3042
struct sss_domain_info *domain,
3046
struct tevent_req *req, *subreq;
3047
struct sysdb_op_state *state;
3048
struct ldb_dn *group_dn, *user_dn;
3051
req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
3052
if (!req) return NULL;
3055
state->handle = handle;
3056
state->ignore_not_found = false;
3057
state->ldbreply = NULL;
3059
group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group);
3061
ERROR_OUT(ret, ENOMEM, fail);
3064
user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user);
3066
ERROR_OUT(ret, ENOMEM, fail);
3069
subreq = sysdb_mod_group_member_send(state, ev, handle,
3073
ERROR_OUT(ret, ENOMEM, fail);
3075
tevent_req_set_callback(subreq, sysdb_remove_group_member_done, req);
3080
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3081
tevent_req_error(req, ret);
3082
tevent_req_post(req, ev);
3086
static void sysdb_remove_group_member_done(struct tevent_req *subreq)
3088
struct tevent_req *req = tevent_req_callback_data(subreq,
3092
ret = sysdb_mod_group_member_recv(subreq);
3093
talloc_zfree(subreq);
3095
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3096
tevent_req_error(req, ret);
3100
tevent_req_done(req);
3103
int sysdb_remove_group_member_recv(struct tevent_req *req)
3105
return sysdb_op_default_recv(req);
3109
/* =Password-Caching====================================================== */
3111
struct sysdb_cache_pw_state {
3112
struct tevent_context *ev;
3113
struct sss_domain_info *domain;
3115
const char *username;
3116
struct sysdb_attrs *attrs;
3118
struct sysdb_handle *handle;
3122
static void sysdb_cache_password_trans(struct tevent_req *subreq);
3123
static void sysdb_cache_password_done(struct tevent_req *subreq);
3125
struct tevent_req *sysdb_cache_password_send(TALLOC_CTX *mem_ctx,
3126
struct tevent_context *ev,
3127
struct sysdb_ctx *sysdb,
3128
struct sysdb_handle *handle,
3129
struct sss_domain_info *domain,
3130
const char *username,
3131
const char *password)
3133
struct tevent_req *req, *subreq;
3134
struct sysdb_cache_pw_state *state;
3139
req = tevent_req_create(mem_ctx, &state, struct sysdb_cache_pw_state);
3140
if (!req) return NULL;
3143
state->domain = domain;
3144
state->username = username;
3146
ret = s3crypt_gen_salt(state, &salt);
3148
DEBUG(4, ("Failed to generate random salt.\n"));
3152
ret = s3crypt_sha512(state, password, salt, &hash);
3154
DEBUG(4, ("Failed to create password hash.\n"));
3158
state->attrs = sysdb_new_attrs(state);
3159
if (!state->attrs) {
3160
ERROR_OUT(ret, ENOMEM, fail);
3163
ret = sysdb_attrs_add_string(state->attrs, SYSDB_CACHEDPWD, hash);
3166
/* FIXME: should we use a different attribute for chache passwords ?? */
3167
ret = sysdb_attrs_add_long(state->attrs, "lastCachedPasswordChange",
3171
state->handle = NULL;
3174
state->handle = handle;
3175
state->commit = false;
3177
subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
3178
state->domain, state->username,
3179
state->attrs, SYSDB_MOD_REP);
3181
ERROR_OUT(ret, ENOMEM, fail);
3183
tevent_req_set_callback(subreq, sysdb_cache_password_done, req);
3185
state->commit = true;
3187
subreq = sysdb_transaction_send(state, state->ev, sysdb);
3192
tevent_req_set_callback(subreq, sysdb_cache_password_trans, req);
3198
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3199
tevent_req_error(req, ret);
3200
tevent_req_post(req, ev);
3204
static void sysdb_cache_password_trans(struct tevent_req *subreq)
3206
struct tevent_req *req = tevent_req_callback_data(subreq,
3208
struct sysdb_cache_pw_state *state = tevent_req_data(req,
3209
struct sysdb_cache_pw_state);
3212
ret = sysdb_transaction_recv(subreq, state, &state->handle);
3213
talloc_zfree(subreq);
3215
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3216
tevent_req_error(req, ret);
3220
subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
3221
state->domain, state->username,
3222
state->attrs, SYSDB_MOD_REP);
3224
DEBUG(6, ("Error: Out of memory\n"));
3225
tevent_req_error(req, ENOMEM);
3228
tevent_req_set_callback(subreq, sysdb_cache_password_done, req);
3231
static void sysdb_cache_password_done(struct tevent_req *subreq)
3233
struct tevent_req *req = tevent_req_callback_data(subreq,
3235
struct sysdb_cache_pw_state *state = tevent_req_data(req,
3236
struct sysdb_cache_pw_state);
3239
ret = sysdb_set_user_attr_recv(subreq);
3240
talloc_zfree(subreq);
3242
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3243
tevent_req_error(req, ret);
3247
if (state->commit) {
3248
subreq = sysdb_transaction_commit_send(state, state->ev,
3251
DEBUG(6, ("Error: Out of memory\n"));
3252
tevent_req_error(req, ENOMEM);
3255
tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
3259
tevent_req_done(req);
3262
int sysdb_cache_password_recv(struct tevent_req *req)
3264
return sysdb_op_default_recv(req);
3267
/* = sysdb_check_handle ================== */
3268
struct sysdb_check_handle_state {
3269
struct tevent_context *ev;
3270
struct sysdb_handle *handle;
3273
static void sysdb_check_handle_done(struct tevent_req *subreq);
3275
struct tevent_req *sysdb_check_handle_send(TALLOC_CTX *mem_ctx,
3276
struct tevent_context *ev,
3277
struct sysdb_ctx *sysdb,
3278
struct sysdb_handle *handle)
3280
struct tevent_req *req;
3281
struct tevent_req *subreq;
3282
struct sysdb_check_handle_state *state;
3284
if (sysdb == NULL && handle == NULL) {
3285
DEBUG(1, ("Sysdb context not available.\n"));
3289
req = tevent_req_create(mem_ctx, &state, struct sysdb_check_handle_state);
3291
DEBUG(1, ("tevent_req_create failed.\n"));
3297
if (handle != NULL) {
3298
state->handle = talloc_memdup(state, handle, sizeof(struct sysdb_handle));
3299
if (state->handle == NULL) {
3300
DEBUG(1, ("talloc_memdup failed.\n"));
3301
tevent_req_error(req, ENOMEM);
3303
tevent_req_done(req);
3305
tevent_req_post(req, ev);
3309
state->handle = NULL;
3311
subreq = sysdb_operation_send(state, state->ev, sysdb);
3313
DEBUG(1, ("sysdb_operation_send failed.\n"));
3314
tevent_req_error(req, ENOMEM);
3315
tevent_req_post(req, ev);
3318
tevent_req_set_callback(subreq, sysdb_check_handle_done, req);
3323
static void sysdb_check_handle_done(struct tevent_req *subreq)
3325
struct tevent_req *req = tevent_req_callback_data(subreq,
3327
struct sysdb_check_handle_state *state = tevent_req_data(req,
3328
struct sysdb_check_handle_state);
3331
ret = sysdb_operation_recv(subreq, state, &state->handle);
3332
talloc_zfree(subreq);
3334
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3335
tevent_req_error(req, ret);
3339
tevent_req_done(req);
3343
int sysdb_check_handle_recv(struct tevent_req *req, TALLOC_CTX *memctx,
3344
struct sysdb_handle **handle)
3346
struct sysdb_check_handle_state *state = tevent_req_data(req,
3347
struct sysdb_check_handle_state);
3349
TEVENT_REQ_RETURN_ON_ERROR(req);
3351
*handle = talloc_move(memctx, &state->handle);
3357
/* =Custom Search================== */
3358
struct sysdb_search_custom_state {
3359
struct tevent_context *ev;
3360
struct sysdb_handle *handle;
3362
struct ldb_dn *basedn;
3366
bool expect_not_more_than_one;
3369
struct ldb_message **msgs;
3372
static void sysdb_search_custom_check_handle_done(struct tevent_req *subreq);
3373
static void sysdb_search_custom_done(struct tevent_req *subreq);
3375
struct tevent_req *sysdb_search_custom_send(TALLOC_CTX *mem_ctx,
3376
struct tevent_context *ev,
3377
struct sysdb_ctx *sysdb,
3378
struct sysdb_handle *handle,
3379
struct sss_domain_info *domain,
3381
const char *subtree_name,
3384
struct tevent_req *req, *subreq;
3385
struct sysdb_search_custom_state *state;
3388
if (sysdb == NULL && handle == NULL) return NULL;
3390
if (filter == NULL || subtree_name == NULL) return NULL;
3392
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_custom_state);
3394
DEBUG(1, ("tevent_req_create failed.\n"));
3399
state->handle = handle;
3400
state->attrs = attrs;
3401
state->filter = filter;
3402
state->scope = LDB_SCOPE_SUBTREE;
3403
state->expect_not_more_than_one = false;
3404
state->msgs_count = 0;
3407
if (sysdb == NULL) {
3408
sysdb = handle->ctx;
3410
state->basedn = sysdb_custom_subtree_dn(sysdb, state, domain->name,
3412
if (state->basedn == NULL) {
3413
DEBUG(1, ("sysdb_custom_subtree_dn failed.\n"));
3417
if (!ldb_dn_validate(state->basedn)) {
3418
DEBUG(1, ("Failed to create DN.\n"));
3423
subreq = sysdb_check_handle_send(state, state->ev, sysdb, state->handle);
3425
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
3429
tevent_req_set_callback(subreq, sysdb_search_custom_check_handle_done, req);
3434
tevent_req_error(req, ret);
3435
tevent_req_post(req, ev);
3439
struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx,
3440
struct tevent_context *ev,
3441
struct sysdb_ctx *sysdb,
3442
struct sysdb_handle *handle,
3443
struct sss_domain_info *domain,
3444
const char *object_name,
3445
const char *subtree_name,
3448
struct tevent_req *req, *subreq;
3449
struct sysdb_search_custom_state *state;
3452
if (sysdb == NULL && handle == NULL) return NULL;
3454
if (object_name == NULL || subtree_name == NULL) return NULL;
3456
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_custom_state);
3458
DEBUG(1, ("tevent_req_create failed.\n"));
3463
state->handle = handle;
3464
state->attrs = attrs;
3465
state->filter = NULL;
3466
state->scope = LDB_SCOPE_BASE;
3467
state->expect_not_more_than_one = true;
3468
state->msgs_count = 0;
3471
if (sysdb == NULL) {
3472
sysdb = handle->ctx;
3474
state->basedn = sysdb_custom_dn(sysdb, state, domain->name, object_name,
3476
if (state->basedn == NULL) {
3477
DEBUG(1, ("sysdb_custom_dn failed.\n"));
3481
if (!ldb_dn_validate(state->basedn)) {
3482
DEBUG(1, ("Failed to create DN.\n"));
3487
subreq = sysdb_check_handle_send(state, state->ev, sysdb, state->handle);
3489
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
3493
tevent_req_set_callback(subreq, sysdb_search_custom_check_handle_done, req);
3498
tevent_req_error(req, ret);
3499
tevent_req_post(req, ev);
3503
static void sysdb_search_custom_check_handle_done(struct tevent_req *subreq)
3505
struct tevent_req *req = tevent_req_callback_data(subreq,
3507
struct sysdb_search_custom_state *state = tevent_req_data(req,
3508
struct sysdb_search_custom_state);
3511
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
3512
talloc_zfree(subreq);
3514
tevent_req_error(req, ret);
3518
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
3519
state->basedn, state->scope,
3520
state->filter, state->attrs);
3522
DEBUG(1, ("sysdb_search_entry_send failed.\n"));
3523
tevent_req_error(req, ENOMEM);
3526
tevent_req_set_callback(subreq, sysdb_search_custom_done, req);
3530
static void sysdb_search_custom_done(struct tevent_req *subreq)
3532
struct tevent_req *req = tevent_req_callback_data(subreq,
3534
struct sysdb_search_custom_state *state = tevent_req_data(req,
3535
struct sysdb_search_custom_state);
3538
ret = sysdb_search_entry_recv(subreq, state, &state->msgs_count,
3540
talloc_zfree(subreq);
3542
tevent_req_error(req, ret);
3546
if (state->expect_not_more_than_one && state->msgs_count > 1) {
3547
DEBUG(1, ("More than one result found.\n"));
3548
tevent_req_error(req, EFAULT);
3552
tevent_req_done(req);
3555
int sysdb_search_custom_recv(struct tevent_req *req,
3556
TALLOC_CTX *mem_ctx,
3558
struct ldb_message ***msgs)
3560
struct sysdb_search_custom_state *state = tevent_req_data(req,
3561
struct sysdb_search_custom_state);
3563
TEVENT_REQ_RETURN_ON_ERROR(req);
3565
*msgs_count = state->msgs_count;
3566
*msgs = talloc_move(mem_ctx, &state->msgs);
3572
/* =Custom Store (replaces-existing-data)================== */
3574
struct sysdb_store_custom_state {
3575
struct tevent_context *ev;
3576
struct sysdb_handle *handle;
3577
struct sss_domain_info *domain;
3579
const char *object_name;
3580
const char *subtree_name;
3582
struct sysdb_attrs *attrs;
3583
struct ldb_message *msg;
3586
static void sysdb_store_custom_check_done(struct tevent_req *subreq);
3587
static void sysdb_store_custom_done(struct tevent_req *subreq);
3589
struct tevent_req *sysdb_store_custom_send(TALLOC_CTX *mem_ctx,
3590
struct tevent_context *ev,
3591
struct sysdb_handle *handle,
3592
struct sss_domain_info *domain,
3593
const char *object_name,
3594
const char *subtree_name,
3595
struct sysdb_attrs *attrs)
3597
struct tevent_req *req, *subreq;
3598
struct sysdb_store_custom_state *state;
3600
const char **search_attrs;
3602
if (object_name == NULL || subtree_name == NULL) return NULL;
3604
if (handle == NULL) {
3605
DEBUG(1, ("Sysdb context not available.\n"));
3609
req = tevent_req_create(mem_ctx, &state, struct sysdb_store_custom_state);
3611
DEBUG(1, ("tevent_req_create failed.\n"));
3616
state->handle = handle;
3617
state->domain = domain;
3618
state->object_name = object_name;
3619
state->subtree_name = subtree_name;
3620
state->attrs = attrs;
3622
state->dn = sysdb_custom_dn(handle->ctx, state, domain->name, object_name,
3624
if (state->dn == NULL) {
3625
DEBUG(1, ("sysdb_custom_dn failed.\n"));
3630
search_attrs = talloc_array(state, const char *, 2);
3631
if (search_attrs == NULL) {
3632
DEBUG(1, ("talloc_array failed.\n"));
3636
search_attrs[0] = "*";
3637
search_attrs[1] = NULL;
3639
subreq = sysdb_search_custom_by_name_send(state, state->ev, NULL,
3643
state->subtree_name,
3646
DEBUG(1, ("sysdb_search_custom_by_name_send failed.\n"));
3650
tevent_req_set_callback(subreq, sysdb_store_custom_check_done, req);
3654
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3655
tevent_req_error(req, ret);
3656
tevent_req_post(req, ev);
3660
static void sysdb_store_custom_check_done(struct tevent_req *subreq)
3662
struct tevent_req *req = tevent_req_callback_data(subreq,
3664
struct sysdb_store_custom_state *state = tevent_req_data(req,
3665
struct sysdb_store_custom_state);
3668
size_t resp_count = 0;
3669
struct ldb_message **resp;
3670
struct ldb_message *msg;
3671
struct ldb_request *ldbreq;
3672
struct ldb_message_element *el;
3673
bool add_object = false;
3675
ret = sysdb_search_custom_recv(subreq, state, &resp_count, &resp);
3676
talloc_zfree(subreq);
3677
if (ret != EOK && ret != ENOENT) {
3678
tevent_req_error(req, ret);
3682
if (ret == ENOENT) {
3686
msg = ldb_msg_new(state);
3688
tevent_req_error(req, ENOMEM);
3692
msg->dn = state->dn;
3694
msg->elements = talloc_array(msg, struct ldb_message_element,
3696
if (!msg->elements) {
3697
tevent_req_error(req, ENOMEM);
3701
for (i = 0; i < state->attrs->num; i++) {
3702
msg->elements[i] = state->attrs->a[i];
3704
msg->elements[i].flags = LDB_FLAG_MOD_ADD;
3706
el = ldb_msg_find_element(resp[0], state->attrs->a[i].name);
3708
msg->elements[i].flags = LDB_FLAG_MOD_ADD;
3710
msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
3714
msg->num_elements = state->attrs->num;
3717
ret = ldb_build_add_req(&ldbreq, state->handle->ctx->ldb, state, msg,
3718
NULL, NULL, NULL, NULL);
3720
ret = ldb_build_mod_req(&ldbreq, state->handle->ctx->ldb, state, msg,
3721
NULL, NULL, NULL, NULL);
3723
if (ret != LDB_SUCCESS) {
3724
DEBUG(1, ("Failed to build request: %s(%d)[%s]\n",
3725
ldb_strerror(ret), ret,
3726
ldb_errstring(state->handle->ctx->ldb)));
3727
tevent_req_error(req, sysdb_error_to_errno(ret));
3731
subreq = sldb_request_send(state, state->ev, state->handle->ctx->ldb,
3734
tevent_req_error(req, ENOMEM);
3737
tevent_req_set_callback(subreq, sysdb_store_custom_done, req);
3741
static void sysdb_store_custom_done(struct tevent_req *subreq)
3743
struct tevent_req *req = tevent_req_callback_data(subreq,
3747
ret = sysdb_op_default_recv(subreq);
3748
talloc_zfree(subreq);
3750
tevent_req_error(req, ret);
3754
tevent_req_done(req);
3758
int sysdb_store_custom_recv(struct tevent_req *req)
3760
TEVENT_REQ_RETURN_ON_ERROR(req);
3765
/* = Custom Delete======================================= */
3767
struct sysdb_delete_custom_state {
3768
struct tevent_context *ev;
3769
struct sysdb_handle *handle;
3770
struct sss_domain_info *domain;
3772
const char *object_name;
3773
const char *subtree_name;
3776
static void sysdb_delete_custom_done(struct tevent_req *subreq);
3778
struct tevent_req *sysdb_delete_custom_send(TALLOC_CTX *mem_ctx,
3779
struct tevent_context *ev,
3780
struct sysdb_handle *handle,
3781
struct sss_domain_info *domain,
3782
const char *object_name,
3783
const char *subtree_name)
3785
struct tevent_req *req, *subreq;
3786
struct sysdb_delete_custom_state *state;
3789
if (object_name == NULL || subtree_name == NULL) return NULL;
3791
if (handle == NULL) {
3792
DEBUG(1, ("Sysdb context not available.\n"));
3796
req = tevent_req_create(mem_ctx, &state, struct sysdb_store_custom_state);
3798
DEBUG(1, ("tevent_req_create failed.\n"));
3803
state->handle = handle;
3804
state->domain = domain;
3805
state->object_name = object_name;
3806
state->subtree_name = subtree_name;
3807
state->dn = sysdb_custom_dn(handle->ctx, state, domain->name, object_name,
3809
if (state->dn == NULL) {
3810
DEBUG(1, ("sysdb_custom_dn failed.\n"));
3815
subreq = sysdb_delete_entry_send(state, state->ev, state->handle,
3818
DEBUG(1, ("sysdb_delete_entry_send failed.\n"));
3822
tevent_req_set_callback(subreq, sysdb_delete_custom_done, req);
3826
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
3827
tevent_req_error(req, ret);
3828
tevent_req_post(req, ev);
3832
static void sysdb_delete_custom_done(struct tevent_req *subreq)
3834
struct tevent_req *req = tevent_req_callback_data(subreq,
3838
ret = sysdb_delete_entry_recv(subreq);
3839
talloc_zfree(subreq);
3841
tevent_req_error(req, ret);
3845
tevent_req_done(req);
3849
int sysdb_delete_custom_recv(struct tevent_req *req)
3851
TEVENT_REQ_RETURN_ON_ERROR(req);
3856
/* = ASQ search request ======================================== */
3857
struct sysdb_asq_search_state {
3858
struct tevent_context *ev;
3859
struct sysdb_ctx *sysdb;
3860
struct sysdb_handle *handle;
3861
struct sss_domain_info *domain;
3862
struct ldb_dn *base_dn;
3863
const char *asq_attribute;
3865
const char *expression;
3868
struct ldb_message **msgs;
3871
void sysdb_asq_search_check_handle_done(struct tevent_req *subreq);
3872
static void sysdb_asq_search_done(struct tevent_req *subreq);
3874
struct tevent_req *sysdb_asq_search_send(TALLOC_CTX *mem_ctx,
3875
struct tevent_context *ev,
3876
struct sysdb_ctx *sysdb,
3877
struct sysdb_handle *handle,
3878
struct sss_domain_info *domain,
3879
struct ldb_dn *base_dn,
3880
const char *expression,
3881
const char *asq_attribute,
3884
struct tevent_req *req;
3885
struct tevent_req *subreq;
3886
struct sysdb_asq_search_state *state;
3889
if (sysdb == NULL && handle == NULL) {
3890
DEBUG(1, ("Sysdb context not available.\n"));
3894
req = tevent_req_create(mem_ctx, &state, struct sysdb_asq_search_state);
3896
DEBUG(1, ("tevent_req_create failed.\n"));
3901
state->sysdb = (sysdb == NULL) ? handle->ctx : sysdb;
3902
state->handle = handle;
3903
state->domain = domain;
3904
state->base_dn = base_dn;
3905
state->expression = expression;
3906
state->asq_attribute = asq_attribute;
3907
state->attrs = attrs;
3909
state->msgs_count = 0;
3912
subreq = sysdb_check_handle_send(state, state->ev, state->sysdb,
3915
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
3919
tevent_req_set_callback(subreq, sysdb_asq_search_check_handle_done, req);
3924
tevent_req_error(req, ret);
3925
tevent_req_post(req, ev);
3929
void sysdb_asq_search_check_handle_done(struct tevent_req *subreq)
3931
struct tevent_req *req = tevent_req_callback_data(subreq,
3933
struct sysdb_asq_search_state *state = tevent_req_data(req,
3934
struct sysdb_asq_search_state);
3935
struct ldb_request *ldb_req;
3936
struct ldb_control **ctrl;
3937
struct ldb_asq_control *asq_control;
3940
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
3941
talloc_zfree(subreq);
3943
tevent_req_error(req, ret);
3947
ctrl = talloc_array(state, struct ldb_control *, 2);
3953
ctrl[0] = talloc(ctrl, struct ldb_control);
3954
if (ctrl[0] == NULL) {
3960
ctrl[0]->oid = LDB_CONTROL_ASQ_OID;
3961
ctrl[0]->critical = 1;
3963
asq_control = talloc(ctrl[0], struct ldb_asq_control);
3964
if (asq_control == NULL) {
3969
asq_control->request = 1;
3970
asq_control->source_attribute = talloc_strdup(asq_control,
3971
state->asq_attribute);
3972
if (asq_control->source_attribute == NULL) {
3976
asq_control->src_attr_len = strlen(asq_control->source_attribute);
3977
ctrl[0]->data = asq_control;
3979
ret = ldb_build_search_req(&ldb_req, state->handle->ctx->ldb, state,
3980
state->base_dn, LDB_SCOPE_BASE,
3981
state->expression, state->attrs, ctrl,
3983
if (ret != LDB_SUCCESS) {
3984
ret = sysdb_error_to_errno(ret);
3988
subreq = sldb_request_send(state, state->ev, state->handle->ctx->ldb,
3995
tevent_req_set_callback(subreq, sysdb_asq_search_done, req);
3999
tevent_req_error(req, ret);
4003
static void sysdb_asq_search_done(struct tevent_req *subreq)
4005
struct tevent_req *req = tevent_req_callback_data(subreq,
4007
struct sysdb_asq_search_state *state = tevent_req_data(req,
4008
struct sysdb_asq_search_state);
4009
struct ldb_reply *ldbreply;
4012
ret = sldb_request_recv(subreq, state, &ldbreply);
4013
/* DO NOT free the subreq here, the subrequest search is not
4014
* finished until we get an ldbreply of type LDB_REPLY_DONE */
4016
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
4017
tevent_req_error(req, ret);
4021
switch (ldbreply->type) {
4022
case LDB_REPLY_ENTRY:
4023
state->msgs = talloc_realloc(state, state->msgs,
4024
struct ldb_message *,
4025
state->msgs_count + 2);
4026
if (state->msgs == NULL) {
4027
tevent_req_error(req, ENOMEM);
4031
state->msgs[state->msgs_count + 1] = NULL;
4033
state->msgs[state->msgs_count] = talloc_steal(state->msgs,
4035
state->msgs_count++;
4037
talloc_zfree(ldbreply);
4040
case LDB_REPLY_DONE:
4041
/* now it is safe to free the subrequest, the search is complete */
4042
talloc_zfree(subreq);
4046
DEBUG(1, ("Unknown ldb reply type [%d].\n", ldbreply->type));
4047
tevent_req_error(req, EINVAL);
4051
tevent_req_done(req);
4054
int sysdb_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
4055
size_t *msgs_count, struct ldb_message ***msgs)
4057
struct sysdb_asq_search_state *state = tevent_req_data(req,
4058
struct sysdb_asq_search_state);
4060
TEVENT_REQ_RETURN_ON_ERROR(req);
4062
*msgs_count = state->msgs_count;
4063
*msgs = talloc_move(mem_ctx, &state->msgs);
4068
/* =Search-Users-with-Custom-Filter====================================== */
4070
struct sysdb_search_users_state {
4071
struct tevent_context *ev;
4072
struct sysdb_handle *handle;
4073
struct sss_domain_info *domain;
4074
const char *sub_filter;
4077
struct ldb_message **msgs;
4081
void sysdb_search_users_check_handle(struct tevent_req *subreq);
4082
static void sysdb_search_users_done(struct tevent_req *subreq);
4084
struct tevent_req *sysdb_search_users_send(TALLOC_CTX *mem_ctx,
4085
struct tevent_context *ev,
4086
struct sysdb_ctx *sysdb,
4087
struct sysdb_handle *handle,
4088
struct sss_domain_info *domain,
4089
const char *sub_filter,
4092
struct tevent_req *req, *subreq;
4093
struct sysdb_search_users_state *state;
4096
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_users_state);
4098
DEBUG(1, ("tevent_req_create failed.\n"));
4103
state->handle = handle;
4104
state->domain = domain;
4105
state->sub_filter = sub_filter;
4106
state->attrs = attrs;
4108
state->msgs_count = 0;
4111
subreq = sysdb_check_handle_send(state, ev, sysdb, handle);
4113
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
4117
tevent_req_set_callback(subreq, sysdb_search_users_check_handle, req);
4122
tevent_req_error(req, ret);
4123
tevent_req_post(req, ev);
4127
void sysdb_search_users_check_handle(struct tevent_req *subreq)
4129
struct tevent_req *req = tevent_req_callback_data(subreq,
4131
struct sysdb_search_users_state *state = tevent_req_data(req,
4132
struct sysdb_search_users_state);
4133
struct ldb_dn *basedn;
4137
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
4138
talloc_zfree(subreq);
4140
tevent_req_error(req, ret);
4144
basedn = ldb_dn_new_fmt(state, state->handle->ctx->ldb,
4145
SYSDB_TMPL_USER_BASE, state->domain->name);
4147
DEBUG(2, ("Failed to build base dn\n"));
4148
tevent_req_error(req, ENOMEM);
4152
filter = talloc_asprintf(state, "(&(%s)%s)",
4153
SYSDB_UC, state->sub_filter);
4155
DEBUG(2, ("Failed to build filter\n"));
4156
tevent_req_error(req, ENOMEM);
4160
DEBUG(6, ("Search users with filter: %s\n", filter));
4162
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
4163
basedn, LDB_SCOPE_SUBTREE,
4164
filter, state->attrs);
4166
tevent_req_error(req, ENOMEM);
4169
tevent_req_set_callback(subreq, sysdb_search_users_done, req);
4172
static void sysdb_search_users_done(struct tevent_req *subreq)
4174
struct tevent_req *req = tevent_req_callback_data(subreq,
4176
struct sysdb_search_users_state *state = tevent_req_data(req,
4177
struct sysdb_search_users_state);
4180
ret = sysdb_search_entry_recv(subreq, state,
4181
&state->msgs_count, &state->msgs);
4182
talloc_zfree(subreq);
4184
tevent_req_error(req, ret);
4188
tevent_req_done(req);
4191
int sysdb_search_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
4192
size_t *msgs_count, struct ldb_message ***msgs)
4194
struct sysdb_search_users_state *state = tevent_req_data(req,
4195
struct sysdb_search_users_state);
4197
TEVENT_REQ_RETURN_ON_ERROR(req);
4199
*msgs_count = state->msgs_count;
4200
*msgs = talloc_move(mem_ctx, &state->msgs);
4205
/* =Delete-User-by-Name-OR-uid============================================ */
4207
struct sysdb_delete_user_state {
4208
struct tevent_context *ev;
4209
struct sss_domain_info *domain;
4214
struct sysdb_handle *handle;
4217
void sysdb_delete_user_check_handle(struct tevent_req *subreq);
4218
static void sysdb_delete_user_found(struct tevent_req *subreq);
4219
static void sysdb_delete_user_done(struct tevent_req *subreq);
4221
struct tevent_req *sysdb_delete_user_send(TALLOC_CTX *mem_ctx,
4222
struct tevent_context *ev,
4223
struct sysdb_ctx *sysdb,
4224
struct sysdb_handle *handle,
4225
struct sss_domain_info *domain,
4226
const char *name, uid_t uid)
4228
struct tevent_req *req, *subreq;
4229
struct sysdb_delete_user_state *state;
4231
req = tevent_req_create(mem_ctx, &state, struct sysdb_delete_user_state);
4232
if (!req) return NULL;
4235
state->handle = handle;
4236
state->domain = domain;
4240
subreq = sysdb_check_handle_send(state, ev, sysdb, handle);
4242
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
4243
tevent_req_error(req, ENOMEM);
4244
tevent_req_post(req, ev);
4247
tevent_req_set_callback(subreq, sysdb_delete_user_check_handle, req);
4252
void sysdb_delete_user_check_handle(struct tevent_req *subreq)
4254
struct tevent_req *req = tevent_req_callback_data(subreq,
4256
struct sysdb_delete_user_state *state = tevent_req_data(req,
4257
struct sysdb_delete_user_state);
4258
static const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL };
4261
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
4262
talloc_zfree(subreq);
4264
tevent_req_error(req, ret);
4269
subreq = sysdb_search_user_by_name_send(state, state->ev, NULL,
4270
state->handle, state->domain,
4271
state->name, attrs);
4273
subreq = sysdb_search_user_by_uid_send(state, state->ev, NULL,
4274
state->handle, state->domain,
4279
tevent_req_error(req, ENOMEM);
4282
tevent_req_set_callback(subreq, sysdb_delete_user_found, req);
4285
static void sysdb_delete_user_found(struct tevent_req *subreq)
4287
struct tevent_req *req = tevent_req_callback_data(subreq,
4289
struct sysdb_delete_user_state *state = tevent_req_data(req,
4290
struct sysdb_delete_user_state);
4291
struct ldb_message *msg;
4294
ret = sysdb_search_user_recv(subreq, state, &msg);
4295
talloc_zfree(subreq);
4297
tevent_req_error(req, ret);
4301
if (state->name && state->uid) {
4302
/* verify name/gid match */
4306
name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
4307
uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
4308
if (name == NULL || uid == 0) {
4309
DEBUG(2, ("Attribute is missing but this should never happen!\n"));
4310
tevent_req_error(req, EFAULT);
4313
if (strcmp(state->name, name) || state->uid != uid) {
4314
/* this is not the entry we are looking for */
4315
tevent_req_error(req, EINVAL);
4320
subreq = sysdb_delete_entry_send(state, state->ev,
4321
state->handle, msg->dn, false);
4323
DEBUG(6, ("Error: Out of memory\n"));
4324
tevent_req_error(req, ENOMEM);
4327
tevent_req_set_callback(subreq, sysdb_delete_user_done, req);
4330
static void sysdb_delete_user_done(struct tevent_req *subreq)
4332
struct tevent_req *req = tevent_req_callback_data(subreq,
4336
ret = sysdb_delete_entry_recv(subreq);
4337
talloc_zfree(subreq);
4339
tevent_req_error(req, ret);
4343
tevent_req_done(req);
4346
int sysdb_delete_user_recv(struct tevent_req *req)
4348
return sysdb_op_default_recv(req);
4352
/* =Search-Groups-with-Custom-Filter===================================== */
4354
struct sysdb_search_groups_state {
4355
struct tevent_context *ev;
4356
struct sysdb_handle *handle;
4357
struct sss_domain_info *domain;
4358
const char *sub_filter;
4361
struct ldb_message **msgs;
4365
void sysdb_search_groups_check_handle(struct tevent_req *subreq);
4366
static void sysdb_search_groups_done(struct tevent_req *subreq);
4368
struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx,
4369
struct tevent_context *ev,
4370
struct sysdb_ctx *sysdb,
4371
struct sysdb_handle *handle,
4372
struct sss_domain_info *domain,
4373
const char *sub_filter,
4376
struct tevent_req *req, *subreq;
4377
struct sysdb_search_groups_state *state;
4380
req = tevent_req_create(mem_ctx, &state, struct sysdb_search_groups_state);
4382
DEBUG(1, ("tevent_req_create failed.\n"));
4387
state->handle = handle;
4388
state->domain = domain;
4389
state->sub_filter = sub_filter;
4390
state->attrs = attrs;
4392
state->msgs_count = 0;
4395
subreq = sysdb_check_handle_send(state, ev, sysdb, handle);
4397
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
4401
tevent_req_set_callback(subreq, sysdb_search_groups_check_handle, req);
4406
tevent_req_error(req, ret);
4407
tevent_req_post(req, ev);
4411
void sysdb_search_groups_check_handle(struct tevent_req *subreq)
4413
struct tevent_req *req = tevent_req_callback_data(subreq,
4415
struct sysdb_search_groups_state *state = tevent_req_data(req,
4416
struct sysdb_search_groups_state);
4417
struct ldb_dn *basedn;
4421
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
4422
talloc_zfree(subreq);
4424
tevent_req_error(req, ret);
4428
basedn = ldb_dn_new_fmt(state, state->handle->ctx->ldb,
4429
SYSDB_TMPL_GROUP_BASE, state->domain->name);
4431
DEBUG(2, ("Failed to build base dn\n"));
4432
tevent_req_error(req, ENOMEM);
4436
filter = talloc_asprintf(state, "(&(%s)%s)",
4437
SYSDB_GC, state->sub_filter);
4439
DEBUG(2, ("Failed to build filter\n"));
4440
tevent_req_error(req, ENOMEM);
4444
DEBUG(6, ("Search groups with filter: %s\n", filter));
4446
subreq = sysdb_search_entry_send(state, state->ev, state->handle,
4447
basedn, LDB_SCOPE_SUBTREE,
4448
filter, state->attrs);
4450
tevent_req_error(req, ENOMEM);
4453
tevent_req_set_callback(subreq, sysdb_search_groups_done, req);
4456
static void sysdb_search_groups_done(struct tevent_req *subreq)
4458
struct tevent_req *req = tevent_req_callback_data(subreq,
4460
struct sysdb_search_groups_state *state = tevent_req_data(req,
4461
struct sysdb_search_groups_state);
4464
ret = sysdb_search_entry_recv(subreq, state,
4465
&state->msgs_count, &state->msgs);
4466
talloc_zfree(subreq);
4468
tevent_req_error(req, ret);
4472
tevent_req_done(req);
4475
int sysdb_search_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
4476
size_t *msgs_count, struct ldb_message ***msgs)
4478
struct sysdb_search_groups_state *state = tevent_req_data(req,
4479
struct sysdb_search_groups_state);
4481
TEVENT_REQ_RETURN_ON_ERROR(req);
4483
*msgs_count = state->msgs_count;
4484
*msgs = talloc_move(mem_ctx, &state->msgs);
4489
/* =Delete-Group-by-Name-OR-gid=========================================== */
4491
struct sysdb_delete_group_state {
4492
struct tevent_context *ev;
4493
struct sss_domain_info *domain;
4498
struct sysdb_handle *handle;
4501
void sysdb_delete_group_check_handle(struct tevent_req *subreq);
4502
static void sysdb_delete_group_found(struct tevent_req *subreq);
4503
static void sysdb_delete_group_done(struct tevent_req *subreq);
4505
struct tevent_req *sysdb_delete_group_send(TALLOC_CTX *mem_ctx,
4506
struct tevent_context *ev,
4507
struct sysdb_ctx *sysdb,
4508
struct sysdb_handle *handle,
4509
struct sss_domain_info *domain,
4510
const char *name, gid_t gid)
4512
struct tevent_req *req, *subreq;
4513
struct sysdb_delete_group_state *state;
4515
req = tevent_req_create(mem_ctx, &state, struct sysdb_delete_group_state);
4516
if (!req) return NULL;
4519
state->handle = handle;
4520
state->domain = domain;
4524
subreq = sysdb_check_handle_send(state, ev, sysdb, handle);
4526
DEBUG(1, ("sysdb_check_handle_send failed.\n"));
4527
tevent_req_error(req, ENOMEM);
4528
tevent_req_post(req, ev);
4531
tevent_req_set_callback(subreq, sysdb_delete_group_check_handle, req);
4536
void sysdb_delete_group_check_handle(struct tevent_req *subreq)
4538
struct tevent_req *req = tevent_req_callback_data(subreq,
4540
struct sysdb_delete_group_state *state = tevent_req_data(req,
4541
struct sysdb_delete_group_state);
4542
static const char *attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL };
4545
ret = sysdb_check_handle_recv(subreq, state, &state->handle);
4546
talloc_zfree(subreq);
4548
tevent_req_error(req, ret);
4553
subreq = sysdb_search_group_by_name_send(state, state->ev, NULL,
4554
state->handle, state->domain,
4555
state->name, attrs);
4557
subreq = sysdb_search_group_by_gid_send(state, state->ev, NULL,
4558
state->handle, state->domain,
4563
tevent_req_error(req, ENOMEM);
4566
tevent_req_set_callback(subreq, sysdb_delete_group_found, req);
4569
static void sysdb_delete_group_found(struct tevent_req *subreq)
4571
struct tevent_req *req = tevent_req_callback_data(subreq,
4573
struct sysdb_delete_group_state *state = tevent_req_data(req,
4574
struct sysdb_delete_group_state);
4575
struct ldb_message *msg;
4578
ret = sysdb_search_group_recv(subreq, state, &msg);
4579
talloc_zfree(subreq);
4581
tevent_req_error(req, ret);
4585
if (state->name && state->gid) {
4586
/* verify name/gid match */
4590
name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
4591
gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);
4592
if (name == NULL || gid == 0) {
4593
DEBUG(2, ("Attribute is missing but this should never happen!\n"));
4594
tevent_req_error(req, EFAULT);
4597
if (strcmp(state->name, name) || state->gid != gid) {
4598
/* this is not the entry we are looking for */
4599
tevent_req_error(req, EINVAL);
4604
subreq = sysdb_delete_entry_send(state, state->ev,
4605
state->handle, msg->dn, false);
4607
DEBUG(6, ("Error: Out of memory\n"));
4608
tevent_req_error(req, ENOMEM);
4611
tevent_req_set_callback(subreq, sysdb_delete_group_done, req);
4614
static void sysdb_delete_group_done(struct tevent_req *subreq)
4616
struct tevent_req *req = tevent_req_callback_data(subreq,
4620
ret = sysdb_delete_entry_recv(subreq);
4621
talloc_zfree(subreq);
4623
tevent_req_error(req, ret);
4627
tevent_req_done(req);
4630
int sysdb_delete_group_recv(struct tevent_req *req)
4632
return sysdb_op_default_recv(req);