s3: Update .clang_complete
[gd/samba-autobuild/.git] / source3 / passdb / pdb_samba4.c
1 /*
2    Unix SMB/CIFS implementation.
3    pdb glue module for samba4
4    Copyright (C) Volker Lendecke 2009-2011
5    Copyright (C) Andrew Bartlett 2010
6    Copyright (C) Matthias Dieter Wallnöfer                 2009
7
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.
12
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.
17
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/>.
20 */
21
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
23
24 #include "includes.h"
25 #include "source3/include/passdb.h"
26 #include "source4/dsdb/samdb/samdb.h"
27 #include "ldb_errors.h"
28 #include "libcli/security/dom_sid.h"
29 #include "source4/winbind/idmap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libds/common/flag_mapping.h"
32 #include "source4/lib/events/events.h"
33 #include "source4/auth/session.h"
34 #include "source4/auth/system_session_proto.h"
35 #include "source4/param/param.h"
36
37 struct pdb_samba4_state {
38         struct tevent_context *ev;
39         struct ldb_context *ldb;
40         struct idmap_context *idmap_ctx;
41         struct loadparm_context *lp_ctx;
42 };
43
44 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
45                                     struct samu *sam_acct,
46                                     const struct dom_sid *sid);
47 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
48                                     const char *filter,
49                                     TALLOC_CTX *mem_ctx,
50                                     struct ldb_message **pmsg);
51 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
52                                  union unid_t *id, enum lsa_SidType *type);
53
54 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
55                               time_t *ptime)
56 {
57         uint64_t tmp;
58         if (! ldb_msg_find_element(msg, attr)) {
59                 return false;
60         }
61         tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
62         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
63         return true;
64 }
65
66 static struct pdb_domain_info *pdb_samba4_get_domain_info(
67         struct pdb_methods *m, TALLOC_CTX *mem_ctx)
68 {
69         struct pdb_samba4_state *state = talloc_get_type_abort(
70                 m->private_data, struct pdb_samba4_state);
71         struct pdb_domain_info *info;
72         struct dom_sid *domain_sid;
73         struct ldb_dn *forest_dn, *domain_dn;
74         struct ldb_result *dom_res = NULL;
75         const char *dom_attrs[] = {
76                 "objectSid", 
77                 "objectGUID", 
78                 "nTMixedDomain",
79                 "fSMORoleOwner",
80                 NULL
81         };
82         char *p;
83         int ret;
84
85         info = talloc(mem_ctx, struct pdb_domain_info);
86         if (info == NULL) {
87                 return NULL;
88         }
89
90         domain_dn = ldb_get_default_basedn(state->ldb); 
91
92         ret = ldb_search(state->ldb, info, &dom_res,
93                          domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
94         if (ret != LDB_SUCCESS) {
95                 goto fail;
96         }
97         if (dom_res->count != 1) {
98                 goto fail;
99         }
100
101         info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
102
103         domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
104         if (!domain_sid) {
105                 goto fail;
106         }
107         info->sid = *domain_sid;
108
109         TALLOC_FREE(dom_res);
110
111         info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
112         info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
113
114         if (!info->dns_domain) {
115                 goto fail;
116         }
117         p = strchr(info->dns_domain, '/');
118         if (p) {
119                 *p = '\0';
120         }
121
122         forest_dn = ldb_get_root_basedn(state->ldb);
123         if (!forest_dn) {
124                 goto fail;
125         }
126
127         info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
128         if (!info->dns_forest) {
129                 goto fail;
130         }
131         p = strchr(info->dns_forest, '/');
132         if (p) {
133                 *p = '\0';
134         }
135
136         return info;
137
138 fail:
139         TALLOC_FREE(dom_res);
140         TALLOC_FREE(info);
141         return NULL;
142 }
143
144 static struct ldb_message *pdb_samba4_get_samu_private(
145         struct pdb_methods *m, struct samu *sam)
146 {
147         struct pdb_samba4_state *state = talloc_get_type_abort(
148                 m->private_data, struct pdb_samba4_state);
149         struct ldb_message *msg;
150         char *sidstr, *filter;
151         NTSTATUS status;
152
153         msg = (struct ldb_message *)
154                 pdb_get_backend_private_data(sam, m);
155
156         if (msg != NULL) {
157                 return talloc_get_type_abort(msg, struct ldb_message);
158         }
159
160         sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
161         if (sidstr == NULL) {
162                 return NULL;
163         }
164
165         filter = talloc_asprintf(
166                 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
167         TALLOC_FREE(sidstr);
168         if (filter == NULL) {
169                 return NULL;
170         }
171
172         status = pdb_samba4_getsamupriv(state, filter, sam, &msg);
173         TALLOC_FREE(filter);
174         if (!NT_STATUS_IS_OK(status)) {
175                 return NULL;
176         }
177
178         return msg;
179 }
180
181 static NTSTATUS pdb_samba4_init_sam_from_priv(struct pdb_methods *m,
182                                            struct samu *sam,
183                                            struct ldb_message *msg)
184 {
185         struct pdb_samba4_state *state = talloc_get_type_abort(
186                 m->private_data, struct pdb_samba4_state);
187         TALLOC_CTX *frame = talloc_stackframe();
188         NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
189         const char *str;
190         time_t tmp_time;
191         struct dom_sid *sid, group_sid;
192         uint64_t n;
193         const DATA_BLOB *blob;
194
195         str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
196         if (str == NULL) {
197                 DEBUG(10, ("no samAccountName\n"));
198                 goto fail;
199         }
200         pdb_set_username(sam, str, PDB_SET);
201
202         if (pdb_samba4_pull_time(msg, "lastLogon", &tmp_time)) {
203                 pdb_set_logon_time(sam, tmp_time, PDB_SET);
204         }
205         if (pdb_samba4_pull_time(msg, "lastLogoff", &tmp_time)) {
206                 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
207         }
208         if (pdb_samba4_pull_time(msg, "pwdLastSet", &tmp_time)) {
209                 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
210         }
211         if (pdb_samba4_pull_time(msg, "accountExpires", &tmp_time)) {
212                 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
213         }
214
215         str = ldb_msg_find_attr_as_string(msg, "displayName",
216                                             NULL);
217         if (str != NULL) {
218                 pdb_set_fullname(sam, str, PDB_SET);
219         }
220
221         str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
222                                             NULL);
223         if (str != NULL) {
224                 pdb_set_homedir(sam, str, PDB_SET);
225         }
226
227         str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
228         if (str != NULL) {
229                 pdb_set_dir_drive(sam, str, PDB_SET);
230         }
231
232         str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
233         if (str != NULL) {
234                 pdb_set_logon_script(sam, str, PDB_SET);
235         }
236
237         str = ldb_msg_find_attr_as_string(msg, "profilePath",
238                                             NULL);
239         if (str != NULL) {
240                 pdb_set_profile_path(sam, str, PDB_SET);
241         }
242
243         str = ldb_msg_find_attr_as_string(msg, "profilePath",
244                                             NULL);
245         if (str != NULL) {
246                 pdb_set_profile_path(sam, str, PDB_SET);
247         }
248
249         str = ldb_msg_find_attr_as_string(msg, "comment",
250                                             NULL);
251         if (str != NULL) {
252                 pdb_set_comment(sam, str, PDB_SET);
253         }
254
255         str = ldb_msg_find_attr_as_string(msg, "description",
256                                             NULL);
257         if (str != NULL) {
258                 pdb_set_acct_desc(sam, str, PDB_SET);
259         }
260
261         str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
262                                             NULL);
263         if (str != NULL) {
264                 pdb_set_workstations(sam, str, PDB_SET);
265         }
266
267         str = ldb_msg_find_attr_as_string(msg, "userParameters",
268                                             NULL);
269         if (str != NULL) {
270                 pdb_set_munged_dial(sam, str, PDB_SET);
271         }
272
273         sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
274         if (!sid) {
275                 DEBUG(10, ("Could not pull SID\n"));
276                 goto fail;
277         }
278         pdb_set_user_sid(sam, sid, PDB_SET);
279
280         n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
281         if (n == 0) {
282                 DEBUG(10, ("Could not pull userAccountControl\n"));
283                 goto fail;
284         }
285         pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
286
287         blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
288         if (blob) {
289                 if (blob->length != NT_HASH_LEN) {
290                         DEBUG(0, ("Got NT hash of length %d, expected %d\n",
291                                   (int)blob->length, NT_HASH_LEN));
292                         goto fail;
293                 }
294                 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
295         }
296         
297         blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
298         if (blob) {
299                 if (blob->length != LM_HASH_LEN) {
300                         DEBUG(0, ("Got LM hash of length %d, expected %d\n",
301                                   (int)blob->length, LM_HASH_LEN));
302                         goto fail;
303                 }
304                 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
305         }
306         
307         n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
308         if (n == 0) {
309                 DEBUG(10, ("Could not pull primaryGroupID\n"));
310                 goto fail;
311         }
312         sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
313         pdb_set_group_sid(sam, &group_sid, PDB_SET);
314
315         status = NT_STATUS_OK;
316 fail:
317         TALLOC_FREE(frame);
318         return status;
319 }
320
321 static bool pdb_samba4_add_time(struct ldb_message *msg, 
322                                 const char *attrib, time_t t)
323 {
324         uint64_t nt_time;
325
326         unix_to_nt_time(&nt_time, t);
327
328         return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
329 }
330
331 /* Like in pdb_ldap(), this will need to be a function pointer when we
332  * start to support 'adds' for migrations from samba3 passdb backends
333  * to samba4 */
334 static bool update_required(struct samu *sam, enum pdb_elements element)
335 {
336         return (IS_SAM_CHANGED(sam, element));
337 }
338
339 static bool pdb_samba4_init_samba4_from_sam(struct pdb_samba4_state *state,
340                                             struct ldb_message *existing,
341                                             TALLOC_CTX *mem_ctx,
342                                             struct ldb_message **pmods, 
343                                             struct samu *sam)
344 {
345         int ret = LDB_SUCCESS;
346         const char *pw;
347         struct ldb_message *msg;
348
349         /* TODO: All fields :-) */
350
351         msg = ldb_msg_new(mem_ctx);
352         if (!msg) {
353                 return false;
354         }
355
356         msg->dn = existing->dn;
357
358         pw = pdb_get_plaintext_passwd(sam);
359         if (update_required(sam, PDB_PLAINTEXT_PW)) {
360                 if (pw == NULL) {
361                         ret = LDB_ERR_OPERATIONS_ERROR;
362                         goto fail;
363                 }
364                 
365                 ret |= ldb_msg_add_string(msg, "clearTextPassword", pw);
366         }
367
368         if (update_required(sam, PDB_FULLNAME)) {
369                 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
370         }
371
372         if (update_required(sam, PDB_SMBHOME)) {
373                 ret |= ldb_msg_add_string(msg, "homeDirectory",
374                                           pdb_get_homedir(sam));
375         }
376
377         if (update_required(sam, PDB_PROFILE)) {
378                 ret |= ldb_msg_add_string(msg, "profilePath",
379                                           pdb_get_profile_path(sam));
380         }
381
382         if (update_required(sam, PDB_DRIVE)) {
383                 ret |= ldb_msg_add_string(msg, "homeDrive",
384                                           pdb_get_dir_drive(sam));
385         }
386
387         if (update_required(sam, PDB_LOGONSCRIPT)) {
388                 ret |= ldb_msg_add_string(msg, "scriptPath",
389                                           pdb_get_logon_script(sam));
390         }
391
392         if (update_required(sam, PDB_KICKOFFTIME)) {
393                 ret |= pdb_samba4_add_time(msg, "accountExpires",
394                                         pdb_get_kickoff_time(sam));
395         }
396
397         if (update_required(sam, PDB_USERNAME)) {
398                 ret |= ldb_msg_add_string(msg, "samAccountName",
399                                           pdb_get_username(sam));
400         }
401
402         if (update_required(sam, PDB_HOURSLEN) || update_required(sam, PDB_HOURS)) {
403                 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
404                 ret |= ldb_msg_add_value(msg, "logonHours",
405                                          &hours, NULL);
406         }
407
408         if (update_required(sam, PDB_ACCTCTRL)) {
409                 ret |= ldb_msg_add_fmt(msg, "userAccountControl",
410                                        "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
411         }
412
413         if (update_required(sam, PDB_COMMENT)) {
414                 ret |= ldb_msg_add_string(msg, "comment",
415                                           pdb_get_comment(sam));
416         }
417
418         if (update_required(sam, PDB_ACCTDESC)) {
419                 ret |= ldb_msg_add_string(msg, "description",
420                                           pdb_get_acct_desc(sam));
421         }
422
423         if (update_required(sam, PDB_WORKSTATIONS)) {
424                 ret |= ldb_msg_add_string(msg, "userWorkstations",
425                                           pdb_get_workstations(sam));
426         }
427
428         /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
429         if (update_required(sam, PDB_MUNGEDDIAL)) {
430                 ret |= ldb_msg_add_string(msg, "userParameters",
431                                           pdb_get_munged_dial(sam));
432         }
433
434         if (update_required(sam, PDB_COUNTRY_CODE)) {
435                 ret |= ldb_msg_add_fmt(msg, "countryCode",
436                                        "%i", (int)pdb_get_country_code(sam));
437         }
438
439         if (update_required(sam, PDB_CODE_PAGE)) {
440                 ret |= ldb_msg_add_fmt(msg, "codePage",
441                                        "%i", (int)pdb_get_code_page(sam));
442         }
443
444         /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
445         PDB_LOGONTIME,
446         PDB_LOGOFFTIME,
447         PDB_BAD_PASSWORD_TIME,
448         PDB_CANCHANGETIME,
449         PDB_MUSTCHANGETIME,
450         PDB_DOMAIN,
451         PDB_NTUSERNAME,
452         PDB_LOGONDIVS,
453         PDB_USERSID,
454         PDB_GROUPSID,
455         PDB_PASSLASTSET,
456         PDB_FIELDS_PRESENT,
457         PDB_BAD_PASSWORD_COUNT,
458         PDB_LOGON_COUNT,
459         PDB_UNKNOWN6,
460         PDB_LMPASSWD,
461         PDB_NTPASSWD,
462         PDB_PWHISTORY,
463         PDB_BACKEND_PRIVATE_DATA,
464
465  */
466
467         *pmods = msg;
468 fail:
469         return ret == LDB_SUCCESS;
470 }
471
472 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
473                                     const char *filter,
474                                     TALLOC_CTX *mem_ctx,
475                                     struct ldb_message **msg)
476 {
477         const char * attrs[] = {
478                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
479                 "sAMAccountName", "displayName", "homeDirectory",
480                 "homeDrive", "scriptPath", "profilePath", "description",
481                 "userWorkstations", "comment", "userParameters", "objectSid",
482                 "primaryGroupID", "userAccountControl", "logonHours",
483                 "badPwdCount", "logonCount", "countryCode", "codePage",
484                 "unicodePwd", "dBCSPwd", NULL };
485
486         int rc = dsdb_search_one(state->ldb, mem_ctx, msg, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter); 
487         if (rc != LDB_SUCCESS) {
488                 DEBUG(10, ("ldap_search failed %s\n",
489                            ldb_errstring(state->ldb)));
490                 return NT_STATUS_LDAP(rc);
491         }
492
493         return NT_STATUS_OK;
494 }
495
496 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
497                                           struct pdb_samba4_state *state,
498                                           struct samu *sam_acct,
499                                           const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
500 {
501         struct ldb_message *priv;
502         NTSTATUS status;
503         va_list ap;
504         char *expression = NULL;
505         TALLOC_CTX *tmp_ctx = talloc_new(state);
506         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
507
508         va_start(ap, exp_fmt);
509         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
510         va_end(ap);
511         
512         if (!expression) {
513                 talloc_free(tmp_ctx);
514                 return NT_STATUS_NO_MEMORY;
515         }
516
517         status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
518         talloc_free(tmp_ctx);
519         if (!NT_STATUS_IS_OK(status)) {
520                 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
521                            nt_errstr(status)));
522                 return status;
523         }
524
525         status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
526         if (!NT_STATUS_IS_OK(status)) {
527                 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
528                            nt_errstr(status)));
529                 TALLOC_FREE(priv);
530                 return status;
531         }
532
533         pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
534         return NT_STATUS_OK;
535 }
536
537 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
538                                     struct samu *sam_acct,
539                                     const char *username)
540 {
541         struct pdb_samba4_state *state = talloc_get_type_abort(
542                 m->private_data, struct pdb_samba4_state);
543
544         return pdb_samba4_getsampwfilter(m, state, sam_acct, 
545                                          "(&(samaccountname=%s)(objectclass=user))",
546                                          username);
547 }
548
549 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
550                                     struct samu *sam_acct,
551                                     const struct dom_sid *sid)
552 {
553         NTSTATUS status;
554         struct pdb_samba4_state *state = talloc_get_type_abort(
555                 m->private_data, struct pdb_samba4_state);
556         char *sidstr;
557
558         sidstr = dom_sid_string(talloc_tos(), sid);
559         NT_STATUS_HAVE_NO_MEMORY(sidstr);
560
561         status = pdb_samba4_getsampwfilter(m, state, sam_acct,  
562                                            "(&(objectsid=%s)(objectclass=user))", 
563                                            sidstr);
564         talloc_free(sidstr);
565         return status;
566 }
567
568 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
569                                     TALLOC_CTX *mem_ctx,
570                                     const char *name, uint32 acct_flags,
571                                     uint32 *rid)
572 {
573         struct pdb_samba4_state *state = talloc_get_type_abort(
574                 m->private_data, struct pdb_samba4_state);
575         struct dom_sid *sid;
576         struct ldb_dn *dn;
577         NTSTATUS status;
578         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
579         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
580
581         /* Internally this uses transactions to ensure all the steps
582          * happen or fail as one */
583         status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, &sid, &dn);
584         if (!NT_STATUS_IS_OK(status)) {
585                 talloc_free(tmp_ctx);
586                 return status;
587         }
588         sid_peek_rid(sid, rid);
589         talloc_free(tmp_ctx);
590         return NT_STATUS_OK;
591 }
592
593 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
594                                        TALLOC_CTX *mem_ctx,
595                                        struct samu *sam)
596 {
597         struct pdb_samba4_state *state = talloc_get_type_abort(
598                 m->private_data, struct pdb_samba4_state);
599         struct ldb_dn *dn;
600         int rc;
601         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
602         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
603
604         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
605         if (!dn || !ldb_dn_validate(dn)) {
606                 talloc_free(tmp_ctx);
607                 return NT_STATUS_NO_MEMORY;
608         }
609         rc = ldb_delete(state->ldb, dn);
610
611         if (rc != LDB_SUCCESS) {
612                 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
613                            ldb_errstring(state->ldb)));
614                 talloc_free(tmp_ctx);
615                 return NT_STATUS_LDAP(rc);
616         }
617         talloc_free(tmp_ctx);
618         return NT_STATUS_OK;
619 }
620
621 /* This interface takes a fully populated struct samu and places it in
622  * the database.  This is not implemented at this time as we need to
623  * be careful around the creation of arbitary SIDs (ie, we must ensrue
624  * they are not left in a RID pool */
625 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
626                                         struct samu *sampass)
627 {
628         return NT_STATUS_NOT_IMPLEMENTED;
629 }
630
631 /*
632  * Update the Samba4 LDB with the changes from a struct samu.
633  *
634  * This takes care not to update elements that have not been changed
635  * by the caller
636  */
637 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
638                                            struct samu *sam)
639 {
640         struct pdb_samba4_state *state = talloc_get_type_abort(
641                 m->private_data, struct pdb_samba4_state);
642         struct ldb_message *msg = pdb_samba4_get_samu_private(
643                 m, sam);
644         struct ldb_message *replace_msg;
645         int rc;
646
647         if (!pdb_samba4_init_samba4_from_sam(state, msg, talloc_tos(),
648                                              &replace_msg, sam)) {
649                 return NT_STATUS_NO_MEMORY;
650         }
651
652         if (replace_msg->num_elements == 0) {
653                 /* Nothing to do, just return success */
654                 return NT_STATUS_OK;
655         }
656
657         rc = dsdb_replace(state->ldb, replace_msg, 0);
658         TALLOC_FREE(replace_msg);
659         if (rc != LDB_SUCCESS) {
660                 DEBUG(10, ("dsdb_replace for %s failed: %s\n", ldb_dn_get_linearized(replace_msg->dn),
661                            ldb_errstring(state->ldb)));
662                 return NT_STATUS_LDAP(rc);
663         }
664
665         return NT_STATUS_OK;
666 }
667
668 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
669                                            struct samu *username)
670 {
671         NTSTATUS status;
672         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
673         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
674         status = pdb_samba4_delete_user(m, tmp_ctx, username);
675         talloc_free(tmp_ctx);
676         return status;
677 }
678
679 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
680                                            struct samu *oldname,
681                                            const char *newname)
682 {
683         return NT_STATUS_NOT_IMPLEMENTED;
684 }
685
686 /* This is not implemented, as this module is exptected to be used
687  * with auth_samba4, and this is responible for login counters etc
688  *
689  */
690 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
691                                               struct samu *sam_acct,
692                                               bool success)
693 {
694         return NT_STATUS_NOT_IMPLEMENTED;
695 }
696
697 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
698                                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
699 {
700         struct pdb_samba4_state *state = talloc_get_type_abort(
701                 m->private_data, struct pdb_samba4_state);
702         const char *attrs[] = { "objectSid", "description", "samAccountName",
703                                 NULL };
704         struct ldb_message *msg;
705         va_list ap;
706         char *expression = NULL;
707         struct dom_sid *sid;
708         const char *str;
709         int rc;
710         union unid_t id;
711         TALLOC_CTX *tmp_ctx = talloc_stackframe();
712         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
713         
714         va_start(ap, exp_fmt);
715         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
716         va_end(ap);
717         
718         if (!expression) {
719                 talloc_free(tmp_ctx);
720                 return NT_STATUS_NO_MEMORY;
721         }
722
723         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
724         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
725                 talloc_free(tmp_ctx);
726                 return NT_STATUS_NO_SUCH_GROUP;
727         } else if (rc != LDB_SUCCESS) {
728                 talloc_free(tmp_ctx);
729                 DEBUG(10, ("dsdb_search_one failed %s\n",
730                            ldb_errstring(state->ldb)));
731                 return NT_STATUS_LDAP(rc);
732         }
733
734         sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
735         if (!sid) {
736                 talloc_free(tmp_ctx);
737                 DEBUG(10, ("Could not pull SID\n"));
738                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
739         }
740         
741         map->sid = *sid;
742         
743         if (!pdb_samba4_sid_to_id(m, sid, &id, &map->sid_name_use)) {
744                 talloc_free(tmp_ctx);
745                 return NT_STATUS_NO_SUCH_GROUP;
746         }
747         if (map->sid_name_use == SID_NAME_USER) {
748                 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
749                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
750         }
751         map->gid = id.gid;
752
753         str = ldb_msg_find_attr_as_string(msg, "samAccountName",
754                                           NULL);
755         if (str == NULL) {
756                 talloc_free(tmp_ctx);
757                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
758         }
759         fstrcpy(map->nt_name, str);
760
761         str = ldb_msg_find_attr_as_string(msg, "description",
762                                             NULL);
763         if (str != NULL) {
764                 fstrcpy(map->comment, str);
765         } else {
766                 map->comment[0] = '\0';
767         }
768
769         talloc_free(tmp_ctx);
770         return NT_STATUS_OK;
771 }
772
773 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
774                                  struct dom_sid sid)
775 {
776         char *filter;
777         NTSTATUS status;
778
779         filter = talloc_asprintf(talloc_tos(),
780                                  "(&(objectsid=%s)(objectclass=group))",
781                                  sid_string_talloc(talloc_tos(), &sid));
782         if (filter == NULL) {
783                 return NT_STATUS_NO_MEMORY;
784         }
785
786         status = pdb_samba4_getgrfilter(m, map, filter);
787         TALLOC_FREE(filter);
788         return status;
789 }
790
791 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
792                                  gid_t gid)
793 {
794         struct pdb_samba4_state *state = talloc_get_type_abort(
795                 m->private_data, struct pdb_samba4_state);
796         NTSTATUS status;
797         struct id_map id_map;
798         struct id_map *id_maps[2];
799         TALLOC_CTX *tmp_ctx = talloc_stackframe();
800         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
801
802         id_map.xid.id = gid;
803         id_map.xid.type = ID_TYPE_GID;
804         id_maps[0] = &id_map;
805         id_maps[1] = NULL;
806
807         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
808         if (!NT_STATUS_IS_OK(status)) {
809                 return status;
810         }
811         status = pdb_samba4_getgrsid(m, map, *id_map.sid);
812         talloc_free(tmp_ctx);
813         return status;
814 }
815
816 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
817                                  const char *name)
818 {
819         char *filter;
820         NTSTATUS status;
821
822         filter = talloc_asprintf(talloc_tos(),
823                                  "(&(samaccountname=%s)(objectclass=group))",
824                                  name);
825         if (filter == NULL) {
826                 return NT_STATUS_NO_MEMORY;
827         }
828
829         status = pdb_samba4_getgrfilter(m, map, filter);
830         TALLOC_FREE(filter);
831         return status;
832 }
833
834 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
835                                          TALLOC_CTX *mem_ctx, const char *name,
836                                          uint32 *rid)
837 {
838         struct pdb_samba4_state *state = talloc_get_type_abort(
839                 m->private_data, struct pdb_samba4_state);
840         NTSTATUS status;
841         struct dom_sid *sid;
842         struct ldb_dn *dn;
843         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
844         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
845
846         status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
847         if (!NT_STATUS_IS_OK(status)) {
848                 talloc_free(tmp_ctx);
849                 return status;
850         }
851
852         sid_peek_rid(sid, rid);
853         talloc_free(tmp_ctx);
854         return NT_STATUS_OK;
855 }
856
857 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
858                                          TALLOC_CTX *mem_ctx, uint32 rid)
859 {
860         const char *attrs[] = { NULL };
861         struct pdb_samba4_state *state = talloc_get_type_abort(
862                 m->private_data, struct pdb_samba4_state);
863         struct dom_sid sid;
864         struct ldb_message *msg;
865         struct ldb_dn *dn;
866         int rc;
867         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
868         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
869
870         sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
871         
872         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
873                 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
874                 return NT_STATUS_INTERNAL_ERROR;
875         }
876
877         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
878         if (!dn || !ldb_dn_validate(dn)) {
879                 talloc_free(tmp_ctx);
880                 ldb_transaction_cancel(state->ldb);
881                 return NT_STATUS_NO_MEMORY;
882         }
883         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
884         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
885                 talloc_free(tmp_ctx);
886                 ldb_transaction_cancel(state->ldb);
887                 return NT_STATUS_NO_SUCH_GROUP;
888         }
889         rc = ldb_delete(state->ldb, dn);
890         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
891                 talloc_free(tmp_ctx);
892                 ldb_transaction_cancel(state->ldb);
893                 return NT_STATUS_NO_SUCH_GROUP;
894         } else if (rc != LDB_SUCCESS) {
895                 DEBUG(10, ("ldb_delete failed %s\n",
896                            ldb_errstring(state->ldb)));
897                 ldb_transaction_cancel(state->ldb);
898                 return NT_STATUS_LDAP(rc);
899         }
900
901         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
902                 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
903                 return NT_STATUS_INTERNAL_ERROR;
904         }
905         return NT_STATUS_OK;
906 }
907
908 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
909                                                 GROUP_MAP *map)
910 {
911         return NT_STATUS_NOT_IMPLEMENTED;
912 }
913
914 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
915                                                    GROUP_MAP *map)
916 {
917         return NT_STATUS_NOT_IMPLEMENTED;
918 }
919
920 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
921                                                    struct dom_sid sid)
922 {
923         return NT_STATUS_NOT_IMPLEMENTED;
924 }
925
926 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
927                                            const struct dom_sid *sid,
928                                            enum lsa_SidType sid_name_use,
929                                            GROUP_MAP **pp_rmap,
930                                            size_t *p_num_entries,
931                                            bool unix_only)
932 {
933         return NT_STATUS_NOT_IMPLEMENTED;
934 }
935
936 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
937                                            TALLOC_CTX *mem_ctx,
938                                            const struct dom_sid *group,
939                                            uint32_t **pmembers,
940                                            size_t *pnum_members)
941 {
942         unsigned int i, num_sids, num_members;
943         struct pdb_samba4_state *state = talloc_get_type_abort(
944                 m->private_data, struct pdb_samba4_state);
945         struct dom_sid *members_as_sids;
946         struct dom_sid *dom_sid;
947         uint32_t *members;
948         struct ldb_dn *dn;
949         NTSTATUS status;
950
951         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
952         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
953
954         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
955         if (!dn || !ldb_dn_validate(dn)) {
956                 return NT_STATUS_NO_MEMORY;
957         }
958
959         status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
960         if (!NT_STATUS_IS_OK(status)) {
961                 talloc_free(tmp_ctx);
962                 return status;
963         }
964         status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
965         if (!NT_STATUS_IS_OK(status)) {
966                 talloc_free(tmp_ctx);
967                 return status;
968         }
969
970         *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
971         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
972         num_members = 0;
973
974         for (i = 0; i < num_sids; i++) {
975                 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
976                         continue;
977                 }
978                 status = dom_sid_split_rid(NULL, &members_as_sids[i], 
979                                            NULL, &members[num_members]);
980                 if (!NT_STATUS_IS_OK(status)) {
981                         talloc_free(tmp_ctx);
982                         return status;
983                 }
984                 num_members++;
985         }
986         *pnum_members = num_members;
987         return NT_STATUS_OK;
988 }
989
990 /* Just convert the primary group SID into a group */
991 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
992                                             TALLOC_CTX *mem_ctx,
993                                             struct samu *user,
994                                             struct dom_sid **pp_sids,
995                                             gid_t **pp_gids,
996                                             uint32_t *p_num_groups)
997 {
998         NTSTATUS status;
999         size_t num_groups = 0;
1000         struct dom_sid *group_sids;
1001         gid_t *gids;
1002         TALLOC_CTX *tmp_ctx;
1003         
1004         tmp_ctx = talloc_new(mem_ctx);
1005         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1006
1007         if (user->group_sid) {
1008                 struct id_map *id_maps[2];
1009                 struct id_map id_map;
1010
1011                 num_groups = 1;
1012
1013                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1014                 if (group_sids == NULL) {
1015                         talloc_free(tmp_ctx);
1016                         return NT_STATUS_NO_MEMORY;
1017                 }
1018                 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1019                 if (gids == NULL) {
1020                         talloc_free(tmp_ctx);
1021                         return NT_STATUS_NO_MEMORY;
1022                 }
1023
1024                 group_sids[0] = *user->group_sid;
1025
1026                 ZERO_STRUCT(id_map);
1027                 id_map.sid = &group_sids[0];
1028                 id_maps[0] = &id_map;
1029                 id_maps[1] = NULL;
1030                 
1031                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1032                 if (!NT_STATUS_IS_OK(status)) {
1033                         talloc_free(tmp_ctx);
1034                         return status;
1035                 }
1036                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1037                         gids[0] = id_map.xid.id;
1038                 } else {
1039                         DEBUG(1, (__location__ 
1040                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1041                                   dom_sid_string(tmp_ctx, &group_sids[0]),
1042                                   dom_sid_string(tmp_ctx, &user->user_sid)));
1043                         talloc_free(tmp_ctx);
1044                         /* We must error out, otherwise a user might
1045                          * avoid a DENY acl based on a group they
1046                          * missed out on */
1047                         return NT_STATUS_NO_SUCH_GROUP;
1048                 }
1049         }
1050
1051         *pp_sids = talloc_steal(mem_ctx, group_sids);
1052         *pp_gids = talloc_steal(mem_ctx, gids);
1053         *p_num_groups = num_groups;
1054         talloc_free(tmp_ctx);
1055         return NT_STATUS_OK;
1056 }
1057
1058 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1059                                                TALLOC_CTX *mem_ctx,
1060                                                struct samu *user,
1061                                                struct dom_sid **pp_sids,
1062                                                gid_t **pp_gids,
1063                                                uint32_t *p_num_groups)
1064 {
1065         struct pdb_samba4_state *state = talloc_get_type_abort(
1066                 m->private_data, struct pdb_samba4_state);
1067         struct ldb_message *msg = pdb_samba4_get_samu_private(
1068                 m, user);
1069         const char *attrs[] = { "tokenGroups", NULL};
1070         struct ldb_message *tokengroups_msg;
1071         struct ldb_message_element *tokengroups;
1072         int i, rc;
1073         NTSTATUS status;
1074         unsigned int count = 0;
1075         size_t num_groups;
1076         struct dom_sid *group_sids;
1077         gid_t *gids;
1078         TALLOC_CTX *tmp_ctx;
1079                 
1080         if (msg == NULL) {
1081                 /* Fake up some things here */
1082                 return fake_enum_group_memberships(state, 
1083                                                    mem_ctx, 
1084                                                    user, pp_sids,
1085                                                    pp_gids, p_num_groups);
1086         }
1087
1088         tmp_ctx = talloc_new(mem_ctx);
1089         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1090
1091         rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1092
1093         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1094                 talloc_free(tmp_ctx);
1095                 return NT_STATUS_NO_SUCH_USER;
1096         } else if (rc != LDB_SUCCESS) {
1097                 DEBUG(10, ("dsdb_search_one failed %s\n",
1098                            ldb_errstring(state->ldb)));
1099                 talloc_free(tmp_ctx);
1100                 return NT_STATUS_LDAP(rc);
1101         }
1102
1103         tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1104
1105         if (tokengroups) {
1106                 count = tokengroups->num_values;
1107         }
1108
1109         group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1110         if (group_sids == NULL) {
1111                 talloc_free(tmp_ctx);
1112                 return NT_STATUS_NO_MEMORY;
1113         }
1114         gids = talloc_array(tmp_ctx, gid_t, count);
1115         if (gids == NULL) {
1116                 talloc_free(tmp_ctx);
1117                 return NT_STATUS_NO_MEMORY;
1118         }
1119         num_groups = 0;
1120
1121         for (i=0; i<count; i++) {
1122                 struct id_map *id_maps[2];
1123                 struct id_map id_map;
1124                 struct ldb_val *v = &tokengroups->values[i];
1125                 enum ndr_err_code ndr_err
1126                         = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1127                                                (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1128                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1129                         talloc_free(tmp_ctx);
1130                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1131                 }
1132                 
1133                 ZERO_STRUCT(id_map);
1134                 id_map.sid = &group_sids[num_groups];
1135                 id_maps[0] = &id_map;
1136                 id_maps[1] = NULL;
1137
1138                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1139                 if (!NT_STATUS_IS_OK(status)) {
1140                         talloc_free(tmp_ctx);
1141                         return status;
1142                 }
1143                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1144                         gids[num_groups] = id_map.xid.id;
1145                 } else {
1146                         DEBUG(1, (__location__ 
1147                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1148                                   dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1149                                   ldb_dn_get_linearized(msg->dn)));
1150                         talloc_free(tmp_ctx);
1151                         /* We must error out, otherwise a user might
1152                          * avoid a DENY acl based on a group they
1153                          * missed out on */
1154                         return NT_STATUS_NO_SUCH_GROUP;
1155                 }
1156
1157                 num_groups += 1;
1158                 if (num_groups == count) {
1159                         break;
1160                 }
1161         }
1162
1163         *pp_sids = talloc_steal(mem_ctx, group_sids);
1164         *pp_gids = talloc_steal(mem_ctx, gids);
1165         *p_num_groups = num_groups;
1166         talloc_free(tmp_ctx);
1167         return NT_STATUS_OK;
1168 }
1169
1170 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1171                                                TALLOC_CTX *mem_ctx,
1172                                                struct samu *user)
1173 {
1174         return NT_STATUS_NOT_IMPLEMENTED;
1175 }
1176
1177 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1178                                                TALLOC_CTX *mem_ctx,
1179                                                const struct dom_sid *groupsid, 
1180                                                const struct dom_sid *membersid,
1181                                                int mod_op)
1182 {
1183         struct pdb_samba4_state *state = talloc_get_type_abort(
1184                 m->private_data, struct pdb_samba4_state);
1185         struct ldb_message *msg;
1186         int ret;
1187         struct ldb_message_element *el;
1188         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1189         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1190         msg = ldb_msg_new(tmp_ctx);
1191         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1192
1193         msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1194         if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1195                 talloc_free(tmp_ctx);
1196                 return NT_STATUS_NO_MEMORY;
1197         }
1198         ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1199         if (ret != LDB_SUCCESS) {
1200                 talloc_free(tmp_ctx);
1201                 return NT_STATUS_NO_MEMORY;
1202         }
1203         el = ldb_msg_find_element(msg, "member");
1204         el->flags = mod_op;
1205
1206         /* No need for transactions here, the ldb auto-transaction
1207          * code will handle things for the single operation */
1208         ret = ldb_modify(state->ldb, msg);
1209         talloc_free(tmp_ctx);
1210         if (ret != LDB_SUCCESS) {
1211                 DEBUG(10, ("ldb_modify failed: %s\n",
1212                            ldb_errstring(state->ldb)));
1213                 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1214                         return NT_STATUS_MEMBER_IN_GROUP;
1215                 }
1216                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1217                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1218                 }
1219                 return NT_STATUS_LDAP(ret);
1220         }
1221
1222         return NT_STATUS_OK;
1223 }
1224
1225 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1226                                      TALLOC_CTX *mem_ctx,
1227                                      uint32 grouprid, uint32 memberrid,
1228                                      int mod_op)
1229 {
1230         struct pdb_samba4_state *state = talloc_get_type_abort(
1231                 m->private_data, struct pdb_samba4_state);
1232         const struct dom_sid *dom_sid, *groupsid, *membersid;
1233         NTSTATUS status;
1234         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1235         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1236
1237         dom_sid = samdb_domain_sid(state->ldb);
1238
1239         groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1240         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1241         membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1242         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1243         status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1244         talloc_free(tmp_ctx);
1245         return status;
1246 }
1247
1248 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1249                                      TALLOC_CTX *mem_ctx,
1250                                      uint32 group_rid, uint32 member_rid)
1251 {
1252         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1253                                     LDB_FLAG_MOD_ADD);
1254 }
1255
1256 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1257                                      TALLOC_CTX *mem_ctx,
1258                                      uint32 group_rid, uint32 member_rid)
1259 {
1260         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1261                                        LDB_FLAG_MOD_DELETE);
1262 }
1263
1264 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1265                                      const char *name, uint32 *rid)
1266 {
1267         TALLOC_CTX *frame = talloc_stackframe();
1268         struct pdb_samba4_state *state = talloc_get_type_abort(
1269                 m->private_data, struct pdb_samba4_state);
1270         struct dom_sid *sid;
1271
1272         struct ldb_dn *dn;
1273         NTSTATUS status;
1274         
1275         /* Internally this uses transactions to ensure all the steps
1276          * happen or fail as one */
1277         status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1278         if (!NT_STATUS_IS_OK(status)) {
1279                 TALLOC_FREE(frame);
1280         }
1281
1282         sid_peek_rid(sid, rid);
1283         TALLOC_FREE(frame);
1284         return NT_STATUS_OK;
1285 }
1286
1287 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1288                                      const struct dom_sid *sid)
1289 {
1290         const char *attrs[] = { NULL };
1291         struct pdb_samba4_state *state = talloc_get_type_abort(
1292                 m->private_data, struct pdb_samba4_state);
1293         struct ldb_message *msg;
1294         struct ldb_dn *dn;
1295         int rc;
1296         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1297         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1298
1299         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1300         if (!dn || !ldb_dn_validate(dn)) {
1301                 talloc_free(tmp_ctx);
1302                 return NT_STATUS_NO_MEMORY;
1303         }
1304
1305         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1306                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1307                 return NT_STATUS_INTERNAL_ERROR;
1308         }
1309
1310         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1311                              "(|(grouptype=%d)(grouptype=%d)))",
1312                              GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1313                              GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1314         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1315                 talloc_free(tmp_ctx);
1316                 ldb_transaction_cancel(state->ldb);
1317                 return NT_STATUS_NO_SUCH_ALIAS;
1318         }
1319         rc = ldb_delete(state->ldb, dn);
1320         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1321                 talloc_free(tmp_ctx);
1322                 ldb_transaction_cancel(state->ldb);
1323                 return NT_STATUS_NO_SUCH_ALIAS;
1324         } else if (rc != LDB_SUCCESS) {
1325                 DEBUG(10, ("ldb_delete failed %s\n",
1326                            ldb_errstring(state->ldb)));
1327                 ldb_transaction_cancel(state->ldb);
1328                 return NT_STATUS_LDAP(rc);
1329         }
1330
1331         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1332                 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1333                           ldb_errstring(state->ldb)));
1334                 return NT_STATUS_INTERNAL_ERROR;
1335         }
1336
1337         return NT_STATUS_OK;
1338 }
1339
1340 #if 0
1341 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1342                                       const struct dom_sid *sid,
1343                                       struct acct_info *info)
1344 {
1345         struct pdb_samba4_state *state = talloc_get_type_abort(
1346                 m->private_data, struct pdb_samba4_state);
1347         struct tldap_context *ld;
1348         const char *attrs[3] = { "objectSid", "description",
1349                                  "samAccountName" };
1350         struct ldb_message **msg;
1351         char *sidstr, *dn;
1352         int rc;
1353         struct tldap_mod *mods;
1354         int num_mods;
1355         bool ok;
1356
1357         ld = pdb_samba4_ld(state);
1358         if (ld == NULL) {
1359                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1360         }
1361
1362         sidstr = sid_binstring(talloc_tos(), sid);
1363         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1364
1365         rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1366                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1367                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1368                                 "(|(grouptype=%d)(grouptype=%d)))",
1369                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1370                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1371         TALLOC_FREE(sidstr)
1372         if (rc != LDB_SUCCESS) {
1373                 DEBUG(10, ("ldap_search failed %s\n",
1374                            ldb_errstring(state->ldb)));
1375                 return NT_STATUS_LDAP(rc);
1376         }
1377         switch talloc_array_length(msg) {
1378         case 0:
1379                 return NT_STATUS_NO_SUCH_ALIAS;
1380         case 1:
1381                 break;
1382         default:
1383                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1384         }
1385
1386         if (!tldap_entry_dn(msg[0], &dn)) {
1387                 TALLOC_FREE(msg);
1388                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1389         }
1390
1391         mods = NULL;
1392         num_mods = 0;
1393         ok = true;
1394
1395         ok &= tldap_make_mod_fmt(
1396                 msg[0], msg, &num_mods, &mods, "description",
1397                 "%s", info->acct_desc);
1398         ok &= tldap_make_mod_fmt(
1399                 msg[0], msg, &num_mods, &mods, "samAccountName",
1400                 "%s", info->acct_name);
1401         if (!ok) {
1402                 TALLOC_FREE(msg);
1403                 return NT_STATUS_NO_MEMORY;
1404         }
1405         if (num_mods == 0) {
1406                 /* no change */
1407                 TALLOC_FREE(msg);
1408                 return NT_STATUS_OK;
1409         }
1410
1411         rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1412         TALLOC_FREE(msg);
1413         if (rc != LDB_SUCCESS) {
1414                 DEBUG(10, ("ldap_modify failed: %s\n",
1415                            ldb_errstring(state->ldb)));
1416                 return NT_STATUS_LDAP(rc);
1417         }
1418         return NT_STATUS_OK;
1419 }
1420 #endif
1421 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1422                                      const struct dom_sid *alias,
1423                                      const struct dom_sid *member)
1424 {
1425         NTSTATUS status;
1426         TALLOC_CTX *frame = talloc_stackframe();
1427         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1428         talloc_free(frame);
1429         return status;
1430 }
1431
1432 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1433                                      const struct dom_sid *alias,
1434                                      const struct dom_sid *member)
1435 {
1436         NTSTATUS status;
1437         TALLOC_CTX *frame = talloc_stackframe();
1438         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1439         talloc_free(frame);
1440         return status;
1441 }
1442
1443 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1444                                       const struct dom_sid *alias,
1445                                       TALLOC_CTX *mem_ctx,
1446                                       struct dom_sid **pmembers,
1447                                       size_t *pnum_members)
1448 {
1449         struct pdb_samba4_state *state = talloc_get_type_abort(
1450                 m->private_data, struct pdb_samba4_state);
1451         struct ldb_dn *dn;
1452         unsigned int num_members;
1453         NTSTATUS status;
1454         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1455         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1456
1457         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1458         if (!dn || !ldb_dn_validate(dn)) {
1459                 return NT_STATUS_NO_MEMORY;
1460         }
1461
1462         status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1463         *pnum_members = num_members;
1464         if (NT_STATUS_IS_OK(status)) {
1465                 talloc_steal(mem_ctx, pmembers);
1466         }
1467         talloc_free(tmp_ctx);
1468         return status;
1469 }
1470
1471 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1472                                                TALLOC_CTX *mem_ctx,
1473                                                const struct dom_sid *domain_sid,
1474                                                const struct dom_sid *members,
1475                                                size_t num_members,
1476                                                uint32_t **palias_rids,
1477                                                size_t *pnum_alias_rids)
1478 {
1479         struct pdb_samba4_state *state = talloc_get_type_abort(
1480                 m->private_data, struct pdb_samba4_state);
1481         uint32_t *alias_rids = NULL;
1482         size_t num_alias_rids = 0;
1483         int i;
1484         struct dom_sid *groupSIDs = NULL;
1485         unsigned int num_groupSIDs = 0;
1486         char *filter;
1487         NTSTATUS status;
1488         const char *sid_string;
1489         const char *sid_dn;
1490         DATA_BLOB sid_blob;
1491
1492         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1493         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1494         /*
1495          * TODO: Get the filter right so that we only get the aliases from
1496          * either the SAM or BUILTIN
1497          */
1498
1499         filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1500                                  GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1501         if (filter == NULL) {
1502                 return NT_STATUS_NO_MEMORY;
1503         }
1504
1505         for (i = 0; i < num_members; i++) {
1506                 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1507                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1508
1509                 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1510                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1511                 
1512                 sid_blob = data_blob_string_const(sid_dn);
1513                 
1514                 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1515                                                    tmp_ctx, &groupSIDs, &num_groupSIDs);
1516                 if (!NT_STATUS_IS_OK(status)) {
1517                         talloc_free(tmp_ctx);
1518                         return status;
1519                 }
1520         }
1521
1522         alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1523         if (alias_rids == NULL) {
1524                 talloc_free(tmp_ctx);
1525                 return NT_STATUS_NO_MEMORY;
1526         }
1527
1528         for (i=0; i<num_groupSIDs; i++) {
1529                 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1530                                        &alias_rids[num_alias_rids])) {
1531                         num_alias_rids++;;
1532                 }
1533         }
1534
1535         *palias_rids = alias_rids;
1536         *pnum_alias_rids = num_alias_rids;
1537         return NT_STATUS_OK;
1538 }
1539
1540 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1541                                     const struct dom_sid *domain_sid,
1542                                     int num_rids,
1543                                     uint32 *rids,
1544                                     const char **names,
1545                                     enum lsa_SidType *lsa_attrs)
1546 {
1547         struct pdb_samba4_state *state = talloc_get_type_abort(
1548                 m->private_data, struct pdb_samba4_state);
1549         NTSTATUS status;
1550
1551         TALLOC_CTX *tmp_ctx;
1552
1553         if (num_rids == 0) {
1554                 return NT_STATUS_NONE_MAPPED;
1555         }
1556
1557         tmp_ctx = talloc_stackframe();
1558         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1559         
1560         status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1561         talloc_free(tmp_ctx);
1562         return status;
1563 }
1564
1565 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1566                                      const struct dom_sid *domain_sid,
1567                                      int num_names,
1568                                      const char **pp_names,
1569                                      uint32 *rids,
1570                                      enum lsa_SidType *attrs)
1571 {
1572         return NT_STATUS_NOT_IMPLEMENTED;
1573 }
1574
1575 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1576                                            enum pdb_policy_type type,
1577                                            uint32_t *value)
1578 {
1579         return account_policy_get(type, value)
1580                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1581 }
1582
1583 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1584                                            enum pdb_policy_type type,
1585                                            uint32_t value)
1586 {
1587         return account_policy_set(type, value)
1588                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1589 }
1590
1591 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1592                                     time_t *seq_num_out)
1593 {
1594         struct pdb_samba4_state *state = talloc_get_type_abort(
1595                 m->private_data, struct pdb_samba4_state);
1596         uint64_t seq_num;
1597         int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1598         if (ret == LDB_SUCCESS) {
1599                 *seq_num_out = seq_num;
1600                 return NT_STATUS_OK;
1601         } else {
1602                 return NT_STATUS_UNSUCCESSFUL;
1603         }
1604 }
1605
1606 struct pdb_samba4_search_state {
1607         uint32_t acct_flags;
1608         struct samr_displayentry *entries;
1609         uint32_t num_entries;
1610         ssize_t array_size;
1611         uint32_t current;
1612 };
1613
1614 static bool pdb_samba4_next_entry(struct pdb_search *search,
1615                                struct samr_displayentry *entry)
1616 {
1617         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1618                 search->private_data, struct pdb_samba4_search_state);
1619
1620         if (state->current == state->num_entries) {
1621                 return false;
1622         }
1623
1624         entry->idx = state->entries[state->current].idx;
1625         entry->rid = state->entries[state->current].rid;
1626         entry->acct_flags = state->entries[state->current].acct_flags;
1627
1628         entry->account_name = talloc_strdup(
1629                 search, state->entries[state->current].account_name);
1630         entry->fullname = talloc_strdup(
1631                 search, state->entries[state->current].fullname);
1632         entry->description = talloc_strdup(
1633                 search, state->entries[state->current].description);
1634
1635         state->current += 1;
1636         return true;
1637 }
1638
1639 static void pdb_samba4_search_end(struct pdb_search *search)
1640 {
1641         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1642                 search->private_data, struct pdb_samba4_search_state);
1643         talloc_free(state);
1644 }
1645
1646 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1647                                      struct pdb_search *search,
1648                                      struct pdb_samba4_search_state **pstate,
1649                                      const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1650 {
1651         struct pdb_samba4_state *state = talloc_get_type_abort(
1652                 m->private_data, struct pdb_samba4_state);
1653         struct pdb_samba4_search_state *sstate;
1654         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1655                                  "userAccountControl", "description", NULL };
1656         struct ldb_result *res;
1657         int i, rc, num_users;
1658
1659         va_list ap;
1660         char *expression = NULL;
1661
1662         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1663         if (!tmp_ctx) {
1664                 return false;
1665         }
1666
1667         va_start(ap, exp_fmt);
1668         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1669         va_end(ap);
1670         
1671         if (!expression) {
1672                 talloc_free(tmp_ctx);
1673                 return LDB_ERR_OPERATIONS_ERROR;
1674         }
1675
1676         sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1677         if (sstate == NULL) {
1678                 talloc_free(tmp_ctx);
1679                 return false;
1680         }
1681
1682         rc = dsdb_search(state->ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1683         if (rc != LDB_SUCCESS) {
1684                 talloc_free(tmp_ctx);
1685                 DEBUG(10, ("dsdb_search failed: %s\n",
1686                            ldb_errstring(state->ldb)));
1687                 return false;
1688         }
1689
1690         num_users = res->count;
1691
1692         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1693                                        num_users);
1694         if (sstate->entries == NULL) {
1695                 talloc_free(tmp_ctx);
1696                 DEBUG(10, ("talloc failed\n"));
1697                 return false;
1698         }
1699
1700         sstate->num_entries = 0;
1701
1702         for (i=0; i<num_users; i++) {
1703                 struct samr_displayentry *e;
1704                 struct dom_sid *sid;
1705
1706                 e = &sstate->entries[sstate->num_entries];
1707
1708                 e->idx = sstate->num_entries;
1709                 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1710                 if (!sid) {
1711                         talloc_free(tmp_ctx);
1712                         DEBUG(10, ("Could not pull SID\n"));
1713                         return false;
1714                 }
1715                 sid_peek_rid(sid, &e->rid);
1716         
1717                 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1718                                                         res->msgs[i], 
1719                                                         ldb_get_default_basedn(state->ldb));
1720                 e->account_name = ldb_msg_find_attr_as_string(
1721                         res->msgs[i], "samAccountName", NULL);
1722                 if (e->account_name == NULL) {
1723                         talloc_free(tmp_ctx);
1724                         return false;
1725                 }
1726                 e->fullname = ldb_msg_find_attr_as_string(
1727                         res->msgs[i], "displayName", "");
1728                 e->description = ldb_msg_find_attr_as_string(
1729                         res->msgs[i], "description", "");
1730
1731                 sstate->num_entries += 1;
1732                 if (sstate->num_entries >= num_users) {
1733                         break;
1734                 }
1735         }
1736         talloc_steal(sstate->entries, res->msgs);
1737         search->private_data = talloc_steal(search, sstate);
1738         search->next_entry = pdb_samba4_next_entry;
1739         search->search_end = pdb_samba4_search_end;
1740         *pstate = sstate;
1741         talloc_free(tmp_ctx);
1742         return true;
1743 }
1744
1745 static bool pdb_samba4_search_users(struct pdb_methods *m,
1746                                  struct pdb_search *search,
1747                                  uint32 acct_flags)
1748 {
1749         struct pdb_samba4_search_state *sstate;
1750         bool ret;
1751
1752         ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1753         if (!ret) {
1754                 return false;
1755         }
1756         sstate->acct_flags = acct_flags;
1757         return true;
1758 }
1759
1760 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1761                                   struct pdb_search *search)
1762 {
1763         struct pdb_samba4_search_state *sstate;
1764         bool ret;
1765
1766         ret = pdb_samba4_search_filter(m, search, &sstate, 
1767                                        "(&(grouptype=%d)(objectclass=group))",
1768                                        GTYPE_SECURITY_GLOBAL_GROUP);
1769         if (!ret) {
1770                 return false;
1771         }
1772         sstate->acct_flags = 0;
1773         return true;
1774 }
1775
1776 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1777                                    struct pdb_search *search,
1778                                    const struct dom_sid *sid)
1779 {
1780         struct pdb_samba4_search_state *sstate;
1781         bool ret;
1782
1783         ret = pdb_samba4_search_filter(m, search, &sstate, 
1784                                        "(&(grouptype=%d)(objectclass=group))",
1785                                        sid_check_is_builtin(sid)
1786                                        ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1787                                        : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1788         if (!ret) {
1789                 return false;
1790         }
1791         sstate->acct_flags = 0;
1792         return true;
1793 }
1794
1795 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1796                                struct dom_sid *sid)
1797 {
1798         struct pdb_samba4_state *state = talloc_get_type_abort(
1799                 m->private_data, struct pdb_samba4_state);
1800         NTSTATUS status;
1801         struct id_map id_map;
1802         struct id_map *id_maps[2];
1803         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1804         if (!tmp_ctx) {
1805                 return false;
1806         }
1807
1808         id_map.xid.id = uid;
1809         id_map.xid.type = ID_TYPE_UID;
1810         id_maps[0] = &id_map;
1811         id_maps[1] = NULL;
1812
1813         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1814         if (!NT_STATUS_IS_OK(status)) {
1815                 talloc_free(tmp_ctx);
1816                 return false;
1817         }
1818         *sid = *id_map.sid;
1819         talloc_free(tmp_ctx);
1820         return true;
1821 }
1822
1823 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1824                                struct dom_sid *sid)
1825 {
1826         struct pdb_samba4_state *state = talloc_get_type_abort(
1827                 m->private_data, struct pdb_samba4_state);
1828         NTSTATUS status;
1829         struct id_map id_map;
1830         struct id_map *id_maps[2];
1831         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1832         if (!tmp_ctx) {
1833                 return false;
1834         }
1835
1836         id_map.xid.id = gid;
1837         id_map.xid.type = ID_TYPE_GID;
1838         id_maps[0] = &id_map;
1839         id_maps[1] = NULL;
1840
1841         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1842         if (!NT_STATUS_IS_OK(status)) {
1843                 return false;
1844         }
1845         *sid = *id_map.sid;
1846         talloc_free(tmp_ctx);
1847         return true;
1848 }
1849
1850 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1851                                  union unid_t *id, enum lsa_SidType *type)
1852 {
1853         struct pdb_samba4_state *state = talloc_get_type_abort(
1854                 m->private_data, struct pdb_samba4_state);
1855         struct id_map id_map;
1856         struct id_map *id_maps[2];
1857         const char *attrs[] = { "objectClass", "groupType", NULL };
1858         struct ldb_message *msg;
1859         struct ldb_dn *dn;
1860         NTSTATUS status;
1861         int rc;
1862         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1863         if (!tmp_ctx) {
1864                 return false;
1865         }
1866
1867         ZERO_STRUCT(id_map);
1868
1869         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1870         if (!dn || !ldb_dn_validate(dn)) {
1871                 talloc_free(tmp_ctx);
1872                 return false;
1873         }
1874         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1875         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1876                 DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s could not be found in the samdb\n", dom_sid_string(tmp_ctx, sid)));
1877                 talloc_free(tmp_ctx);
1878                 return false;
1879         }
1880         if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
1881                 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
1882                 switch (grouptype) {
1883                 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
1884                 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
1885                         *type = SID_NAME_ALIAS;
1886                         break;
1887                 case GTYPE_SECURITY_GLOBAL_GROUP:
1888                         *type = SID_NAME_DOM_GRP;
1889                         break;
1890                 default:
1891                         talloc_free(tmp_ctx);
1892                         DEBUG(10, ("Could not pull groupType\n"));
1893                         return false;
1894                 }
1895
1896                 *type = SID_NAME_DOM_GRP;
1897
1898                 ZERO_STRUCT(id_map);
1899                 id_map.sid = sid;
1900                 id_maps[0] = &id_map;
1901                 id_maps[1] = NULL;
1902                 
1903                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1904                 talloc_free(tmp_ctx);
1905                 if (!NT_STATUS_IS_OK(status)) {
1906                         return false;
1907                 }
1908                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1909                         id->gid = id_map.xid.id;
1910                         return true;
1911                 }
1912                 return false;
1913         } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
1914                 *type = SID_NAME_USER;
1915                 ZERO_STRUCT(id_map);
1916                 id_map.sid = sid;
1917                 id_maps[0] = &id_map;
1918                 id_maps[1] = NULL;
1919                 
1920                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1921                 talloc_free(tmp_ctx);
1922                 if (!NT_STATUS_IS_OK(status)) {
1923                         return false;
1924                 }
1925                 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
1926                         id->uid = id_map.xid.id;
1927                         return true;
1928                 }
1929                 return false;
1930         }
1931         DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s was found, but was not a user or group\n", dom_sid_string(tmp_ctx, sid)));
1932         talloc_free(tmp_ctx);
1933         return false;
1934 }
1935
1936 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
1937 {
1938         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1939 }
1940
1941 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
1942 {
1943         return false;
1944 }
1945
1946 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
1947                                       const char *domain, char** pwd,
1948                                       struct dom_sid *sid,
1949                                       time_t *pass_last_set_time)
1950 {
1951         return false;
1952 }
1953
1954 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
1955                                       const char* domain, const char* pwd,
1956                                       const struct dom_sid *sid)
1957 {
1958         return false;
1959 }
1960
1961 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
1962                                       const char *domain)
1963 {
1964         return false;
1965 }
1966
1967 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
1968                                          TALLOC_CTX *mem_ctx,
1969                                          uint32 *num_domains,
1970                                          struct trustdom_info ***domains)
1971 {
1972         *num_domains = 0;
1973         *domains = NULL;
1974         return NT_STATUS_OK;
1975 }
1976
1977 static void pdb_samba4_init_methods(struct pdb_methods *m)
1978 {
1979         m->name = "samba4";
1980         m->get_domain_info = pdb_samba4_get_domain_info;
1981         m->getsampwnam = pdb_samba4_getsampwnam;
1982         m->getsampwsid = pdb_samba4_getsampwsid;
1983         m->create_user = pdb_samba4_create_user;
1984         m->delete_user = pdb_samba4_delete_user;
1985         m->add_sam_account = pdb_samba4_add_sam_account;
1986         m->update_sam_account = pdb_samba4_update_sam_account;
1987         m->delete_sam_account = pdb_samba4_delete_sam_account;
1988         m->rename_sam_account = pdb_samba4_rename_sam_account;
1989         m->update_login_attempts = pdb_samba4_update_login_attempts;
1990         m->getgrsid = pdb_samba4_getgrsid;
1991         m->getgrgid = pdb_samba4_getgrgid;
1992         m->getgrnam = pdb_samba4_getgrnam;
1993         m->create_dom_group = pdb_samba4_create_dom_group;
1994         m->delete_dom_group = pdb_samba4_delete_dom_group;
1995         m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
1996         m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
1997         m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
1998         m->enum_group_mapping = pdb_samba4_enum_group_mapping;
1999         m->enum_group_members = pdb_samba4_enum_group_members;
2000         m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2001         m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2002         m->add_groupmem = pdb_samba4_add_groupmem;
2003         m->del_groupmem = pdb_samba4_del_groupmem;
2004         m->create_alias = pdb_samba4_create_alias;
2005         m->delete_alias = pdb_samba4_delete_alias;
2006         m->get_aliasinfo = pdb_default_get_aliasinfo;
2007         m->add_aliasmem = pdb_samba4_add_aliasmem;
2008         m->del_aliasmem = pdb_samba4_del_aliasmem;
2009         m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2010         m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2011         m->lookup_rids = pdb_samba4_lookup_rids;
2012         m->lookup_names = pdb_samba4_lookup_names;
2013         m->get_account_policy = pdb_samba4_get_account_policy;
2014         m->set_account_policy = pdb_samba4_set_account_policy;
2015         m->get_seq_num = pdb_samba4_get_seq_num;
2016         m->search_users = pdb_samba4_search_users;
2017         m->search_groups = pdb_samba4_search_groups;
2018         m->search_aliases = pdb_samba4_search_aliases;
2019         m->uid_to_sid = pdb_samba4_uid_to_sid;
2020         m->gid_to_sid = pdb_samba4_gid_to_sid;
2021         m->sid_to_id = pdb_samba4_sid_to_id;
2022         m->capabilities = pdb_samba4_capabilities;
2023         m->new_rid = pdb_samba4_new_rid;
2024         m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2025         m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2026         m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2027         m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2028 }
2029
2030 static void free_private_data(void **vp)
2031 {
2032         struct pdb_samba4_state *state = talloc_get_type_abort(
2033                 *vp, struct pdb_samba4_state);
2034         talloc_unlink(state, state->ldb);
2035         return;
2036 }
2037
2038 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2039                              const char *location)
2040 {
2041         struct pdb_methods *m;
2042         struct pdb_samba4_state *state;
2043         NTSTATUS status;
2044
2045         if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2046                 return status;
2047         }
2048
2049         state = talloc_zero(m, struct pdb_samba4_state);
2050         if (state == NULL) {
2051                 goto nomem;
2052         }
2053         m->private_data = state;
2054         m->free_private_data = free_private_data;
2055         pdb_samba4_init_methods(m);
2056
2057         state->ev = s4_event_context_init(state);
2058         if (!state->ev) {
2059                 DEBUG(10, ("s4_event_context_init failed\n"));
2060                 goto fail;
2061         }
2062
2063         state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2064         if (state->lp_ctx == NULL) {
2065                 DEBUG(10, ("loadparm_init_s3 failed\n"));
2066                 goto fail;
2067         }
2068
2069         state->ldb = samdb_connect(state,
2070                                    state->ev,
2071                                    state->lp_ctx,
2072                                    system_session(state->lp_ctx), 0);
2073
2074         if (!state->ldb) {
2075                 DEBUG(10, ("samdb_connect failed\n"));
2076                 goto fail;
2077         }
2078
2079         state->idmap_ctx = idmap_init(state, state->ev,
2080                                       state->lp_ctx);
2081         if (!state->idmap_ctx) {
2082                 DEBUG(10, ("samdb_connect failed\n"));
2083                 goto fail;
2084         }
2085
2086         *pdb_method = m;
2087         return NT_STATUS_OK;
2088 nomem:
2089         status = NT_STATUS_NO_MEMORY;
2090 fail:
2091         TALLOC_FREE(m);
2092         return status;
2093 }
2094
2095 NTSTATUS pdb_samba4_init(void);
2096 NTSTATUS pdb_samba4_init(void)
2097 {
2098         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2099                                    pdb_init_samba4);
2100 }