aa3352a65887a130c19c4eaaf0d9e7633c3e010e
[amitay/samba.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, NULL,
584                                &sid, &dn);
585         if (!NT_STATUS_IS_OK(status)) {
586                 talloc_free(tmp_ctx);
587                 return status;
588         }
589         sid_peek_rid(sid, rid);
590         talloc_free(tmp_ctx);
591         return NT_STATUS_OK;
592 }
593
594 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
595                                        TALLOC_CTX *mem_ctx,
596                                        struct samu *sam)
597 {
598         struct pdb_samba4_state *state = talloc_get_type_abort(
599                 m->private_data, struct pdb_samba4_state);
600         struct ldb_dn *dn;
601         int rc;
602         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
603         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
604
605         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
606         if (!dn || !ldb_dn_validate(dn)) {
607                 talloc_free(tmp_ctx);
608                 return NT_STATUS_NO_MEMORY;
609         }
610         rc = ldb_delete(state->ldb, dn);
611
612         if (rc != LDB_SUCCESS) {
613                 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
614                            ldb_errstring(state->ldb)));
615                 talloc_free(tmp_ctx);
616                 return NT_STATUS_LDAP(rc);
617         }
618         talloc_free(tmp_ctx);
619         return NT_STATUS_OK;
620 }
621
622 /* This interface takes a fully populated struct samu and places it in
623  * the database.  This is not implemented at this time as we need to
624  * be careful around the creation of arbitary SIDs (ie, we must ensrue
625  * they are not left in a RID pool */
626 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
627                                         struct samu *sampass)
628 {
629         return NT_STATUS_NOT_IMPLEMENTED;
630 }
631
632 /*
633  * Update the Samba4 LDB with the changes from a struct samu.
634  *
635  * This takes care not to update elements that have not been changed
636  * by the caller
637  */
638 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
639                                            struct samu *sam)
640 {
641         struct pdb_samba4_state *state = talloc_get_type_abort(
642                 m->private_data, struct pdb_samba4_state);
643         struct ldb_message *msg = pdb_samba4_get_samu_private(
644                 m, sam);
645         struct ldb_message *replace_msg;
646         int rc;
647
648         if (!pdb_samba4_init_samba4_from_sam(state, msg, talloc_tos(),
649                                              &replace_msg, sam)) {
650                 return NT_STATUS_NO_MEMORY;
651         }
652
653         if (replace_msg->num_elements == 0) {
654                 /* Nothing to do, just return success */
655                 return NT_STATUS_OK;
656         }
657
658         rc = dsdb_replace(state->ldb, replace_msg, 0);
659         TALLOC_FREE(replace_msg);
660         if (rc != LDB_SUCCESS) {
661                 DEBUG(10, ("dsdb_replace for %s failed: %s\n", ldb_dn_get_linearized(replace_msg->dn),
662                            ldb_errstring(state->ldb)));
663                 return NT_STATUS_LDAP(rc);
664         }
665
666         return NT_STATUS_OK;
667 }
668
669 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
670                                            struct samu *username)
671 {
672         NTSTATUS status;
673         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
674         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
675         status = pdb_samba4_delete_user(m, tmp_ctx, username);
676         talloc_free(tmp_ctx);
677         return status;
678 }
679
680 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
681                                            struct samu *oldname,
682                                            const char *newname)
683 {
684         return NT_STATUS_NOT_IMPLEMENTED;
685 }
686
687 /* This is not implemented, as this module is exptected to be used
688  * with auth_samba4, and this is responible for login counters etc
689  *
690  */
691 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
692                                               struct samu *sam_acct,
693                                               bool success)
694 {
695         return NT_STATUS_NOT_IMPLEMENTED;
696 }
697
698 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
699                                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
700 {
701         struct pdb_samba4_state *state = talloc_get_type_abort(
702                 m->private_data, struct pdb_samba4_state);
703         const char *attrs[] = { "objectSid", "description", "samAccountName",
704                                 NULL };
705         struct ldb_message *msg;
706         va_list ap;
707         char *expression = NULL;
708         struct dom_sid *sid;
709         const char *str;
710         int rc;
711         union unid_t id;
712         TALLOC_CTX *tmp_ctx = talloc_stackframe();
713         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
714         
715         va_start(ap, exp_fmt);
716         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
717         va_end(ap);
718         
719         if (!expression) {
720                 talloc_free(tmp_ctx);
721                 return NT_STATUS_NO_MEMORY;
722         }
723
724         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
725         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
726                 talloc_free(tmp_ctx);
727                 return NT_STATUS_NO_SUCH_GROUP;
728         } else if (rc != LDB_SUCCESS) {
729                 talloc_free(tmp_ctx);
730                 DEBUG(10, ("dsdb_search_one failed %s\n",
731                            ldb_errstring(state->ldb)));
732                 return NT_STATUS_LDAP(rc);
733         }
734
735         sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
736         if (!sid) {
737                 talloc_free(tmp_ctx);
738                 DEBUG(10, ("Could not pull SID\n"));
739                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
740         }
741         
742         map->sid = *sid;
743         
744         if (!pdb_samba4_sid_to_id(m, sid, &id, &map->sid_name_use)) {
745                 talloc_free(tmp_ctx);
746                 return NT_STATUS_NO_SUCH_GROUP;
747         }
748         if (map->sid_name_use == SID_NAME_USER) {
749                 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
750                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
751         }
752         map->gid = id.gid;
753
754         str = ldb_msg_find_attr_as_string(msg, "samAccountName",
755                                           NULL);
756         if (str == NULL) {
757                 talloc_free(tmp_ctx);
758                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
759         }
760         fstrcpy(map->nt_name, str);
761
762         str = ldb_msg_find_attr_as_string(msg, "description",
763                                             NULL);
764         if (str != NULL) {
765                 fstrcpy(map->comment, str);
766         } else {
767                 map->comment[0] = '\0';
768         }
769
770         talloc_free(tmp_ctx);
771         return NT_STATUS_OK;
772 }
773
774 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
775                                  struct dom_sid sid)
776 {
777         char *filter;
778         NTSTATUS status;
779
780         filter = talloc_asprintf(talloc_tos(),
781                                  "(&(objectsid=%s)(objectclass=group))",
782                                  sid_string_talloc(talloc_tos(), &sid));
783         if (filter == NULL) {
784                 return NT_STATUS_NO_MEMORY;
785         }
786
787         status = pdb_samba4_getgrfilter(m, map, filter);
788         TALLOC_FREE(filter);
789         return status;
790 }
791
792 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
793                                  gid_t gid)
794 {
795         struct pdb_samba4_state *state = talloc_get_type_abort(
796                 m->private_data, struct pdb_samba4_state);
797         NTSTATUS status;
798         struct id_map id_map;
799         struct id_map *id_maps[2];
800         TALLOC_CTX *tmp_ctx = talloc_stackframe();
801         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
802
803         id_map.xid.id = gid;
804         id_map.xid.type = ID_TYPE_GID;
805         id_maps[0] = &id_map;
806         id_maps[1] = NULL;
807
808         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
809         if (!NT_STATUS_IS_OK(status)) {
810                 return status;
811         }
812         status = pdb_samba4_getgrsid(m, map, *id_map.sid);
813         talloc_free(tmp_ctx);
814         return status;
815 }
816
817 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
818                                  const char *name)
819 {
820         char *filter;
821         NTSTATUS status;
822
823         filter = talloc_asprintf(talloc_tos(),
824                                  "(&(samaccountname=%s)(objectclass=group))",
825                                  name);
826         if (filter == NULL) {
827                 return NT_STATUS_NO_MEMORY;
828         }
829
830         status = pdb_samba4_getgrfilter(m, map, filter);
831         TALLOC_FREE(filter);
832         return status;
833 }
834
835 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
836                                          TALLOC_CTX *mem_ctx, const char *name,
837                                          uint32 *rid)
838 {
839         struct pdb_samba4_state *state = talloc_get_type_abort(
840                 m->private_data, struct pdb_samba4_state);
841         NTSTATUS status;
842         struct dom_sid *sid;
843         struct ldb_dn *dn;
844         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
845         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
846
847         status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
848         if (!NT_STATUS_IS_OK(status)) {
849                 talloc_free(tmp_ctx);
850                 return status;
851         }
852
853         sid_peek_rid(sid, rid);
854         talloc_free(tmp_ctx);
855         return NT_STATUS_OK;
856 }
857
858 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
859                                          TALLOC_CTX *mem_ctx, uint32 rid)
860 {
861         const char *attrs[] = { NULL };
862         struct pdb_samba4_state *state = talloc_get_type_abort(
863                 m->private_data, struct pdb_samba4_state);
864         struct dom_sid sid;
865         struct ldb_message *msg;
866         struct ldb_dn *dn;
867         int rc;
868         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
869         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
870
871         sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
872         
873         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
874                 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
875                 return NT_STATUS_INTERNAL_ERROR;
876         }
877
878         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
879         if (!dn || !ldb_dn_validate(dn)) {
880                 talloc_free(tmp_ctx);
881                 ldb_transaction_cancel(state->ldb);
882                 return NT_STATUS_NO_MEMORY;
883         }
884         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
885         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
886                 talloc_free(tmp_ctx);
887                 ldb_transaction_cancel(state->ldb);
888                 return NT_STATUS_NO_SUCH_GROUP;
889         }
890         rc = ldb_delete(state->ldb, dn);
891         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
892                 talloc_free(tmp_ctx);
893                 ldb_transaction_cancel(state->ldb);
894                 return NT_STATUS_NO_SUCH_GROUP;
895         } else if (rc != LDB_SUCCESS) {
896                 DEBUG(10, ("ldb_delete failed %s\n",
897                            ldb_errstring(state->ldb)));
898                 ldb_transaction_cancel(state->ldb);
899                 return NT_STATUS_LDAP(rc);
900         }
901
902         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
903                 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
904                 return NT_STATUS_INTERNAL_ERROR;
905         }
906         return NT_STATUS_OK;
907 }
908
909 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
910                                                 GROUP_MAP *map)
911 {
912         return NT_STATUS_NOT_IMPLEMENTED;
913 }
914
915 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
916                                                    GROUP_MAP *map)
917 {
918         return NT_STATUS_NOT_IMPLEMENTED;
919 }
920
921 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
922                                                    struct dom_sid sid)
923 {
924         return NT_STATUS_NOT_IMPLEMENTED;
925 }
926
927 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
928                                            const struct dom_sid *sid,
929                                            enum lsa_SidType sid_name_use,
930                                            GROUP_MAP **pp_rmap,
931                                            size_t *p_num_entries,
932                                            bool unix_only)
933 {
934         return NT_STATUS_NOT_IMPLEMENTED;
935 }
936
937 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
938                                            TALLOC_CTX *mem_ctx,
939                                            const struct dom_sid *group,
940                                            uint32_t **pmembers,
941                                            size_t *pnum_members)
942 {
943         unsigned int i, num_sids, num_members;
944         struct pdb_samba4_state *state = talloc_get_type_abort(
945                 m->private_data, struct pdb_samba4_state);
946         struct dom_sid *members_as_sids;
947         struct dom_sid *dom_sid;
948         uint32_t *members;
949         struct ldb_dn *dn;
950         NTSTATUS status;
951
952         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
953         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
954
955         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
956         if (!dn || !ldb_dn_validate(dn)) {
957                 return NT_STATUS_NO_MEMORY;
958         }
959
960         status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
961         if (!NT_STATUS_IS_OK(status)) {
962                 talloc_free(tmp_ctx);
963                 return status;
964         }
965         status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
966         if (!NT_STATUS_IS_OK(status)) {
967                 talloc_free(tmp_ctx);
968                 return status;
969         }
970
971         *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
972         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
973         num_members = 0;
974
975         for (i = 0; i < num_sids; i++) {
976                 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
977                         continue;
978                 }
979                 status = dom_sid_split_rid(NULL, &members_as_sids[i], 
980                                            NULL, &members[num_members]);
981                 if (!NT_STATUS_IS_OK(status)) {
982                         talloc_free(tmp_ctx);
983                         return status;
984                 }
985                 num_members++;
986         }
987         *pnum_members = num_members;
988         return NT_STATUS_OK;
989 }
990
991 /* Just convert the primary group SID into a group */
992 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
993                                             TALLOC_CTX *mem_ctx,
994                                             struct samu *user,
995                                             struct dom_sid **pp_sids,
996                                             gid_t **pp_gids,
997                                             uint32_t *p_num_groups)
998 {
999         NTSTATUS status;
1000         size_t num_groups = 0;
1001         struct dom_sid *group_sids;
1002         gid_t *gids;
1003         TALLOC_CTX *tmp_ctx;
1004         
1005         tmp_ctx = talloc_new(mem_ctx);
1006         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1007
1008         if (user->group_sid) {
1009                 struct id_map *id_maps[2];
1010                 struct id_map id_map;
1011
1012                 num_groups = 1;
1013
1014                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1015                 if (group_sids == NULL) {
1016                         talloc_free(tmp_ctx);
1017                         return NT_STATUS_NO_MEMORY;
1018                 }
1019                 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1020                 if (gids == NULL) {
1021                         talloc_free(tmp_ctx);
1022                         return NT_STATUS_NO_MEMORY;
1023                 }
1024
1025                 group_sids[0] = *user->group_sid;
1026
1027                 ZERO_STRUCT(id_map);
1028                 id_map.sid = &group_sids[0];
1029                 id_maps[0] = &id_map;
1030                 id_maps[1] = NULL;
1031                 
1032                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1033                 if (!NT_STATUS_IS_OK(status)) {
1034                         talloc_free(tmp_ctx);
1035                         return status;
1036                 }
1037                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1038                         gids[0] = id_map.xid.id;
1039                 } else {
1040                         DEBUG(1, (__location__ 
1041                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1042                                   dom_sid_string(tmp_ctx, &group_sids[0]),
1043                                   dom_sid_string(tmp_ctx, &user->user_sid)));
1044                         talloc_free(tmp_ctx);
1045                         /* We must error out, otherwise a user might
1046                          * avoid a DENY acl based on a group they
1047                          * missed out on */
1048                         return NT_STATUS_NO_SUCH_GROUP;
1049                 }
1050         }
1051
1052         *pp_sids = talloc_steal(mem_ctx, group_sids);
1053         *pp_gids = talloc_steal(mem_ctx, gids);
1054         *p_num_groups = num_groups;
1055         talloc_free(tmp_ctx);
1056         return NT_STATUS_OK;
1057 }
1058
1059 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1060                                                TALLOC_CTX *mem_ctx,
1061                                                struct samu *user,
1062                                                struct dom_sid **pp_sids,
1063                                                gid_t **pp_gids,
1064                                                uint32_t *p_num_groups)
1065 {
1066         struct pdb_samba4_state *state = talloc_get_type_abort(
1067                 m->private_data, struct pdb_samba4_state);
1068         struct ldb_message *msg = pdb_samba4_get_samu_private(
1069                 m, user);
1070         const char *attrs[] = { "tokenGroups", NULL};
1071         struct ldb_message *tokengroups_msg;
1072         struct ldb_message_element *tokengroups;
1073         int i, rc;
1074         NTSTATUS status;
1075         unsigned int count = 0;
1076         size_t num_groups;
1077         struct dom_sid *group_sids;
1078         gid_t *gids;
1079         TALLOC_CTX *tmp_ctx;
1080                 
1081         if (msg == NULL) {
1082                 /* Fake up some things here */
1083                 return fake_enum_group_memberships(state, 
1084                                                    mem_ctx, 
1085                                                    user, pp_sids,
1086                                                    pp_gids, p_num_groups);
1087         }
1088
1089         tmp_ctx = talloc_new(mem_ctx);
1090         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1091
1092         rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1093
1094         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1095                 talloc_free(tmp_ctx);
1096                 return NT_STATUS_NO_SUCH_USER;
1097         } else if (rc != LDB_SUCCESS) {
1098                 DEBUG(10, ("dsdb_search_one failed %s\n",
1099                            ldb_errstring(state->ldb)));
1100                 talloc_free(tmp_ctx);
1101                 return NT_STATUS_LDAP(rc);
1102         }
1103
1104         tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1105
1106         if (tokengroups) {
1107                 count = tokengroups->num_values;
1108         }
1109
1110         group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1111         if (group_sids == NULL) {
1112                 talloc_free(tmp_ctx);
1113                 return NT_STATUS_NO_MEMORY;
1114         }
1115         gids = talloc_array(tmp_ctx, gid_t, count);
1116         if (gids == NULL) {
1117                 talloc_free(tmp_ctx);
1118                 return NT_STATUS_NO_MEMORY;
1119         }
1120         num_groups = 0;
1121
1122         for (i=0; i<count; i++) {
1123                 struct id_map *id_maps[2];
1124                 struct id_map id_map;
1125                 struct ldb_val *v = &tokengroups->values[i];
1126                 enum ndr_err_code ndr_err
1127                         = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1128                                                (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1129                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1130                         talloc_free(tmp_ctx);
1131                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1132                 }
1133                 
1134                 ZERO_STRUCT(id_map);
1135                 id_map.sid = &group_sids[num_groups];
1136                 id_maps[0] = &id_map;
1137                 id_maps[1] = NULL;
1138
1139                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1140                 if (!NT_STATUS_IS_OK(status)) {
1141                         talloc_free(tmp_ctx);
1142                         return status;
1143                 }
1144                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1145                         gids[num_groups] = id_map.xid.id;
1146                 } else {
1147                         DEBUG(1, (__location__ 
1148                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1149                                   dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1150                                   ldb_dn_get_linearized(msg->dn)));
1151                         talloc_free(tmp_ctx);
1152                         /* We must error out, otherwise a user might
1153                          * avoid a DENY acl based on a group they
1154                          * missed out on */
1155                         return NT_STATUS_NO_SUCH_GROUP;
1156                 }
1157
1158                 num_groups += 1;
1159                 if (num_groups == count) {
1160                         break;
1161                 }
1162         }
1163
1164         *pp_sids = talloc_steal(mem_ctx, group_sids);
1165         *pp_gids = talloc_steal(mem_ctx, gids);
1166         *p_num_groups = num_groups;
1167         talloc_free(tmp_ctx);
1168         return NT_STATUS_OK;
1169 }
1170
1171 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1172                                                TALLOC_CTX *mem_ctx,
1173                                                struct samu *user)
1174 {
1175         return NT_STATUS_NOT_IMPLEMENTED;
1176 }
1177
1178 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1179                                                TALLOC_CTX *mem_ctx,
1180                                                const struct dom_sid *groupsid, 
1181                                                const struct dom_sid *membersid,
1182                                                int mod_op)
1183 {
1184         struct pdb_samba4_state *state = talloc_get_type_abort(
1185                 m->private_data, struct pdb_samba4_state);
1186         struct ldb_message *msg;
1187         int ret;
1188         struct ldb_message_element *el;
1189         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1190         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1191         msg = ldb_msg_new(tmp_ctx);
1192         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1193
1194         msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1195         if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1196                 talloc_free(tmp_ctx);
1197                 return NT_STATUS_NO_MEMORY;
1198         }
1199         ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1200         if (ret != LDB_SUCCESS) {
1201                 talloc_free(tmp_ctx);
1202                 return NT_STATUS_NO_MEMORY;
1203         }
1204         el = ldb_msg_find_element(msg, "member");
1205         el->flags = mod_op;
1206
1207         /* No need for transactions here, the ldb auto-transaction
1208          * code will handle things for the single operation */
1209         ret = ldb_modify(state->ldb, msg);
1210         talloc_free(tmp_ctx);
1211         if (ret != LDB_SUCCESS) {
1212                 DEBUG(10, ("ldb_modify failed: %s\n",
1213                            ldb_errstring(state->ldb)));
1214                 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1215                         return NT_STATUS_MEMBER_IN_GROUP;
1216                 }
1217                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1218                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1219                 }
1220                 return NT_STATUS_LDAP(ret);
1221         }
1222
1223         return NT_STATUS_OK;
1224 }
1225
1226 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1227                                      TALLOC_CTX *mem_ctx,
1228                                      uint32 grouprid, uint32 memberrid,
1229                                      int mod_op)
1230 {
1231         struct pdb_samba4_state *state = talloc_get_type_abort(
1232                 m->private_data, struct pdb_samba4_state);
1233         const struct dom_sid *dom_sid, *groupsid, *membersid;
1234         NTSTATUS status;
1235         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1236         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1237
1238         dom_sid = samdb_domain_sid(state->ldb);
1239
1240         groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1241         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1242         membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1243         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1244         status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1245         talloc_free(tmp_ctx);
1246         return status;
1247 }
1248
1249 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1250                                      TALLOC_CTX *mem_ctx,
1251                                      uint32 group_rid, uint32 member_rid)
1252 {
1253         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1254                                     LDB_FLAG_MOD_ADD);
1255 }
1256
1257 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1258                                      TALLOC_CTX *mem_ctx,
1259                                      uint32 group_rid, uint32 member_rid)
1260 {
1261         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1262                                        LDB_FLAG_MOD_DELETE);
1263 }
1264
1265 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1266                                      const char *name, uint32 *rid)
1267 {
1268         TALLOC_CTX *frame = talloc_stackframe();
1269         struct pdb_samba4_state *state = talloc_get_type_abort(
1270                 m->private_data, struct pdb_samba4_state);
1271         struct dom_sid *sid;
1272
1273         struct ldb_dn *dn;
1274         NTSTATUS status;
1275         
1276         /* Internally this uses transactions to ensure all the steps
1277          * happen or fail as one */
1278         status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 TALLOC_FREE(frame);
1281         }
1282
1283         sid_peek_rid(sid, rid);
1284         TALLOC_FREE(frame);
1285         return NT_STATUS_OK;
1286 }
1287
1288 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1289                                      const struct dom_sid *sid)
1290 {
1291         const char *attrs[] = { NULL };
1292         struct pdb_samba4_state *state = talloc_get_type_abort(
1293                 m->private_data, struct pdb_samba4_state);
1294         struct ldb_message *msg;
1295         struct ldb_dn *dn;
1296         int rc;
1297         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1298         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1299
1300         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1301         if (!dn || !ldb_dn_validate(dn)) {
1302                 talloc_free(tmp_ctx);
1303                 return NT_STATUS_NO_MEMORY;
1304         }
1305
1306         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1307                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1308                 return NT_STATUS_INTERNAL_ERROR;
1309         }
1310
1311         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1312                              "(|(grouptype=%d)(grouptype=%d)))",
1313                              GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1314                              GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1315         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1316                 talloc_free(tmp_ctx);
1317                 ldb_transaction_cancel(state->ldb);
1318                 return NT_STATUS_NO_SUCH_ALIAS;
1319         }
1320         rc = ldb_delete(state->ldb, dn);
1321         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1322                 talloc_free(tmp_ctx);
1323                 ldb_transaction_cancel(state->ldb);
1324                 return NT_STATUS_NO_SUCH_ALIAS;
1325         } else if (rc != LDB_SUCCESS) {
1326                 DEBUG(10, ("ldb_delete failed %s\n",
1327                            ldb_errstring(state->ldb)));
1328                 ldb_transaction_cancel(state->ldb);
1329                 return NT_STATUS_LDAP(rc);
1330         }
1331
1332         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1333                 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1334                           ldb_errstring(state->ldb)));
1335                 return NT_STATUS_INTERNAL_ERROR;
1336         }
1337
1338         return NT_STATUS_OK;
1339 }
1340
1341 #if 0
1342 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1343                                       const struct dom_sid *sid,
1344                                       struct acct_info *info)
1345 {
1346         struct pdb_samba4_state *state = talloc_get_type_abort(
1347                 m->private_data, struct pdb_samba4_state);
1348         struct tldap_context *ld;
1349         const char *attrs[3] = { "objectSid", "description",
1350                                  "samAccountName" };
1351         struct ldb_message **msg;
1352         char *sidstr, *dn;
1353         int rc;
1354         struct tldap_mod *mods;
1355         int num_mods;
1356         bool ok;
1357
1358         ld = pdb_samba4_ld(state);
1359         if (ld == NULL) {
1360                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1361         }
1362
1363         sidstr = sid_binstring(talloc_tos(), sid);
1364         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1365
1366         rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1367                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1368                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1369                                 "(|(grouptype=%d)(grouptype=%d)))",
1370                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1371                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1372         TALLOC_FREE(sidstr)
1373         if (rc != LDB_SUCCESS) {
1374                 DEBUG(10, ("ldap_search failed %s\n",
1375                            ldb_errstring(state->ldb)));
1376                 return NT_STATUS_LDAP(rc);
1377         }
1378         switch talloc_array_length(msg) {
1379         case 0:
1380                 return NT_STATUS_NO_SUCH_ALIAS;
1381         case 1:
1382                 break;
1383         default:
1384                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1385         }
1386
1387         if (!tldap_entry_dn(msg[0], &dn)) {
1388                 TALLOC_FREE(msg);
1389                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1390         }
1391
1392         mods = NULL;
1393         num_mods = 0;
1394         ok = true;
1395
1396         ok &= tldap_make_mod_fmt(
1397                 msg[0], msg, &num_mods, &mods, "description",
1398                 "%s", info->acct_desc);
1399         ok &= tldap_make_mod_fmt(
1400                 msg[0], msg, &num_mods, &mods, "samAccountName",
1401                 "%s", info->acct_name);
1402         if (!ok) {
1403                 TALLOC_FREE(msg);
1404                 return NT_STATUS_NO_MEMORY;
1405         }
1406         if (num_mods == 0) {
1407                 /* no change */
1408                 TALLOC_FREE(msg);
1409                 return NT_STATUS_OK;
1410         }
1411
1412         rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1413         TALLOC_FREE(msg);
1414         if (rc != LDB_SUCCESS) {
1415                 DEBUG(10, ("ldap_modify failed: %s\n",
1416                            ldb_errstring(state->ldb)));
1417                 return NT_STATUS_LDAP(rc);
1418         }
1419         return NT_STATUS_OK;
1420 }
1421 #endif
1422 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1423                                      const struct dom_sid *alias,
1424                                      const struct dom_sid *member)
1425 {
1426         NTSTATUS status;
1427         TALLOC_CTX *frame = talloc_stackframe();
1428         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1429         talloc_free(frame);
1430         return status;
1431 }
1432
1433 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1434                                      const struct dom_sid *alias,
1435                                      const struct dom_sid *member)
1436 {
1437         NTSTATUS status;
1438         TALLOC_CTX *frame = talloc_stackframe();
1439         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1440         talloc_free(frame);
1441         return status;
1442 }
1443
1444 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1445                                       const struct dom_sid *alias,
1446                                       TALLOC_CTX *mem_ctx,
1447                                       struct dom_sid **pmembers,
1448                                       size_t *pnum_members)
1449 {
1450         struct pdb_samba4_state *state = talloc_get_type_abort(
1451                 m->private_data, struct pdb_samba4_state);
1452         struct ldb_dn *dn;
1453         unsigned int num_members;
1454         NTSTATUS status;
1455         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1456         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1457
1458         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1459         if (!dn || !ldb_dn_validate(dn)) {
1460                 return NT_STATUS_NO_MEMORY;
1461         }
1462
1463         status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1464         *pnum_members = num_members;
1465         if (NT_STATUS_IS_OK(status)) {
1466                 talloc_steal(mem_ctx, pmembers);
1467         }
1468         talloc_free(tmp_ctx);
1469         return status;
1470 }
1471
1472 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1473                                                TALLOC_CTX *mem_ctx,
1474                                                const struct dom_sid *domain_sid,
1475                                                const struct dom_sid *members,
1476                                                size_t num_members,
1477                                                uint32_t **palias_rids,
1478                                                size_t *pnum_alias_rids)
1479 {
1480         struct pdb_samba4_state *state = talloc_get_type_abort(
1481                 m->private_data, struct pdb_samba4_state);
1482         uint32_t *alias_rids = NULL;
1483         size_t num_alias_rids = 0;
1484         int i;
1485         struct dom_sid *groupSIDs = NULL;
1486         unsigned int num_groupSIDs = 0;
1487         char *filter;
1488         NTSTATUS status;
1489         const char *sid_string;
1490         const char *sid_dn;
1491         DATA_BLOB sid_blob;
1492
1493         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1494         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1495         /*
1496          * TODO: Get the filter right so that we only get the aliases from
1497          * either the SAM or BUILTIN
1498          */
1499
1500         filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1501                                  GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1502         if (filter == NULL) {
1503                 return NT_STATUS_NO_MEMORY;
1504         }
1505
1506         for (i = 0; i < num_members; i++) {
1507                 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1508                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1509
1510                 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1511                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1512                 
1513                 sid_blob = data_blob_string_const(sid_dn);
1514                 
1515                 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1516                                                    tmp_ctx, &groupSIDs, &num_groupSIDs);
1517                 if (!NT_STATUS_IS_OK(status)) {
1518                         talloc_free(tmp_ctx);
1519                         return status;
1520                 }
1521         }
1522
1523         alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1524         if (alias_rids == NULL) {
1525                 talloc_free(tmp_ctx);
1526                 return NT_STATUS_NO_MEMORY;
1527         }
1528
1529         for (i=0; i<num_groupSIDs; i++) {
1530                 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1531                                        &alias_rids[num_alias_rids])) {
1532                         num_alias_rids++;;
1533                 }
1534         }
1535
1536         *palias_rids = alias_rids;
1537         *pnum_alias_rids = num_alias_rids;
1538         return NT_STATUS_OK;
1539 }
1540
1541 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1542                                     const struct dom_sid *domain_sid,
1543                                     int num_rids,
1544                                     uint32 *rids,
1545                                     const char **names,
1546                                     enum lsa_SidType *lsa_attrs)
1547 {
1548         struct pdb_samba4_state *state = talloc_get_type_abort(
1549                 m->private_data, struct pdb_samba4_state);
1550         NTSTATUS status;
1551
1552         TALLOC_CTX *tmp_ctx;
1553
1554         if (num_rids == 0) {
1555                 return NT_STATUS_NONE_MAPPED;
1556         }
1557
1558         tmp_ctx = talloc_stackframe();
1559         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1560         
1561         status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1562         talloc_free(tmp_ctx);
1563         return status;
1564 }
1565
1566 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1567                                      const struct dom_sid *domain_sid,
1568                                      int num_names,
1569                                      const char **pp_names,
1570                                      uint32 *rids,
1571                                      enum lsa_SidType *attrs)
1572 {
1573         return NT_STATUS_NOT_IMPLEMENTED;
1574 }
1575
1576 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1577                                            enum pdb_policy_type type,
1578                                            uint32_t *value)
1579 {
1580         return account_policy_get(type, value)
1581                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1582 }
1583
1584 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1585                                            enum pdb_policy_type type,
1586                                            uint32_t value)
1587 {
1588         return account_policy_set(type, value)
1589                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1590 }
1591
1592 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1593                                     time_t *seq_num_out)
1594 {
1595         struct pdb_samba4_state *state = talloc_get_type_abort(
1596                 m->private_data, struct pdb_samba4_state);
1597         uint64_t seq_num;
1598         int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1599         if (ret == LDB_SUCCESS) {
1600                 *seq_num_out = seq_num;
1601                 return NT_STATUS_OK;
1602         } else {
1603                 return NT_STATUS_UNSUCCESSFUL;
1604         }
1605 }
1606
1607 struct pdb_samba4_search_state {
1608         uint32_t acct_flags;
1609         struct samr_displayentry *entries;
1610         uint32_t num_entries;
1611         ssize_t array_size;
1612         uint32_t current;
1613 };
1614
1615 static bool pdb_samba4_next_entry(struct pdb_search *search,
1616                                struct samr_displayentry *entry)
1617 {
1618         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1619                 search->private_data, struct pdb_samba4_search_state);
1620
1621         if (state->current == state->num_entries) {
1622                 return false;
1623         }
1624
1625         entry->idx = state->entries[state->current].idx;
1626         entry->rid = state->entries[state->current].rid;
1627         entry->acct_flags = state->entries[state->current].acct_flags;
1628
1629         entry->account_name = talloc_strdup(
1630                 search, state->entries[state->current].account_name);
1631         entry->fullname = talloc_strdup(
1632                 search, state->entries[state->current].fullname);
1633         entry->description = talloc_strdup(
1634                 search, state->entries[state->current].description);
1635
1636         state->current += 1;
1637         return true;
1638 }
1639
1640 static void pdb_samba4_search_end(struct pdb_search *search)
1641 {
1642         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1643                 search->private_data, struct pdb_samba4_search_state);
1644         talloc_free(state);
1645 }
1646
1647 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1648                                      struct pdb_search *search,
1649                                      struct pdb_samba4_search_state **pstate,
1650                                      const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1651 {
1652         struct pdb_samba4_state *state = talloc_get_type_abort(
1653                 m->private_data, struct pdb_samba4_state);
1654         struct pdb_samba4_search_state *sstate;
1655         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1656                                  "userAccountControl", "description", NULL };
1657         struct ldb_result *res;
1658         int i, rc, num_users;
1659
1660         va_list ap;
1661         char *expression = NULL;
1662
1663         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1664         if (!tmp_ctx) {
1665                 return false;
1666         }
1667
1668         va_start(ap, exp_fmt);
1669         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1670         va_end(ap);
1671         
1672         if (!expression) {
1673                 talloc_free(tmp_ctx);
1674                 return LDB_ERR_OPERATIONS_ERROR;
1675         }
1676
1677         sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1678         if (sstate == NULL) {
1679                 talloc_free(tmp_ctx);
1680                 return false;
1681         }
1682
1683         rc = dsdb_search(state->ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1684         if (rc != LDB_SUCCESS) {
1685                 talloc_free(tmp_ctx);
1686                 DEBUG(10, ("dsdb_search failed: %s\n",
1687                            ldb_errstring(state->ldb)));
1688                 return false;
1689         }
1690
1691         num_users = res->count;
1692
1693         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1694                                        num_users);
1695         if (sstate->entries == NULL) {
1696                 talloc_free(tmp_ctx);
1697                 DEBUG(10, ("talloc failed\n"));
1698                 return false;
1699         }
1700
1701         sstate->num_entries = 0;
1702
1703         for (i=0; i<num_users; i++) {
1704                 struct samr_displayentry *e;
1705                 struct dom_sid *sid;
1706
1707                 e = &sstate->entries[sstate->num_entries];
1708
1709                 e->idx = sstate->num_entries;
1710                 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1711                 if (!sid) {
1712                         talloc_free(tmp_ctx);
1713                         DEBUG(10, ("Could not pull SID\n"));
1714                         return false;
1715                 }
1716                 sid_peek_rid(sid, &e->rid);
1717         
1718                 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1719                                                         res->msgs[i], 
1720                                                         ldb_get_default_basedn(state->ldb));
1721                 e->account_name = ldb_msg_find_attr_as_string(
1722                         res->msgs[i], "samAccountName", NULL);
1723                 if (e->account_name == NULL) {
1724                         talloc_free(tmp_ctx);
1725                         return false;
1726                 }
1727                 e->fullname = ldb_msg_find_attr_as_string(
1728                         res->msgs[i], "displayName", "");
1729                 e->description = ldb_msg_find_attr_as_string(
1730                         res->msgs[i], "description", "");
1731
1732                 sstate->num_entries += 1;
1733                 if (sstate->num_entries >= num_users) {
1734                         break;
1735                 }
1736         }
1737         talloc_steal(sstate->entries, res->msgs);
1738         search->private_data = talloc_steal(search, sstate);
1739         search->next_entry = pdb_samba4_next_entry;
1740         search->search_end = pdb_samba4_search_end;
1741         *pstate = sstate;
1742         talloc_free(tmp_ctx);
1743         return true;
1744 }
1745
1746 static bool pdb_samba4_search_users(struct pdb_methods *m,
1747                                  struct pdb_search *search,
1748                                  uint32 acct_flags)
1749 {
1750         struct pdb_samba4_search_state *sstate;
1751         bool ret;
1752
1753         ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1754         if (!ret) {
1755                 return false;
1756         }
1757         sstate->acct_flags = acct_flags;
1758         return true;
1759 }
1760
1761 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1762                                   struct pdb_search *search)
1763 {
1764         struct pdb_samba4_search_state *sstate;
1765         bool ret;
1766
1767         ret = pdb_samba4_search_filter(m, search, &sstate, 
1768                                        "(&(grouptype=%d)(objectclass=group))",
1769                                        GTYPE_SECURITY_GLOBAL_GROUP);
1770         if (!ret) {
1771                 return false;
1772         }
1773         sstate->acct_flags = 0;
1774         return true;
1775 }
1776
1777 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1778                                    struct pdb_search *search,
1779                                    const struct dom_sid *sid)
1780 {
1781         struct pdb_samba4_search_state *sstate;
1782         bool ret;
1783
1784         ret = pdb_samba4_search_filter(m, search, &sstate, 
1785                                        "(&(grouptype=%d)(objectclass=group))",
1786                                        sid_check_is_builtin(sid)
1787                                        ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1788                                        : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1789         if (!ret) {
1790                 return false;
1791         }
1792         sstate->acct_flags = 0;
1793         return true;
1794 }
1795
1796 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1797                                struct dom_sid *sid)
1798 {
1799         struct pdb_samba4_state *state = talloc_get_type_abort(
1800                 m->private_data, struct pdb_samba4_state);
1801         NTSTATUS status;
1802         struct id_map id_map;
1803         struct id_map *id_maps[2];
1804         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1805         if (!tmp_ctx) {
1806                 return false;
1807         }
1808
1809         id_map.xid.id = uid;
1810         id_map.xid.type = ID_TYPE_UID;
1811         id_maps[0] = &id_map;
1812         id_maps[1] = NULL;
1813
1814         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1815         if (!NT_STATUS_IS_OK(status)) {
1816                 talloc_free(tmp_ctx);
1817                 return false;
1818         }
1819         *sid = *id_map.sid;
1820         talloc_free(tmp_ctx);
1821         return true;
1822 }
1823
1824 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1825                                struct dom_sid *sid)
1826 {
1827         struct pdb_samba4_state *state = talloc_get_type_abort(
1828                 m->private_data, struct pdb_samba4_state);
1829         NTSTATUS status;
1830         struct id_map id_map;
1831         struct id_map *id_maps[2];
1832         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1833         if (!tmp_ctx) {
1834                 return false;
1835         }
1836
1837         id_map.xid.id = gid;
1838         id_map.xid.type = ID_TYPE_GID;
1839         id_maps[0] = &id_map;
1840         id_maps[1] = NULL;
1841
1842         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1843         if (!NT_STATUS_IS_OK(status)) {
1844                 return false;
1845         }
1846         *sid = *id_map.sid;
1847         talloc_free(tmp_ctx);
1848         return true;
1849 }
1850
1851 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1852                                  union unid_t *id, enum lsa_SidType *type)
1853 {
1854         struct pdb_samba4_state *state = talloc_get_type_abort(
1855                 m->private_data, struct pdb_samba4_state);
1856         struct id_map id_map;
1857         struct id_map *id_maps[2];
1858         const char *attrs[] = { "objectClass", "groupType", NULL };
1859         struct ldb_message *msg;
1860         struct ldb_dn *dn;
1861         NTSTATUS status;
1862         int rc;
1863         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1864         if (!tmp_ctx) {
1865                 return false;
1866         }
1867
1868         ZERO_STRUCT(id_map);
1869
1870         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1871         if (!dn || !ldb_dn_validate(dn)) {
1872                 talloc_free(tmp_ctx);
1873                 return false;
1874         }
1875         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1876         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1877                 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)));
1878                 talloc_free(tmp_ctx);
1879                 return false;
1880         }
1881         if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
1882                 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
1883                 switch (grouptype) {
1884                 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
1885                 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
1886                         *type = SID_NAME_ALIAS;
1887                         break;
1888                 case GTYPE_SECURITY_GLOBAL_GROUP:
1889                         *type = SID_NAME_DOM_GRP;
1890                         break;
1891                 default:
1892                         talloc_free(tmp_ctx);
1893                         DEBUG(10, ("Could not pull groupType\n"));
1894                         return false;
1895                 }
1896
1897                 *type = SID_NAME_DOM_GRP;
1898
1899                 ZERO_STRUCT(id_map);
1900                 id_map.sid = sid;
1901                 id_maps[0] = &id_map;
1902                 id_maps[1] = NULL;
1903                 
1904                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1905                 talloc_free(tmp_ctx);
1906                 if (!NT_STATUS_IS_OK(status)) {
1907                         return false;
1908                 }
1909                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1910                         id->gid = id_map.xid.id;
1911                         return true;
1912                 }
1913                 return false;
1914         } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
1915                 *type = SID_NAME_USER;
1916                 ZERO_STRUCT(id_map);
1917                 id_map.sid = sid;
1918                 id_maps[0] = &id_map;
1919                 id_maps[1] = NULL;
1920                 
1921                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1922                 talloc_free(tmp_ctx);
1923                 if (!NT_STATUS_IS_OK(status)) {
1924                         return false;
1925                 }
1926                 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
1927                         id->uid = id_map.xid.id;
1928                         return true;
1929                 }
1930                 return false;
1931         }
1932         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)));
1933         talloc_free(tmp_ctx);
1934         return false;
1935 }
1936
1937 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
1938 {
1939         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1940 }
1941
1942 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
1943 {
1944         return false;
1945 }
1946
1947 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
1948                                       const char *domain, char** pwd,
1949                                       struct dom_sid *sid,
1950                                       time_t *pass_last_set_time)
1951 {
1952         return false;
1953 }
1954
1955 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
1956                                       const char* domain, const char* pwd,
1957                                       const struct dom_sid *sid)
1958 {
1959         return false;
1960 }
1961
1962 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
1963                                       const char *domain)
1964 {
1965         return false;
1966 }
1967
1968 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
1969                                          TALLOC_CTX *mem_ctx,
1970                                          uint32 *num_domains,
1971                                          struct trustdom_info ***domains)
1972 {
1973         *num_domains = 0;
1974         *domains = NULL;
1975         return NT_STATUS_OK;
1976 }
1977
1978 static void pdb_samba4_init_methods(struct pdb_methods *m)
1979 {
1980         m->name = "samba4";
1981         m->get_domain_info = pdb_samba4_get_domain_info;
1982         m->getsampwnam = pdb_samba4_getsampwnam;
1983         m->getsampwsid = pdb_samba4_getsampwsid;
1984         m->create_user = pdb_samba4_create_user;
1985         m->delete_user = pdb_samba4_delete_user;
1986         m->add_sam_account = pdb_samba4_add_sam_account;
1987         m->update_sam_account = pdb_samba4_update_sam_account;
1988         m->delete_sam_account = pdb_samba4_delete_sam_account;
1989         m->rename_sam_account = pdb_samba4_rename_sam_account;
1990         m->update_login_attempts = pdb_samba4_update_login_attempts;
1991         m->getgrsid = pdb_samba4_getgrsid;
1992         m->getgrgid = pdb_samba4_getgrgid;
1993         m->getgrnam = pdb_samba4_getgrnam;
1994         m->create_dom_group = pdb_samba4_create_dom_group;
1995         m->delete_dom_group = pdb_samba4_delete_dom_group;
1996         m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
1997         m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
1998         m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
1999         m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2000         m->enum_group_members = pdb_samba4_enum_group_members;
2001         m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2002         m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2003         m->add_groupmem = pdb_samba4_add_groupmem;
2004         m->del_groupmem = pdb_samba4_del_groupmem;
2005         m->create_alias = pdb_samba4_create_alias;
2006         m->delete_alias = pdb_samba4_delete_alias;
2007         m->get_aliasinfo = pdb_default_get_aliasinfo;
2008         m->add_aliasmem = pdb_samba4_add_aliasmem;
2009         m->del_aliasmem = pdb_samba4_del_aliasmem;
2010         m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2011         m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2012         m->lookup_rids = pdb_samba4_lookup_rids;
2013         m->lookup_names = pdb_samba4_lookup_names;
2014         m->get_account_policy = pdb_samba4_get_account_policy;
2015         m->set_account_policy = pdb_samba4_set_account_policy;
2016         m->get_seq_num = pdb_samba4_get_seq_num;
2017         m->search_users = pdb_samba4_search_users;
2018         m->search_groups = pdb_samba4_search_groups;
2019         m->search_aliases = pdb_samba4_search_aliases;
2020         m->uid_to_sid = pdb_samba4_uid_to_sid;
2021         m->gid_to_sid = pdb_samba4_gid_to_sid;
2022         m->sid_to_id = pdb_samba4_sid_to_id;
2023         m->capabilities = pdb_samba4_capabilities;
2024         m->new_rid = pdb_samba4_new_rid;
2025         m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2026         m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2027         m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2028         m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2029 }
2030
2031 static void free_private_data(void **vp)
2032 {
2033         struct pdb_samba4_state *state = talloc_get_type_abort(
2034                 *vp, struct pdb_samba4_state);
2035         talloc_unlink(state, state->ldb);
2036         return;
2037 }
2038
2039 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2040                              const char *location)
2041 {
2042         struct pdb_methods *m;
2043         struct pdb_samba4_state *state;
2044         NTSTATUS status;
2045
2046         if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2047                 return status;
2048         }
2049
2050         state = talloc_zero(m, struct pdb_samba4_state);
2051         if (state == NULL) {
2052                 goto nomem;
2053         }
2054         m->private_data = state;
2055         m->free_private_data = free_private_data;
2056         pdb_samba4_init_methods(m);
2057
2058         state->ev = s4_event_context_init(state);
2059         if (!state->ev) {
2060                 DEBUG(10, ("s4_event_context_init failed\n"));
2061                 goto fail;
2062         }
2063
2064         state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2065         if (state->lp_ctx == NULL) {
2066                 DEBUG(10, ("loadparm_init_s3 failed\n"));
2067                 goto fail;
2068         }
2069
2070         state->ldb = samdb_connect(state,
2071                                    state->ev,
2072                                    state->lp_ctx,
2073                                    system_session(state->lp_ctx), 0);
2074
2075         if (!state->ldb) {
2076                 DEBUG(10, ("samdb_connect failed\n"));
2077                 goto fail;
2078         }
2079
2080         state->idmap_ctx = idmap_init(state, state->ev,
2081                                       state->lp_ctx);
2082         if (!state->idmap_ctx) {
2083                 DEBUG(10, ("samdb_connect failed\n"));
2084                 goto fail;
2085         }
2086
2087         *pdb_method = m;
2088         return NT_STATUS_OK;
2089 nomem:
2090         status = NT_STATUS_NO_MEMORY;
2091 fail:
2092         TALLOC_FREE(m);
2093         return status;
2094 }
2095
2096 NTSTATUS pdb_samba4_init(void);
2097 NTSTATUS pdb_samba4_init(void)
2098 {
2099         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2100                                    pdb_init_samba4);
2101 }