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