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