s3-auth move the s3 auth context onto gensec_ntlmssp once we start
[obnox/samba/samba-obnox.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 "lib/param/param.h"
36 #include "source4/dsdb/common/util.h"
37
38 struct pdb_samba4_state {
39         struct tevent_context *ev;
40         struct ldb_context *ldb;
41         struct idmap_context *idmap_ctx;
42         struct loadparm_context *lp_ctx;
43 };
44
45 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
46                                     struct samu *sam_acct,
47                                     const struct dom_sid *sid);
48 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
49                                     const char *filter,
50                                     TALLOC_CTX *mem_ctx,
51                                     struct ldb_message **pmsg);
52 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
53                                  union unid_t *id, enum lsa_SidType *type);
54
55 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
56                               time_t *ptime)
57 {
58         uint64_t tmp;
59         if (! ldb_msg_find_element(msg, attr)) {
60                 return false;
61         }
62         tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
63         *ptime = uint64s_nt_time_to_unix_abs(&tmp);
64         return true;
65 }
66
67 static struct pdb_domain_info *pdb_samba4_get_domain_info(
68         struct pdb_methods *m, TALLOC_CTX *mem_ctx)
69 {
70         struct pdb_samba4_state *state = talloc_get_type_abort(
71                 m->private_data, struct pdb_samba4_state);
72         struct pdb_domain_info *info;
73         struct dom_sid *domain_sid;
74         struct ldb_dn *forest_dn, *domain_dn;
75         struct ldb_result *dom_res = NULL;
76         const char *dom_attrs[] = {
77                 "objectSid", 
78                 "objectGUID", 
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 static int pdb_samba4_replace_by_sam(struct pdb_samba4_state *state,
332                                      bool (*need_update)(const struct samu *,
333                                                          enum pdb_elements),
334                                      struct ldb_dn *dn,
335                                      struct samu *sam)
336 {
337         int ret = LDB_SUCCESS;
338         const char *pw;
339         struct ldb_message *msg;
340         struct ldb_request *req;
341         uint32_t dsdb_flags = 0;
342         /* TODO: All fields :-) */
343
344         msg = ldb_msg_new(talloc_tos());
345         if (!msg) {
346                 return false;
347         }
348
349         msg->dn = dn;
350
351         /* build modify request */
352         ret = ldb_build_mod_req(&req, state->ldb, talloc_tos(), msg, NULL, NULL,
353                                 ldb_op_default_callback,
354                                 NULL);
355         if (ret != LDB_SUCCESS) {
356                 talloc_free(msg);
357                 return ret;
358         }
359
360         pw = pdb_get_plaintext_passwd(sam);
361         if (need_update(sam, PDB_PLAINTEXT_PW)) {
362                 if (pw == NULL) {
363                         return LDB_ERR_OPERATIONS_ERROR;
364                 }
365                 
366                 ret |= ldb_msg_add_string(msg, "clearTextPassword", pw);
367         } else {
368                 bool changed_lm_pw = false;
369                 bool changed_nt_pw = false;
370                 bool changed_history = false;
371                 if (need_update(sam, PDB_LMPASSWD)) {
372                         struct ldb_val val;
373                         val.data = pdb_get_lanman_passwd(sam);
374                         if (!val.data) {
375                                 samdb_msg_add_delete(state->ldb, msg, msg,
376                                                      "dBCSPwd");
377                         } else {
378                                 val.length = LM_HASH_LEN;
379                                 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
380                         }
381                         changed_lm_pw = true;
382                 }
383                 if (need_update(sam, PDB_NTPASSWD)) {
384                         struct ldb_val val;
385                         val.data = pdb_get_nt_passwd(sam);
386                         if (!val.data) {
387                                 samdb_msg_add_delete(state->ldb, msg, msg,
388                                                      "unicodePwd");
389                         } else {
390                                 val.length = NT_HASH_LEN;
391                                 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
392                         }
393                         changed_nt_pw = true;
394                 }
395
396                 /* Try to ensure we don't get out of sync */
397                 if (changed_lm_pw && !changed_nt_pw) {
398                         samdb_msg_add_delete(state->ldb, msg, msg,
399                                              "unicodePwd");
400                 } else if (changed_nt_pw && !changed_lm_pw) {
401                         samdb_msg_add_delete(state->ldb, msg, msg,
402                                              "dBCSPwd");
403                 }
404                 if (changed_lm_pw || changed_nt_pw) {
405                         samdb_msg_add_delete(state->ldb, msg, msg,
406                                              "supplementalCredentials");
407
408                 }
409
410                 /* If we set a plaintext password, the system will
411                  * force the pwdLastSet to now(), and it isn't worth
412                  * working around this for the real world use cases of
413                  * pdb_samba4 */
414                 if (need_update(sam, PDB_PASSLASTSET)) {
415                         ret |= pdb_samba4_add_time(msg, "pwdLastSet",
416                                                    pdb_get_pass_last_set_time(sam));
417                 }
418
419                 if (need_update(sam, PDB_PWHISTORY)) {
420                         uint32_t current_hist_len;
421                         const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
422
423                         bool invalid_history = false;
424                         struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
425                                                                             current_hist_len);
426                         if (!history) {
427                                 invalid_history = true;
428                         } else {
429                                 unsigned int i;
430                                 static const uint8_t zeros[16];
431                                 /* Parse the history into the correct format */
432                                 for (i = 0; i < current_hist_len; i++) {
433                                         if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
434                                                 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
435                                                 invalid_history = true;
436                                                 break;
437                                         }
438                                         /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
439                                         memcpy(history_hashes[i].hash,
440                                                &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
441                                                sizeof(history_hashes[i].hash));
442                                 }
443                         }
444                         if (invalid_history) {
445                                 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
446                                                      "ntPwdHistory");
447
448                                 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
449                                                      "lmPwdHistory");
450                         } else {
451                                 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
452                                                             "ntPwdHistory",
453                                                             history_hashes,
454                                                             current_hist_len);
455                         }
456                         changed_history = true;
457                 }
458                 if (changed_lm_pw || changed_nt_pw || changed_history) {
459                         /* These attributes can only be modified directly by using a special control */
460                         dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
461                 }
462         }
463
464         /* PDB_USERSID is only allowed on ADD, handled in caller */
465         if (need_update(sam, PDB_GROUPSID)) {
466                 const struct dom_sid *sid = pdb_get_group_sid(sam);
467                 uint32_t rid;
468                 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
469                 if (!NT_STATUS_IS_OK(status)) {
470                         return LDB_ERR_OPERATIONS_ERROR;
471                 }
472                 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
473                         return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
474                 }
475                 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
476         }
477         if (need_update(sam, PDB_FULLNAME)) {
478                 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
479         }
480
481         if (need_update(sam, PDB_SMBHOME)) {
482                 ret |= ldb_msg_add_string(msg, "homeDirectory",
483                                           pdb_get_homedir(sam));
484         }
485
486         if (need_update(sam, PDB_PROFILE)) {
487                 ret |= ldb_msg_add_string(msg, "profilePath",
488                                           pdb_get_profile_path(sam));
489         }
490
491         if (need_update(sam, PDB_DRIVE)) {
492                 ret |= ldb_msg_add_string(msg, "homeDrive",
493                                           pdb_get_dir_drive(sam));
494         }
495
496         if (need_update(sam, PDB_LOGONSCRIPT)) {
497                 ret |= ldb_msg_add_string(msg, "scriptPath",
498                                           pdb_get_logon_script(sam));
499         }
500
501         if (need_update(sam, PDB_KICKOFFTIME)) {
502                 ret |= pdb_samba4_add_time(msg, "accountExpires",
503                                         pdb_get_kickoff_time(sam));
504         }
505
506         if (need_update(sam, PDB_USERNAME)) {
507                 ret |= ldb_msg_add_string(msg, "samAccountName",
508                                           pdb_get_username(sam));
509         }
510
511         if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
512                 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
513                 ret |= ldb_msg_add_value(msg, "logonHours",
514                                          &hours, NULL);
515         }
516
517         if (need_update(sam, PDB_ACCTCTRL)) {
518                 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
519                                                 "userAccountControl", pdb_get_acct_ctrl(sam));
520         }
521
522         if (need_update(sam, PDB_COMMENT)) {
523                 ret |= ldb_msg_add_string(msg, "comment",
524                                           pdb_get_comment(sam));
525         }
526
527         if (need_update(sam, PDB_ACCTDESC)) {
528                 ret |= ldb_msg_add_string(msg, "description",
529                                           pdb_get_acct_desc(sam));
530         }
531
532         if (need_update(sam, PDB_WORKSTATIONS)) {
533                 ret |= ldb_msg_add_string(msg, "userWorkstations",
534                                           pdb_get_workstations(sam));
535         }
536
537         /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
538         if (need_update(sam, PDB_MUNGEDDIAL)) {
539                 ret |= ldb_msg_add_string(msg, "userParameters",
540                                           pdb_get_munged_dial(sam));
541         }
542
543         if (need_update(sam, PDB_COUNTRY_CODE)) {
544                 ret |= ldb_msg_add_fmt(msg, "countryCode",
545                                        "%i", (int)pdb_get_country_code(sam));
546         }
547
548         if (need_update(sam, PDB_CODE_PAGE)) {
549                 ret |= ldb_msg_add_fmt(msg, "codePage",
550                                        "%i", (int)pdb_get_code_page(sam));
551         }
552
553         /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
554         PDB_LOGONTIME,
555         PDB_LOGOFFTIME,
556         PDB_BAD_PASSWORD_TIME,
557         PDB_CANCHANGETIME, - these are calculated per policy, not stored
558         PDB_MUSTCHANGETIME, - these are calculated per policy, not stored
559         PDB_DOMAIN,
560         PDB_NTUSERNAME, - this makes no sense, and never really did
561         PDB_LOGONDIVS,
562         PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
563         PDB_FIELDS_PRESENT,
564         PDB_BAD_PASSWORD_COUNT,
565         PDB_LOGON_COUNT,
566         PDB_UNKNOWN6,
567         PDB_BACKEND_PRIVATE_DATA,
568
569  */
570         if (ret != LDB_SUCCESS) {
571                 return LDB_ERR_OPERATIONS_ERROR;
572         }
573
574         if (msg->num_elements == 0) {
575                 /* Nothing to do, just return success */
576                 return LDB_SUCCESS;
577         }
578
579         ret = dsdb_replace(state->ldb, msg, dsdb_flags);
580
581         if (ret != LDB_SUCCESS) {
582                 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
583                          ldb_dn_get_linearized(msg->dn),
584                          ldb_errstring(state->ldb)));
585         }
586
587         return ret;
588 }
589
590 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
591                                     const char *filter,
592                                     TALLOC_CTX *mem_ctx,
593                                     struct ldb_message **msg)
594 {
595         const char * attrs[] = {
596                 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
597                 "sAMAccountName", "displayName", "homeDirectory",
598                 "homeDrive", "scriptPath", "profilePath", "description",
599                 "userWorkstations", "comment", "userParameters", "objectSid",
600                 "primaryGroupID", "userAccountControl", "logonHours",
601                 "badPwdCount", "logonCount", "countryCode", "codePage",
602                 "unicodePwd", "dBCSPwd", NULL };
603
604         int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
605         if (rc != LDB_SUCCESS) {
606                 DEBUG(10, ("ldap_search failed %s\n",
607                            ldb_errstring(state->ldb)));
608                 return NT_STATUS_LDAP(rc);
609         }
610
611         return NT_STATUS_OK;
612 }
613
614 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
615                                           struct pdb_samba4_state *state,
616                                           struct samu *sam_acct,
617                                           const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
618 {
619         struct ldb_message *priv;
620         NTSTATUS status;
621         va_list ap;
622         char *expression = NULL;
623         TALLOC_CTX *tmp_ctx = talloc_new(state);
624         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
625
626         va_start(ap, exp_fmt);
627         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
628         va_end(ap);
629         
630         if (!expression) {
631                 talloc_free(tmp_ctx);
632                 return NT_STATUS_NO_MEMORY;
633         }
634
635         status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
636         talloc_free(tmp_ctx);
637         if (!NT_STATUS_IS_OK(status)) {
638                 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
639                            nt_errstr(status)));
640                 return status;
641         }
642
643         status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
644         if (!NT_STATUS_IS_OK(status)) {
645                 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
646                            nt_errstr(status)));
647                 TALLOC_FREE(priv);
648                 return status;
649         }
650
651         pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
652         return NT_STATUS_OK;
653 }
654
655 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
656                                     struct samu *sam_acct,
657                                     const char *username)
658 {
659         struct pdb_samba4_state *state = talloc_get_type_abort(
660                 m->private_data, struct pdb_samba4_state);
661
662         return pdb_samba4_getsampwfilter(m, state, sam_acct, 
663                                          "(&(samaccountname=%s)(objectclass=user))",
664                                          username);
665 }
666
667 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
668                                     struct samu *sam_acct,
669                                     const struct dom_sid *sid)
670 {
671         NTSTATUS status;
672         struct pdb_samba4_state *state = talloc_get_type_abort(
673                 m->private_data, struct pdb_samba4_state);
674         char *sidstr;
675
676         sidstr = dom_sid_string(talloc_tos(), sid);
677         NT_STATUS_HAVE_NO_MEMORY(sidstr);
678
679         status = pdb_samba4_getsampwfilter(m, state, sam_acct,  
680                                            "(&(objectsid=%s)(objectclass=user))", 
681                                            sidstr);
682         talloc_free(sidstr);
683         return status;
684 }
685
686 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
687                                     TALLOC_CTX *mem_ctx,
688                                     const char *name, uint32 acct_flags,
689                                     uint32 *rid)
690 {
691         struct pdb_samba4_state *state = talloc_get_type_abort(
692                 m->private_data, struct pdb_samba4_state);
693         struct dom_sid *sid;
694         struct ldb_dn *dn;
695         NTSTATUS status;
696         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
697         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
698
699         /* Internally this uses transactions to ensure all the steps
700          * happen or fail as one */
701         status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
702                                &sid, &dn);
703         if (!NT_STATUS_IS_OK(status)) {
704                 talloc_free(tmp_ctx);
705                 return status;
706         }
707         sid_peek_rid(sid, rid);
708         talloc_free(tmp_ctx);
709         return NT_STATUS_OK;
710 }
711
712 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
713                                        TALLOC_CTX *mem_ctx,
714                                        struct samu *sam)
715 {
716         struct pdb_samba4_state *state = talloc_get_type_abort(
717                 m->private_data, struct pdb_samba4_state);
718         struct ldb_dn *dn;
719         int rc;
720         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
721         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
722
723         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
724         if (!dn || !ldb_dn_validate(dn)) {
725                 talloc_free(tmp_ctx);
726                 return NT_STATUS_NO_MEMORY;
727         }
728         rc = ldb_delete(state->ldb, dn);
729
730         if (rc != LDB_SUCCESS) {
731                 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
732                            ldb_errstring(state->ldb)));
733                 talloc_free(tmp_ctx);
734                 return NT_STATUS_LDAP(rc);
735         }
736         talloc_free(tmp_ctx);
737         return NT_STATUS_OK;
738 }
739
740 /* This interface takes a fully populated struct samu and places it in
741  * the database.  This is not implemented at this time as we need to
742  * be careful around the creation of arbitary SIDs (ie, we must ensrue
743  * they are not left in a RID pool */
744 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
745                                         struct samu *sampass)
746 {
747         int ret;
748         NTSTATUS status;
749         struct ldb_dn *dn;
750         struct pdb_samba4_state *state = talloc_get_type_abort(
751                 m->private_data, struct pdb_samba4_state);
752         uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
753         const char *username = pdb_get_username(sampass);
754         const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
755         TALLOC_CTX *tframe = talloc_stackframe();
756
757         acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
758
759         ret = ldb_transaction_start(state->ldb);
760         if (ret != LDB_SUCCESS) {
761                 talloc_free(tframe);
762                 return NT_STATUS_LOCK_NOT_GRANTED;
763         }
764
765         status = dsdb_add_user(state->ldb, talloc_tos(), username,
766                                acb_flags, user_sid, NULL, &dn);
767         if (!NT_STATUS_IS_OK(status)) {
768                 ldb_transaction_cancel(state->ldb);
769                 talloc_free(tframe);
770                 return status;
771         }
772
773         ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
774                                         dn, sampass);
775         if (ret != LDB_SUCCESS) {
776                 ldb_transaction_cancel(state->ldb);
777                 talloc_free(tframe);
778                 return dsdb_ldb_err_to_ntstatus(ret);
779         }
780
781         ret = ldb_transaction_commit(state->ldb);
782         if (ret != LDB_SUCCESS) {
783                 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
784                          ldb_dn_get_linearized(dn),
785                          ldb_errstring(state->ldb)));
786                 talloc_free(tframe);
787                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
788         }
789         talloc_free(tframe);
790         return NT_STATUS_OK;
791 }
792
793 /*
794  * Update the Samba4 LDB with the changes from a struct samu.
795  *
796  * This takes care not to update elements that have not been changed
797  * by the caller
798  */
799 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
800                                            struct samu *sam)
801 {
802         struct pdb_samba4_state *state = talloc_get_type_abort(
803                 m->private_data, struct pdb_samba4_state);
804         struct ldb_message *msg = pdb_samba4_get_samu_private(
805                 m, sam);
806         int ret;
807
808         ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
809                                         sam);
810         return dsdb_ldb_err_to_ntstatus(ret);
811 }
812
813 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
814                                            struct samu *username)
815 {
816         NTSTATUS status;
817         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
818         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
819         status = pdb_samba4_delete_user(m, tmp_ctx, username);
820         talloc_free(tmp_ctx);
821         return status;
822 }
823
824 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
825                                            struct samu *oldname,
826                                            const char *newname)
827 {
828         return NT_STATUS_NOT_IMPLEMENTED;
829 }
830
831 /* This is not implemented, as this module is exptected to be used
832  * with auth_samba4, and this is responible for login counters etc
833  *
834  */
835 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
836                                               struct samu *sam_acct,
837                                               bool success)
838 {
839         return NT_STATUS_NOT_IMPLEMENTED;
840 }
841
842 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
843                                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
844 {
845         struct pdb_samba4_state *state = talloc_get_type_abort(
846                 m->private_data, struct pdb_samba4_state);
847         const char *attrs[] = { "objectSid", "description", "samAccountName",
848                                 NULL };
849         struct ldb_message *msg;
850         va_list ap;
851         char *expression = NULL;
852         struct dom_sid *sid;
853         const char *str;
854         int rc;
855         union unid_t id;
856         TALLOC_CTX *tmp_ctx = talloc_stackframe();
857         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
858         
859         va_start(ap, exp_fmt);
860         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
861         va_end(ap);
862         
863         if (!expression) {
864                 talloc_free(tmp_ctx);
865                 return NT_STATUS_NO_MEMORY;
866         }
867
868         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
869         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
870                 talloc_free(tmp_ctx);
871                 return NT_STATUS_NO_SUCH_GROUP;
872         } else if (rc != LDB_SUCCESS) {
873                 talloc_free(tmp_ctx);
874                 DEBUG(10, ("dsdb_search_one failed %s\n",
875                            ldb_errstring(state->ldb)));
876                 return NT_STATUS_LDAP(rc);
877         }
878
879         sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
880         if (!sid) {
881                 talloc_free(tmp_ctx);
882                 DEBUG(10, ("Could not pull SID\n"));
883                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
884         }
885         
886         map->sid = *sid;
887         
888         if (!pdb_samba4_sid_to_id(m, sid, &id, &map->sid_name_use)) {
889                 talloc_free(tmp_ctx);
890                 return NT_STATUS_NO_SUCH_GROUP;
891         }
892         if (map->sid_name_use == SID_NAME_USER) {
893                 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
894                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
895         }
896         map->gid = id.gid;
897
898         str = ldb_msg_find_attr_as_string(msg, "samAccountName",
899                                           NULL);
900         if (str == NULL) {
901                 talloc_free(tmp_ctx);
902                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
903         }
904         map->nt_name = talloc_strdup(map, str);
905         if (!map->nt_name) {
906                 talloc_free(tmp_ctx);
907                 return NT_STATUS_NO_MEMORY;
908         }
909
910         str = ldb_msg_find_attr_as_string(msg, "description",
911                                             NULL);
912         if (str != NULL) {
913                 map->comment = talloc_strdup(map, str);
914         } else {
915                 map->comment = talloc_strdup(map, "");
916         }
917         if (!map->comment) {
918                 talloc_free(tmp_ctx);
919                 return NT_STATUS_NO_MEMORY;
920         }
921
922         talloc_free(tmp_ctx);
923         return NT_STATUS_OK;
924 }
925
926 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
927                                  struct dom_sid sid)
928 {
929         char *filter;
930         NTSTATUS status;
931
932         filter = talloc_asprintf(talloc_tos(),
933                                  "(&(objectsid=%s)(objectclass=group))",
934                                  sid_string_talloc(talloc_tos(), &sid));
935         if (filter == NULL) {
936                 return NT_STATUS_NO_MEMORY;
937         }
938
939         status = pdb_samba4_getgrfilter(m, map, filter);
940         TALLOC_FREE(filter);
941         return status;
942 }
943
944 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
945                                  gid_t gid)
946 {
947         struct pdb_samba4_state *state = talloc_get_type_abort(
948                 m->private_data, struct pdb_samba4_state);
949         NTSTATUS status;
950         struct id_map id_map;
951         struct id_map *id_maps[2];
952         TALLOC_CTX *tmp_ctx = talloc_stackframe();
953         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
954
955         id_map.xid.id = gid;
956         id_map.xid.type = ID_TYPE_GID;
957         id_maps[0] = &id_map;
958         id_maps[1] = NULL;
959
960         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
961         if (!NT_STATUS_IS_OK(status)) {
962                 return status;
963         }
964         status = pdb_samba4_getgrsid(m, map, *id_map.sid);
965         talloc_free(tmp_ctx);
966         return status;
967 }
968
969 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
970                                  const char *name)
971 {
972         char *filter;
973         NTSTATUS status;
974
975         filter = talloc_asprintf(talloc_tos(),
976                                  "(&(samaccountname=%s)(objectclass=group))",
977                                  name);
978         if (filter == NULL) {
979                 return NT_STATUS_NO_MEMORY;
980         }
981
982         status = pdb_samba4_getgrfilter(m, map, filter);
983         TALLOC_FREE(filter);
984         return status;
985 }
986
987 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
988                                          TALLOC_CTX *mem_ctx, const char *name,
989                                          uint32 *rid)
990 {
991         struct pdb_samba4_state *state = talloc_get_type_abort(
992                 m->private_data, struct pdb_samba4_state);
993         NTSTATUS status;
994         struct dom_sid *sid;
995         struct ldb_dn *dn;
996         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
997         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
998
999         status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 talloc_free(tmp_ctx);
1002                 return status;
1003         }
1004
1005         sid_peek_rid(sid, rid);
1006         talloc_free(tmp_ctx);
1007         return NT_STATUS_OK;
1008 }
1009
1010 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1011                                          TALLOC_CTX *mem_ctx, uint32 rid)
1012 {
1013         const char *attrs[] = { NULL };
1014         struct pdb_samba4_state *state = talloc_get_type_abort(
1015                 m->private_data, struct pdb_samba4_state);
1016         struct dom_sid sid;
1017         struct ldb_message *msg;
1018         struct ldb_dn *dn;
1019         int rc;
1020         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1021         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1022
1023         sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1024         
1025         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1026                 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1027                 return NT_STATUS_INTERNAL_ERROR;
1028         }
1029
1030         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1031         if (!dn || !ldb_dn_validate(dn)) {
1032                 talloc_free(tmp_ctx);
1033                 ldb_transaction_cancel(state->ldb);
1034                 return NT_STATUS_NO_MEMORY;
1035         }
1036         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1037         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1038                 talloc_free(tmp_ctx);
1039                 ldb_transaction_cancel(state->ldb);
1040                 return NT_STATUS_NO_SUCH_GROUP;
1041         }
1042         rc = ldb_delete(state->ldb, dn);
1043         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1044                 talloc_free(tmp_ctx);
1045                 ldb_transaction_cancel(state->ldb);
1046                 return NT_STATUS_NO_SUCH_GROUP;
1047         } else if (rc != LDB_SUCCESS) {
1048                 DEBUG(10, ("ldb_delete failed %s\n",
1049                            ldb_errstring(state->ldb)));
1050                 ldb_transaction_cancel(state->ldb);
1051                 return NT_STATUS_LDAP(rc);
1052         }
1053
1054         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1055                 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1056                 return NT_STATUS_INTERNAL_ERROR;
1057         }
1058         return NT_STATUS_OK;
1059 }
1060
1061 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1062                                                 GROUP_MAP *map)
1063 {
1064         return NT_STATUS_NOT_IMPLEMENTED;
1065 }
1066
1067 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1068                                                    GROUP_MAP *map)
1069 {
1070         return NT_STATUS_NOT_IMPLEMENTED;
1071 }
1072
1073 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1074                                                    struct dom_sid sid)
1075 {
1076         return NT_STATUS_NOT_IMPLEMENTED;
1077 }
1078
1079 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1080                                            const struct dom_sid *sid,
1081                                            enum lsa_SidType sid_name_use,
1082                                            GROUP_MAP ***pp_rmap,
1083                                            size_t *p_num_entries,
1084                                            bool unix_only)
1085 {
1086         return NT_STATUS_NOT_IMPLEMENTED;
1087 }
1088
1089 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1090                                            TALLOC_CTX *mem_ctx,
1091                                            const struct dom_sid *group,
1092                                            uint32_t **pmembers,
1093                                            size_t *pnum_members)
1094 {
1095         unsigned int i, num_sids, num_members;
1096         struct pdb_samba4_state *state = talloc_get_type_abort(
1097                 m->private_data, struct pdb_samba4_state);
1098         struct dom_sid *members_as_sids;
1099         struct dom_sid *dom_sid;
1100         uint32_t *members;
1101         struct ldb_dn *dn;
1102         NTSTATUS status;
1103
1104         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1105         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1106
1107         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1108         if (!dn || !ldb_dn_validate(dn)) {
1109                 return NT_STATUS_NO_MEMORY;
1110         }
1111
1112         status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1113         if (!NT_STATUS_IS_OK(status)) {
1114                 talloc_free(tmp_ctx);
1115                 return status;
1116         }
1117         status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1118         if (!NT_STATUS_IS_OK(status)) {
1119                 talloc_free(tmp_ctx);
1120                 return status;
1121         }
1122
1123         *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1124         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1125         num_members = 0;
1126
1127         for (i = 0; i < num_sids; i++) {
1128                 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1129                         continue;
1130                 }
1131                 status = dom_sid_split_rid(NULL, &members_as_sids[i], 
1132                                            NULL, &members[num_members]);
1133                 if (!NT_STATUS_IS_OK(status)) {
1134                         talloc_free(tmp_ctx);
1135                         return status;
1136                 }
1137                 num_members++;
1138         }
1139         *pnum_members = num_members;
1140         return NT_STATUS_OK;
1141 }
1142
1143 /* Just convert the primary group SID into a group */
1144 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1145                                             TALLOC_CTX *mem_ctx,
1146                                             struct samu *user,
1147                                             struct dom_sid **pp_sids,
1148                                             gid_t **pp_gids,
1149                                             uint32_t *p_num_groups)
1150 {
1151         NTSTATUS status;
1152         size_t num_groups = 0;
1153         struct dom_sid *group_sids;
1154         gid_t *gids;
1155         TALLOC_CTX *tmp_ctx;
1156         
1157         tmp_ctx = talloc_new(mem_ctx);
1158         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1159
1160         if (user->group_sid) {
1161                 struct id_map *id_maps[2];
1162                 struct id_map id_map;
1163
1164                 num_groups = 1;
1165
1166                 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1167                 if (group_sids == NULL) {
1168                         talloc_free(tmp_ctx);
1169                         return NT_STATUS_NO_MEMORY;
1170                 }
1171                 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1172                 if (gids == NULL) {
1173                         talloc_free(tmp_ctx);
1174                         return NT_STATUS_NO_MEMORY;
1175                 }
1176
1177                 group_sids[0] = *user->group_sid;
1178
1179                 ZERO_STRUCT(id_map);
1180                 id_map.sid = &group_sids[0];
1181                 id_maps[0] = &id_map;
1182                 id_maps[1] = NULL;
1183                 
1184                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1185                 if (!NT_STATUS_IS_OK(status)) {
1186                         talloc_free(tmp_ctx);
1187                         return status;
1188                 }
1189                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1190                         gids[0] = id_map.xid.id;
1191                 } else {
1192                         DEBUG(1, (__location__ 
1193                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1194                                   dom_sid_string(tmp_ctx, &group_sids[0]),
1195                                   dom_sid_string(tmp_ctx, &user->user_sid)));
1196                         talloc_free(tmp_ctx);
1197                         /* We must error out, otherwise a user might
1198                          * avoid a DENY acl based on a group they
1199                          * missed out on */
1200                         return NT_STATUS_NO_SUCH_GROUP;
1201                 }
1202         }
1203
1204         *pp_sids = talloc_steal(mem_ctx, group_sids);
1205         *pp_gids = talloc_steal(mem_ctx, gids);
1206         *p_num_groups = num_groups;
1207         talloc_free(tmp_ctx);
1208         return NT_STATUS_OK;
1209 }
1210
1211 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1212                                                TALLOC_CTX *mem_ctx,
1213                                                struct samu *user,
1214                                                struct dom_sid **pp_sids,
1215                                                gid_t **pp_gids,
1216                                                uint32_t *p_num_groups)
1217 {
1218         struct pdb_samba4_state *state = talloc_get_type_abort(
1219                 m->private_data, struct pdb_samba4_state);
1220         struct ldb_message *msg = pdb_samba4_get_samu_private(
1221                 m, user);
1222         const char *attrs[] = { "tokenGroups", NULL};
1223         struct ldb_message *tokengroups_msg;
1224         struct ldb_message_element *tokengroups;
1225         int i, rc;
1226         NTSTATUS status;
1227         unsigned int count = 0;
1228         size_t num_groups;
1229         struct dom_sid *group_sids;
1230         gid_t *gids;
1231         TALLOC_CTX *tmp_ctx;
1232                 
1233         if (msg == NULL) {
1234                 /* Fake up some things here */
1235                 return fake_enum_group_memberships(state, 
1236                                                    mem_ctx, 
1237                                                    user, pp_sids,
1238                                                    pp_gids, p_num_groups);
1239         }
1240
1241         tmp_ctx = talloc_new(mem_ctx);
1242         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1243
1244         rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1245
1246         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1247                 talloc_free(tmp_ctx);
1248                 return NT_STATUS_NO_SUCH_USER;
1249         } else if (rc != LDB_SUCCESS) {
1250                 DEBUG(10, ("dsdb_search_one failed %s\n",
1251                            ldb_errstring(state->ldb)));
1252                 talloc_free(tmp_ctx);
1253                 return NT_STATUS_LDAP(rc);
1254         }
1255
1256         tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1257
1258         if (tokengroups) {
1259                 count = tokengroups->num_values;
1260         }
1261
1262         group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1263         if (group_sids == NULL) {
1264                 talloc_free(tmp_ctx);
1265                 return NT_STATUS_NO_MEMORY;
1266         }
1267         gids = talloc_array(tmp_ctx, gid_t, count);
1268         if (gids == NULL) {
1269                 talloc_free(tmp_ctx);
1270                 return NT_STATUS_NO_MEMORY;
1271         }
1272         num_groups = 0;
1273
1274         for (i=0; i<count; i++) {
1275                 struct id_map *id_maps[2];
1276                 struct id_map id_map;
1277                 struct ldb_val *v = &tokengroups->values[i];
1278                 enum ndr_err_code ndr_err
1279                         = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1280                                                (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1281                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1282                         talloc_free(tmp_ctx);
1283                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1284                 }
1285                 
1286                 ZERO_STRUCT(id_map);
1287                 id_map.sid = &group_sids[num_groups];
1288                 id_maps[0] = &id_map;
1289                 id_maps[1] = NULL;
1290
1291                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1292                 if (!NT_STATUS_IS_OK(status)) {
1293                         talloc_free(tmp_ctx);
1294                         return status;
1295                 }
1296                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1297                         gids[num_groups] = id_map.xid.id;
1298                 } else {
1299                         DEBUG(1, (__location__ 
1300                                   "Group %s, of which %s is a member, could not be converted to a GID\n",
1301                                   dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1302                                   ldb_dn_get_linearized(msg->dn)));
1303                         talloc_free(tmp_ctx);
1304                         /* We must error out, otherwise a user might
1305                          * avoid a DENY acl based on a group they
1306                          * missed out on */
1307                         return NT_STATUS_NO_SUCH_GROUP;
1308                 }
1309
1310                 num_groups += 1;
1311                 if (num_groups == count) {
1312                         break;
1313                 }
1314         }
1315
1316         *pp_sids = talloc_steal(mem_ctx, group_sids);
1317         *pp_gids = talloc_steal(mem_ctx, gids);
1318         *p_num_groups = num_groups;
1319         talloc_free(tmp_ctx);
1320         return NT_STATUS_OK;
1321 }
1322
1323 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1324                                                TALLOC_CTX *mem_ctx,
1325                                                struct samu *user)
1326 {
1327         return NT_STATUS_NOT_IMPLEMENTED;
1328 }
1329
1330 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1331                                                TALLOC_CTX *mem_ctx,
1332                                                const struct dom_sid *groupsid, 
1333                                                const struct dom_sid *membersid,
1334                                                int mod_op)
1335 {
1336         struct pdb_samba4_state *state = talloc_get_type_abort(
1337                 m->private_data, struct pdb_samba4_state);
1338         struct ldb_message *msg;
1339         int ret;
1340         struct ldb_message_element *el;
1341         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1342         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1343         msg = ldb_msg_new(tmp_ctx);
1344         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1345
1346         msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1347         if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1348                 talloc_free(tmp_ctx);
1349                 return NT_STATUS_NO_MEMORY;
1350         }
1351         ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1352         if (ret != LDB_SUCCESS) {
1353                 talloc_free(tmp_ctx);
1354                 return NT_STATUS_NO_MEMORY;
1355         }
1356         el = ldb_msg_find_element(msg, "member");
1357         el->flags = mod_op;
1358
1359         /* No need for transactions here, the ldb auto-transaction
1360          * code will handle things for the single operation */
1361         ret = ldb_modify(state->ldb, msg);
1362         talloc_free(tmp_ctx);
1363         if (ret != LDB_SUCCESS) {
1364                 DEBUG(10, ("ldb_modify failed: %s\n",
1365                            ldb_errstring(state->ldb)));
1366                 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1367                         return NT_STATUS_MEMBER_IN_GROUP;
1368                 }
1369                 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1370                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
1371                 }
1372                 return NT_STATUS_LDAP(ret);
1373         }
1374
1375         return NT_STATUS_OK;
1376 }
1377
1378 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1379                                      TALLOC_CTX *mem_ctx,
1380                                      uint32 grouprid, uint32 memberrid,
1381                                      int mod_op)
1382 {
1383         struct pdb_samba4_state *state = talloc_get_type_abort(
1384                 m->private_data, struct pdb_samba4_state);
1385         const struct dom_sid *dom_sid, *groupsid, *membersid;
1386         NTSTATUS status;
1387         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1388         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1389
1390         dom_sid = samdb_domain_sid(state->ldb);
1391
1392         groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1393         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1394         membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1395         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1396         status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1397         talloc_free(tmp_ctx);
1398         return status;
1399 }
1400
1401 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1402                                      TALLOC_CTX *mem_ctx,
1403                                      uint32 group_rid, uint32 member_rid)
1404 {
1405         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1406                                     LDB_FLAG_MOD_ADD);
1407 }
1408
1409 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1410                                      TALLOC_CTX *mem_ctx,
1411                                      uint32 group_rid, uint32 member_rid)
1412 {
1413         return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1414                                        LDB_FLAG_MOD_DELETE);
1415 }
1416
1417 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1418                                      const char *name, uint32 *rid)
1419 {
1420         TALLOC_CTX *frame = talloc_stackframe();
1421         struct pdb_samba4_state *state = talloc_get_type_abort(
1422                 m->private_data, struct pdb_samba4_state);
1423         struct dom_sid *sid;
1424
1425         struct ldb_dn *dn;
1426         NTSTATUS status;
1427         
1428         /* Internally this uses transactions to ensure all the steps
1429          * happen or fail as one */
1430         status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1431         if (!NT_STATUS_IS_OK(status)) {
1432                 TALLOC_FREE(frame);
1433         }
1434
1435         sid_peek_rid(sid, rid);
1436         TALLOC_FREE(frame);
1437         return NT_STATUS_OK;
1438 }
1439
1440 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1441                                      const struct dom_sid *sid)
1442 {
1443         const char *attrs[] = { NULL };
1444         struct pdb_samba4_state *state = talloc_get_type_abort(
1445                 m->private_data, struct pdb_samba4_state);
1446         struct ldb_message *msg;
1447         struct ldb_dn *dn;
1448         int rc;
1449         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1450         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1451
1452         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1453         if (!dn || !ldb_dn_validate(dn)) {
1454                 talloc_free(tmp_ctx);
1455                 return NT_STATUS_NO_MEMORY;
1456         }
1457
1458         if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1459                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1460                 return NT_STATUS_INTERNAL_ERROR;
1461         }
1462
1463         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1464                              "(|(grouptype=%d)(grouptype=%d)))",
1465                              GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1466                              GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1467         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1468                 talloc_free(tmp_ctx);
1469                 ldb_transaction_cancel(state->ldb);
1470                 return NT_STATUS_NO_SUCH_ALIAS;
1471         }
1472         rc = ldb_delete(state->ldb, dn);
1473         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1474                 talloc_free(tmp_ctx);
1475                 ldb_transaction_cancel(state->ldb);
1476                 return NT_STATUS_NO_SUCH_ALIAS;
1477         } else if (rc != LDB_SUCCESS) {
1478                 DEBUG(10, ("ldb_delete failed %s\n",
1479                            ldb_errstring(state->ldb)));
1480                 ldb_transaction_cancel(state->ldb);
1481                 return NT_STATUS_LDAP(rc);
1482         }
1483
1484         if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1485                 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1486                           ldb_errstring(state->ldb)));
1487                 return NT_STATUS_INTERNAL_ERROR;
1488         }
1489
1490         return NT_STATUS_OK;
1491 }
1492
1493 #if 0
1494 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1495                                       const struct dom_sid *sid,
1496                                       struct acct_info *info)
1497 {
1498         struct pdb_samba4_state *state = talloc_get_type_abort(
1499                 m->private_data, struct pdb_samba4_state);
1500         struct tldap_context *ld;
1501         const char *attrs[3] = { "objectSid", "description",
1502                                  "samAccountName" };
1503         struct ldb_message **msg;
1504         char *sidstr, *dn;
1505         int rc;
1506         struct tldap_mod *mods;
1507         int num_mods;
1508         bool ok;
1509
1510         ld = pdb_samba4_ld(state);
1511         if (ld == NULL) {
1512                 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1513         }
1514
1515         sidstr = sid_binstring(talloc_tos(), sid);
1516         NT_STATUS_HAVE_NO_MEMORY(sidstr);
1517
1518         rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1519                                 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1520                                 &msg, "(&(objectSid=%s)(objectclass=group)"
1521                                 "(|(grouptype=%d)(grouptype=%d)))",
1522                                 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1523                                 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1524         TALLOC_FREE(sidstr)
1525         if (rc != LDB_SUCCESS) {
1526                 DEBUG(10, ("ldap_search failed %s\n",
1527                            ldb_errstring(state->ldb)));
1528                 return NT_STATUS_LDAP(rc);
1529         }
1530         switch talloc_array_length(msg) {
1531         case 0:
1532                 return NT_STATUS_NO_SUCH_ALIAS;
1533         case 1:
1534                 break;
1535         default:
1536                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1537         }
1538
1539         if (!tldap_entry_dn(msg[0], &dn)) {
1540                 TALLOC_FREE(msg);
1541                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1542         }
1543
1544         mods = NULL;
1545         num_mods = 0;
1546         ok = true;
1547
1548         ok &= tldap_make_mod_fmt(
1549                 msg[0], msg, &num_mods, &mods, "description",
1550                 "%s", info->acct_desc);
1551         ok &= tldap_make_mod_fmt(
1552                 msg[0], msg, &num_mods, &mods, "samAccountName",
1553                 "%s", info->acct_name);
1554         if (!ok) {
1555                 TALLOC_FREE(msg);
1556                 return NT_STATUS_NO_MEMORY;
1557         }
1558         if (num_mods == 0) {
1559                 /* no change */
1560                 TALLOC_FREE(msg);
1561                 return NT_STATUS_OK;
1562         }
1563
1564         rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1565         TALLOC_FREE(msg);
1566         if (rc != LDB_SUCCESS) {
1567                 DEBUG(10, ("ldap_modify failed: %s\n",
1568                            ldb_errstring(state->ldb)));
1569                 return NT_STATUS_LDAP(rc);
1570         }
1571         return NT_STATUS_OK;
1572 }
1573 #endif
1574 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1575                                      const struct dom_sid *alias,
1576                                      const struct dom_sid *member)
1577 {
1578         NTSTATUS status;
1579         TALLOC_CTX *frame = talloc_stackframe();
1580         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1581         talloc_free(frame);
1582         return status;
1583 }
1584
1585 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1586                                      const struct dom_sid *alias,
1587                                      const struct dom_sid *member)
1588 {
1589         NTSTATUS status;
1590         TALLOC_CTX *frame = talloc_stackframe();
1591         status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1592         talloc_free(frame);
1593         return status;
1594 }
1595
1596 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1597                                       const struct dom_sid *alias,
1598                                       TALLOC_CTX *mem_ctx,
1599                                       struct dom_sid **pmembers,
1600                                       size_t *pnum_members)
1601 {
1602         struct pdb_samba4_state *state = talloc_get_type_abort(
1603                 m->private_data, struct pdb_samba4_state);
1604         struct ldb_dn *dn;
1605         unsigned int num_members;
1606         NTSTATUS status;
1607         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1608         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1609
1610         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1611         if (!dn || !ldb_dn_validate(dn)) {
1612                 return NT_STATUS_NO_MEMORY;
1613         }
1614
1615         status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1616         *pnum_members = num_members;
1617         if (NT_STATUS_IS_OK(status)) {
1618                 talloc_steal(mem_ctx, pmembers);
1619         }
1620         talloc_free(tmp_ctx);
1621         return status;
1622 }
1623
1624 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1625                                                TALLOC_CTX *mem_ctx,
1626                                                const struct dom_sid *domain_sid,
1627                                                const struct dom_sid *members,
1628                                                size_t num_members,
1629                                                uint32_t **palias_rids,
1630                                                size_t *pnum_alias_rids)
1631 {
1632         struct pdb_samba4_state *state = talloc_get_type_abort(
1633                 m->private_data, struct pdb_samba4_state);
1634         uint32_t *alias_rids = NULL;
1635         size_t num_alias_rids = 0;
1636         int i;
1637         struct dom_sid *groupSIDs = NULL;
1638         unsigned int num_groupSIDs = 0;
1639         char *filter;
1640         NTSTATUS status;
1641         const char *sid_string;
1642         const char *sid_dn;
1643         DATA_BLOB sid_blob;
1644
1645         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1646         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1647         /*
1648          * TODO: Get the filter right so that we only get the aliases from
1649          * either the SAM or BUILTIN
1650          */
1651
1652         filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1653                                  GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1654         if (filter == NULL) {
1655                 return NT_STATUS_NO_MEMORY;
1656         }
1657
1658         for (i = 0; i < num_members; i++) {
1659                 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1660                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1661
1662                 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1663                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1664                 
1665                 sid_blob = data_blob_string_const(sid_dn);
1666                 
1667                 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1668                                                    tmp_ctx, &groupSIDs, &num_groupSIDs);
1669                 if (!NT_STATUS_IS_OK(status)) {
1670                         talloc_free(tmp_ctx);
1671                         return status;
1672                 }
1673         }
1674
1675         alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1676         if (alias_rids == NULL) {
1677                 talloc_free(tmp_ctx);
1678                 return NT_STATUS_NO_MEMORY;
1679         }
1680
1681         for (i=0; i<num_groupSIDs; i++) {
1682                 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1683                                        &alias_rids[num_alias_rids])) {
1684                         num_alias_rids++;;
1685                 }
1686         }
1687
1688         *palias_rids = alias_rids;
1689         *pnum_alias_rids = num_alias_rids;
1690         return NT_STATUS_OK;
1691 }
1692
1693 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1694                                     const struct dom_sid *domain_sid,
1695                                     int num_rids,
1696                                     uint32 *rids,
1697                                     const char **names,
1698                                     enum lsa_SidType *lsa_attrs)
1699 {
1700         struct pdb_samba4_state *state = talloc_get_type_abort(
1701                 m->private_data, struct pdb_samba4_state);
1702         NTSTATUS status;
1703
1704         TALLOC_CTX *tmp_ctx;
1705
1706         if (num_rids == 0) {
1707                 return NT_STATUS_NONE_MAPPED;
1708         }
1709
1710         tmp_ctx = talloc_stackframe();
1711         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1712         
1713         status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1714         talloc_free(tmp_ctx);
1715         return status;
1716 }
1717
1718 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1719                                      const struct dom_sid *domain_sid,
1720                                      int num_names,
1721                                      const char **pp_names,
1722                                      uint32 *rids,
1723                                      enum lsa_SidType *attrs)
1724 {
1725         return NT_STATUS_NOT_IMPLEMENTED;
1726 }
1727
1728 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1729                                            enum pdb_policy_type type,
1730                                            uint32_t *value)
1731 {
1732         return account_policy_get(type, value)
1733                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1734 }
1735
1736 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1737                                            enum pdb_policy_type type,
1738                                            uint32_t value)
1739 {
1740         return account_policy_set(type, value)
1741                 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1742 }
1743
1744 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1745                                     time_t *seq_num_out)
1746 {
1747         struct pdb_samba4_state *state = talloc_get_type_abort(
1748                 m->private_data, struct pdb_samba4_state);
1749         uint64_t seq_num;
1750         int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1751         if (ret == LDB_SUCCESS) {
1752                 *seq_num_out = seq_num;
1753                 return NT_STATUS_OK;
1754         } else {
1755                 return NT_STATUS_UNSUCCESSFUL;
1756         }
1757 }
1758
1759 struct pdb_samba4_search_state {
1760         uint32_t acct_flags;
1761         struct samr_displayentry *entries;
1762         uint32_t num_entries;
1763         ssize_t array_size;
1764         uint32_t current;
1765 };
1766
1767 static bool pdb_samba4_next_entry(struct pdb_search *search,
1768                                struct samr_displayentry *entry)
1769 {
1770         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1771                 search->private_data, struct pdb_samba4_search_state);
1772
1773         if (state->current == state->num_entries) {
1774                 return false;
1775         }
1776
1777         entry->idx = state->entries[state->current].idx;
1778         entry->rid = state->entries[state->current].rid;
1779         entry->acct_flags = state->entries[state->current].acct_flags;
1780
1781         entry->account_name = talloc_strdup(
1782                 search, state->entries[state->current].account_name);
1783         entry->fullname = talloc_strdup(
1784                 search, state->entries[state->current].fullname);
1785         entry->description = talloc_strdup(
1786                 search, state->entries[state->current].description);
1787
1788         state->current += 1;
1789         return true;
1790 }
1791
1792 static void pdb_samba4_search_end(struct pdb_search *search)
1793 {
1794         struct pdb_samba4_search_state *state = talloc_get_type_abort(
1795                 search->private_data, struct pdb_samba4_search_state);
1796         talloc_free(state);
1797 }
1798
1799 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1800                                      struct pdb_search *search,
1801                                      struct pdb_samba4_search_state **pstate,
1802                                      const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1803 {
1804         struct pdb_samba4_state *state = talloc_get_type_abort(
1805                 m->private_data, struct pdb_samba4_state);
1806         struct pdb_samba4_search_state *sstate;
1807         const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1808                                  "userAccountControl", "description", NULL };
1809         struct ldb_result *res;
1810         int i, rc, num_users;
1811
1812         va_list ap;
1813         char *expression = NULL;
1814
1815         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1816         if (!tmp_ctx) {
1817                 return false;
1818         }
1819
1820         va_start(ap, exp_fmt);
1821         expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1822         va_end(ap);
1823         
1824         if (!expression) {
1825                 talloc_free(tmp_ctx);
1826                 return LDB_ERR_OPERATIONS_ERROR;
1827         }
1828
1829         sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1830         if (sstate == NULL) {
1831                 talloc_free(tmp_ctx);
1832                 return false;
1833         }
1834
1835         rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1836         if (rc != LDB_SUCCESS) {
1837                 talloc_free(tmp_ctx);
1838                 DEBUG(10, ("dsdb_search failed: %s\n",
1839                            ldb_errstring(state->ldb)));
1840                 return false;
1841         }
1842
1843         num_users = res->count;
1844
1845         sstate->entries = talloc_array(sstate, struct samr_displayentry,
1846                                        num_users);
1847         if (sstate->entries == NULL) {
1848                 talloc_free(tmp_ctx);
1849                 DEBUG(10, ("talloc failed\n"));
1850                 return false;
1851         }
1852
1853         sstate->num_entries = 0;
1854
1855         for (i=0; i<num_users; i++) {
1856                 struct samr_displayentry *e;
1857                 struct dom_sid *sid;
1858
1859                 e = &sstate->entries[sstate->num_entries];
1860
1861                 e->idx = sstate->num_entries;
1862                 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1863                 if (!sid) {
1864                         talloc_free(tmp_ctx);
1865                         DEBUG(10, ("Could not pull SID\n"));
1866                         return false;
1867                 }
1868                 sid_peek_rid(sid, &e->rid);
1869         
1870                 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1871                                                         res->msgs[i], 
1872                                                         ldb_get_default_basedn(state->ldb));
1873                 e->account_name = ldb_msg_find_attr_as_string(
1874                         res->msgs[i], "samAccountName", NULL);
1875                 if (e->account_name == NULL) {
1876                         talloc_free(tmp_ctx);
1877                         return false;
1878                 }
1879                 e->fullname = ldb_msg_find_attr_as_string(
1880                         res->msgs[i], "displayName", "");
1881                 e->description = ldb_msg_find_attr_as_string(
1882                         res->msgs[i], "description", "");
1883
1884                 sstate->num_entries += 1;
1885                 if (sstate->num_entries >= num_users) {
1886                         break;
1887                 }
1888         }
1889         talloc_steal(sstate->entries, res->msgs);
1890         search->private_data = talloc_steal(search, sstate);
1891         search->next_entry = pdb_samba4_next_entry;
1892         search->search_end = pdb_samba4_search_end;
1893         *pstate = sstate;
1894         talloc_free(tmp_ctx);
1895         return true;
1896 }
1897
1898 static bool pdb_samba4_search_users(struct pdb_methods *m,
1899                                  struct pdb_search *search,
1900                                  uint32 acct_flags)
1901 {
1902         struct pdb_samba4_search_state *sstate;
1903         bool ret;
1904
1905         ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1906         if (!ret) {
1907                 return false;
1908         }
1909         sstate->acct_flags = acct_flags;
1910         return true;
1911 }
1912
1913 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1914                                   struct pdb_search *search)
1915 {
1916         struct pdb_samba4_search_state *sstate;
1917         bool ret;
1918
1919         ret = pdb_samba4_search_filter(m, search, &sstate, 
1920                                        "(&(grouptype=%d)(objectclass=group))",
1921                                        GTYPE_SECURITY_GLOBAL_GROUP);
1922         if (!ret) {
1923                 return false;
1924         }
1925         sstate->acct_flags = 0;
1926         return true;
1927 }
1928
1929 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1930                                    struct pdb_search *search,
1931                                    const struct dom_sid *sid)
1932 {
1933         struct pdb_samba4_search_state *sstate;
1934         bool ret;
1935
1936         ret = pdb_samba4_search_filter(m, search, &sstate, 
1937                                        "(&(grouptype=%d)(objectclass=group))",
1938                                        sid_check_is_builtin(sid)
1939                                        ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1940                                        : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1941         if (!ret) {
1942                 return false;
1943         }
1944         sstate->acct_flags = 0;
1945         return true;
1946 }
1947
1948 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1949                                struct dom_sid *sid)
1950 {
1951         struct pdb_samba4_state *state = talloc_get_type_abort(
1952                 m->private_data, struct pdb_samba4_state);
1953         NTSTATUS status;
1954         struct id_map id_map;
1955         struct id_map *id_maps[2];
1956         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1957         if (!tmp_ctx) {
1958                 return false;
1959         }
1960
1961         id_map.xid.id = uid;
1962         id_map.xid.type = ID_TYPE_UID;
1963         id_maps[0] = &id_map;
1964         id_maps[1] = NULL;
1965
1966         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1967         if (!NT_STATUS_IS_OK(status)) {
1968                 talloc_free(tmp_ctx);
1969                 return false;
1970         }
1971         *sid = *id_map.sid;
1972         talloc_free(tmp_ctx);
1973         return true;
1974 }
1975
1976 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1977                                struct dom_sid *sid)
1978 {
1979         struct pdb_samba4_state *state = talloc_get_type_abort(
1980                 m->private_data, struct pdb_samba4_state);
1981         NTSTATUS status;
1982         struct id_map id_map;
1983         struct id_map *id_maps[2];
1984         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1985         if (!tmp_ctx) {
1986                 return false;
1987         }
1988
1989         id_map.xid.id = gid;
1990         id_map.xid.type = ID_TYPE_GID;
1991         id_maps[0] = &id_map;
1992         id_maps[1] = NULL;
1993
1994         status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1995         if (!NT_STATUS_IS_OK(status)) {
1996                 return false;
1997         }
1998         *sid = *id_map.sid;
1999         talloc_free(tmp_ctx);
2000         return true;
2001 }
2002
2003 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2004                                  union unid_t *id, enum lsa_SidType *type)
2005 {
2006         struct pdb_samba4_state *state = talloc_get_type_abort(
2007                 m->private_data, struct pdb_samba4_state);
2008         struct id_map id_map;
2009         struct id_map *id_maps[2];
2010         const char *attrs[] = { "objectClass", "groupType", NULL };
2011         struct ldb_message *msg;
2012         struct ldb_dn *dn;
2013         NTSTATUS status;
2014         int rc;
2015         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2016         if (!tmp_ctx) {
2017                 return false;
2018         }
2019
2020         ZERO_STRUCT(id_map);
2021
2022         dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2023         if (!dn || !ldb_dn_validate(dn)) {
2024                 talloc_free(tmp_ctx);
2025                 return false;
2026         }
2027         rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2028         if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2029                 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)));
2030                 talloc_free(tmp_ctx);
2031                 return false;
2032         }
2033         if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2034                 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2035                 switch (grouptype) {
2036                 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2037                 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2038                         *type = SID_NAME_ALIAS;
2039                         break;
2040                 case GTYPE_SECURITY_GLOBAL_GROUP:
2041                         *type = SID_NAME_DOM_GRP;
2042                         break;
2043                 default:
2044                         talloc_free(tmp_ctx);
2045                         DEBUG(10, ("Could not pull groupType\n"));
2046                         return false;
2047                 }
2048
2049                 *type = SID_NAME_DOM_GRP;
2050
2051                 ZERO_STRUCT(id_map);
2052                 id_map.sid = sid;
2053                 id_maps[0] = &id_map;
2054                 id_maps[1] = NULL;
2055                 
2056                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2057                 talloc_free(tmp_ctx);
2058                 if (!NT_STATUS_IS_OK(status)) {
2059                         return false;
2060                 }
2061                 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2062                         id->gid = id_map.xid.id;
2063                         return true;
2064                 }
2065                 return false;
2066         } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2067                 *type = SID_NAME_USER;
2068                 ZERO_STRUCT(id_map);
2069                 id_map.sid = sid;
2070                 id_maps[0] = &id_map;
2071                 id_maps[1] = NULL;
2072                 
2073                 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2074                 talloc_free(tmp_ctx);
2075                 if (!NT_STATUS_IS_OK(status)) {
2076                         return false;
2077                 }
2078                 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2079                         id->uid = id_map.xid.id;
2080                         return true;
2081                 }
2082                 return false;
2083         }
2084         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)));
2085         talloc_free(tmp_ctx);
2086         return false;
2087 }
2088
2089 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2090 {
2091         return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2092 }
2093
2094 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2095 {
2096         return false;
2097 }
2098
2099 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2100                                       const char *domain, char** pwd,
2101                                       struct dom_sid *sid,
2102                                       time_t *pass_last_set_time)
2103 {
2104         return false;
2105 }
2106
2107 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2108                                       const char* domain, const char* pwd,
2109                                       const struct dom_sid *sid)
2110 {
2111         return false;
2112 }
2113
2114 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2115                                       const char *domain)
2116 {
2117         return false;
2118 }
2119
2120 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2121                                          TALLOC_CTX *mem_ctx,
2122                                          uint32 *num_domains,
2123                                          struct trustdom_info ***domains)
2124 {
2125         *num_domains = 0;
2126         *domains = NULL;
2127         return NT_STATUS_OK;
2128 }
2129
2130 static void pdb_samba4_init_methods(struct pdb_methods *m)
2131 {
2132         m->name = "samba4";
2133         m->get_domain_info = pdb_samba4_get_domain_info;
2134         m->getsampwnam = pdb_samba4_getsampwnam;
2135         m->getsampwsid = pdb_samba4_getsampwsid;
2136         m->create_user = pdb_samba4_create_user;
2137         m->delete_user = pdb_samba4_delete_user;
2138         m->add_sam_account = pdb_samba4_add_sam_account;
2139         m->update_sam_account = pdb_samba4_update_sam_account;
2140         m->delete_sam_account = pdb_samba4_delete_sam_account;
2141         m->rename_sam_account = pdb_samba4_rename_sam_account;
2142         m->update_login_attempts = pdb_samba4_update_login_attempts;
2143         m->getgrsid = pdb_samba4_getgrsid;
2144         m->getgrgid = pdb_samba4_getgrgid;
2145         m->getgrnam = pdb_samba4_getgrnam;
2146         m->create_dom_group = pdb_samba4_create_dom_group;
2147         m->delete_dom_group = pdb_samba4_delete_dom_group;
2148         m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2149         m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2150         m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2151         m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2152         m->enum_group_members = pdb_samba4_enum_group_members;
2153         m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2154         m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2155         m->add_groupmem = pdb_samba4_add_groupmem;
2156         m->del_groupmem = pdb_samba4_del_groupmem;
2157         m->create_alias = pdb_samba4_create_alias;
2158         m->delete_alias = pdb_samba4_delete_alias;
2159         m->get_aliasinfo = pdb_default_get_aliasinfo;
2160         m->add_aliasmem = pdb_samba4_add_aliasmem;
2161         m->del_aliasmem = pdb_samba4_del_aliasmem;
2162         m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2163         m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2164         m->lookup_rids = pdb_samba4_lookup_rids;
2165         m->lookup_names = pdb_samba4_lookup_names;
2166         m->get_account_policy = pdb_samba4_get_account_policy;
2167         m->set_account_policy = pdb_samba4_set_account_policy;
2168         m->get_seq_num = pdb_samba4_get_seq_num;
2169         m->search_users = pdb_samba4_search_users;
2170         m->search_groups = pdb_samba4_search_groups;
2171         m->search_aliases = pdb_samba4_search_aliases;
2172         m->uid_to_sid = pdb_samba4_uid_to_sid;
2173         m->gid_to_sid = pdb_samba4_gid_to_sid;
2174         m->sid_to_id = pdb_samba4_sid_to_id;
2175         m->capabilities = pdb_samba4_capabilities;
2176         m->new_rid = pdb_samba4_new_rid;
2177         m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2178         m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2179         m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2180         m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2181 }
2182
2183 static void free_private_data(void **vp)
2184 {
2185         struct pdb_samba4_state *state = talloc_get_type_abort(
2186                 *vp, struct pdb_samba4_state);
2187         talloc_unlink(state, state->ldb);
2188         return;
2189 }
2190
2191 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2192                              const char *location)
2193 {
2194         struct pdb_methods *m;
2195         struct pdb_samba4_state *state;
2196         NTSTATUS status;
2197
2198         if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2199                 return status;
2200         }
2201
2202         state = talloc_zero(m, struct pdb_samba4_state);
2203         if (state == NULL) {
2204                 goto nomem;
2205         }
2206         m->private_data = state;
2207         m->free_private_data = free_private_data;
2208         pdb_samba4_init_methods(m);
2209
2210         state->ev = s4_event_context_init(state);
2211         if (!state->ev) {
2212                 DEBUG(0, ("s4_event_context_init failed\n"));
2213                 goto nomem;
2214         }
2215
2216         state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2217         if (state->lp_ctx == NULL) {
2218                 DEBUG(0, ("loadparm_init_s3 failed\n"));
2219                 goto nomem;
2220         }
2221
2222         if (location) {
2223                 state->ldb = samdb_connect_url(state,
2224                                    state->ev,
2225                                    state->lp_ctx,
2226                                    system_session(state->lp_ctx),
2227                                    0, location);
2228         } else {
2229                 state->ldb = samdb_connect(state,
2230                                    state->ev,
2231                                    state->lp_ctx,
2232                                    system_session(state->lp_ctx), 0);
2233         }
2234
2235         if (!state->ldb) {
2236                 DEBUG(0, ("samdb_connect failed\n"));
2237                 status = NT_STATUS_INTERNAL_ERROR;
2238                 goto fail;
2239         }
2240
2241         state->idmap_ctx = idmap_init(state, state->ev,
2242                                       state->lp_ctx);
2243         if (!state->idmap_ctx) {
2244                 DEBUG(0, ("idmap failed\n"));
2245                 status = NT_STATUS_INTERNAL_ERROR;
2246                 goto fail;
2247         }
2248
2249         *pdb_method = m;
2250         return NT_STATUS_OK;
2251 nomem:
2252         status = NT_STATUS_NO_MEMORY;
2253 fail:
2254         TALLOC_FREE(m);
2255         return status;
2256 }
2257
2258 NTSTATUS pdb_samba4_init(void);
2259 NTSTATUS pdb_samba4_init(void)
2260 {
2261         return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2262                                    pdb_init_samba4);
2263 }