2 Unix SMB/CIFS implementation.
3 dump the remote SAM using rpc samsync operations
5 Copyright (C) Andrew Tridgell 2002
6 Copyright (C) Tim Potter 2001,2002
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
8 Modified by Volker Lendecke 2002
9 Copyright (C) Jeremy Allison 2005.
10 Copyright (C) Guenther Deschner 2008.
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "utils/net.h"
29 /* uid's and gid's for writing deltas to ldif */
30 static uint32 ldif_gid = 999;
31 static uint32 ldif_uid = 999;
33 static void display_group_mem_info(uint32_t rid,
34 struct netr_DELTA_GROUP_MEMBER *r)
37 d_printf("Group mem %u: ", rid);
38 for (i=0; i< r->num_rids; i++) {
39 d_printf("%u ", r->rids[i]);
44 static void display_alias_info(uint32_t rid,
45 struct netr_DELTA_ALIAS *r)
47 d_printf("Alias '%s' ", r->alias_name.string);
48 d_printf("desc='%s' rid=%u\n", r->description.string, r->rid);
51 static void display_alias_mem(uint32_t rid,
52 struct netr_DELTA_ALIAS_MEMBER *r)
55 d_printf("Alias rid %u: ", rid);
56 for (i=0; i< r->sids.num_sids; i++) {
57 d_printf("%s ", sid_string_tos(r->sids.sids[i].sid));
62 static void display_account_info(uint32_t rid,
63 struct netr_DELTA_USER *r)
65 fstring hex_nt_passwd, hex_lm_passwd;
66 uchar lm_passwd[16], nt_passwd[16];
67 static uchar zero_buf[16];
69 /* Decode hashes from password hash (if they are not NULL) */
71 if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
72 sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
73 pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
75 pdb_sethexpwd(hex_lm_passwd, NULL, 0);
78 if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
79 sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
80 pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
82 pdb_sethexpwd(hex_nt_passwd, NULL, 0);
85 printf("%s:%d:%s:%s:%s:LCT-0\n",
86 r->account_name.string,
87 r->rid, hex_lm_passwd, hex_nt_passwd,
88 pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN));
91 static time_t uint64s_nt_time_to_unix_abs(const uint64 *src)
95 return nt_time_to_unix_abs(&nttime);
98 static NTSTATUS pull_netr_AcctLockStr(TALLOC_CTX *mem_ctx,
99 struct lsa_BinaryString *r,
100 struct netr_AcctLockStr **str_p)
102 struct netr_AcctLockStr *str;
103 enum ndr_err_code ndr_err;
106 if (!mem_ctx || !r || !str_p) {
107 return NT_STATUS_INVALID_PARAMETER;
112 str = TALLOC_ZERO_P(mem_ctx, struct netr_AcctLockStr);
114 return NT_STATUS_NO_MEMORY;
117 blob = data_blob_const(r->array, r->length);
119 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, str,
120 (ndr_pull_flags_fn_t)ndr_pull_netr_AcctLockStr);
121 data_blob_free(&blob);
123 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
124 return ndr_map_error2ntstatus(ndr_err);
132 static void display_domain_info(struct netr_DELTA_DOMAIN *r)
135 struct netr_AcctLockStr *lockstr = NULL;
137 TALLOC_CTX *mem_ctx = talloc_tos();
139 status = pull_netr_AcctLockStr(mem_ctx, &r->account_lockout,
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("failed to pull account lockout string: %s\n",
146 u_logout = uint64s_nt_time_to_unix_abs((const uint64 *)&r->force_logoff_time);
148 d_printf("Domain name: %s\n", r->domain_name.string);
150 d_printf("Minimal Password Length: %d\n", r->min_password_length);
151 d_printf("Password History Length: %d\n", r->password_history_length);
153 d_printf("Force Logoff: %d\n", (int)u_logout);
155 d_printf("Max Password Age: %s\n", display_time(r->max_password_age));
156 d_printf("Min Password Age: %s\n", display_time(r->min_password_age));
159 d_printf("Lockout Time: %s\n", display_time((NTTIME)lockstr->lockout_duration));
160 d_printf("Lockout Reset Time: %s\n", display_time((NTTIME)lockstr->reset_count));
161 d_printf("Bad Attempt Lockout: %d\n", lockstr->bad_attempt_lockout);
164 d_printf("User must logon to change password: %d\n", r->logon_to_chgpass);
167 static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r)
169 d_printf("Group '%s' ", r->group_name.string);
170 d_printf("desc='%s', rid=%u\n", r->description.string, rid);
173 static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
174 enum netr_SamDatabaseID database_id,
175 struct netr_DELTA_ENUM *r,
177 struct samsync_context *ctx)
179 union netr_DELTA_UNION u = r->delta_union;
180 union netr_DELTA_ID_UNION id = r->delta_id_union;
182 switch (r->delta_type) {
183 case NETR_DELTA_DOMAIN:
184 display_domain_info(u.domain);
186 case NETR_DELTA_GROUP:
187 display_group_info(id.rid, u.group);
190 case NETR_DELTA_DELETE_GROUP:
191 printf("Delete Group: %d\n",
192 u.delete_account.unknown);
194 case NETR_DELTA_RENAME_GROUP:
195 printf("Rename Group: %s -> %s\n",
196 u.rename_group->OldName.string,
197 u.rename_group->NewName.string);
200 case NETR_DELTA_USER:
201 display_account_info(id.rid, u.user);
204 case NETR_DELTA_DELETE_USER:
205 printf("Delete User: %d\n",
208 case NETR_DELTA_RENAME_USER:
209 printf("Rename user: %s -> %s\n",
210 u.rename_user->OldName.string,
211 u.rename_user->NewName.string);
214 case NETR_DELTA_GROUP_MEMBER:
215 display_group_mem_info(id.rid, u.group_member);
217 case NETR_DELTA_ALIAS:
218 display_alias_info(id.rid, u.alias);
221 case NETR_DELTA_DELETE_ALIAS:
222 printf("Delete Alias: %d\n",
225 case NETR_DELTA_RENAME_ALIAS:
226 printf("Rename alias: %s -> %s\n",
227 u.rename_alias->OldName.string,
228 u.rename_alias->NewName.string);
231 case NETR_DELTA_ALIAS_MEMBER:
232 display_alias_mem(id.rid, u.alias_member);
235 case NETR_DELTA_POLICY:
238 case NETR_DELTA_TRUSTED_DOMAIN:
239 printf("Trusted Domain: %s\n",
240 u.trusted_domain->domain_name.string);
242 case NETR_DELTA_DELETE_TRUST:
243 printf("Delete Trust: %d\n",
244 u.delete_trust.unknown);
246 case NETR_DELTA_ACCOUNT:
249 case NETR_DELTA_DELETE_ACCOUNT:
250 printf("Delete Account: %d\n",
251 u.delete_account.unknown);
253 case NETR_DELTA_SECRET:
256 case NETR_DELTA_DELETE_SECRET:
257 printf("Delete Secret: %d\n",
258 u.delete_secret.unknown);
260 case NETR_DELTA_DELETE_GROUP2:
261 printf("Delete Group2: %s\n",
262 u.delete_group->account_name);
264 case NETR_DELTA_DELETE_USER2:
265 printf("Delete User2: %s\n",
266 u.delete_user->account_name);
268 case NETR_DELTA_MODIFY_COUNT:
269 printf("sam sequence update: 0x%016llx\n",
270 (unsigned long long) *u.modified_count);
273 /* The following types are recognised but not handled */
274 case NETR_DELTA_RENAME_GROUP:
275 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
277 case NETR_DELTA_RENAME_USER:
278 d_printf("NETR_DELTA_RENAME_USER not handled\n");
280 case NETR_DELTA_RENAME_ALIAS:
281 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
283 case NETR_DELTA_POLICY:
284 d_printf("NETR_DELTA_POLICY not handled\n");
286 case NETR_DELTA_TRUSTED_DOMAIN:
287 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
289 case NETR_DELTA_ACCOUNT:
290 d_printf("NETR_DELTA_ACCOUNT not handled\n");
292 case NETR_DELTA_SECRET:
293 d_printf("NETR_DELTA_SECRET not handled\n");
295 case NETR_DELTA_DELETE_GROUP:
296 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
298 case NETR_DELTA_DELETE_USER:
299 d_printf("NETR_DELTA_DELETE_USER not handled\n");
301 case NETR_DELTA_MODIFY_COUNT:
302 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
304 case NETR_DELTA_DELETE_ALIAS:
305 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
307 case NETR_DELTA_DELETE_TRUST:
308 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
310 case NETR_DELTA_DELETE_ACCOUNT:
311 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
313 case NETR_DELTA_DELETE_SECRET:
314 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
316 case NETR_DELTA_DELETE_GROUP2:
317 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
319 case NETR_DELTA_DELETE_USER2:
320 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
323 printf("unknown delta type 0x%02x\n",
331 static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
332 enum netr_SamDatabaseID database_id,
333 struct netr_DELTA_ENUM_ARRAY *r,
335 struct samsync_context *ctx)
339 for (i = 0; i < r->num_deltas; i++) {
340 display_sam_entry(mem_ctx, database_id, &r->delta_enum[i], status, ctx);
346 typedef NTSTATUS (*samsync_fn_t)(TALLOC_CTX *,
347 enum netr_SamDatabaseID,
348 struct netr_DELTA_ENUM_ARRAY *,
350 struct samsync_context *);
352 static NTSTATUS process_database(struct rpc_pipe_client *pipe_hnd,
353 enum netr_SamDatabaseID database_id,
354 samsync_fn_t callback_fn,
355 struct samsync_context *ctx)
359 const char *logon_server = pipe_hnd->desthost;
360 const char *computername = global_myname();
361 struct netr_Authenticator credential;
362 struct netr_Authenticator return_authenticator;
363 uint16_t restart_state = 0;
364 uint32_t sync_context = 0;
365 DATA_BLOB session_key;
366 const char *action = NULL;
368 ZERO_STRUCT(return_authenticator);
370 if (!(mem_ctx = talloc_init("process_database"))) {
371 return NT_STATUS_NO_MEMORY;
375 case NET_SAMSYNC_MODE_DUMP:
376 action = "Dumping (to stdout)";
378 case NET_SAMSYNC_MODE_FETCH_PASSDB:
379 action = "Fetching (to passdb)";
381 case NET_SAMSYNC_MODE_FETCH_LDIF:
382 action = "Fetching (to ldif)";
389 switch (database_id) {
390 case SAM_DATABASE_DOMAIN:
391 d_fprintf(stderr, "%s DOMAIN database\n", action);
393 case SAM_DATABASE_BUILTIN:
394 d_fprintf(stderr, "%s BUILTIN database\n", action);
396 case SAM_DATABASE_PRIVS:
397 d_fprintf(stderr, "%s PRIVS databases\n", action);
400 d_fprintf(stderr, "%s unknown database type %u\n",
401 action, database_id);
406 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
408 netlogon_creds_client_step(pipe_hnd->dc, &credential);
410 result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx,
414 &return_authenticator,
420 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
424 /* Check returned credentials. */
425 if (!netlogon_creds_client_check(pipe_hnd->dc,
426 &return_authenticator.cred)) {
427 DEBUG(0,("credentials chain check failed\n"));
428 return NT_STATUS_ACCESS_DENIED;
431 if (NT_STATUS_IS_ERR(result)) {
435 session_key = data_blob_const(pipe_hnd->dc->sess_key, 16);
437 samsync_fix_delta_array(mem_ctx,
443 /* Process results */
444 callback_fn(mem_ctx, database_id, delta_enum_array, result, ctx);
446 TALLOC_FREE(delta_enum_array);
448 /* Increment sync_context */
451 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
453 talloc_destroy(mem_ctx);
458 /* dump sam database via samsync rpc calls */
459 NTSTATUS rpc_samdump_internals(struct net_context *c,
460 const DOM_SID *domain_sid,
461 const char *domain_name,
462 struct cli_state *cli,
463 struct rpc_pipe_client *pipe_hnd,
468 struct samsync_context *ctx;
470 ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context);
471 NT_STATUS_HAVE_NO_MEMORY(ctx);
473 ctx->mode = NET_SAMSYNC_MODE_DUMP;
474 ctx->domain_sid = domain_sid;
476 process_database(pipe_hnd, SAM_DATABASE_DOMAIN,
477 display_sam_entries, ctx);
479 process_database(pipe_hnd, SAM_DATABASE_BUILTIN,
480 display_sam_entries, ctx);
482 process_database(pipe_hnd, SAM_DATABASE_PRIVS,
483 display_sam_entries, ctx);
488 /* Convert a struct samu_DELTA to a struct samu. */
489 #define STRING_CHANGED (old_string && !new_string) ||\
490 (!old_string && new_string) ||\
491 (old_string && new_string && (strcmp(old_string, new_string) != 0))
493 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
495 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
497 static NTSTATUS sam_account_from_delta(struct samu *account,
498 struct netr_DELTA_USER *r)
500 const char *old_string, *new_string;
501 time_t unix_time, stored_time;
502 uchar lm_passwd[16], nt_passwd[16];
503 static uchar zero_buf[16];
505 /* Username, fullname, home dir, dir drive, logon script, acct
506 desc, workstations, profile. */
508 if (r->account_name.string) {
509 old_string = pdb_get_nt_username(account);
510 new_string = r->account_name.string;
512 if (STRING_CHANGED) {
513 pdb_set_nt_username(account, new_string, PDB_CHANGED);
516 /* Unix username is the same - for sanity */
517 old_string = pdb_get_username( account );
518 if (STRING_CHANGED) {
519 pdb_set_username(account, new_string, PDB_CHANGED);
523 if (r->full_name.string) {
524 old_string = pdb_get_fullname(account);
525 new_string = r->full_name.string;
528 pdb_set_fullname(account, new_string, PDB_CHANGED);
531 if (r->home_directory.string) {
532 old_string = pdb_get_homedir(account);
533 new_string = r->home_directory.string;
536 pdb_set_homedir(account, new_string, PDB_CHANGED);
539 if (r->home_drive.string) {
540 old_string = pdb_get_dir_drive(account);
541 new_string = r->home_drive.string;
544 pdb_set_dir_drive(account, new_string, PDB_CHANGED);
547 if (r->logon_script.string) {
548 old_string = pdb_get_logon_script(account);
549 new_string = r->logon_script.string;
552 pdb_set_logon_script(account, new_string, PDB_CHANGED);
555 if (r->description.string) {
556 old_string = pdb_get_acct_desc(account);
557 new_string = r->description.string;
560 pdb_set_acct_desc(account, new_string, PDB_CHANGED);
563 if (r->workstations.string) {
564 old_string = pdb_get_workstations(account);
565 new_string = r->workstations.string;
568 pdb_set_workstations(account, new_string, PDB_CHANGED);
571 if (r->profile_path.string) {
572 old_string = pdb_get_profile_path(account);
573 new_string = r->profile_path.string;
576 pdb_set_profile_path(account, new_string, PDB_CHANGED);
579 if (r->parameters.string) {
582 old_string = pdb_get_munged_dial(account);
583 mung.length = r->parameters.length;
584 mung.data = (uint8 *) r->parameters.string;
585 newstr = (mung.length == 0) ? NULL :
586 base64_encode_data_blob(talloc_tos(), mung);
588 if (STRING_CHANGED_NC(old_string, newstr))
589 pdb_set_munged_dial(account, newstr, PDB_CHANGED);
593 /* User and group sid */
594 if (pdb_get_user_rid(account) != r->rid)
595 pdb_set_user_sid_from_rid(account, r->rid, PDB_CHANGED);
596 if (pdb_get_group_rid(account) != r->primary_gid)
597 pdb_set_group_sid_from_rid(account, r->primary_gid, PDB_CHANGED);
599 /* Logon and password information */
600 if (!nt_time_is_zero(&r->last_logon)) {
601 unix_time = nt_time_to_unix(r->last_logon);
602 stored_time = pdb_get_logon_time(account);
603 if (stored_time != unix_time)
604 pdb_set_logon_time(account, unix_time, PDB_CHANGED);
607 if (!nt_time_is_zero(&r->last_logoff)) {
608 unix_time = nt_time_to_unix(r->last_logoff);
609 stored_time = pdb_get_logoff_time(account);
610 if (stored_time != unix_time)
611 pdb_set_logoff_time(account, unix_time,PDB_CHANGED);
615 if (pdb_get_logon_divs(account) != r->logon_hours.units_per_week)
616 pdb_set_logon_divs(account, r->logon_hours.units_per_week, PDB_CHANGED);
619 /* no idea what to do with this one - gd */
620 /* Max Logon Hours */
621 if (delta->unknown1 != pdb_get_unknown_6(account)) {
622 pdb_set_unknown_6(account, delta->unknown1, PDB_CHANGED);
625 /* Logon Hours Len */
626 if (r->logon_hours.units_per_week/8 != pdb_get_hours_len(account)) {
627 pdb_set_hours_len(account, r->logon_hours.units_per_week/8, PDB_CHANGED);
631 if (r->logon_hours.bits) {
632 char oldstr[44], newstr[44];
633 pdb_sethexhours(oldstr, pdb_get_hours(account));
634 pdb_sethexhours(newstr, r->logon_hours.bits);
635 if (!strequal(oldstr, newstr))
636 pdb_set_hours(account, r->logon_hours.bits, PDB_CHANGED);
639 if (pdb_get_bad_password_count(account) != r->bad_password_count)
640 pdb_set_bad_password_count(account, r->bad_password_count, PDB_CHANGED);
642 if (pdb_get_logon_count(account) != r->logon_count)
643 pdb_set_logon_count(account, r->logon_count, PDB_CHANGED);
645 if (!nt_time_is_zero(&r->last_password_change)) {
646 unix_time = nt_time_to_unix(r->last_password_change);
647 stored_time = pdb_get_pass_last_set_time(account);
648 if (stored_time != unix_time)
649 pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED);
651 /* no last set time, make it now */
652 pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED);
655 if (!nt_time_is_zero(&r->acct_expiry)) {
656 unix_time = nt_time_to_unix(r->acct_expiry);
657 stored_time = pdb_get_kickoff_time(account);
658 if (stored_time != unix_time)
659 pdb_set_kickoff_time(account, unix_time, PDB_CHANGED);
662 /* Decode hashes from password hash
663 Note that win2000 may send us all zeros for the hashes if it doesn't
664 think this channel is secure enough - don't set the passwords at all
667 if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
668 sam_pwd_hash(r->rid, r->ntpassword.hash, lm_passwd, 0);
669 pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED);
672 if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
673 sam_pwd_hash(r->rid, r->lmpassword.hash, nt_passwd, 0);
674 pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED);
677 /* TODO: account expiry time */
679 pdb_set_acct_ctrl(account, r->acct_flags, PDB_CHANGED);
681 pdb_set_domain(account, lp_workgroup(), PDB_CHANGED);
686 static NTSTATUS fetch_account_info(uint32_t rid,
687 struct netr_DELTA_USER *r)
690 NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL;
692 char *add_script = NULL;
693 struct samu *sam_account=NULL;
698 struct passwd *passwd;
701 fstrcpy(account, r->account_name.string);
702 d_printf("Creating account: %s\n", account);
704 if ( !(sam_account = samu_new( NULL )) ) {
705 return NT_STATUS_NO_MEMORY;
708 if (!(passwd = Get_Pwnam_alloc(sam_account, account))) {
709 /* Create appropriate user */
710 if (r->acct_flags & ACB_NORMAL) {
711 add_script = talloc_strdup(sam_account,
712 lp_adduser_script());
713 } else if ( (r->acct_flags & ACB_WSTRUST) ||
714 (r->acct_flags & ACB_SVRTRUST) ||
715 (r->acct_flags & ACB_DOMTRUST) ) {
716 add_script = talloc_strdup(sam_account,
717 lp_addmachine_script());
719 DEBUG(1, ("Unknown user type: %s\n",
720 pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN)));
721 nt_ret = NT_STATUS_UNSUCCESSFUL;
725 nt_ret = NT_STATUS_NO_MEMORY;
730 add_script = talloc_all_string_sub(sam_account,
735 nt_ret = NT_STATUS_NO_MEMORY;
738 add_ret = smbrun(add_script,NULL);
739 DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' "
740 "gave %d\n", add_script, add_ret));
742 smb_nscd_flush_user_cache();
746 /* try and find the possible unix account again */
747 if ( !(passwd = Get_Pwnam_alloc(sam_account, account)) ) {
748 d_fprintf(stderr, "Could not create posix account info for '%s'\n", account);
749 nt_ret = NT_STATUS_NO_SUCH_USER;
754 sid_copy(&user_sid, get_global_sam_sid());
755 sid_append_rid(&user_sid, r->rid);
757 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
758 sid_to_fstring(sid_string, &user_sid), account));
759 if (!pdb_getsampwsid(sam_account, &user_sid)) {
760 sam_account_from_delta(sam_account, r);
761 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
762 sid_to_fstring(sid_string, &user_sid),
763 pdb_get_username(sam_account)));
764 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) {
765 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
767 return NT_STATUS_ACCESS_DENIED;
770 sam_account_from_delta(sam_account, r);
771 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
772 sid_to_fstring(sid_string, &user_sid),
773 pdb_get_username(sam_account)));
774 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account))) {
775 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
777 TALLOC_FREE(sam_account);
778 return NT_STATUS_ACCESS_DENIED;
782 if (pdb_get_group_sid(sam_account) == NULL) {
783 return NT_STATUS_UNSUCCESSFUL;
786 group_sid = *pdb_get_group_sid(sam_account);
788 if (!pdb_getgrsid(&map, group_sid)) {
789 DEBUG(0, ("Primary group of %s has no mapping!\n",
790 pdb_get_username(sam_account)));
792 if (map.gid != passwd->pw_gid) {
793 if (!(grp = getgrgid(map.gid))) {
794 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
795 (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_tos(&group_sid)));
797 smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
803 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
804 pdb_get_username(sam_account)));
808 TALLOC_FREE(sam_account);
812 static NTSTATUS fetch_group_info(uint32_t rid,
813 struct netr_DELTA_GROUP *r)
817 struct group *grp = NULL;
823 fstrcpy(name, r->group_name.string);
824 fstrcpy(comment, r->description.string);
826 /* add the group to the mapping table */
827 sid_copy(&group_sid, get_global_sam_sid());
828 sid_append_rid(&group_sid, rid);
829 sid_to_fstring(sid_string, &group_sid);
831 if (pdb_getgrsid(&map, group_sid)) {
833 grp = getgrgid(map.gid);
840 /* No group found from mapping, find it from its name. */
841 if ((grp = getgrnam(name)) == NULL) {
843 /* No appropriate group found, create one */
845 d_printf("Creating unix group: '%s'\n", name);
847 if (smb_create_group(name, &gid) != 0)
848 return NT_STATUS_ACCESS_DENIED;
850 if ((grp = getgrnam(name)) == NULL)
851 return NT_STATUS_ACCESS_DENIED;
855 map.gid = grp->gr_gid;
857 map.sid_name_use = SID_NAME_DOM_GRP;
858 fstrcpy(map.nt_name, name);
859 if (r->description.string) {
860 fstrcpy(map.comment, comment);
862 fstrcpy(map.comment, "");
866 pdb_add_group_mapping_entry(&map);
868 pdb_update_group_mapping_entry(&map);
873 static NTSTATUS fetch_group_mem_info(uint32_t rid,
874 struct netr_DELTA_GROUP_MEMBER *r)
877 TALLOC_CTX *t = NULL;
878 char **nt_members = NULL;
884 if (r->num_rids == 0) {
888 sid_copy(&group_sid, get_global_sam_sid());
889 sid_append_rid(&group_sid, rid);
891 if (!get_domain_group_from_sid(group_sid, &map)) {
892 DEBUG(0, ("Could not find global group %d\n", rid));
893 return NT_STATUS_NO_SUCH_GROUP;
896 if (!(grp = getgrgid(map.gid))) {
897 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid));
898 return NT_STATUS_NO_SUCH_GROUP;
901 d_printf("Group members of %s: ", grp->gr_name);
903 if (!(t = talloc_init("fetch_group_mem_info"))) {
904 DEBUG(0, ("could not talloc_init\n"));
905 return NT_STATUS_NO_MEMORY;
909 if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, r->num_rids)) == NULL) {
910 DEBUG(0, ("talloc failed\n"));
912 return NT_STATUS_NO_MEMORY;
918 for (i=0; i < r->num_rids; i++) {
919 struct samu *member = NULL;
922 if ( !(member = samu_new(t)) ) {
924 return NT_STATUS_NO_MEMORY;
927 sid_copy(&member_sid, get_global_sam_sid());
928 sid_append_rid(&member_sid, r->rids[i]);
930 if (!pdb_getsampwsid(member, &member_sid)) {
931 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
932 r->rids[i], sid_string_tos(&member_sid), grp->gr_name));
937 if (pdb_get_group_rid(member) == rid) {
938 d_printf("%s(primary),", pdb_get_username(member));
943 d_printf("%s,", pdb_get_username(member));
944 nt_members[i] = talloc_strdup(t, pdb_get_username(member));
950 unix_members = grp->gr_mem;
952 while (*unix_members) {
953 bool is_nt_member = false;
954 for (i=0; i < r->num_rids; i++) {
955 if (nt_members[i] == NULL) {
956 /* This was a primary group */
960 if (strcmp(*unix_members, nt_members[i]) == 0) {
966 /* We look at a unix group member that is not
967 an nt group member. So, remove it. NT is
969 smb_delete_user_group(grp->gr_name, *unix_members);
974 for (i=0; i < r->num_rids; i++) {
975 bool is_unix_member = false;
977 if (nt_members[i] == NULL) {
978 /* This was the primary group */
982 unix_members = grp->gr_mem;
984 while (*unix_members) {
985 if (strcmp(*unix_members, nt_members[i]) == 0) {
986 is_unix_member = true;
992 if (!is_unix_member) {
993 /* We look at a nt group member that is not a
994 unix group member currently. So, add the nt
996 smb_add_user_group(grp->gr_name, nt_members[i]);
1001 return NT_STATUS_OK;
1004 static NTSTATUS fetch_alias_info(uint32_t rid,
1005 struct netr_DELTA_ALIAS *r,
1006 const DOM_SID *dom_sid)
1010 struct group *grp = NULL;
1016 fstrcpy(name, r->alias_name.string);
1017 fstrcpy(comment, r->description.string);
1019 /* Find out whether the group is already mapped */
1020 sid_copy(&alias_sid, dom_sid);
1021 sid_append_rid(&alias_sid, rid);
1022 sid_to_fstring(sid_string, &alias_sid);
1024 if (pdb_getgrsid(&map, alias_sid)) {
1025 grp = getgrgid(map.gid);
1032 /* No group found from mapping, find it from its name. */
1033 if ((grp = getgrnam(name)) == NULL) {
1034 /* No appropriate group found, create one */
1035 d_printf("Creating unix group: '%s'\n", name);
1036 if (smb_create_group(name, &gid) != 0)
1037 return NT_STATUS_ACCESS_DENIED;
1038 if ((grp = getgrgid(gid)) == NULL)
1039 return NT_STATUS_ACCESS_DENIED;
1043 map.gid = grp->gr_gid;
1044 map.sid = alias_sid;
1046 if (sid_equal(dom_sid, &global_sid_Builtin))
1047 map.sid_name_use = SID_NAME_WKN_GRP;
1049 map.sid_name_use = SID_NAME_ALIAS;
1051 fstrcpy(map.nt_name, name);
1052 fstrcpy(map.comment, comment);
1055 pdb_add_group_mapping_entry(&map);
1057 pdb_update_group_mapping_entry(&map);
1059 return NT_STATUS_OK;
1062 static NTSTATUS fetch_alias_mem(uint32_t rid,
1063 struct netr_DELTA_ALIAS_MEMBER *r,
1064 const DOM_SID *dom_sid)
1066 return NT_STATUS_OK;
1069 static NTSTATUS fetch_domain_info(uint32_t rid,
1070 struct netr_DELTA_DOMAIN *r)
1072 time_t u_max_age, u_min_age, u_logout;
1073 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1074 const char *domname;
1075 struct netr_AcctLockStr *lockstr = NULL;
1077 TALLOC_CTX *mem_ctx = talloc_tos();
1079 status = pull_netr_AcctLockStr(mem_ctx, &r->account_lockout,
1081 if (!NT_STATUS_IS_OK(status)) {
1082 d_printf("failed to pull account lockout string: %s\n",
1086 u_max_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->max_password_age);
1087 u_min_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->min_password_age);
1088 u_logout = uint64s_nt_time_to_unix_abs((uint64 *)&r->force_logoff_time);
1090 domname = r->domain_name.string;
1092 return NT_STATUS_NO_MEMORY;
1095 /* we don't handle BUILTIN account policies */
1096 if (!strequal(domname, get_global_sam_name())) {
1097 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname);
1098 return NT_STATUS_OK;
1102 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY,
1103 r->password_history_length))
1106 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
1107 r->min_password_length))
1110 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
1113 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
1116 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
1120 time_t u_lockoutreset, u_lockouttime;
1122 u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count);
1123 u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration);
1125 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
1126 lockstr->bad_attempt_lockout))
1129 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60))
1132 if (u_lockouttime != -1)
1133 u_lockouttime /= 60;
1135 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime))
1139 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1140 r->logon_to_chgpass))
1143 return NT_STATUS_OK;
1146 static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
1147 enum netr_SamDatabaseID database_id,
1148 struct netr_DELTA_ENUM *r,
1149 struct samsync_context *ctx)
1151 switch(r->delta_type) {
1152 case NETR_DELTA_USER:
1153 fetch_account_info(r->delta_id_union.rid,
1154 r->delta_union.user);
1156 case NETR_DELTA_GROUP:
1157 fetch_group_info(r->delta_id_union.rid,
1158 r->delta_union.group);
1160 case NETR_DELTA_GROUP_MEMBER:
1161 fetch_group_mem_info(r->delta_id_union.rid,
1162 r->delta_union.group_member);
1164 case NETR_DELTA_ALIAS:
1165 fetch_alias_info(r->delta_id_union.rid,
1166 r->delta_union.alias,
1169 case NETR_DELTA_ALIAS_MEMBER:
1170 fetch_alias_mem(r->delta_id_union.rid,
1171 r->delta_union.alias_member,
1174 case NETR_DELTA_DOMAIN:
1175 fetch_domain_info(r->delta_id_union.rid,
1176 r->delta_union.domain);
1178 /* The following types are recognised but not handled */
1179 case NETR_DELTA_RENAME_GROUP:
1180 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1182 case NETR_DELTA_RENAME_USER:
1183 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1185 case NETR_DELTA_RENAME_ALIAS:
1186 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1188 case NETR_DELTA_POLICY:
1189 d_printf("NETR_DELTA_POLICY not handled\n");
1191 case NETR_DELTA_TRUSTED_DOMAIN:
1192 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1194 case NETR_DELTA_ACCOUNT:
1195 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1197 case NETR_DELTA_SECRET:
1198 d_printf("NETR_DELTA_SECRET not handled\n");
1200 case NETR_DELTA_DELETE_GROUP:
1201 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1203 case NETR_DELTA_DELETE_USER:
1204 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1206 case NETR_DELTA_MODIFY_COUNT:
1207 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1209 case NETR_DELTA_DELETE_ALIAS:
1210 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1212 case NETR_DELTA_DELETE_TRUST:
1213 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1215 case NETR_DELTA_DELETE_ACCOUNT:
1216 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1218 case NETR_DELTA_DELETE_SECRET:
1219 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1221 case NETR_DELTA_DELETE_GROUP2:
1222 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1224 case NETR_DELTA_DELETE_USER2:
1225 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1228 d_printf("Unknown delta record type %d\n", r->delta_type);
1232 return NT_STATUS_OK;
1235 static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
1236 enum netr_SamDatabaseID database_id,
1237 struct netr_DELTA_ENUM_ARRAY *r,
1239 struct samsync_context *ctx)
1243 for (i = 0; i < r->num_deltas; i++) {
1244 fetch_sam_entry(mem_ctx, database_id, &r->delta_enum[i], ctx);
1247 return NT_STATUS_OK;
1250 /****************************************************************
1251 ****************************************************************/
1253 static NTSTATUS populate_ldap_for_ldif(const char *sid,
1255 const char *builtin_sid,
1258 const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix;
1259 char *user_attr=NULL, *group_attr=NULL;
1263 /* Get the suffix attribute */
1264 suffix_attr = sstring_sub(suffix, '=', ',');
1265 if (suffix_attr == NULL) {
1266 len = strlen(suffix);
1267 suffix_attr = (char*)SMB_MALLOC(len+1);
1268 memcpy(suffix_attr, suffix, len);
1269 suffix_attr[len] = '\0';
1272 /* Write the base */
1273 fprintf(add_fd, "# %s\n", suffix);
1274 fprintf(add_fd, "dn: %s\n", suffix);
1275 fprintf(add_fd, "objectClass: dcObject\n");
1276 fprintf(add_fd, "objectClass: organization\n");
1277 fprintf(add_fd, "o: %s\n", suffix_attr);
1278 fprintf(add_fd, "dc: %s\n", suffix_attr);
1279 fprintf(add_fd, "\n");
1282 user_suffix = lp_ldap_user_suffix();
1283 if (user_suffix == NULL) {
1284 SAFE_FREE(suffix_attr);
1285 return NT_STATUS_NO_MEMORY;
1287 /* If it exists and is distinct from other containers,
1288 Write the Users entity */
1289 if (*user_suffix && strcmp(user_suffix, suffix)) {
1290 user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ',');
1291 fprintf(add_fd, "# %s\n", user_suffix);
1292 fprintf(add_fd, "dn: %s\n", user_suffix);
1293 fprintf(add_fd, "objectClass: organizationalUnit\n");
1294 fprintf(add_fd, "ou: %s\n", user_attr);
1295 fprintf(add_fd, "\n");
1300 group_suffix = lp_ldap_group_suffix();
1301 if (group_suffix == NULL) {
1302 SAFE_FREE(suffix_attr);
1303 SAFE_FREE(user_attr);
1304 return NT_STATUS_NO_MEMORY;
1306 /* If it exists and is distinct from other containers,
1307 Write the Groups entity */
1308 if (*group_suffix && strcmp(group_suffix, suffix)) {
1309 group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1310 fprintf(add_fd, "# %s\n", group_suffix);
1311 fprintf(add_fd, "dn: %s\n", group_suffix);
1312 fprintf(add_fd, "objectClass: organizationalUnit\n");
1313 fprintf(add_fd, "ou: %s\n", group_attr);
1314 fprintf(add_fd, "\n");
1318 /* If it exists and is distinct from other containers,
1319 Write the Computers entity */
1320 machine_suffix = lp_ldap_machine_suffix();
1321 if (machine_suffix == NULL) {
1322 SAFE_FREE(suffix_attr);
1323 SAFE_FREE(user_attr);
1324 SAFE_FREE(group_attr);
1325 return NT_STATUS_NO_MEMORY;
1327 if (*machine_suffix && strcmp(machine_suffix, user_suffix) &&
1328 strcmp(machine_suffix, suffix)) {
1329 char *machine_ou = NULL;
1330 fprintf(add_fd, "# %s\n", machine_suffix);
1331 fprintf(add_fd, "dn: %s\n", machine_suffix);
1332 fprintf(add_fd, "objectClass: organizationalUnit\n");
1333 /* this isn't totally correct as it assumes that
1334 there _must_ be an ou. just fixing memleak now. jmcd */
1335 machine_ou = sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1336 fprintf(add_fd, "ou: %s\n", machine_ou);
1337 SAFE_FREE(machine_ou);
1338 fprintf(add_fd, "\n");
1342 /* If it exists and is distinct from other containers,
1343 Write the IdMap entity */
1344 idmap_suffix = lp_ldap_idmap_suffix();
1345 if (idmap_suffix == NULL) {
1346 SAFE_FREE(suffix_attr);
1347 SAFE_FREE(user_attr);
1348 SAFE_FREE(group_attr);
1349 return NT_STATUS_NO_MEMORY;
1351 if (*idmap_suffix &&
1352 strcmp(idmap_suffix, user_suffix) &&
1353 strcmp(idmap_suffix, suffix)) {
1355 fprintf(add_fd, "# %s\n", idmap_suffix);
1356 fprintf(add_fd, "dn: %s\n", idmap_suffix);
1357 fprintf(add_fd, "ObjectClass: organizationalUnit\n");
1358 s = sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1359 fprintf(add_fd, "ou: %s\n", s);
1361 fprintf(add_fd, "\n");
1365 /* Write the domain entity */
1366 fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix);
1367 fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1369 fprintf(add_fd, "objectClass: sambaDomain\n");
1370 fprintf(add_fd, "objectClass: sambaUnixIdPool\n");
1371 fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup());
1372 fprintf(add_fd, "sambaSID: %s\n", sid);
1373 fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid);
1374 fprintf(add_fd, "gidNumber: %d\n", ++ldif_gid);
1375 fprintf(add_fd, "\n");
1378 /* Write the Domain Admins entity */
1379 fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr,
1381 fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr,
1383 fprintf(add_fd, "objectClass: posixGroup\n");
1384 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1385 fprintf(add_fd, "cn: Domain Admins\n");
1386 fprintf(add_fd, "memberUid: Administrator\n");
1387 fprintf(add_fd, "description: Netbios Domain Administrators\n");
1388 fprintf(add_fd, "gidNumber: 512\n");
1389 fprintf(add_fd, "sambaSID: %s-512\n", sid);
1390 fprintf(add_fd, "sambaGroupType: 2\n");
1391 fprintf(add_fd, "displayName: Domain Admins\n");
1392 fprintf(add_fd, "\n");
1395 /* Write the Domain Users entity */
1396 fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr,
1398 fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr,
1400 fprintf(add_fd, "objectClass: posixGroup\n");
1401 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1402 fprintf(add_fd, "cn: Domain Users\n");
1403 fprintf(add_fd, "description: Netbios Domain Users\n");
1404 fprintf(add_fd, "gidNumber: 513\n");
1405 fprintf(add_fd, "sambaSID: %s-513\n", sid);
1406 fprintf(add_fd, "sambaGroupType: 2\n");
1407 fprintf(add_fd, "displayName: Domain Users\n");
1408 fprintf(add_fd, "\n");
1411 /* Write the Domain Guests entity */
1412 fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr,
1414 fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr,
1416 fprintf(add_fd, "objectClass: posixGroup\n");
1417 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1418 fprintf(add_fd, "cn: Domain Guests\n");
1419 fprintf(add_fd, "description: Netbios Domain Guests\n");
1420 fprintf(add_fd, "gidNumber: 514\n");
1421 fprintf(add_fd, "sambaSID: %s-514\n", sid);
1422 fprintf(add_fd, "sambaGroupType: 2\n");
1423 fprintf(add_fd, "displayName: Domain Guests\n");
1424 fprintf(add_fd, "\n");
1427 /* Write the Domain Computers entity */
1428 fprintf(add_fd, "# Domain Computers, %s, %s\n", group_attr,
1430 fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n",
1431 group_attr, suffix);
1432 fprintf(add_fd, "objectClass: posixGroup\n");
1433 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1434 fprintf(add_fd, "gidNumber: 515\n");
1435 fprintf(add_fd, "cn: Domain Computers\n");
1436 fprintf(add_fd, "description: Netbios Domain Computers accounts\n");
1437 fprintf(add_fd, "sambaSID: %s-515\n", sid);
1438 fprintf(add_fd, "sambaGroupType: 2\n");
1439 fprintf(add_fd, "displayName: Domain Computers\n");
1440 fprintf(add_fd, "\n");
1443 /* Write the Admininistrators Groups entity */
1444 fprintf(add_fd, "# Administrators, %s, %s\n", group_attr,
1446 fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr,
1448 fprintf(add_fd, "objectClass: posixGroup\n");
1449 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1450 fprintf(add_fd, "gidNumber: 544\n");
1451 fprintf(add_fd, "cn: Administrators\n");
1452 fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1453 fprintf(add_fd, "sambaSID: %s-544\n", builtin_sid);
1454 fprintf(add_fd, "sambaGroupType: 5\n");
1455 fprintf(add_fd, "displayName: Administrators\n");
1456 fprintf(add_fd, "\n");
1458 /* Write the Print Operator entity */
1459 fprintf(add_fd, "# Print Operators, %s, %s\n", group_attr,
1461 fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n",
1462 group_attr, suffix);
1463 fprintf(add_fd, "objectClass: posixGroup\n");
1464 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1465 fprintf(add_fd, "gidNumber: 550\n");
1466 fprintf(add_fd, "cn: Print Operators\n");
1467 fprintf(add_fd, "description: Netbios Domain Print Operators\n");
1468 fprintf(add_fd, "sambaSID: %s-550\n", builtin_sid);
1469 fprintf(add_fd, "sambaGroupType: 5\n");
1470 fprintf(add_fd, "displayName: Print Operators\n");
1471 fprintf(add_fd, "\n");
1474 /* Write the Backup Operators entity */
1475 fprintf(add_fd, "# Backup Operators, %s, %s\n", group_attr,
1477 fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n",
1478 group_attr, suffix);
1479 fprintf(add_fd, "objectClass: posixGroup\n");
1480 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1481 fprintf(add_fd, "gidNumber: 551\n");
1482 fprintf(add_fd, "cn: Backup Operators\n");
1483 fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n");
1484 fprintf(add_fd, "sambaSID: %s-551\n", builtin_sid);
1485 fprintf(add_fd, "sambaGroupType: 5\n");
1486 fprintf(add_fd, "displayName: Backup Operators\n");
1487 fprintf(add_fd, "\n");
1490 /* Write the Replicators entity */
1491 fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix);
1492 fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr,
1494 fprintf(add_fd, "objectClass: posixGroup\n");
1495 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1496 fprintf(add_fd, "gidNumber: 552\n");
1497 fprintf(add_fd, "cn: Replicators\n");
1498 fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1499 fprintf(add_fd, "sambaSID: %s-552\n", builtin_sid);
1500 fprintf(add_fd, "sambaGroupType: 5\n");
1501 fprintf(add_fd, "displayName: Replicators\n");
1502 fprintf(add_fd, "\n");
1505 /* Deallocate memory, and return */
1506 SAFE_FREE(suffix_attr);
1507 SAFE_FREE(user_attr);
1508 SAFE_FREE(group_attr);
1509 return NT_STATUS_OK;
1512 /****************************************************************
1513 ****************************************************************/
1515 static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
1517 ACCOUNTMAP *accountmap,
1520 const char *builtin_sid)
1522 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1524 /* Map the groups created by populate_ldap_for_ldif */
1525 groupmap[0].rid = 512;
1526 groupmap[0].gidNumber = 512;
1527 groupmap[0].sambaSID = talloc_asprintf(mem_ctx, "%s-512", sid);
1528 groupmap[0].group_dn = talloc_asprintf(mem_ctx,
1529 "cn=Domain Admins,ou=%s,%s", group_attr, suffix);
1530 NT_STATUS_HAVE_NO_MEMORY(groupmap[0].sambaSID);
1531 NT_STATUS_HAVE_NO_MEMORY(groupmap[0].group_dn);
1533 accountmap[0].rid = 512;
1534 accountmap[0].cn = talloc_strdup(mem_ctx, "Domain Admins");
1535 NT_STATUS_HAVE_NO_MEMORY(accountmap[0].cn);
1537 groupmap[1].rid = 513;
1538 groupmap[1].gidNumber = 513;
1539 groupmap[1].sambaSID = talloc_asprintf(mem_ctx, "%s-513", sid);
1540 groupmap[1].group_dn = talloc_asprintf(mem_ctx,
1541 "cn=Domain Users,ou=%s,%s", group_attr, suffix);
1542 NT_STATUS_HAVE_NO_MEMORY(groupmap[1].sambaSID);
1543 NT_STATUS_HAVE_NO_MEMORY(groupmap[1].group_dn);
1545 accountmap[1].rid = 513;
1546 accountmap[1].cn = talloc_strdup(mem_ctx, "Domain Users");
1547 NT_STATUS_HAVE_NO_MEMORY(accountmap[1].cn);
1549 groupmap[2].rid = 514;
1550 groupmap[2].gidNumber = 514;
1551 groupmap[2].sambaSID = talloc_asprintf(mem_ctx, "%s-514", sid);
1552 groupmap[2].group_dn = talloc_asprintf(mem_ctx,
1553 "cn=Domain Guests,ou=%s,%s", group_attr, suffix);
1554 NT_STATUS_HAVE_NO_MEMORY(groupmap[2].sambaSID);
1555 NT_STATUS_HAVE_NO_MEMORY(groupmap[2].group_dn);
1557 accountmap[2].rid = 514;
1558 accountmap[2].cn = talloc_strdup(mem_ctx, "Domain Guests");
1559 NT_STATUS_HAVE_NO_MEMORY(accountmap[2].cn);
1561 groupmap[3].rid = 515;
1562 groupmap[3].gidNumber = 515;
1563 groupmap[3].sambaSID = talloc_asprintf(mem_ctx, "%s-515", sid);
1564 groupmap[3].group_dn = talloc_asprintf(mem_ctx,
1565 "cn=Domain Computers,ou=%s,%s", group_attr, suffix);
1566 NT_STATUS_HAVE_NO_MEMORY(groupmap[3].sambaSID);
1567 NT_STATUS_HAVE_NO_MEMORY(groupmap[3].group_dn);
1569 accountmap[3].rid = 515;
1570 accountmap[3].cn = talloc_strdup(mem_ctx, "Domain Computers");
1571 NT_STATUS_HAVE_NO_MEMORY(accountmap[3].cn);
1573 groupmap[4].rid = 544;
1574 groupmap[4].gidNumber = 544;
1575 groupmap[4].sambaSID = talloc_asprintf(mem_ctx, "%s-544", builtin_sid);
1576 groupmap[4].group_dn = talloc_asprintf(mem_ctx,
1577 "cn=Administrators,ou=%s,%s", group_attr, suffix);
1578 NT_STATUS_HAVE_NO_MEMORY(groupmap[4].sambaSID);
1579 NT_STATUS_HAVE_NO_MEMORY(groupmap[4].group_dn);
1581 accountmap[4].rid = 515;
1582 accountmap[4].cn = talloc_strdup(mem_ctx, "Administrators");
1583 NT_STATUS_HAVE_NO_MEMORY(accountmap[4].cn);
1585 groupmap[5].rid = 550;
1586 groupmap[5].gidNumber = 550;
1587 groupmap[5].sambaSID = talloc_asprintf(mem_ctx, "%s-550", builtin_sid);
1588 groupmap[5].group_dn = talloc_asprintf(mem_ctx,
1589 "cn=Print Operators,ou=%s,%s", group_attr, suffix);
1590 NT_STATUS_HAVE_NO_MEMORY(groupmap[5].sambaSID);
1591 NT_STATUS_HAVE_NO_MEMORY(groupmap[5].group_dn);
1593 accountmap[5].rid = 550;
1594 accountmap[5].cn = talloc_strdup(mem_ctx, "Print Operators");
1595 NT_STATUS_HAVE_NO_MEMORY(accountmap[5].cn);
1597 groupmap[6].rid = 551;
1598 groupmap[6].gidNumber = 551;
1599 groupmap[6].sambaSID = talloc_asprintf(mem_ctx, "%s-551", builtin_sid);
1600 groupmap[6].group_dn = talloc_asprintf(mem_ctx,
1601 "cn=Backup Operators,ou=%s,%s", group_attr, suffix);
1602 NT_STATUS_HAVE_NO_MEMORY(groupmap[6].sambaSID);
1603 NT_STATUS_HAVE_NO_MEMORY(groupmap[6].group_dn);
1605 accountmap[6].rid = 551;
1606 accountmap[6].cn = talloc_strdup(mem_ctx, "Backup Operators");
1607 NT_STATUS_HAVE_NO_MEMORY(accountmap[6].cn);
1609 groupmap[7].rid = 552;
1610 groupmap[7].gidNumber = 552;
1611 groupmap[7].sambaSID = talloc_asprintf(mem_ctx, "%s-552", builtin_sid);
1612 groupmap[7].group_dn = talloc_asprintf(mem_ctx,
1613 "cn=Replicators,ou=%s,%s", group_attr, suffix);
1614 NT_STATUS_HAVE_NO_MEMORY(groupmap[7].sambaSID);
1615 NT_STATUS_HAVE_NO_MEMORY(groupmap[7].group_dn);
1617 accountmap[7].rid = 551;
1618 accountmap[7].cn = talloc_strdup(mem_ctx, "Replicators");
1619 NT_STATUS_HAVE_NO_MEMORY(accountmap[7].cn);
1621 SAFE_FREE(group_attr);
1623 return NT_STATUS_OK;
1627 * This is a crap routine, but I think it's the quickest way to solve the
1628 * UTF8->base64 problem.
1631 static int fprintf_attr(FILE *add_fd, const char *attr_name,
1632 const char *fmt, ...)
1635 char *value, *p, *base64;
1636 DATA_BLOB base64_blob;
1637 bool do_base64 = false;
1641 value = talloc_vasprintf(NULL, fmt, ap);
1644 SMB_ASSERT(value != NULL);
1646 for (p=value; *p; p++) {
1654 bool only_whitespace = true;
1655 for (p=value; *p; p++) {
1657 * I know that this not multibyte safe, but we break
1658 * on the first non-whitespace character anyway.
1661 only_whitespace = false;
1665 if (only_whitespace) {
1671 res = fprintf(add_fd, "%s: %s\n", attr_name, value);
1676 base64_blob.data = (unsigned char *)value;
1677 base64_blob.length = strlen(value);
1679 base64 = base64_encode_data_blob(value, base64_blob);
1680 SMB_ASSERT(base64 != NULL);
1682 res = fprintf(add_fd, "%s:: %s\n", attr_name, base64);
1687 /****************************************************************
1688 ****************************************************************/
1690 static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
1691 struct netr_DELTA_GROUP *r,
1697 const char *groupname = r->group_name.string;
1698 uint32 grouptype = 0, g_rid = 0;
1699 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1701 /* Set up the group type (always 2 for group info) */
1704 /* These groups are entered by populate_ldap_for_ldif */
1705 if (strcmp(groupname, "Domain Admins") == 0 ||
1706 strcmp(groupname, "Domain Users") == 0 ||
1707 strcmp(groupname, "Domain Guests") == 0 ||
1708 strcmp(groupname, "Domain Computers") == 0 ||
1709 strcmp(groupname, "Administrators") == 0 ||
1710 strcmp(groupname, "Print Operators") == 0 ||
1711 strcmp(groupname, "Backup Operators") == 0 ||
1712 strcmp(groupname, "Replicators") == 0) {
1713 SAFE_FREE(group_attr);
1714 return NT_STATUS_OK;
1716 /* Increment the gid for the new group */
1720 /* Map the group rid, gid, and dn */
1722 groupmap->rid = g_rid;
1723 groupmap->gidNumber = ldif_gid;
1724 groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
1725 groupmap->group_dn = talloc_asprintf(mem_ctx,
1726 "cn=%s,ou=%s,%s", groupname, group_attr, suffix);
1727 NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
1728 NT_STATUS_HAVE_NO_MEMORY(groupmap->group_dn);
1730 /* Write the data to the temporary add ldif file */
1731 fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr,
1733 fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", groupname, group_attr,
1735 fprintf(add_fd, "objectClass: posixGroup\n");
1736 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1737 fprintf_attr(add_fd, "cn", "%s", groupname);
1738 fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
1739 fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
1740 fprintf(add_fd, "sambaGroupType: %d\n", grouptype);
1741 fprintf_attr(add_fd, "displayName", "%s", groupname);
1742 fprintf(add_fd, "\n");
1745 SAFE_FREE(group_attr);
1747 return NT_STATUS_OK;
1750 /****************************************************************
1751 ****************************************************************/
1753 static NTSTATUS fetch_account_info_to_ldif(TALLOC_CTX *mem_ctx,
1754 struct netr_DELTA_USER *r,
1756 ACCOUNTMAP *accountmap,
1762 fstring username, logonscript, homedrive, homepath = "", homedir = "";
1763 fstring hex_nt_passwd, hex_lm_passwd;
1764 fstring description, profilepath, fullname, sambaSID;
1765 uchar lm_passwd[16], nt_passwd[16];
1766 char *flags, *user_rdn;
1768 const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1769 static uchar zero_buf[16];
1770 uint32 rid = 0, group_rid = 0, gidNumber = 0;
1774 /* Get the username */
1775 fstrcpy(username, r->account_name.string);
1780 /* Map the rid and username for group member info later */
1781 accountmap->rid = rid;
1782 accountmap->cn = talloc_strdup(mem_ctx, username);
1783 NT_STATUS_HAVE_NO_MEMORY(accountmap->cn);
1785 /* Get the home directory */
1786 if (r->acct_flags & ACB_NORMAL) {
1787 fstrcpy(homedir, r->home_directory.string);
1789 snprintf(homedir, sizeof(homedir), "/home/%s", username);
1791 snprintf(homedir, sizeof(homedir), "/nobodyshomedir");
1793 ou = lp_ldap_user_suffix();
1795 ou = lp_ldap_machine_suffix();
1796 snprintf(homedir, sizeof(homedir), "/machinehomedir");
1799 /* Get the logon script */
1800 fstrcpy(logonscript, r->logon_script.string);
1802 /* Get the home drive */
1803 fstrcpy(homedrive, r->home_drive.string);
1805 /* Get the home path */
1806 fstrcpy(homepath, r->home_directory.string);
1808 /* Get the description */
1809 fstrcpy(description, r->description.string);
1811 /* Get the display name */
1812 fstrcpy(fullname, r->full_name.string);
1814 /* Get the profile path */
1815 fstrcpy(profilepath, r->profile_path.string);
1817 /* Get lm and nt password data */
1818 if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) {
1819 sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0);
1820 pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags);
1822 pdb_sethexpwd(hex_lm_passwd, NULL, 0);
1824 if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) {
1825 sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0);
1826 pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags);
1828 pdb_sethexpwd(hex_nt_passwd, NULL, 0);
1830 unix_time = nt_time_to_unix(r->last_password_change);
1832 /* Increment the uid for the new user */
1835 /* Set up group id and sambaSID for the user */
1836 group_rid = r->primary_gid;
1837 for (i=0; i<alloced; i++) {
1838 if (groupmap[i].rid == group_rid) break;
1841 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1843 return NT_STATUS_UNSUCCESSFUL;
1845 gidNumber = groupmap[i].gidNumber;
1846 snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID);
1848 /* Set up sambaAcctFlags */
1849 flags = pdb_encode_acct_ctrl(r->acct_flags,
1850 NEW_PW_FORMAT_SPACE_PADDED_LEN);
1852 /* Add the user to the temporary add ldif file */
1853 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1854 user_rdn = sstring_sub(ou, '=', ',');
1855 fprintf(add_fd, "# %s, %s, %s\n", username, user_rdn, suffix);
1856 fprintf_attr(add_fd, "dn", "uid=%s,ou=%s,%s", username, user_rdn,
1858 SAFE_FREE(user_rdn);
1859 fprintf(add_fd, "ObjectClass: top\n");
1860 fprintf(add_fd, "objectClass: inetOrgPerson\n");
1861 fprintf(add_fd, "objectClass: posixAccount\n");
1862 fprintf(add_fd, "objectClass: shadowAccount\n");
1863 fprintf(add_fd, "objectClass: sambaSamAccount\n");
1864 fprintf_attr(add_fd, "cn", "%s", username);
1865 fprintf_attr(add_fd, "sn", "%s", username);
1866 fprintf_attr(add_fd, "uid", "%s", username);
1867 fprintf(add_fd, "uidNumber: %d\n", ldif_uid);
1868 fprintf(add_fd, "gidNumber: %d\n", gidNumber);
1869 fprintf_attr(add_fd, "homeDirectory", "%s", homedir);
1871 fprintf_attr(add_fd, "sambaHomePath", "%s", homepath);
1873 fprintf_attr(add_fd, "sambaHomeDrive", "%s", homedrive);
1875 fprintf_attr(add_fd, "sambaLogonScript", "%s", logonscript);
1876 fprintf(add_fd, "loginShell: %s\n",
1877 ((r->acct_flags & ACB_NORMAL) ?
1878 "/bin/bash" : "/bin/false"));
1879 fprintf(add_fd, "gecos: System User\n");
1881 fprintf_attr(add_fd, "description", "%s", description);
1882 fprintf(add_fd, "sambaSID: %s-%d\n", sid, rid);
1883 fprintf(add_fd, "sambaPrimaryGroupSID: %s\n", sambaSID);
1885 fprintf_attr(add_fd, "displayName", "%s", fullname);
1887 fprintf_attr(add_fd, "sambaProfilePath", "%s", profilepath);
1888 if (strcmp(nopasswd, hex_lm_passwd) != 0)
1889 fprintf(add_fd, "sambaLMPassword: %s\n", hex_lm_passwd);
1890 if (strcmp(nopasswd, hex_nt_passwd) != 0)
1891 fprintf(add_fd, "sambaNTPassword: %s\n", hex_nt_passwd);
1892 fprintf(add_fd, "sambaPwdLastSet: %d\n", (int)unix_time);
1893 fprintf(add_fd, "sambaAcctFlags: %s\n", flags);
1894 fprintf(add_fd, "\n");
1898 return NT_STATUS_OK;
1901 /****************************************************************
1902 ****************************************************************/
1904 static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
1905 struct netr_DELTA_ALIAS *r,
1910 enum netr_SamDatabaseID database_id)
1912 fstring aliasname, description;
1913 uint32 grouptype = 0, g_rid = 0;
1914 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
1916 /* Get the alias name */
1917 fstrcpy(aliasname, r->alias_name.string);
1919 /* Get the alias description */
1920 fstrcpy(description, r->description.string);
1922 /* Set up the group type */
1923 switch (database_id) {
1924 case SAM_DATABASE_DOMAIN:
1927 case SAM_DATABASE_BUILTIN:
1936 These groups are entered by populate_ldap_for_ldif
1937 Note that populate creates a group called Relicators,
1938 but NT returns a group called Replicator
1940 if (strcmp(aliasname, "Domain Admins") == 0 ||
1941 strcmp(aliasname, "Domain Users") == 0 ||
1942 strcmp(aliasname, "Domain Guests") == 0 ||
1943 strcmp(aliasname, "Domain Computers") == 0 ||
1944 strcmp(aliasname, "Administrators") == 0 ||
1945 strcmp(aliasname, "Print Operators") == 0 ||
1946 strcmp(aliasname, "Backup Operators") == 0 ||
1947 strcmp(aliasname, "Replicator") == 0) {
1948 SAFE_FREE(group_attr);
1949 return NT_STATUS_OK;
1951 /* Increment the gid for the new group */
1955 /* Map the group rid and gid */
1957 groupmap->gidNumber = ldif_gid;
1958 groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
1959 NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
1961 /* Write the data to the temporary add ldif file */
1962 fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr,
1964 fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", aliasname, group_attr,
1966 fprintf(add_fd, "objectClass: posixGroup\n");
1967 fprintf(add_fd, "objectClass: sambaGroupMapping\n");
1968 fprintf(add_fd, "cn: %s\n", aliasname);
1969 fprintf(add_fd, "gidNumber: %d\n", ldif_gid);
1970 fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID);
1971 fprintf(add_fd, "sambaGroupType: %d\n", grouptype);
1972 fprintf_attr(add_fd, "displayName", "%s", aliasname);
1974 fprintf_attr(add_fd, "description", "%s", description);
1975 fprintf(add_fd, "\n");
1978 SAFE_FREE(group_attr);
1980 return NT_STATUS_OK;
1983 /****************************************************************
1984 ****************************************************************/
1986 static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r,
1989 ACCOUNTMAP *accountmap,
1990 FILE *mod_fd, int alloced)
1993 uint32 group_rid = 0, rid = 0;
1996 /* Get the dn for the group */
1997 if (r->num_rids > 0) {
1999 for (j=0; j<alloced; j++) {
2000 if (groupmap[j].rid == group_rid) break;
2003 DEBUG(1, ("Could not find rid %d in groupmap array\n",
2005 return NT_STATUS_UNSUCCESSFUL;
2007 snprintf(group_dn, sizeof(group_dn), "%s", groupmap[j].group_dn);
2008 fprintf(mod_fd, "dn: %s\n", group_dn);
2010 /* Get the cn for each member */
2011 for (i=0; i < r->num_rids; i++) {
2013 for (k=0; k<alloced; k++) {
2014 if (accountmap[k].rid == rid) break;
2017 DEBUG(1, ("Could not find rid %d in "
2018 "accountmap array\n", rid));
2019 return NT_STATUS_UNSUCCESSFUL;
2021 fprintf(mod_fd, "memberUid: %s\n", accountmap[k].cn);
2023 fprintf(mod_fd, "\n");
2028 return NT_STATUS_OK;
2031 /****************************************************************
2032 ****************************************************************/
2034 static NTSTATUS ldif_init_context(TALLOC_CTX *mem_ctx,
2035 struct samsync_context *ctx,
2036 enum netr_SamDatabaseID database_id)
2038 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2039 struct samsync_ldif_context *r;
2040 const char *add_template = "/tmp/add.ldif.XXXXXX";
2041 const char *mod_template = "/tmp/mod.ldif.XXXXXX";
2042 const char *builtin_sid = "S-1-5-32";
2044 if (ctx->ldif && ctx->ldif->initialized) {
2045 return NT_STATUS_OK;
2048 r = TALLOC_ZERO_P(mem_ctx, struct samsync_ldif_context);
2049 NT_STATUS_HAVE_NO_MEMORY(r);
2051 /* Get other smb.conf data */
2052 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2053 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2057 /* Get the ldap suffix */
2058 r->suffix = lp_ldap_suffix();
2059 if (r->suffix == NULL || strcmp(r->suffix, "") == 0) {
2060 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2065 ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
2066 NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid_str);
2068 /* Ensure we have an output file */
2069 if (ctx->ldif_filename) {
2070 r->ldif_file = fopen(ctx->ldif_filename, "a");
2072 r->ldif_file = stdout;
2075 if (!r->ldif_file) {
2076 fprintf(stderr, "Could not open %s\n", ctx->ldif_filename);
2077 DEBUG(1, ("Could not open %s\n", ctx->ldif_filename));
2078 status = NT_STATUS_UNSUCCESSFUL;
2082 r->add_template = talloc_strdup(mem_ctx, add_template);
2083 r->mod_template = talloc_strdup(mem_ctx, mod_template);
2084 if (!r->add_template || !r->mod_template) {
2085 status = NT_STATUS_NO_MEMORY;
2089 r->add_name = talloc_strdup(mem_ctx, add_template);
2090 r->mod_name = talloc_strdup(mem_ctx, mod_template);
2091 if (!r->add_name || !r->mod_name) {
2092 status = NT_STATUS_NO_MEMORY;
2096 /* Open the add and mod ldif files */
2097 if (!(r->add_file = fdopen(smb_mkstemp(r->add_name),"w"))) {
2098 DEBUG(1, ("Could not open %s\n", r->add_name));
2099 status = NT_STATUS_UNSUCCESSFUL;
2102 if (!(r->mod_file = fdopen(smb_mkstemp(r->mod_name),"w"))) {
2103 DEBUG(1, ("Could not open %s\n", r->mod_name));
2104 status = NT_STATUS_UNSUCCESSFUL;
2108 /* Allocate initial memory for groupmap and accountmap arrays */
2109 r->groupmap = TALLOC_ZERO_ARRAY(mem_ctx, GROUPMAP, 8);
2110 r->accountmap = TALLOC_ZERO_ARRAY(mem_ctx, ACCOUNTMAP, 8);
2111 if (r->groupmap == NULL || r->accountmap == NULL) {
2112 DEBUG(1,("GROUPMAP talloc failed\n"));
2113 status = NT_STATUS_NO_MEMORY;
2117 /* Remember how many we malloced */
2120 /* Initial database population */
2121 if (database_id == SAM_DATABASE_DOMAIN) {
2123 status = populate_ldap_for_ldif(ctx->domain_sid_str,
2127 if (!NT_STATUS_IS_OK(status)) {
2131 status = map_populate_groups(mem_ctx,
2134 ctx->domain_sid_str,
2137 if (!NT_STATUS_IS_OK(status)) {
2142 r->initialized = true;
2146 return NT_STATUS_OK;
2152 /****************************************************************
2153 ****************************************************************/
2155 static void ldif_free_context(struct samsync_ldif_context *r)
2161 /* Close and delete the ldif files */
2163 fclose(r->add_file);
2166 if ((r->add_name != NULL) &&
2167 strcmp(r->add_name, r->add_template) && (unlink(r->add_name))) {
2168 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2169 r->add_name, strerror(errno)));
2173 fclose(r->mod_file);
2176 if ((r->mod_name != NULL) &&
2177 strcmp(r->mod_name, r->mod_template) && (unlink(r->mod_name))) {
2178 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2179 r->mod_name, strerror(errno)));
2182 if (r->ldif_file && (r->ldif_file != stdout)) {
2183 fclose(r->ldif_file);
2189 /****************************************************************
2190 ****************************************************************/
2192 static void ldif_write_output(enum netr_SamDatabaseID database_id,
2193 struct samsync_context *ctx)
2195 struct samsync_ldif_context *l = ctx->ldif;
2197 /* Write ldif data to the user's file */
2198 if (database_id == SAM_DATABASE_DOMAIN) {
2199 fprintf(l->ldif_file,
2200 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2201 fprintf(l->ldif_file,
2202 "# =================================\n\n");
2203 fflush(l->ldif_file);
2204 } else if (database_id == SAM_DATABASE_BUILTIN) {
2205 fprintf(l->ldif_file,
2206 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2207 fprintf(l->ldif_file,
2208 "# ==================================\n\n");
2209 fflush(l->ldif_file);
2211 fseek(l->add_file, 0, SEEK_SET);
2212 transfer_file(fileno(l->add_file), fileno(l->ldif_file), (size_t) -1);
2214 if (database_id == SAM_DATABASE_DOMAIN) {
2215 fprintf(l->ldif_file,
2216 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2217 fprintf(l->ldif_file,
2218 "# ====================================\n\n");
2219 fflush(l->ldif_file);
2220 } else if (database_id == SAM_DATABASE_BUILTIN) {
2221 fprintf(l->ldif_file,
2222 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2223 fprintf(l->ldif_file,
2224 "# =====================================\n\n");
2225 fflush(l->ldif_file);
2227 fseek(l->mod_file, 0, SEEK_SET);
2228 transfer_file(fileno(l->mod_file), fileno(l->ldif_file), (size_t) -1);
2231 /****************************************************************
2232 ****************************************************************/
2234 static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
2235 enum netr_SamDatabaseID database_id,
2236 struct netr_DELTA_ENUM *r,
2237 struct samsync_context *ctx,
2241 union netr_DELTA_UNION u = r->delta_union;
2242 union netr_DELTA_ID_UNION id = r->delta_id_union;
2243 struct samsync_ldif_context *l = ctx->ldif;
2245 switch (r->delta_type) {
2246 case NETR_DELTA_DOMAIN:
2249 case NETR_DELTA_GROUP:
2250 fetch_group_info_to_ldif(mem_ctx,
2252 &l->groupmap[*g_index],
2254 ctx->domain_sid_str,
2259 case NETR_DELTA_USER:
2260 fetch_account_info_to_ldif(mem_ctx,
2263 &l->accountmap[*a_index],
2265 ctx->domain_sid_str,
2271 case NETR_DELTA_ALIAS:
2272 fetch_alias_info_to_ldif(mem_ctx,
2274 &l->groupmap[*g_index],
2276 ctx->domain_sid_str,
2282 case NETR_DELTA_GROUP_MEMBER:
2283 fetch_groupmem_info_to_ldif(u.group_member,
2291 case NETR_DELTA_ALIAS_MEMBER:
2292 case NETR_DELTA_POLICY:
2293 case NETR_DELTA_ACCOUNT:
2294 case NETR_DELTA_TRUSTED_DOMAIN:
2295 case NETR_DELTA_SECRET:
2296 case NETR_DELTA_RENAME_GROUP:
2297 case NETR_DELTA_RENAME_USER:
2298 case NETR_DELTA_RENAME_ALIAS:
2299 case NETR_DELTA_DELETE_GROUP:
2300 case NETR_DELTA_DELETE_USER:
2301 case NETR_DELTA_MODIFY_COUNT:
2304 } /* end of switch */
2306 return NT_STATUS_OK;
2309 /****************************************************************
2310 ****************************************************************/
2312 static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
2313 struct samsync_context *ctx,
2314 uint32_t num_entries)
2316 struct samsync_ldif_context *l = ctx->ldif;
2319 return NT_STATUS_INVALID_PARAMETER;
2322 /* Re-allocate memory for groupmap and accountmap arrays */
2323 l->groupmap = TALLOC_REALLOC_ARRAY(mem_ctx,
2326 num_entries + l->num_alloced);
2328 l->accountmap = TALLOC_REALLOC_ARRAY(mem_ctx,
2331 num_entries + l->num_alloced);
2333 if (l->groupmap == NULL || l->accountmap == NULL) {
2334 DEBUG(1,("GROUPMAP talloc failed\n"));
2335 return NT_STATUS_NO_MEMORY;
2338 /* Initialize the new records */
2339 memset(&(l->groupmap[l->num_alloced]), 0,
2340 sizeof(GROUPMAP) * num_entries);
2341 memset(&(l->accountmap[l->num_alloced]), 0,
2342 sizeof(ACCOUNTMAP) * num_entries);
2344 /* Remember how many we alloced this time */
2345 l->num_alloced += num_entries;
2347 return NT_STATUS_OK;
2350 /****************************************************************
2351 ****************************************************************/
2353 static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
2354 enum netr_SamDatabaseID database_id,
2355 struct netr_DELTA_ENUM_ARRAY *r,
2357 struct samsync_context *ctx)
2361 uint32_t g_index = 0, a_index = 0;
2363 status = ldif_init_context(mem_ctx, ctx, database_id);
2364 if (!NT_STATUS_IS_OK(status)) {
2368 status = ldif_realloc_maps(mem_ctx, ctx, r->num_deltas);
2369 if (!NT_STATUS_IS_OK(status)) {
2373 for (i = 0; i < r->num_deltas; i++) {
2374 status = fetch_sam_entry_ldif(mem_ctx, database_id,
2375 &r->delta_enum[i], ctx,
2376 &g_index, &a_index);
2377 if (!NT_STATUS_IS_OK(status)) {
2382 /* This was the last query */
2383 if (NT_STATUS_IS_OK(result)) {
2384 ldif_write_output(database_id, ctx);
2385 ldif_free_context(ctx->ldif);
2389 return NT_STATUS_OK;
2392 ldif_free_context(ctx->ldif);
2398 * Basic usage function for 'net rpc vampire'
2400 * @param c A net_context structure
2401 * @param argc Standard main() style argc
2402 * @param argc Standard main() style argv. Initial components are already
2406 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
2408 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2409 "\t to pull accounts from a remote PDC where we are a BDC\n"
2410 "\t\t no args puts accounts in local passdb from smb.conf\n"
2411 "\t\t ldif - put accounts in ldif format (file defaults to "
2414 net_common_flags_usage(c, argc, argv);
2419 /* dump sam database via samsync rpc calls */
2420 NTSTATUS rpc_vampire_internals(struct net_context *c,
2421 const DOM_SID *domain_sid,
2422 const char *domain_name,
2423 struct cli_state *cli,
2424 struct rpc_pipe_client *pipe_hnd,
2425 TALLOC_CTX *mem_ctx,
2430 fstring my_dom_sid_str;
2431 fstring rem_dom_sid_str;
2432 struct samsync_context *ctx;
2435 ctx = TALLOC_ZERO_P(mem_ctx, struct samsync_context);
2436 NT_STATUS_HAVE_NO_MEMORY(ctx);
2438 if (!sid_equal(domain_sid, get_global_sam_sid())) {
2439 d_printf("Cannot import users from %s at this time, "
2440 "as the current domain:\n\t%s: %s\nconflicts "
2441 "with the remote domain\n\t%s: %s\n"
2442 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2443 "workgroup=%s\n\n in your smb.conf?\n",
2445 get_global_sam_name(),
2446 sid_to_fstring(my_dom_sid_str,
2447 get_global_sam_sid()),
2448 domain_name, sid_to_fstring(rem_dom_sid_str,
2451 return NT_STATUS_UNSUCCESSFUL;
2454 if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
2455 ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF;
2456 ctx->ldif_filename = argv[1];
2457 fn = (samsync_fn_t *)fetch_sam_entries_ldif;
2459 ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB;
2460 fn = (samsync_fn_t *)fetch_sam_entries;
2464 ctx->domain_sid = domain_sid;
2465 result = process_database(pipe_hnd, SAM_DATABASE_DOMAIN,
2466 (samsync_fn_t)fn, ctx);
2467 if (!NT_STATUS_IS_OK(result)) {
2468 d_fprintf(stderr, "Failed to fetch domain database: %s\n",
2470 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED))
2471 d_fprintf(stderr, "Perhaps %s is a Windows 2000 "
2472 "native mode domain?\n", domain_name);
2477 ctx->domain_sid = &global_sid_Builtin;
2478 result = process_database(pipe_hnd, SAM_DATABASE_BUILTIN,
2479 (samsync_fn_t)fn, ctx);
2480 if (!NT_STATUS_IS_OK(result)) {
2481 d_fprintf(stderr, "Failed to fetch builtin database: %s\n",
2486 /* Currently we crash on PRIVS somewhere in unmarshalling */
2487 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */