bb09cc483bc72fd4590389582ed53387035b883b
[kai/samba.git] / source3 / utils / net_rpc_samsync.c
1 /*
2    Unix SMB/CIFS implementation.
3    dump the remote SAM using rpc samsync operations
4
5    Copyright (C) Andrew Tridgell 2002
6    Copyright (C) Tim Potter 2001,2002
7    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
8    Modified by Volker Lendecke 2002
9    Copyright (C) Jeremy Allison 2005.
10    Copyright (C) Guenther Deschner 2008.
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "utils/net.h"
28
29 /* uid's and gid's for writing deltas to ldif */
30 static uint32 ldif_gid = 999;
31 static uint32 ldif_uid = 999;
32 /* Keep track of ldap initialization */
33 static int init_ldap = 1;
34
35 static void display_group_mem_info(uint32_t rid,
36                                    struct netr_DELTA_GROUP_MEMBER *r)
37 {
38         int i;
39         d_printf("Group mem %u: ", rid);
40         for (i=0; i< r->num_rids; i++) {
41                 d_printf("%u ", r->rids[i]);
42         }
43         d_printf("\n");
44 }
45
46 static void display_alias_info(uint32_t rid,
47                                struct netr_DELTA_ALIAS *r)
48 {
49         d_printf("Alias '%s' ", r->alias_name.string);
50         d_printf("desc='%s' rid=%u\n", r->description.string, r->rid);
51 }
52
53 static void display_alias_mem(uint32_t rid,
54                               struct netr_DELTA_ALIAS_MEMBER *r)
55 {
56         int i;
57         d_printf("Alias rid %u: ", rid);
58         for (i=0; i< r->sids.num_sids; i++) {
59                 d_printf("%s ", sid_string_tos(r->sids.sids[i].sid));
60         }
61         d_printf("\n");
62 }
63
64 static void display_account_info(uint32_t rid,
65                                  struct netr_DELTA_USER *r)
66 {
67         fstring hex_nt_passwd, hex_lm_passwd;
68         uchar lm_passwd[16], nt_passwd[16];
69         static uchar zero_buf[16];
70
71         /* Decode hashes from password hash (if they are not NULL) */
72
73         if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
74                 sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
75                 pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
76         } else {
77                 pdb_sethexpwd(hex_lm_passwd, NULL, 0);
78         }
79
80         if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
81                 sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
82                 pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
83         } else {
84                 pdb_sethexpwd(hex_nt_passwd, NULL, 0);
85         }
86
87         printf("%s:%d:%s:%s:%s:LCT-0\n",
88                 r->account_name.string,
89                 r->rid, hex_lm_passwd, hex_nt_passwd,
90                 pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN));
91 }
92
93 static time_t uint64s_nt_time_to_unix_abs(const uint64 *src)
94 {
95         NTTIME nttime;
96         nttime = *src;
97         return nt_time_to_unix_abs(&nttime);
98 }
99
100 static NTSTATUS pull_netr_AcctLockStr(TALLOC_CTX *mem_ctx,
101                                       struct lsa_BinaryString *r,
102                                       struct netr_AcctLockStr **str_p)
103 {
104         struct netr_AcctLockStr *str;
105         enum ndr_err_code ndr_err;
106         DATA_BLOB blob;
107
108         if (!mem_ctx || !r || !str_p) {
109                 return NT_STATUS_INVALID_PARAMETER;
110         }
111
112         *str_p = NULL;
113
114         str = TALLOC_ZERO_P(mem_ctx, struct netr_AcctLockStr);
115         if (!str) {
116                 return NT_STATUS_NO_MEMORY;
117         }
118
119         blob = data_blob_const(r->array, r->length);
120
121         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, str,
122                        (ndr_pull_flags_fn_t)ndr_pull_netr_AcctLockStr);
123         data_blob_free(&blob);
124
125         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
126                 return ndr_map_error2ntstatus(ndr_err);
127         }
128
129         *str_p = str;
130
131         return NT_STATUS_OK;
132 }
133
134 static void display_domain_info(struct netr_DELTA_DOMAIN *r)
135 {
136         time_t u_logout;
137         struct netr_AcctLockStr *lockstr = NULL;
138         NTSTATUS status;
139         TALLOC_CTX *mem_ctx = talloc_tos();
140
141         status = pull_netr_AcctLockStr(mem_ctx, &r->account_lockout,
142                                        &lockstr);
143         if (!NT_STATUS_IS_OK(status)) {
144                 d_printf("failed to pull account lockout string: %s\n",
145                         nt_errstr(status));
146         }
147
148         u_logout = uint64s_nt_time_to_unix_abs((const uint64 *)&r->force_logoff_time);
149
150         d_printf("Domain name: %s\n", r->domain_name.string);
151
152         d_printf("Minimal Password Length: %d\n", r->min_password_length);
153         d_printf("Password History Length: %d\n", r->password_history_length);
154
155         d_printf("Force Logoff: %d\n", (int)u_logout);
156
157         d_printf("Max Password Age: %s\n", display_time(r->max_password_age));
158         d_printf("Min Password Age: %s\n", display_time(r->min_password_age));
159
160         if (lockstr) {
161                 d_printf("Lockout Time: %s\n", display_time((NTTIME)lockstr->lockout_duration));
162                 d_printf("Lockout Reset Time: %s\n", display_time((NTTIME)lockstr->reset_count));
163                 d_printf("Bad Attempt Lockout: %d\n", lockstr->bad_attempt_lockout);
164         }
165
166         d_printf("User must logon to change password: %d\n", r->logon_to_chgpass);
167 }
168
169 static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r)
170 {
171         d_printf("Group '%s' ", r->group_name.string);
172         d_printf("desc='%s', rid=%u\n", r->description.string, rid);
173 }
174
175 static void display_sam_entry(struct netr_DELTA_ENUM *r)
176 {
177         union netr_DELTA_UNION u = r->delta_union;
178         union netr_DELTA_ID_UNION id = r->delta_id_union;
179
180         switch (r->delta_type) {
181         case NETR_DELTA_DOMAIN:
182                 display_domain_info(u.domain);
183                 break;
184         case NETR_DELTA_GROUP:
185                 display_group_info(id.rid, u.group);
186                 break;
187 #if 0
188         case NETR_DELTA_DELETE_GROUP:
189                 printf("Delete Group: %d\n",
190                         u.delete_account.unknown);
191                 break;
192         case NETR_DELTA_RENAME_GROUP:
193                 printf("Rename Group: %s -> %s\n",
194                         u.rename_group->OldName.string,
195                         u.rename_group->NewName.string);
196                 break;
197 #endif
198         case NETR_DELTA_USER:
199                 display_account_info(id.rid, u.user);
200                 break;
201 #if 0
202         case NETR_DELTA_DELETE_USER:
203                 printf("Delete User: %d\n",
204                         id.rid);
205                 break;
206         case NETR_DELTA_RENAME_USER:
207                 printf("Rename user: %s -> %s\n",
208                         u.rename_user->OldName.string,
209                         u.rename_user->NewName.string);
210                 break;
211 #endif
212         case NETR_DELTA_GROUP_MEMBER:
213                 display_group_mem_info(id.rid, u.group_member);
214                 break;
215         case NETR_DELTA_ALIAS:
216                 display_alias_info(id.rid, u.alias);
217                 break;
218 #if 0
219         case NETR_DELTA_DELETE_ALIAS:
220                 printf("Delete Alias: %d\n",
221                         id.rid);
222                 break;
223         case NETR_DELTA_RENAME_ALIAS:
224                 printf("Rename alias: %s -> %s\n",
225                         u.rename_alias->OldName.string,
226                         u.rename_alias->NewName.string);
227                 break;
228 #endif
229         case NETR_DELTA_ALIAS_MEMBER:
230                 display_alias_mem(id.rid, u.alias_member);
231                 break;
232 #if 0
233         case NETR_DELTA_POLICY:
234                 printf("Policy\n");
235                 break;
236         case NETR_DELTA_TRUSTED_DOMAIN:
237                 printf("Trusted Domain: %s\n",
238                         u.trusted_domain->domain_name.string);
239                 break;
240         case NETR_DELTA_DELETE_TRUST:
241                 printf("Delete Trust: %d\n",
242                         u.delete_trust.unknown);
243                 break;
244         case NETR_DELTA_ACCOUNT:
245                 printf("Account\n");
246                 break;
247         case NETR_DELTA_DELETE_ACCOUNT:
248                 printf("Delete Account: %d\n",
249                         u.delete_account.unknown);
250                 break;
251         case NETR_DELTA_SECRET:
252                 printf("Secret\n");
253                 break;
254         case NETR_DELTA_DELETE_SECRET:
255                 printf("Delete Secret: %d\n",
256                         u.delete_secret.unknown);
257                 break;
258         case NETR_DELTA_DELETE_GROUP2:
259                 printf("Delete Group2: %s\n",
260                         u.delete_group->account_name);
261                 break;
262         case NETR_DELTA_DELETE_USER2:
263                 printf("Delete User2: %s\n",
264                         u.delete_user->account_name);
265                 break;
266         case NETR_DELTA_MODIFY_COUNT:
267                 printf("sam sequence update: 0x%016llx\n",
268                         (unsigned long long) *u.modified_count);
269                 break;
270 #endif
271         /* The following types are recognised but not handled */
272         case NETR_DELTA_RENAME_GROUP:
273                 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
274                 break;
275         case NETR_DELTA_RENAME_USER:
276                 d_printf("NETR_DELTA_RENAME_USER not handled\n");
277                 break;
278         case NETR_DELTA_RENAME_ALIAS:
279                 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
280                 break;
281         case NETR_DELTA_POLICY:
282                 d_printf("NETR_DELTA_POLICY not handled\n");
283                 break;
284         case NETR_DELTA_TRUSTED_DOMAIN:
285                 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
286                 break;
287         case NETR_DELTA_ACCOUNT:
288                 d_printf("NETR_DELTA_ACCOUNT not handled\n");
289                 break;
290         case NETR_DELTA_SECRET:
291                 d_printf("NETR_DELTA_SECRET not handled\n");
292                 break;
293         case NETR_DELTA_DELETE_GROUP:
294                 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
295                 break;
296         case NETR_DELTA_DELETE_USER:
297                 d_printf("NETR_DELTA_DELETE_USER not handled\n");
298                 break;
299         case NETR_DELTA_MODIFY_COUNT:
300                 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
301                 break;
302         case NETR_DELTA_DELETE_ALIAS:
303                 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
304                 break;
305         case NETR_DELTA_DELETE_TRUST:
306                 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
307                 break;
308         case NETR_DELTA_DELETE_ACCOUNT:
309                 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
310                 break;
311         case NETR_DELTA_DELETE_SECRET:
312                 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
313                 break;
314         case NETR_DELTA_DELETE_GROUP2:
315                 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
316                 break;
317         case NETR_DELTA_DELETE_USER2:
318                 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
319                 break;
320         default:
321                 printf("unknown delta type 0x%02x\n",
322                         r->delta_type);
323                 break;
324         }
325 }
326
327 static void dump_database(struct rpc_pipe_client *pipe_hnd,
328                           enum netr_SamDatabaseID database_id)
329 {
330         NTSTATUS result;
331         int i;
332         TALLOC_CTX *mem_ctx;
333         const char *logon_server = pipe_hnd->desthost;
334         const char *computername = global_myname();
335         struct netr_Authenticator credential;
336         struct netr_Authenticator return_authenticator;
337         uint16_t restart_state = 0;
338         uint32_t sync_context = 0;
339
340         ZERO_STRUCT(return_authenticator);
341
342         if (!(mem_ctx = talloc_init("dump_database"))) {
343                 return;
344         }
345
346         switch(database_id) {
347         case SAM_DATABASE_DOMAIN:
348                 d_printf("Dumping DOMAIN database\n");
349                 break;
350         case SAM_DATABASE_BUILTIN:
351                 d_printf("Dumping BUILTIN database\n");
352                 break;
353         case SAM_DATABASE_PRIVS:
354                 d_printf("Dumping PRIVS databases\n");
355                 break;
356         default:
357                 d_printf("Dumping unknown database type %u\n",
358                         database_id);
359                 break;
360         }
361
362         do {
363                 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
364
365                 netlogon_creds_client_step(pipe_hnd->dc, &credential);
366
367                 result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx,
368                                                    logon_server,
369                                                    computername,
370                                                    &credential,
371                                                    &return_authenticator,
372                                                    database_id,
373                                                    restart_state,
374                                                    &sync_context,
375                                                    &delta_enum_array,
376                                                    0xffff);
377
378                 /* Check returned credentials. */
379                 if (!netlogon_creds_client_check(pipe_hnd->dc,
380                                                  &return_authenticator.cred)) {
381                         DEBUG(0,("credentials chain check failed\n"));
382                         return;
383                 }
384
385                 if (NT_STATUS_IS_ERR(result)) {
386                         break;
387                 }
388
389                 /* Display results */
390                 for (i = 0; i < delta_enum_array->num_deltas; i++) {
391                         display_sam_entry(&delta_enum_array->delta_enum[i]);
392                 }
393
394                 TALLOC_FREE(delta_enum_array);
395
396         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
397
398         talloc_destroy(mem_ctx);
399 }
400
401 /* dump sam database via samsync rpc calls */
402 NTSTATUS rpc_samdump_internals(struct net_context *c,
403                                 const DOM_SID *domain_sid,
404                                 const char *domain_name,
405                                 struct cli_state *cli,
406                                 struct rpc_pipe_client *pipe_hnd,
407                                 TALLOC_CTX *mem_ctx,
408                                 int argc,
409                                 const char **argv)
410 {
411 #if 0
412         /* net_rpc.c now always tries to create an schannel pipe.. */
413
414         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
415         uchar trust_password[16];
416         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
417         uint32 sec_channel_type = 0;
418
419         if (!secrets_fetch_trust_account_password(domain_name,
420                                                   trust_password,
421                                                   NULL, &sec_channel_type)) {
422                 DEBUG(0,("Could not fetch trust account password\n"));
423                 goto fail;
424         }
425
426         nt_status = rpccli_netlogon_setup_creds(pipe_hnd,
427                                                 cli->desthost,
428                                                 domain_name,
429                                                 global_myname(),
430                                                 trust_password,
431                                                 sec_channel_type,
432                                                 &neg_flags);
433
434         if (!NT_STATUS_IS_OK(nt_status)) {
435                 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
436                 goto fail;
437         }
438 #endif
439
440         dump_database(pipe_hnd, SAM_DATABASE_DOMAIN);
441         dump_database(pipe_hnd, SAM_DATABASE_BUILTIN);
442         dump_database(pipe_hnd, SAM_DATABASE_PRIVS);
443
444         return NT_STATUS_OK;
445 }
446
447 /* Convert a struct samu_DELTA to a struct samu. */
448 #define STRING_CHANGED (old_string && !new_string) ||\
449                     (!old_string && new_string) ||\
450                 (old_string && new_string && (strcmp(old_string, new_string) != 0))
451
452 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
453                     (!(s1) && (s2)) ||\
454                 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
455
456 static NTSTATUS sam_account_from_delta(struct samu *account,
457                                        struct netr_DELTA_USER *r)
458 {
459         const char *old_string, *new_string;
460         time_t unix_time, stored_time;
461         uchar lm_passwd[16], nt_passwd[16];
462         static uchar zero_buf[16];
463
464         /* Username, fullname, home dir, dir drive, logon script, acct
465            desc, workstations, profile. */
466
467         if (r->account_name.string) {
468                 old_string = pdb_get_nt_username(account);
469                 new_string = r->account_name.string;
470
471                 if (STRING_CHANGED) {
472                         pdb_set_nt_username(account, new_string, PDB_CHANGED);
473                 }
474
475                 /* Unix username is the same - for sanity */
476                 old_string = pdb_get_username( account );
477                 if (STRING_CHANGED) {
478                         pdb_set_username(account, new_string, PDB_CHANGED);
479                 }
480         }
481
482         if (r->full_name.string) {
483                 old_string = pdb_get_fullname(account);
484                 new_string = r->full_name.string;
485
486                 if (STRING_CHANGED)
487                         pdb_set_fullname(account, new_string, PDB_CHANGED);
488         }
489
490         if (r->home_directory.string) {
491                 old_string = pdb_get_homedir(account);
492                 new_string = r->home_directory.string;
493
494                 if (STRING_CHANGED)
495                         pdb_set_homedir(account, new_string, PDB_CHANGED);
496         }
497
498         if (r->home_drive.string) {
499                 old_string = pdb_get_dir_drive(account);
500                 new_string = r->home_drive.string;
501
502                 if (STRING_CHANGED)
503                         pdb_set_dir_drive(account, new_string, PDB_CHANGED);
504         }
505
506         if (r->logon_script.string) {
507                 old_string = pdb_get_logon_script(account);
508                 new_string = r->logon_script.string;
509
510                 if (STRING_CHANGED)
511                         pdb_set_logon_script(account, new_string, PDB_CHANGED);
512         }
513
514         if (r->description.string) {
515                 old_string = pdb_get_acct_desc(account);
516                 new_string = r->description.string;
517
518                 if (STRING_CHANGED)
519                         pdb_set_acct_desc(account, new_string, PDB_CHANGED);
520         }
521
522         if (r->workstations.string) {
523                 old_string = pdb_get_workstations(account);
524                 new_string = r->workstations.string;
525
526                 if (STRING_CHANGED)
527                         pdb_set_workstations(account, new_string, PDB_CHANGED);
528         }
529
530         if (r->profile_path.string) {
531                 old_string = pdb_get_profile_path(account);
532                 new_string = r->profile_path.string;
533
534                 if (STRING_CHANGED)
535                         pdb_set_profile_path(account, new_string, PDB_CHANGED);
536         }
537
538         if (r->parameters.string) {
539                 DATA_BLOB mung;
540                 char *newstr;
541                 old_string = pdb_get_munged_dial(account);
542                 mung.length = r->parameters.length;
543                 mung.data = (uint8 *) r->parameters.string;
544                 newstr = (mung.length == 0) ? NULL :
545                         base64_encode_data_blob(talloc_tos(), mung);
546
547                 if (STRING_CHANGED_NC(old_string, newstr))
548                         pdb_set_munged_dial(account, newstr, PDB_CHANGED);
549                 TALLOC_FREE(newstr);
550         }
551
552         /* User and group sid */
553         if (pdb_get_user_rid(account) != r->rid)
554                 pdb_set_user_sid_from_rid(account, r->rid, PDB_CHANGED);
555         if (pdb_get_group_rid(account) != r->primary_gid)
556                 pdb_set_group_sid_from_rid(account, r->primary_gid, PDB_CHANGED);
557
558         /* Logon and password information */
559         if (!nt_time_is_zero(&r->last_logon)) {
560                 unix_time = nt_time_to_unix(r->last_logon);
561                 stored_time = pdb_get_logon_time(account);
562                 if (stored_time != unix_time)
563                         pdb_set_logon_time(account, unix_time, PDB_CHANGED);
564         }
565
566         if (!nt_time_is_zero(&r->last_logoff)) {
567                 unix_time = nt_time_to_unix(r->last_logoff);
568                 stored_time = pdb_get_logoff_time(account);
569                 if (stored_time != unix_time)
570                         pdb_set_logoff_time(account, unix_time,PDB_CHANGED);
571         }
572
573         /* Logon Divs */
574         if (pdb_get_logon_divs(account) != r->logon_hours.units_per_week)
575                 pdb_set_logon_divs(account, r->logon_hours.units_per_week, PDB_CHANGED);
576
577 #if 0
578         /* no idea what to do with this one - gd */
579         /* Max Logon Hours */
580         if (delta->unknown1 != pdb_get_unknown_6(account)) {
581                 pdb_set_unknown_6(account, delta->unknown1, PDB_CHANGED);
582         }
583 #endif
584         /* Logon Hours Len */
585         if (r->logon_hours.units_per_week/8 != pdb_get_hours_len(account)) {
586                 pdb_set_hours_len(account, r->logon_hours.units_per_week/8, PDB_CHANGED);
587         }
588
589         /* Logon Hours */
590         if (r->logon_hours.bits) {
591                 char oldstr[44], newstr[44];
592                 pdb_sethexhours(oldstr, pdb_get_hours(account));
593                 pdb_sethexhours(newstr, r->logon_hours.bits);
594                 if (!strequal(oldstr, newstr))
595                         pdb_set_hours(account, r->logon_hours.bits, PDB_CHANGED);
596         }
597
598         if (pdb_get_bad_password_count(account) != r->bad_password_count)
599                 pdb_set_bad_password_count(account, r->bad_password_count, PDB_CHANGED);
600
601         if (pdb_get_logon_count(account) != r->logon_count)
602                 pdb_set_logon_count(account, r->logon_count, PDB_CHANGED);
603
604         if (!nt_time_is_zero(&r->last_password_change)) {
605                 unix_time = nt_time_to_unix(r->last_password_change);
606                 stored_time = pdb_get_pass_last_set_time(account);
607                 if (stored_time != unix_time)
608                         pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED);
609         } else {
610                 /* no last set time, make it now */
611                 pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED);
612         }
613
614         if (!nt_time_is_zero(&r->acct_expiry)) {
615                 unix_time = nt_time_to_unix(r->acct_expiry);
616                 stored_time = pdb_get_kickoff_time(account);
617                 if (stored_time != unix_time)
618                         pdb_set_kickoff_time(account, unix_time, PDB_CHANGED);
619         }
620
621         /* Decode hashes from password hash
622            Note that win2000 may send us all zeros for the hashes if it doesn't
623            think this channel is secure enough - don't set the passwords at all
624            in that case
625         */
626         if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
627                 sam_pwd_hash(r->rid, r->ntpassword.hash, lm_passwd, 0);
628                 pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
629         }
630
631         if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
632                 sam_pwd_hash(r->rid, r->lmpassword.hash, nt_passwd, 0);
633                 pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
634         }
635
636         /* TODO: account expiry time */
637
638         pdb_set_acct_ctrl(account, r->acct_flags, PDB_CHANGED);
639
640         pdb_set_domain(account, lp_workgroup(), PDB_CHANGED);
641
642         return NT_STATUS_OK;
643 }
644
645 static NTSTATUS fetch_account_info(uint32_t rid,
646                                    struct netr_DELTA_USER *r)
647 {
648
649         NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL;
650         fstring account;
651         char *add_script = NULL;
652         struct samu *sam_account=NULL;
653         GROUP_MAP map;
654         struct group *grp;
655         DOM_SID user_sid;
656         DOM_SID group_sid;
657         struct passwd *passwd;
658         fstring sid_string;
659
660         fstrcpy(account, r->account_name.string);
661         d_printf("Creating account: %s\n", account);
662
663         if ( !(sam_account = samu_new( NULL )) ) {
664                 return NT_STATUS_NO_MEMORY;
665         }
666
667         if (!(passwd = Get_Pwnam_alloc(sam_account, account))) {
668                 /* Create appropriate user */
669                 if (r->acct_flags & ACB_NORMAL) {
670                         add_script = talloc_strdup(sam_account,
671                                         lp_adduser_script());
672                 } else if ( (r->acct_flags & ACB_WSTRUST) ||
673                             (r->acct_flags & ACB_SVRTRUST) ||
674                             (r->acct_flags & ACB_DOMTRUST) ) {
675                         add_script = talloc_strdup(sam_account,
676                                         lp_addmachine_script());
677                 } else {
678                         DEBUG(1, ("Unknown user type: %s\n",
679                                   pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN)));
680                         nt_ret = NT_STATUS_UNSUCCESSFUL;
681                         goto done;
682                 }
683                 if (!add_script) {
684                         nt_ret = NT_STATUS_NO_MEMORY;
685                         goto done;
686                 }
687                 if (*add_script) {
688                         int add_ret;
689                         add_script = talloc_all_string_sub(sam_account,
690                                         add_script,
691                                         "%u",
692                                         account);
693                         if (!add_script) {
694                                 nt_ret = NT_STATUS_NO_MEMORY;
695                                 goto done;
696                         }
697                         add_ret = smbrun(add_script,NULL);
698                         DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' "
699                                  "gave %d\n", add_script, add_ret));
700                         if (add_ret == 0) {
701                                 smb_nscd_flush_user_cache();
702                         }
703                 }
704
705                 /* try and find the possible unix account again */
706                 if ( !(passwd = Get_Pwnam_alloc(sam_account, account)) ) {
707                         d_fprintf(stderr, "Could not create posix account info for '%s'\n", account);
708                         nt_ret = NT_STATUS_NO_SUCH_USER;
709                         goto done;
710                 }
711         }
712
713         sid_copy(&user_sid, get_global_sam_sid());
714         sid_append_rid(&user_sid, r->rid);
715
716         DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
717                   sid_to_fstring(sid_string, &user_sid), account));
718         if (!pdb_getsampwsid(sam_account, &user_sid)) {
719                 sam_account_from_delta(sam_account, r);
720                 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
721                           sid_to_fstring(sid_string, &user_sid),
722                           pdb_get_username(sam_account)));
723                 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) {
724                         DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
725                                   account));
726                         return NT_STATUS_ACCESS_DENIED;
727                 }
728         } else {
729                 sam_account_from_delta(sam_account, r);
730                 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
731                           sid_to_fstring(sid_string, &user_sid),
732                           pdb_get_username(sam_account)));
733                 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account))) {
734                         DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
735                                   account));
736                         TALLOC_FREE(sam_account);
737                         return NT_STATUS_ACCESS_DENIED;
738                 }
739         }
740
741         if (pdb_get_group_sid(sam_account) == NULL) {
742                 return NT_STATUS_UNSUCCESSFUL;
743         }
744
745         group_sid = *pdb_get_group_sid(sam_account);
746
747         if (!pdb_getgrsid(&map, group_sid)) {
748                 DEBUG(0, ("Primary group of %s has no mapping!\n",
749                           pdb_get_username(sam_account)));
750         } else {
751                 if (map.gid != passwd->pw_gid) {
752                         if (!(grp = getgrgid(map.gid))) {
753                                 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
754                                           (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_tos(&group_sid)));
755                         } else {
756                                 smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
757                         }
758                 }
759         }
760
761         if ( !passwd ) {
762                 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
763                         pdb_get_username(sam_account)));
764         }
765
766  done:
767         TALLOC_FREE(sam_account);
768         return nt_ret;
769 }
770
771 static NTSTATUS fetch_group_info(uint32_t rid,
772                                  struct netr_DELTA_GROUP *r)
773 {
774         fstring name;
775         fstring comment;
776         struct group *grp = NULL;
777         DOM_SID group_sid;
778         fstring sid_string;
779         GROUP_MAP map;
780         bool insert = True;
781
782         fstrcpy(name, r->group_name.string);
783         fstrcpy(comment, r->description.string);
784
785         /* add the group to the mapping table */
786         sid_copy(&group_sid, get_global_sam_sid());
787         sid_append_rid(&group_sid, rid);
788         sid_to_fstring(sid_string, &group_sid);
789
790         if (pdb_getgrsid(&map, group_sid)) {
791                 if ( map.gid != -1 )
792                         grp = getgrgid(map.gid);
793                 insert = False;
794         }
795
796         if (grp == NULL) {
797                 gid_t gid;
798
799                 /* No group found from mapping, find it from its name. */
800                 if ((grp = getgrnam(name)) == NULL) {
801
802                         /* No appropriate group found, create one */
803
804                         d_printf("Creating unix group: '%s'\n", name);
805
806                         if (smb_create_group(name, &gid) != 0)
807                                 return NT_STATUS_ACCESS_DENIED;
808
809                         if ((grp = getgrnam(name)) == NULL)
810                                 return NT_STATUS_ACCESS_DENIED;
811                 }
812         }
813
814         map.gid = grp->gr_gid;
815         map.sid = group_sid;
816         map.sid_name_use = SID_NAME_DOM_GRP;
817         fstrcpy(map.nt_name, name);
818         if (r->description.string) {
819                 fstrcpy(map.comment, comment);
820         } else {
821                 fstrcpy(map.comment, "");
822         }
823
824         if (insert)
825                 pdb_add_group_mapping_entry(&map);
826         else
827                 pdb_update_group_mapping_entry(&map);
828
829         return NT_STATUS_OK;
830 }
831
832 static NTSTATUS fetch_group_mem_info(uint32_t rid,
833                                      struct netr_DELTA_GROUP_MEMBER *r)
834 {
835         int i;
836         TALLOC_CTX *t = NULL;
837         char **nt_members = NULL;
838         char **unix_members;
839         DOM_SID group_sid;
840         GROUP_MAP map;
841         struct group *grp;
842
843         if (r->num_rids == 0) {
844                 return NT_STATUS_OK;
845         }
846
847         sid_copy(&group_sid, get_global_sam_sid());
848         sid_append_rid(&group_sid, rid);
849
850         if (!get_domain_group_from_sid(group_sid, &map)) {
851                 DEBUG(0, ("Could not find global group %d\n", rid));
852                 return NT_STATUS_NO_SUCH_GROUP;
853         }
854
855         if (!(grp = getgrgid(map.gid))) {
856                 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid));
857                 return NT_STATUS_NO_SUCH_GROUP;
858         }
859
860         d_printf("Group members of %s: ", grp->gr_name);
861
862         if (!(t = talloc_init("fetch_group_mem_info"))) {
863                 DEBUG(0, ("could not talloc_init\n"));
864                 return NT_STATUS_NO_MEMORY;
865         }
866
867         if (r->num_rids) {
868                 if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, r->num_rids)) == NULL) {
869                         DEBUG(0, ("talloc failed\n"));
870                         talloc_free(t);
871                         return NT_STATUS_NO_MEMORY;
872                 }
873         } else {
874                 nt_members = NULL;
875         }
876
877         for (i=0; i < r->num_rids; i++) {
878                 struct samu *member = NULL;
879                 DOM_SID member_sid;
880
881                 if ( !(member = samu_new(t)) ) {
882                         talloc_destroy(t);
883                         return NT_STATUS_NO_MEMORY;
884                 }
885
886                 sid_copy(&member_sid, get_global_sam_sid());
887                 sid_append_rid(&member_sid, r->rids[i]);
888
889                 if (!pdb_getsampwsid(member, &member_sid)) {
890                         DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
891                                   r->rids[i], sid_string_tos(&member_sid), grp->gr_name));
892                         TALLOC_FREE(member);
893                         continue;
894                 }
895
896                 if (pdb_get_group_rid(member) == rid) {
897                         d_printf("%s(primary),", pdb_get_username(member));
898                         TALLOC_FREE(member);
899                         continue;
900                 }
901
902                 d_printf("%s,", pdb_get_username(member));
903                 nt_members[i] = talloc_strdup(t, pdb_get_username(member));
904                 TALLOC_FREE(member);
905         }
906
907         d_printf("\n");
908
909         unix_members = grp->gr_mem;
910
911         while (*unix_members) {
912                 bool is_nt_member = False;
913                 for (i=0; i < r->num_rids; i++) {
914                         if (nt_members[i] == NULL) {
915                                 /* This was a primary group */
916                                 continue;
917                         }
918
919                         if (strcmp(*unix_members, nt_members[i]) == 0) {
920                                 is_nt_member = True;
921                                 break;
922                         }
923                 }
924                 if (!is_nt_member) {
925                         /* We look at a unix group member that is not
926                            an nt group member. So, remove it. NT is
927                            boss here. */
928                         smb_delete_user_group(grp->gr_name, *unix_members);
929                 }
930                 unix_members += 1;
931         }
932
933         for (i=0; i < r->num_rids; i++) {
934                 bool is_unix_member = False;
935
936                 if (nt_members[i] == NULL) {
937                         /* This was the primary group */
938                         continue;
939                 }
940
941                 unix_members = grp->gr_mem;
942
943                 while (*unix_members) {
944                         if (strcmp(*unix_members, nt_members[i]) == 0) {
945                                 is_unix_member = True;
946                                 break;
947                         }
948                         unix_members += 1;
949                 }
950
951                 if (!is_unix_member) {
952                         /* We look at a nt group member that is not a
953                            unix group member currently. So, add the nt
954                            group member. */
955                         smb_add_user_group(grp->gr_name, nt_members[i]);
956                 }
957         }
958
959         talloc_destroy(t);
960         return NT_STATUS_OK;
961 }
962
963 static NTSTATUS fetch_alias_info(uint32_t rid,
964                                  struct netr_DELTA_ALIAS *r,
965                                  DOM_SID dom_sid)
966 {
967         fstring name;
968         fstring comment;
969         struct group *grp = NULL;
970         DOM_SID alias_sid;
971         fstring sid_string;
972         GROUP_MAP map;
973         bool insert = True;
974
975         fstrcpy(name, r->alias_name.string);
976         fstrcpy(comment, r->description.string);
977
978         /* Find out whether the group is already mapped */
979         sid_copy(&alias_sid, &dom_sid);
980         sid_append_rid(&alias_sid, rid);
981         sid_to_fstring(sid_string, &alias_sid);
982
983         if (pdb_getgrsid(&map, alias_sid)) {
984                 grp = getgrgid(map.gid);
985                 insert = False;
986         }
987
988         if (grp == NULL) {
989                 gid_t gid;
990
991                 /* No group found from mapping, find it from its name. */
992                 if ((grp = getgrnam(name)) == NULL) {
993                         /* No appropriate group found, create one */
994                         d_printf("Creating unix group: '%s'\n", name);
995                         if (smb_create_group(name, &gid) != 0)
996                                 return NT_STATUS_ACCESS_DENIED;
997                         if ((grp = getgrgid(gid)) == NULL)
998                                 return NT_STATUS_ACCESS_DENIED;
999                 }
1000         }
1001
1002         map.gid = grp->gr_gid;
1003         map.sid = alias_sid;
1004
1005         if (sid_equal(&dom_sid, &global_sid_Builtin))
1006                 map.sid_name_use = SID_NAME_WKN_GRP;
1007         else
1008                 map.sid_name_use = SID_NAME_ALIAS;
1009
1010         fstrcpy(map.nt_name, name);
1011         fstrcpy(map.comment, comment);
1012
1013         if (insert)
1014                 pdb_add_group_mapping_entry(&map);
1015         else
1016                 pdb_update_group_mapping_entry(&map);
1017
1018         return NT_STATUS_OK;
1019 }
1020
1021 static NTSTATUS fetch_alias_mem(uint32_t rid,
1022                                 struct netr_DELTA_ALIAS_MEMBER *r,
1023                                 DOM_SID dom_sid)
1024 {
1025         return NT_STATUS_OK;
1026 }
1027
1028 static NTSTATUS fetch_domain_info(uint32_t rid,
1029                                   struct netr_DELTA_DOMAIN *r)
1030 {
1031         time_t u_max_age, u_min_age, u_logout;
1032         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1033         const char *domname;
1034         struct netr_AcctLockStr *lockstr = NULL;
1035         NTSTATUS status;
1036         TALLOC_CTX *mem_ctx = talloc_tos();
1037
1038         status = pull_netr_AcctLockStr(mem_ctx, &r->account_lockout,
1039                                        &lockstr);
1040         if (!NT_STATUS_IS_OK(status)) {
1041                 d_printf("failed to pull account lockout string: %s\n",
1042                         nt_errstr(status));
1043         }
1044
1045         u_max_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->max_password_age);
1046         u_min_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->min_password_age);
1047         u_logout = uint64s_nt_time_to_unix_abs((uint64 *)&r->force_logoff_time);
1048
1049         domname = r->domain_name.string;
1050         if (!domname) {
1051                 return NT_STATUS_NO_MEMORY;
1052         }
1053
1054         /* we don't handle BUILTIN account policies */
1055         if (!strequal(domname, get_global_sam_name())) {
1056                 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname);
1057                 return NT_STATUS_OK;
1058         }
1059
1060
1061         if (!pdb_set_account_policy(AP_PASSWORD_HISTORY,
1062                                     r->password_history_length))
1063                 return nt_status;
1064
1065         if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
1066                                     r->min_password_length))
1067                 return nt_status;
1068
1069         if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
1070                 return nt_status;
1071
1072         if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
1073                 return nt_status;
1074
1075         if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
1076                 return nt_status;
1077
1078         if (lockstr) {
1079                 time_t u_lockoutreset, u_lockouttime;
1080
1081                 u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count);
1082                 u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration);
1083
1084                 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
1085                                             lockstr->bad_attempt_lockout))
1086                         return nt_status;
1087
1088                 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60))
1089                         return nt_status;
1090
1091                 if (u_lockouttime != -1)
1092                         u_lockouttime /= 60;
1093
1094                 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime))
1095                         return nt_status;
1096         }
1097
1098         if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1099                                     r->logon_to_chgpass))
1100                 return nt_status;
1101
1102         return NT_STATUS_OK;
1103 }
1104
1105 static void fetch_sam_entry(struct netr_DELTA_ENUM *r, DOM_SID dom_sid)
1106 {
1107         switch(r->delta_type) {
1108         case NETR_DELTA_USER:
1109                 fetch_account_info(r->delta_id_union.rid,
1110                                    r->delta_union.user);
1111                 break;
1112         case NETR_DELTA_GROUP:
1113                 fetch_group_info(r->delta_id_union.rid,
1114                                  r->delta_union.group);
1115                 break;
1116         case NETR_DELTA_GROUP_MEMBER:
1117                 fetch_group_mem_info(r->delta_id_union.rid,
1118                                      r->delta_union.group_member);
1119                 break;
1120         case NETR_DELTA_ALIAS:
1121                 fetch_alias_info(r->delta_id_union.rid,
1122                                  r->delta_union.alias,
1123                                  dom_sid);
1124                 break;
1125         case NETR_DELTA_ALIAS_MEMBER:
1126                 fetch_alias_mem(r->delta_id_union.rid,
1127                                 r->delta_union.alias_member,
1128                                 dom_sid);
1129                 break;
1130         case NETR_DELTA_DOMAIN:
1131                 fetch_domain_info(r->delta_id_union.rid,
1132                                   r->delta_union.domain);
1133                 break;
1134         /* The following types are recognised but not handled */
1135         case NETR_DELTA_RENAME_GROUP:
1136                 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1137                 break;
1138         case NETR_DELTA_RENAME_USER:
1139                 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1140                 break;
1141         case NETR_DELTA_RENAME_ALIAS:
1142                 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1143                 break;
1144         case NETR_DELTA_POLICY:
1145                 d_printf("NETR_DELTA_POLICY not handled\n");
1146                 break;
1147         case NETR_DELTA_TRUSTED_DOMAIN:
1148                 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1149                 break;
1150         case NETR_DELTA_ACCOUNT:
1151                 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1152                 break;
1153         case NETR_DELTA_SECRET:
1154                 d_printf("NETR_DELTA_SECRET not handled\n");
1155                 break;
1156         case NETR_DELTA_DELETE_GROUP:
1157                 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1158                 break;
1159         case NETR_DELTA_DELETE_USER:
1160                 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1161                 break;
1162         case NETR_DELTA_MODIFY_COUNT:
1163                 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1164                 break;
1165         case NETR_DELTA_DELETE_ALIAS:
1166                 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1167                 break;
1168         case NETR_DELTA_DELETE_TRUST:
1169                 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1170                 break;
1171         case NETR_DELTA_DELETE_ACCOUNT:
1172                 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1173                 break;
1174         case NETR_DELTA_DELETE_SECRET:
1175                 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1176                 break;
1177         case NETR_DELTA_DELETE_GROUP2:
1178                 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1179                 break;
1180         case NETR_DELTA_DELETE_USER2:
1181                 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1182                 break;
1183         default:
1184                 d_printf("Unknown delta record type %d\n", r->delta_type);
1185                 break;
1186         }
1187 }
1188
1189 static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, DOM_SID dom_sid)
1190 {
1191         NTSTATUS result;
1192         int i;
1193         TALLOC_CTX *mem_ctx;
1194         const char *logon_server = pipe_hnd->desthost;
1195         const char *computername = global_myname();
1196         struct netr_Authenticator credential;
1197         struct netr_Authenticator return_authenticator;
1198         enum netr_SamDatabaseID database_id = db_type;
1199         uint16_t restart_state = 0;
1200         uint32_t sync_context = 0;
1201
1202         if (!(mem_ctx = talloc_init("fetch_database")))
1203                 return NT_STATUS_NO_MEMORY;
1204
1205         switch( db_type ) {
1206         case SAM_DATABASE_DOMAIN:
1207                 d_printf("Fetching DOMAIN database\n");
1208                 break;
1209         case SAM_DATABASE_BUILTIN:
1210                 d_printf("Fetching BUILTIN database\n");
1211                 break;
1212         case SAM_DATABASE_PRIVS:
1213                 d_printf("Fetching PRIVS databases\n");
1214                 break;
1215         default:
1216                 d_printf("Fetching unknown database type %u\n", db_type );
1217                 break;
1218         }
1219
1220         do {
1221                 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1222
1223                 netlogon_creds_client_step(pipe_hnd->dc, &credential);
1224
1225                 result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx,
1226                                                    logon_server,
1227                                                    computername,
1228                                                    &credential,
1229                                                    &return_authenticator,
1230                                                    database_id,
1231                                                    restart_state,
1232                                                    &sync_context,
1233                                                    &delta_enum_array,
1234                                                    0xffff);
1235
1236                 /* Check returned credentials. */
1237                 if (!netlogon_creds_client_check(pipe_hnd->dc,
1238                                                  &return_authenticator.cred)) {
1239                         DEBUG(0,("credentials chain check failed\n"));
1240                         return NT_STATUS_ACCESS_DENIED;
1241                 }
1242
1243                 if (NT_STATUS_IS_ERR(result)) {
1244                         break;
1245                 }
1246
1247                 for (i = 0; i < delta_enum_array->num_deltas; i++) {
1248                         fetch_sam_entry(&delta_enum_array->delta_enum[i], dom_sid);
1249                 }
1250
1251         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1252
1253         talloc_destroy(mem_ctx);
1254
1255         return result;
1256 }
1257
1258 static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char
1259                        *builtin_sid, FILE *add_fd)
1260 {
1261         const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix;
1262         char *user_attr=NULL, *group_attr=NULL;
1263         char *suffix_attr;
1264         int len;
1265
1266         /* Get the suffix attribute */
1267         suffix_attr = sstring_sub(suffix, '=', ',');
1268         if (suffix_attr == NULL) {
1269                 len = strlen(suffix);
1270                 suffix_attr = (char*)SMB_MALLOC(len+1);
1271                 memcpy(suffix_attr, suffix, len);
1272                 suffix_attr[len] = '\0';
1273         }
1274
1275         /* Write the base */
1276         fprintf(add_fd, "# %s\n", suffix);
1277         fprintf(add_fd, "dn: %s\n", suffix);
1278         fprintf(add_fd, "objectClass: dcObject\n");
1279         fprintf(add_fd, "objectClass: organization\n");
1280         fprintf(add_fd, "o: %s\n", suffix_attr);
1281         fprintf(add_fd, "dc: %s\n", suffix_attr);
1282         fprintf(add_fd, "\n");
1283         fflush(add_fd);
1284
1285         user_suffix = lp_ldap_user_suffix();
1286         if (user_suffix == NULL) {
1287                 SAFE_FREE(suffix_attr);
1288                 return NT_STATUS_NO_MEMORY;
1289         }
1290         /* If it exists and is distinct from other containers,
1291            Write the Users entity */
1292         if (*user_suffix && strcmp(user_suffix, suffix)) {
1293                 user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ',');
1294                 fprintf(add_fd, "# %s\n", user_suffix);
1295                 fprintf(add_fd, "dn: %s\n", user_suffix);
1296                 fprintf(add_fd, "objectClass: organizationalUnit\n");
1297                 fprintf(add_fd, "ou: %s\n", user_attr);
1298                 fprintf(add_fd, "\n");
1299                 fflush(add_fd);
1300         }
1301
1302
1303         group_suffix = lp_ldap_group_suffix();
1304         if (group_suffix == NULL) {
1305                 SAFE_FREE(suffix_attr);
1306                 SAFE_FREE(user_attr);
1307                 return NT_STATUS_NO_MEMORY;
1308         }
1309         /* If it exists and is distinct from other containers,
1310            Write the Groups entity */
1311         if (*group_suffix && strcmp(group_suffix, suffix)) {
1312                 group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1313                 fprintf(add_fd, "# %s\n", group_suffix);
1314                 fprintf(add_fd, "dn: %s\n", group_suffix);
1315                 fprintf(add_fd, "objectClass: organizationalUnit\n");
1316                 fprintf(add_fd, "ou: %s\n", group_attr);
1317                 fprintf(add_fd, "\n");
1318                 fflush(add_fd);
1319         }
1320
1321         /* If it exists and is distinct from other containers,
1322            Write the Computers entity */
1323         machine_suffix = lp_ldap_machine_suffix();
1324         if (machine_suffix == NULL) {
1325                 SAFE_FREE(suffix_attr);
1326                 SAFE_FREE(user_attr);
1327                 SAFE_FREE(group_attr);
1328                 return NT_STATUS_NO_MEMORY;
1329         }
1330         if (*machine_suffix && strcmp(machine_suffix, user_suffix) &&
1331             strcmp(machine_suffix, suffix)) {
1332                 char *machine_ou = NULL;
1333                 fprintf(add_fd, "# %s\n", machine_suffix);
1334                 fprintf(add_fd, "dn: %s\n", machine_suffix);
1335                 fprintf(add_fd, "objectClass: organizationalUnit\n");
1336                 /* this isn't totally correct as it assumes that
1337                    there _must_ be an ou. just fixing memleak now. jmcd */
1338                 machine_ou = sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1339                 fprintf(add_fd, "ou: %s\n", machine_ou);
1340                 SAFE_FREE(machine_ou);
1341                 fprintf(add_fd, "\n");
1342                 fflush(add_fd);
1343         }
1344
1345         /* If it exists and is distinct from other containers,
1346            Write the IdMap entity */
1347         idmap_suffix = lp_ldap_idmap_suffix();
1348         if (idmap_suffix == NULL) {
1349                 SAFE_FREE(suffix_attr);
1350                 SAFE_FREE(user_attr);
1351                 SAFE_FREE(group_attr);
1352                 return NT_STATUS_NO_MEMORY;
1353         }
1354         if (*idmap_suffix &&
1355             strcmp(idmap_suffix, user_suffix) &&
1356             strcmp(idmap_suffix, suffix)) {
1357                 char *s;
1358                 fprintf(add_fd, "# %s\n", idmap_suffix);
1359                 fprintf(add_fd, "dn: %s\n", idmap_suffix);
1360                 fprintf(add_fd, "ObjectClass: organizationalUnit\n");
1361                 s = sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1362                 fprintf(add_fd, "ou: %s\n", s);
1363                 SAFE_FREE(s);
1364                 fprintf(add_fd, "\n");
1365                 fflush(add_fd);
1366         }
1367
1368         /* Write the domain entity */
1369         fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix);
1370         fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1371                 suffix);
1372         fprintf(add_fd, "objectClass: sambaDomain\n");
1373         fprintf(add_fd, "objectClass: sambaUnixIdPool\n");
1374         fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup());
1375         fprintf(add_fd, "sambaSID: %s\n", sid);
1376         fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid);
1377         fprintf(add_fd, "gidNumber: %d\n", ++ldif_gid);
1378         fprintf(add_fd, "\n");
1379         fflush(add_fd);
1380
1381         /* Write the Domain Admins entity */
1382         fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr,
1383                 suffix);
1384         fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr,
1385                 suffix);
1386         fprintf(add_fd, "objectClass: posixGroup\n");
1387         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1388         fprintf(add_fd, "cn: Domain Admins\n");
1389         fprintf(add_fd, "memberUid: Administrator\n");
1390         fprintf(add_fd, "description: Netbios Domain Administrators\n");
1391         fprintf(add_fd, "gidNumber: 512\n");
1392         fprintf(add_fd, "sambaSID: %s-512\n", sid);
1393         fprintf(add_fd, "sambaGroupType: 2\n");
1394         fprintf(add_fd, "displayName: Domain Admins\n");
1395         fprintf(add_fd, "\n");
1396         fflush(add_fd);
1397
1398         /* Write the Domain Users entity */
1399         fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr,
1400                 suffix);
1401         fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr,
1402                 suffix);
1403         fprintf(add_fd, "objectClass: posixGroup\n");
1404         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1405         fprintf(add_fd, "cn: Domain Users\n");
1406         fprintf(add_fd, "description: Netbios Domain Users\n");
1407         fprintf(add_fd, "gidNumber: 513\n");
1408         fprintf(add_fd, "sambaSID: %s-513\n", sid);
1409         fprintf(add_fd, "sambaGroupType: 2\n");
1410         fprintf(add_fd, "displayName: Domain Users\n");
1411         fprintf(add_fd, "\n");
1412         fflush(add_fd);
1413
1414         /* Write the Domain Guests entity */
1415         fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr,
1416                 suffix);
1417         fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr,
1418                 suffix);
1419         fprintf(add_fd, "objectClass: posixGroup\n");
1420         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1421         fprintf(add_fd, "cn: Domain Guests\n");
1422         fprintf(add_fd, "description: Netbios Domain Guests\n");
1423         fprintf(add_fd, "gidNumber: 514\n");
1424         fprintf(add_fd, "sambaSID: %s-514\n", sid);
1425         fprintf(add_fd, "sambaGroupType: 2\n");
1426         fprintf(add_fd, "displayName: Domain Guests\n");
1427         fprintf(add_fd, "\n");
1428         fflush(add_fd);
1429
1430         /* Write the Domain Computers entity */
1431         fprintf(add_fd, "# Domain Computers, %s, %s\n", group_attr,
1432                 suffix);
1433         fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n",
1434                 group_attr, suffix);
1435         fprintf(add_fd, "objectClass: posixGroup\n");
1436         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1437         fprintf(add_fd, "gidNumber: 515\n");
1438         fprintf(add_fd, "cn: Domain Computers\n");
1439         fprintf(add_fd, "description: Netbios Domain Computers accounts\n");
1440         fprintf(add_fd, "sambaSID: %s-515\n", sid);
1441         fprintf(add_fd, "sambaGroupType: 2\n");
1442         fprintf(add_fd, "displayName: Domain Computers\n");
1443         fprintf(add_fd, "\n");
1444         fflush(add_fd);
1445
1446         /* Write the Admininistrators Groups entity */
1447         fprintf(add_fd, "# Administrators, %s, %s\n", group_attr,
1448                 suffix);
1449         fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr,
1450                 suffix);
1451         fprintf(add_fd, "objectClass: posixGroup\n");
1452         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1453         fprintf(add_fd, "gidNumber: 544\n");
1454         fprintf(add_fd, "cn: Administrators\n");
1455         fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1456         fprintf(add_fd, "sambaSID: %s-544\n", builtin_sid);
1457         fprintf(add_fd, "sambaGroupType: 5\n");
1458         fprintf(add_fd, "displayName: Administrators\n");
1459         fprintf(add_fd, "\n");
1460
1461         /* Write the Print Operator entity */
1462         fprintf(add_fd, "# Print Operators, %s, %s\n", group_attr,
1463                 suffix);
1464         fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n",
1465                 group_attr, suffix);
1466         fprintf(add_fd, "objectClass: posixGroup\n");
1467         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1468         fprintf(add_fd, "gidNumber: 550\n");
1469         fprintf(add_fd, "cn: Print Operators\n");
1470         fprintf(add_fd, "description: Netbios Domain Print Operators\n");
1471         fprintf(add_fd, "sambaSID: %s-550\n", builtin_sid);
1472         fprintf(add_fd, "sambaGroupType: 5\n");
1473         fprintf(add_fd, "displayName: Print Operators\n");
1474         fprintf(add_fd, "\n");
1475         fflush(add_fd);
1476
1477         /* Write the Backup Operators entity */
1478         fprintf(add_fd, "# Backup Operators, %s, %s\n", group_attr,
1479                 suffix);
1480         fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n",
1481                 group_attr, suffix);
1482         fprintf(add_fd, "objectClass: posixGroup\n");
1483         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1484         fprintf(add_fd, "gidNumber: 551\n");
1485         fprintf(add_fd, "cn: Backup Operators\n");
1486         fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n");
1487         fprintf(add_fd, "sambaSID: %s-551\n", builtin_sid);
1488         fprintf(add_fd, "sambaGroupType: 5\n");
1489         fprintf(add_fd, "displayName: Backup Operators\n");
1490         fprintf(add_fd, "\n");
1491         fflush(add_fd);
1492
1493         /* Write the Replicators entity */
1494         fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix);
1495         fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr,
1496                 suffix);
1497         fprintf(add_fd, "objectClass: posixGroup\n");
1498         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1499         fprintf(add_fd, "gidNumber: 552\n");
1500         fprintf(add_fd, "cn: Replicators\n");
1501         fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1502         fprintf(add_fd, "sambaSID: %s-552\n", builtin_sid);
1503         fprintf(add_fd, "sambaGroupType: 5\n");
1504         fprintf(add_fd, "displayName: Replicators\n");
1505         fprintf(add_fd, "\n");
1506         fflush(add_fd);
1507
1508         /* Deallocate memory, and return */
1509         SAFE_FREE(suffix_attr);
1510         SAFE_FREE(user_attr);
1511         SAFE_FREE(group_attr);
1512         return NT_STATUS_OK;
1513 }
1514
1515 static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid,
1516                     const char *suffix, const char *builtin_sid)
1517 {
1518         char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1519
1520         /* Map the groups created by populate_ldap_for_ldif */
1521         groupmap[0].rid = 512;
1522         groupmap[0].gidNumber = 512;
1523         snprintf(groupmap[0].sambaSID, sizeof(groupmap[0].sambaSID),
1524                         "%s-512", sid);
1525         snprintf(groupmap[0].group_dn, sizeof(groupmap[0].group_dn),
1526                         "cn=Domain Admins,ou=%s,%s",
1527                         group_attr, suffix);
1528         accountmap[0].rid = 512;
1529         snprintf(accountmap[0].cn, sizeof(accountmap[0].cn),
1530                         "%s", "Domain Admins");
1531
1532         groupmap[1].rid = 513;
1533         groupmap[1].gidNumber = 513;
1534         snprintf(groupmap[1].sambaSID, sizeof(groupmap[1].sambaSID),
1535                         "%s-513", sid);
1536         snprintf(groupmap[1].group_dn, sizeof(groupmap[1].group_dn),
1537                         "cn=Domain Users,ou=%s,%s",
1538                         group_attr, suffix);
1539         accountmap[1].rid = 513;
1540         snprintf(accountmap[1].cn, sizeof(accountmap[1].cn),
1541                         "%s", "Domain Users");
1542
1543         groupmap[2].rid = 514;
1544         groupmap[2].gidNumber = 514;
1545         snprintf(groupmap[2].sambaSID, sizeof(groupmap[2].sambaSID),
1546                         "%s-514", sid);
1547         snprintf(groupmap[2].group_dn, sizeof(groupmap[2].group_dn),
1548                         "cn=Domain Guests,ou=%s,%s",
1549                         group_attr, suffix);
1550         accountmap[2].rid = 514;
1551         snprintf(accountmap[2].cn, sizeof(accountmap[2].cn),
1552                         "%s", "Domain Guests");
1553
1554         groupmap[3].rid = 515;
1555         groupmap[3].gidNumber = 515;
1556         snprintf(groupmap[3].sambaSID, sizeof(groupmap[3].sambaSID),
1557                         "%s-515", sid);
1558         snprintf(groupmap[3].group_dn, sizeof(groupmap[3].group_dn),
1559                         "cn=Domain Computers,ou=%s,%s",
1560                         group_attr, suffix);
1561         accountmap[3].rid = 515;
1562         snprintf(accountmap[3].cn, sizeof(accountmap[3].cn),
1563                         "%s", "Domain Computers");
1564
1565         groupmap[4].rid = 544;
1566         groupmap[4].gidNumber = 544;
1567         snprintf(groupmap[4].sambaSID, sizeof(groupmap[4].sambaSID),
1568                         "%s-544", builtin_sid);
1569         snprintf(groupmap[4].group_dn, sizeof(groupmap[4].group_dn),
1570                         "cn=Administrators,ou=%s,%s",
1571                         group_attr, suffix);
1572         accountmap[4].rid = 515;
1573         snprintf(accountmap[4].cn, sizeof(accountmap[4].cn),
1574                         "%s", "Administrators");
1575
1576         groupmap[5].rid = 550;
1577         groupmap[5].gidNumber = 550;
1578         snprintf(groupmap[5].sambaSID, sizeof(groupmap[5].sambaSID),
1579                         "%s-550", builtin_sid);
1580         snprintf(groupmap[5].group_dn, sizeof(groupmap[5].group_dn),
1581                         "cn=Print Operators,ou=%s,%s",
1582                         group_attr, suffix);
1583         accountmap[5].rid = 550;
1584         snprintf(accountmap[5].cn, sizeof(accountmap[5].cn),
1585                         "%s", "Print Operators");
1586
1587         groupmap[6].rid = 551;
1588         groupmap[6].gidNumber = 551;
1589         snprintf(groupmap[6].sambaSID, sizeof(groupmap[6].sambaSID),
1590                         "%s-551", builtin_sid);
1591         snprintf(groupmap[6].group_dn, sizeof(groupmap[6].group_dn),
1592                         "cn=Backup Operators,ou=%s,%s",
1593                         group_attr, suffix);
1594         accountmap[6].rid = 551;
1595         snprintf(accountmap[6].cn, sizeof(accountmap[6].cn),
1596                         "%s", "Backup Operators");
1597
1598         groupmap[7].rid = 552;
1599         groupmap[7].gidNumber = 552;
1600         snprintf(groupmap[7].sambaSID, sizeof(groupmap[7].sambaSID),
1601                         "%s-552", builtin_sid);
1602         snprintf(groupmap[7].group_dn, sizeof(groupmap[7].group_dn),
1603                         "cn=Replicators,ou=%s,%s",
1604                         group_attr, suffix);
1605         accountmap[7].rid = 551;
1606         snprintf(accountmap[7].cn, sizeof(accountmap[7].cn),
1607                         "%s", "Replicators");
1608         SAFE_FREE(group_attr);
1609         return NT_STATUS_OK;
1610 }
1611
1612 /*
1613  * This is a crap routine, but I think it's the quickest way to solve the
1614  * UTF8->base64 problem.
1615  */
1616
1617 static int fprintf_attr(FILE *add_fd, const char *attr_name,
1618                         const char *fmt, ...)
1619 {
1620         va_list ap;
1621         char *value, *p, *base64;
1622         DATA_BLOB base64_blob;
1623         bool do_base64 = False;
1624         int res;
1625
1626         va_start(ap, fmt);
1627         value = talloc_vasprintf(NULL, fmt, ap);
1628         va_end(ap);
1629
1630         SMB_ASSERT(value != NULL);
1631
1632         for (p=value; *p; p++) {
1633                 if (*p & 0x80) {
1634                         do_base64 = True;
1635                         break;
1636                 }
1637         }
1638
1639         if (!do_base64) {
1640                 bool only_whitespace = True;
1641                 for (p=value; *p; p++) {
1642                         /*
1643                          * I know that this not multibyte safe, but we break
1644                          * on the first non-whitespace character anyway.
1645                          */
1646                         if (!isspace(*p)) {
1647                                 only_whitespace = False;
1648                                 break;
1649                         }
1650                 }
1651                 if (only_whitespace) {
1652                         do_base64 = True;
1653                 }
1654         }
1655
1656         if (!do_base64) {
1657                 res = fprintf(add_fd, "%s: %s\n", attr_name, value);
1658                 TALLOC_FREE(value);
1659                 return res;
1660         }
1661
1662         base64_blob.data = (unsigned char *)value;
1663         base64_blob.length = strlen(value);
1664
1665         base64 = base64_encode_data_blob(value, base64_blob);
1666         SMB_ASSERT(base64 != NULL);
1667
1668         res = fprintf(add_fd, "%s:: %s\n", attr_name, base64);
1669         TALLOC_FREE(value);
1670         return res;
1671 }
1672
1673 static NTSTATUS fetch_group_info_to_ldif(struct netr_DELTA_GROUP *r, GROUPMAP *groupmap,
1674                          FILE *add_fd, fstring sid, char *suffix)
1675 {
1676         fstring groupname;
1677         uint32 grouptype = 0, g_rid = 0;
1678         char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1679
1680         /* Get the group name */
1681         fstrcpy(groupname, r->group_name.string);
1682
1683         /* Set up the group type (always 2 for group info) */
1684         grouptype = 2;
1685
1686         /* These groups are entered by populate_ldap_for_ldif */
1687         if (strcmp(groupname, "Domain Admins") == 0 ||
1688             strcmp(groupname, "Domain Users") == 0 ||
1689             strcmp(groupname, "Domain Guests") == 0 ||
1690             strcmp(groupname, "Domain Computers") == 0 ||
1691             strcmp(groupname, "Administrators") == 0 ||
1692             strcmp(groupname, "Print Operators") == 0 ||
1693             strcmp(groupname, "Backup Operators") == 0 ||
1694             strcmp(groupname, "Replicators") == 0) {
1695                 SAFE_FREE(group_attr);
1696                 return NT_STATUS_OK;
1697         } else {
1698                 /* Increment the gid for the new group */
1699                 ldif_gid++;
1700         }
1701
1702         /* Map the group rid, gid, and dn */
1703         g_rid = r->rid;
1704         groupmap->rid = g_rid;
1705         groupmap->gidNumber = ldif_gid;
1706         snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID),
1707                         "%s-%d", sid, g_rid);
1708         snprintf(groupmap->group_dn, sizeof(groupmap->group_dn),
1709                      "cn=%s,ou=%s,%s", groupname, group_attr, suffix);
1710
1711         /* Write the data to the temporary add ldif file */
1712         fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr,
1713                 suffix);
1714         fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", groupname, group_attr,
1715                      suffix);
1716         fprintf(add_fd, "objectClass: posixGroup\n");
1717         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1718         fprintf_attr(add_fd, "cn", "%s", groupname);
1719         fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
1720         fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
1721         fprintf(add_fd, "sambaGroupType: %d\n", grouptype);
1722         fprintf_attr(add_fd, "displayName", "%s", groupname);
1723         fprintf(add_fd, "\n");
1724         fflush(add_fd);
1725
1726         SAFE_FREE(group_attr);
1727         /* Return */
1728         return NT_STATUS_OK;
1729 }
1730
1731 static NTSTATUS fetch_account_info_to_ldif(struct netr_DELTA_USER *r,
1732                                            GROUPMAP *groupmap,
1733                                            ACCOUNTMAP *accountmap,
1734                                            FILE *add_fd,
1735                                            fstring sid, char *suffix,
1736                                            int alloced)
1737 {
1738         fstring username, logonscript, homedrive, homepath = "", homedir = "";
1739         fstring hex_nt_passwd, hex_lm_passwd;
1740         fstring description, profilepath, fullname, sambaSID;
1741         uchar lm_passwd[16], nt_passwd[16];
1742         char *flags, *user_rdn;
1743         const char *ou;
1744         const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1745         static uchar zero_buf[16];
1746         uint32 rid = 0, group_rid = 0, gidNumber = 0;
1747         time_t unix_time;
1748         int i;
1749
1750         /* Get the username */
1751         fstrcpy(username, r->account_name.string);
1752
1753         /* Get the rid */
1754         rid = r->rid;
1755
1756         /* Map the rid and username for group member info later */
1757         accountmap->rid = rid;
1758         snprintf(accountmap->cn, sizeof(accountmap->cn), "%s", username);
1759
1760         /* Get the home directory */
1761         if (r->acct_flags & ACB_NORMAL) {
1762                 fstrcpy(homedir, r->home_directory.string);
1763                 if (!*homedir) {
1764                         snprintf(homedir, sizeof(homedir), "/home/%s", username);
1765                 } else {
1766                         snprintf(homedir, sizeof(homedir), "/nobodyshomedir");
1767                 }
1768                 ou = lp_ldap_user_suffix();
1769         } else {
1770                 ou = lp_ldap_machine_suffix();
1771                 snprintf(homedir, sizeof(homedir), "/machinehomedir");
1772         }
1773
1774         /* Get the logon script */
1775         fstrcpy(logonscript, r->logon_script.string);
1776
1777         /* Get the home drive */
1778         fstrcpy(homedrive, r->home_drive.string);
1779
1780         /* Get the home path */
1781         fstrcpy(homepath, r->home_directory.string);
1782
1783         /* Get the description */
1784         fstrcpy(description, r->description.string);
1785
1786         /* Get the display name */
1787         fstrcpy(fullname, r->full_name.string);
1788
1789         /* Get the profile path */
1790         fstrcpy(profilepath, r->profile_path.string);
1791
1792         /* Get lm and nt password data */
1793         if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
1794                 sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
1795                 pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
1796         } else {
1797                 pdb_sethexpwd(hex_lm_passwd, NULL, 0);
1798         }
1799         if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
1800                 sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
1801                 pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
1802         } else {
1803                 pdb_sethexpwd(hex_nt_passwd, NULL, 0);
1804         }
1805         unix_time = nt_time_to_unix(r->last_password_change);
1806
1807         /* Increment the uid for the new user */
1808         ldif_uid++;
1809
1810         /* Set up group id and sambaSID for the user */
1811         group_rid = r->primary_gid;
1812         for (i=0; i<alloced; i++) {
1813                 if (groupmap[i].rid == group_rid) break;
1814         }
1815         if (i == alloced){
1816                 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1817                           group_rid));
1818                 return NT_STATUS_UNSUCCESSFUL;
1819         }
1820         gidNumber = groupmap[i].gidNumber;
1821         snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID);
1822
1823         /* Set up sambaAcctFlags */
1824         flags = pdb_encode_acct_ctrl(r->acct_flags,
1825                                      NEW_PW_FORMAT_SPACE_PADDED_LEN);
1826
1827         /* Add the user to the temporary add ldif file */
1828         /* this isn't quite right...we can't assume there's just OU=. jmcd */
1829         user_rdn = sstring_sub(ou, '=', ',');
1830         fprintf(add_fd, "# %s, %s, %s\n", username, user_rdn, suffix);
1831         fprintf_attr(add_fd, "dn", "uid=%s,ou=%s,%s", username, user_rdn,
1832                      suffix);
1833         SAFE_FREE(user_rdn);
1834         fprintf(add_fd, "ObjectClass: top\n");
1835         fprintf(add_fd, "objectClass: inetOrgPerson\n");
1836         fprintf(add_fd, "objectClass: posixAccount\n");
1837         fprintf(add_fd, "objectClass: shadowAccount\n");
1838         fprintf(add_fd, "objectClass: sambaSamAccount\n");
1839         fprintf_attr(add_fd, "cn", "%s", username);
1840         fprintf_attr(add_fd, "sn", "%s", username);
1841         fprintf_attr(add_fd, "uid", "%s", username);
1842         fprintf(add_fd, "uidNumber: %d\n", ldif_uid);
1843         fprintf(add_fd, "gidNumber: %d\n", gidNumber);
1844         fprintf_attr(add_fd, "homeDirectory", "%s", homedir);
1845         if (*homepath)
1846                 fprintf_attr(add_fd, "sambaHomePath", "%s", homepath);
1847         if (*homedrive)
1848                 fprintf_attr(add_fd, "sambaHomeDrive", "%s", homedrive);
1849         if (*logonscript)
1850                 fprintf_attr(add_fd, "sambaLogonScript", "%s", logonscript);
1851         fprintf(add_fd, "loginShell: %s\n",
1852                 ((r->acct_flags & ACB_NORMAL) ?
1853                  "/bin/bash" : "/bin/false"));
1854         fprintf(add_fd, "gecos: System User\n");
1855         if (*description)
1856                 fprintf_attr(add_fd, "description", "%s", description);
1857         fprintf(add_fd, "sambaSID: %s-%d\n", sid, rid);
1858         fprintf(add_fd, "sambaPrimaryGroupSID: %s\n", sambaSID);
1859         if(*fullname)
1860                 fprintf_attr(add_fd, "displayName", "%s", fullname);
1861         if(*profilepath)
1862                 fprintf_attr(add_fd, "sambaProfilePath", "%s", profilepath);
1863         if (strcmp(nopasswd, hex_lm_passwd) != 0)
1864                 fprintf(add_fd, "sambaLMPassword: %s\n", hex_lm_passwd);
1865         if (strcmp(nopasswd, hex_nt_passwd) != 0)
1866                 fprintf(add_fd, "sambaNTPassword: %s\n", hex_nt_passwd);
1867         fprintf(add_fd, "sambaPwdLastSet: %d\n", (int)unix_time);
1868         fprintf(add_fd, "sambaAcctFlags: %s\n", flags);
1869         fprintf(add_fd, "\n");
1870         fflush(add_fd);
1871
1872         /* Return */
1873         return NT_STATUS_OK;
1874 }
1875
1876 static NTSTATUS fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS *r,
1877                                          GROUPMAP *groupmap,
1878                                          FILE *add_fd, fstring sid,
1879                                          char *suffix,
1880                                          unsigned db_type)
1881 {
1882         fstring aliasname, description;
1883         uint32 grouptype = 0, g_rid = 0;
1884         char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1885
1886         /* Get the alias name */
1887         fstrcpy(aliasname, r->alias_name.string);
1888
1889         /* Get the alias description */
1890         fstrcpy(description, r->description.string);
1891
1892         /* Set up the group type */
1893         switch (db_type) {
1894         case SAM_DATABASE_DOMAIN:
1895                 grouptype = 4;
1896                 break;
1897         case SAM_DATABASE_BUILTIN:
1898                 grouptype = 5;
1899                 break;
1900         default:
1901                 grouptype = 4;
1902                 break;
1903         }
1904
1905         /*
1906           These groups are entered by populate_ldap_for_ldif
1907           Note that populate creates a group called Relicators,
1908           but NT returns a group called Replicator
1909         */
1910         if (strcmp(aliasname, "Domain Admins") == 0 ||
1911             strcmp(aliasname, "Domain Users") == 0 ||
1912             strcmp(aliasname, "Domain Guests") == 0 ||
1913             strcmp(aliasname, "Domain Computers") == 0 ||
1914             strcmp(aliasname, "Administrators") == 0 ||
1915             strcmp(aliasname, "Print Operators") == 0 ||
1916             strcmp(aliasname, "Backup Operators") == 0 ||
1917             strcmp(aliasname, "Replicator") == 0) {
1918                 SAFE_FREE(group_attr);
1919                 return NT_STATUS_OK;
1920         } else {
1921                 /* Increment the gid for the new group */
1922                 ldif_gid++;
1923         }
1924
1925         /* Map the group rid and gid */
1926         g_rid = r->rid;
1927         groupmap->gidNumber = ldif_gid;
1928         snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID),
1929                         "%s-%d", sid, g_rid);
1930
1931         /* Write the data to the temporary add ldif file */
1932         fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr,
1933                 suffix);
1934         fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", aliasname, group_attr,
1935                      suffix);
1936         fprintf(add_fd, "objectClass: posixGroup\n");
1937         fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1938         fprintf(add_fd, "cn: %s\n", aliasname);
1939         fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
1940         fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
1941         fprintf(add_fd, "sambaGroupType: %d\n", grouptype);
1942         fprintf_attr(add_fd, "displayName", "%s", aliasname);
1943         if (description[0])
1944                 fprintf_attr(add_fd, "description", "%s", description);
1945         fprintf(add_fd, "\n");
1946         fflush(add_fd);
1947
1948         SAFE_FREE(group_attr);
1949         /* Return */
1950         return NT_STATUS_OK;
1951 }
1952
1953 static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r,
1954                                             uint32_t id_rid,
1955                                             GROUPMAP *groupmap,
1956                                             ACCOUNTMAP *accountmap,
1957                                             FILE *mod_fd, int alloced)
1958 {
1959         fstring group_dn;
1960         uint32 group_rid = 0, rid = 0;
1961         int i, j, k;
1962
1963         /* Get the dn for the group */
1964         if (r->num_rids > 0) {
1965                 group_rid = id_rid;
1966                 for (j=0; j<alloced; j++) {
1967                         if (groupmap[j].rid == group_rid) break;
1968                 }
1969                 if (j == alloced){
1970                         DEBUG(1, ("Could not find rid %d in groupmap array\n",
1971                                   group_rid));
1972                         return NT_STATUS_UNSUCCESSFUL;
1973                 }
1974                 snprintf(group_dn, sizeof(group_dn), "%s", groupmap[j].group_dn);
1975                 fprintf(mod_fd, "dn: %s\n", group_dn);
1976
1977                 /* Get the cn for each member */
1978                 for (i=0; i < r->num_rids; i++) {
1979                         rid = r->rids[i];
1980                         for (k=0; k<alloced; k++) {
1981                                 if (accountmap[k].rid == rid) break;
1982                         }
1983                         if (k == alloced){
1984                                 DEBUG(1, ("Could not find rid %d in "
1985                                           "accountmap array\n", rid));
1986                                 return NT_STATUS_UNSUCCESSFUL;
1987                         }
1988                         fprintf(mod_fd, "memberUid: %s\n", accountmap[k].cn);
1989                 }
1990                 fprintf(mod_fd, "\n");
1991         }
1992         fflush(mod_fd);
1993
1994         /* Return */
1995         return NT_STATUS_OK;
1996 }
1997
1998 static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
1999                                        uint32 db_type,
2000                                        DOM_SID dom_sid,
2001                                        const char *user_file)
2002 {
2003         char *suffix;
2004         const char *builtin_sid = "S-1-5-32";
2005         char *add_name = NULL, *mod_name = NULL;
2006         const char *add_template = "/tmp/add.ldif.XXXXXX";
2007         const char *mod_template = "/tmp/mod.ldif.XXXXXX";
2008         fstring sid, domainname;
2009         NTSTATUS ret = NT_STATUS_OK, result;
2010         int k;
2011         TALLOC_CTX *mem_ctx;
2012         uint32 num_deltas;
2013         FILE *add_file = NULL, *mod_file = NULL, *ldif_file = NULL;
2014         int num_alloced = 0, g_index = 0, a_index = 0;
2015         const char *logon_server = pipe_hnd->desthost;
2016         const char *computername = global_myname();
2017         struct netr_Authenticator credential;
2018         struct netr_Authenticator return_authenticator;
2019         enum netr_SamDatabaseID database_id = db_type;
2020         uint16_t restart_state = 0;
2021         uint32_t sync_context = 0;
2022
2023         /* Set up array for mapping accounts to groups */
2024         /* Array element is the group rid */
2025         GROUPMAP *groupmap = NULL;
2026
2027         /* Set up array for mapping account rid's to cn's */
2028         /* Array element is the account rid */
2029         ACCOUNTMAP *accountmap = NULL;
2030
2031         if (!(mem_ctx = talloc_init("fetch_database"))) {
2032                 return NT_STATUS_NO_MEMORY;
2033         }
2034
2035         /* Ensure we have an output file */
2036         if (user_file)
2037                 ldif_file = fopen(user_file, "a");
2038         else
2039                 ldif_file = stdout;
2040
2041         if (!ldif_file) {
2042                 fprintf(stderr, "Could not open %s\n", user_file);
2043                 DEBUG(1, ("Could not open %s\n", user_file));
2044                 ret = NT_STATUS_UNSUCCESSFUL;
2045                 goto done;
2046         }
2047
2048         add_name = talloc_strdup(mem_ctx, add_template);
2049         mod_name = talloc_strdup(mem_ctx, mod_template);
2050         if (!add_name || !mod_name) {
2051                 ret = NT_STATUS_NO_MEMORY;
2052                 goto done;
2053         }
2054
2055         /* Open the add and mod ldif files */
2056         if (!(add_file = fdopen(smb_mkstemp(add_name),"w"))) {
2057                 DEBUG(1, ("Could not open %s\n", add_name));
2058                 ret = NT_STATUS_UNSUCCESSFUL;
2059                 goto done;
2060         }
2061         if (!(mod_file = fdopen(smb_mkstemp(mod_name),"w"))) {
2062                 DEBUG(1, ("Could not open %s\n", mod_name));
2063                 ret = NT_STATUS_UNSUCCESSFUL;
2064                 goto done;
2065         }
2066
2067         /* Get the sid */
2068         sid_to_fstring(sid, &dom_sid);
2069
2070         /* Get the ldap suffix */
2071         suffix = lp_ldap_suffix();
2072         if (suffix == NULL || strcmp(suffix, "") == 0) {
2073                 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2074                 exit(1);
2075         }
2076
2077         /* Get other smb.conf data */
2078         if (!(lp_workgroup()) || !*(lp_workgroup())) {
2079                 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2080                 exit(1);
2081         }
2082
2083         /* Allocate initial memory for groupmap and accountmap arrays */
2084         if (init_ldap == 1) {
2085                 groupmap = SMB_MALLOC_ARRAY(GROUPMAP, 8);
2086                 accountmap = SMB_MALLOC_ARRAY(ACCOUNTMAP, 8);
2087                 if (groupmap == NULL || accountmap == NULL) {
2088                         DEBUG(1,("GROUPMAP malloc failed\n"));
2089                         ret = NT_STATUS_NO_MEMORY;
2090                         goto done;
2091                 }
2092
2093                 /* Initialize the arrays */
2094                 memset(groupmap, 0, sizeof(GROUPMAP)*8);
2095                 memset(accountmap, 0, sizeof(ACCOUNTMAP)*8);
2096
2097                 /* Remember how many we malloced */
2098                 num_alloced = 8;
2099
2100                 /* Initial database population */
2101                 populate_ldap_for_ldif(sid, suffix, builtin_sid, add_file);
2102                 map_populate_groups(groupmap, accountmap, sid, suffix,
2103                                     builtin_sid);
2104
2105                 /* Don't do this again */
2106                 init_ldap = 0;
2107         }
2108
2109         /* Announce what we are doing */
2110         switch( db_type ) {
2111         case SAM_DATABASE_DOMAIN:
2112                 d_fprintf(stderr, "Fetching DOMAIN database\n");
2113                 break;
2114         case SAM_DATABASE_BUILTIN:
2115                 d_fprintf(stderr, "Fetching BUILTIN database\n");
2116                 break;
2117         case SAM_DATABASE_PRIVS:
2118                 d_fprintf(stderr, "Fetching PRIVS databases\n");
2119                 break;
2120         default:
2121                 d_fprintf(stderr,
2122                           "Fetching unknown database type %u\n",
2123                           db_type );
2124                 break;
2125         }
2126
2127         do {
2128                 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2129
2130                 netlogon_creds_client_step(pipe_hnd->dc, &credential);
2131
2132                 result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx,
2133                                                    logon_server,
2134                                                    computername,
2135                                                    &credential,
2136                                                    &return_authenticator,
2137                                                    database_id,
2138                                                    restart_state,
2139                                                    &sync_context,
2140                                                    &delta_enum_array,
2141                                                    0xffff);
2142
2143                 /* Check returned credentials. */
2144                 if (!netlogon_creds_client_check(pipe_hnd->dc,
2145                                                  &return_authenticator.cred)) {
2146                         DEBUG(0,("credentials chain check failed\n"));
2147                         return NT_STATUS_ACCESS_DENIED;
2148                 }
2149
2150                 if (NT_STATUS_IS_ERR(result)) {
2151                         break;
2152                 }
2153
2154                 num_deltas = delta_enum_array->num_deltas;
2155
2156                 /* Re-allocate memory for groupmap and accountmap arrays */
2157                 groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP,
2158                                              num_deltas+num_alloced);
2159                 accountmap = SMB_REALLOC_ARRAY(accountmap, ACCOUNTMAP,
2160                                                num_deltas+num_alloced);
2161                 if (groupmap == NULL || accountmap == NULL) {
2162                         DEBUG(1,("GROUPMAP malloc failed\n"));
2163                         ret = NT_STATUS_NO_MEMORY;
2164                         goto done;
2165                 }
2166
2167                 /* Initialize the new records */
2168                 memset(&groupmap[num_alloced], 0,
2169                        sizeof(GROUPMAP)*num_deltas);
2170                 memset(&accountmap[num_alloced], 0,
2171                        sizeof(ACCOUNTMAP)*num_deltas);
2172
2173                 /* Remember how many we alloced this time */
2174                 num_alloced += num_deltas;
2175
2176                 /* Loop through the deltas */
2177                 for (k=0; k<num_deltas; k++) {
2178
2179                         union netr_DELTA_UNION u =
2180                                 delta_enum_array->delta_enum[k].delta_union;
2181                         union netr_DELTA_ID_UNION id =
2182                                 delta_enum_array->delta_enum[k].delta_id_union;
2183
2184                         switch(delta_enum_array->delta_enum[k].delta_type) {
2185                         case NETR_DELTA_DOMAIN:
2186                                 /* Is this case needed? */
2187                                 fstrcpy(domainname,
2188                                         u.domain->domain_name.string);
2189                                 break;
2190
2191                         case NETR_DELTA_GROUP:
2192                                 fetch_group_info_to_ldif(
2193                                         u.group,
2194                                         &groupmap[g_index],
2195                                         add_file, sid, suffix);
2196                                 g_index++;
2197                                 break;
2198
2199                         case NETR_DELTA_USER:
2200                                 fetch_account_info_to_ldif(
2201                                         u.user, groupmap,
2202                                         &accountmap[a_index], add_file,
2203                                         sid, suffix, num_alloced);
2204                                 a_index++;
2205                                 break;
2206
2207                         case NETR_DELTA_ALIAS:
2208                                 fetch_alias_info_to_ldif(
2209                                         u.alias, &groupmap[g_index],
2210                                         add_file, sid, suffix, db_type);
2211                                 g_index++;
2212                                 break;
2213
2214                         case NETR_DELTA_GROUP_MEMBER:
2215                                 fetch_groupmem_info_to_ldif(
2216                                         u.group_member, id.rid,
2217                                         groupmap, accountmap,
2218                                         mod_file, num_alloced);
2219                                 break;
2220
2221                         case NETR_DELTA_ALIAS_MEMBER:
2222                         case NETR_DELTA_POLICY:
2223                         case NETR_DELTA_ACCOUNT:
2224                         case NETR_DELTA_TRUSTED_DOMAIN:
2225                         case NETR_DELTA_SECRET:
2226                         case NETR_DELTA_RENAME_GROUP:
2227                         case NETR_DELTA_RENAME_USER:
2228                         case NETR_DELTA_RENAME_ALIAS:
2229                         case NETR_DELTA_DELETE_GROUP:
2230                         case NETR_DELTA_DELETE_USER:
2231                         case NETR_DELTA_MODIFY_COUNT:
2232                         default:
2233                                 break;
2234                         } /* end of switch */
2235                 } /* end of for loop */
2236
2237                 /* Increment sync_context */
2238                 sync_context += 1;
2239
2240         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2241
2242         /* Write ldif data to the user's file */
2243         if (db_type == SAM_DATABASE_DOMAIN) {
2244                 fprintf(ldif_file,
2245                         "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2246                 fprintf(ldif_file,
2247                         "# =================================\n\n");
2248                 fflush(ldif_file);
2249         } else if (db_type == SAM_DATABASE_BUILTIN) {
2250                 fprintf(ldif_file,
2251                         "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2252                 fprintf(ldif_file,
2253                         "# ==================================\n\n");
2254                 fflush(ldif_file);
2255         }
2256         fseek(add_file, 0, SEEK_SET);
2257         transfer_file(fileno(add_file), fileno(ldif_file), (size_t) -1);
2258
2259         if (db_type == SAM_DATABASE_DOMAIN) {
2260                 fprintf(ldif_file,
2261                         "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2262                 fprintf(ldif_file,
2263                         "# ====================================\n\n");
2264                 fflush(ldif_file);
2265         } else if (db_type == SAM_DATABASE_BUILTIN) {
2266                 fprintf(ldif_file,
2267                         "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2268                 fprintf(ldif_file,
2269                         "# =====================================\n\n");
2270                 fflush(ldif_file);
2271         }
2272         fseek(mod_file, 0, SEEK_SET);
2273         transfer_file(fileno(mod_file), fileno(ldif_file), (size_t) -1);
2274
2275
2276  done:
2277         /* Close and delete the ldif files */
2278         if (add_file) {
2279                 fclose(add_file);
2280         }
2281
2282         if ((add_name != NULL) &&
2283             strcmp(add_name, add_template) && (unlink(add_name))) {
2284                 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2285                          add_name, strerror(errno)));
2286         }
2287
2288         if (mod_file) {
2289                 fclose(mod_file);
2290         }
2291
2292         if ((mod_name != NULL) &&
2293             strcmp(mod_name, mod_template) && (unlink(mod_name))) {
2294                 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2295                          mod_name, strerror(errno)));
2296         }
2297
2298         if (ldif_file && (ldif_file != stdout)) {
2299                 fclose(ldif_file);
2300         }
2301
2302         /* Deallocate memory for the mapping arrays */
2303         SAFE_FREE(groupmap);
2304         SAFE_FREE(accountmap);
2305
2306         /* Return */
2307         talloc_destroy(mem_ctx);
2308         return ret;
2309 }
2310
2311 /**
2312  * Basic usage function for 'net rpc vampire'
2313  *
2314  * @param c     A net_context structure
2315  * @param argc  Standard main() style argc
2316  * @param argc  Standard main() style argv.  Initial components are already
2317  *              stripped
2318  **/
2319
2320 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
2321 {
2322         d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2323                  "\t to pull accounts from a remote PDC where we are a BDC\n"
2324                  "\t\t no args puts accounts in local passdb from smb.conf\n"
2325                  "\t\t ldif - put accounts in ldif format (file defaults to "
2326                  "/tmp/tmp.ldif\n");
2327
2328         net_common_flags_usage(c, argc, argv);
2329         return -1;
2330 }
2331
2332
2333 /* dump sam database via samsync rpc calls */
2334 NTSTATUS rpc_vampire_internals(struct net_context *c,
2335                                 const DOM_SID *domain_sid,
2336                                 const char *domain_name,
2337                                 struct cli_state *cli,
2338                                 struct rpc_pipe_client *pipe_hnd,
2339                                 TALLOC_CTX *mem_ctx,
2340                                 int argc,
2341                                 const char **argv)
2342 {
2343         NTSTATUS result;
2344         fstring my_dom_sid_str;
2345         fstring rem_dom_sid_str;
2346
2347         if (!sid_equal(domain_sid, get_global_sam_sid())) {
2348                 d_printf("Cannot import users from %s at this time, "
2349                          "as the current domain:\n\t%s: %s\nconflicts "
2350                          "with the remote domain\n\t%s: %s\n"
2351                          "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2352                          "workgroup=%s\n\n in your smb.conf?\n",
2353                          domain_name,
2354                          get_global_sam_name(),
2355                          sid_to_fstring(my_dom_sid_str,
2356                                         get_global_sam_sid()),
2357                          domain_name, sid_to_fstring(rem_dom_sid_str,
2358                                                      domain_sid),
2359                          domain_name);
2360                 return NT_STATUS_UNSUCCESSFUL;
2361         }
2362
2363         if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
2364                 result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_DOMAIN,
2365                                                 *domain_sid, argv[1]);
2366         } else {
2367                 result = fetch_database(pipe_hnd, SAM_DATABASE_DOMAIN,
2368                                         *domain_sid);
2369         }
2370
2371         if (!NT_STATUS_IS_OK(result)) {
2372                 d_fprintf(stderr, "Failed to fetch domain database: %s\n",
2373                           nt_errstr(result));
2374                 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED))
2375                         d_fprintf(stderr, "Perhaps %s is a Windows 2000 "
2376                                   "native mode domain?\n", domain_name);
2377                 goto fail;
2378         }
2379
2380         if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
2381                 result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_BUILTIN,
2382                                                 global_sid_Builtin, argv[1]);
2383         } else {
2384                 result = fetch_database(pipe_hnd, SAM_DATABASE_BUILTIN,
2385                                         global_sid_Builtin);
2386         }
2387
2388         if (!NT_STATUS_IS_OK(result)) {
2389                 d_fprintf(stderr, "Failed to fetch builtin database: %s\n",
2390                           nt_errstr(result));
2391                 goto fail;
2392         }
2393
2394         /* Currently we crash on PRIVS somewhere in unmarshalling */
2395         /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
2396
2397  fail:
2398         return result;
2399 }