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;
32 /* Keep track of ldap initialization */
33 static int init_ldap
= 1;
35 static void display_group_mem_info(uint32_t rid
,
36 struct netr_DELTA_GROUP_MEMBER
*r
)
39 d_printf("Group mem %u: ", rid
);
40 for (i
=0; i
< r
->num_rids
; i
++) {
41 d_printf("%u ", r
->rids
[i
]);
46 static void display_alias_info(uint32_t rid
,
47 struct netr_DELTA_ALIAS
*r
)
49 d_printf("Alias '%s' ", r
->alias_name
.string
);
50 d_printf("desc='%s' rid=%u\n", r
->description
.string
, r
->rid
);
53 static void display_alias_mem(uint32_t rid
,
54 struct netr_DELTA_ALIAS_MEMBER
*r
)
57 d_printf("Alias rid %u: ", rid
);
58 for (i
=0; i
< r
->sids
.num_sids
; i
++) {
59 d_printf("%s ", sid_string_tos(r
->sids
.sids
[i
].sid
));
64 static void display_account_info(uint32_t rid
,
65 struct netr_DELTA_USER
*r
)
67 fstring hex_nt_passwd
, hex_lm_passwd
;
68 uchar lm_passwd
[16], nt_passwd
[16];
69 static uchar zero_buf
[16];
71 /* Decode hashes from password hash (if they are not NULL) */
73 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
74 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
75 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
77 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
80 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
81 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
82 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
84 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
87 printf("%s:%d:%s:%s:%s:LCT-0\n",
88 r
->account_name
.string
,
89 r
->rid
, hex_lm_passwd
, hex_nt_passwd
,
90 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
));
93 static time_t uint64s_nt_time_to_unix_abs(const uint64
*src
)
97 return nt_time_to_unix_abs(&nttime
);
100 static NTSTATUS
pull_netr_AcctLockStr(TALLOC_CTX
*mem_ctx
,
101 struct lsa_BinaryString
*r
,
102 struct netr_AcctLockStr
**str_p
)
104 struct netr_AcctLockStr
*str
;
105 enum ndr_err_code ndr_err
;
108 if (!mem_ctx
|| !r
|| !str_p
) {
109 return NT_STATUS_INVALID_PARAMETER
;
114 str
= TALLOC_ZERO_P(mem_ctx
, struct netr_AcctLockStr
);
116 return NT_STATUS_NO_MEMORY
;
119 blob
= data_blob_const(r
->array
, r
->length
);
121 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, str
,
122 (ndr_pull_flags_fn_t
)ndr_pull_netr_AcctLockStr
);
123 data_blob_free(&blob
);
125 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
126 return ndr_map_error2ntstatus(ndr_err
);
134 static void display_domain_info(struct netr_DELTA_DOMAIN
*r
)
137 struct netr_AcctLockStr
*lockstr
= NULL
;
139 TALLOC_CTX
*mem_ctx
= talloc_tos();
141 status
= pull_netr_AcctLockStr(mem_ctx
, &r
->account_lockout
,
143 if (!NT_STATUS_IS_OK(status
)) {
144 d_printf("failed to pull account lockout string: %s\n",
148 u_logout
= uint64s_nt_time_to_unix_abs((const uint64
*)&r
->force_logoff_time
);
150 d_printf("Domain name: %s\n", r
->domain_name
.string
);
152 d_printf("Minimal Password Length: %d\n", r
->min_password_length
);
153 d_printf("Password History Length: %d\n", r
->password_history_length
);
155 d_printf("Force Logoff: %d\n", (int)u_logout
);
157 d_printf("Max Password Age: %s\n", display_time(r
->max_password_age
));
158 d_printf("Min Password Age: %s\n", display_time(r
->min_password_age
));
161 d_printf("Lockout Time: %s\n", display_time((NTTIME
)lockstr
->lockout_duration
));
162 d_printf("Lockout Reset Time: %s\n", display_time((NTTIME
)lockstr
->reset_count
));
163 d_printf("Bad Attempt Lockout: %d\n", lockstr
->bad_attempt_lockout
);
166 d_printf("User must logon to change password: %d\n", r
->logon_to_chgpass
);
169 static void display_group_info(uint32_t rid
, struct netr_DELTA_GROUP
*r
)
171 d_printf("Group '%s' ", r
->group_name
.string
);
172 d_printf("desc='%s', rid=%u\n", r
->description
.string
, rid
);
175 static void display_sam_entry(struct netr_DELTA_ENUM
*r
)
177 union netr_DELTA_UNION u
= r
->delta_union
;
178 union netr_DELTA_ID_UNION id
= r
->delta_id_union
;
180 switch (r
->delta_type
) {
181 case NETR_DELTA_DOMAIN
:
182 display_domain_info(u
.domain
);
184 case NETR_DELTA_GROUP
:
185 display_group_info(id
.rid
, u
.group
);
188 case NETR_DELTA_DELETE_GROUP
:
189 printf("Delete Group: %d\n",
190 u
.delete_account
.unknown
);
192 case NETR_DELTA_RENAME_GROUP
:
193 printf("Rename Group: %s -> %s\n",
194 u
.rename_group
->OldName
.string
,
195 u
.rename_group
->NewName
.string
);
198 case NETR_DELTA_USER
:
199 display_account_info(id
.rid
, u
.user
);
202 case NETR_DELTA_DELETE_USER
:
203 printf("Delete User: %d\n",
206 case NETR_DELTA_RENAME_USER
:
207 printf("Rename user: %s -> %s\n",
208 u
.rename_user
->OldName
.string
,
209 u
.rename_user
->NewName
.string
);
212 case NETR_DELTA_GROUP_MEMBER
:
213 display_group_mem_info(id
.rid
, u
.group_member
);
215 case NETR_DELTA_ALIAS
:
216 display_alias_info(id
.rid
, u
.alias
);
219 case NETR_DELTA_DELETE_ALIAS
:
220 printf("Delete Alias: %d\n",
223 case NETR_DELTA_RENAME_ALIAS
:
224 printf("Rename alias: %s -> %s\n",
225 u
.rename_alias
->OldName
.string
,
226 u
.rename_alias
->NewName
.string
);
229 case NETR_DELTA_ALIAS_MEMBER
:
230 display_alias_mem(id
.rid
, u
.alias_member
);
233 case NETR_DELTA_POLICY
:
236 case NETR_DELTA_TRUSTED_DOMAIN
:
237 printf("Trusted Domain: %s\n",
238 u
.trusted_domain
->domain_name
.string
);
240 case NETR_DELTA_DELETE_TRUST
:
241 printf("Delete Trust: %d\n",
242 u
.delete_trust
.unknown
);
244 case NETR_DELTA_ACCOUNT
:
247 case NETR_DELTA_DELETE_ACCOUNT
:
248 printf("Delete Account: %d\n",
249 u
.delete_account
.unknown
);
251 case NETR_DELTA_SECRET
:
254 case NETR_DELTA_DELETE_SECRET
:
255 printf("Delete Secret: %d\n",
256 u
.delete_secret
.unknown
);
258 case NETR_DELTA_DELETE_GROUP2
:
259 printf("Delete Group2: %s\n",
260 u
.delete_group
->account_name
);
262 case NETR_DELTA_DELETE_USER2
:
263 printf("Delete User2: %s\n",
264 u
.delete_user
->account_name
);
266 case NETR_DELTA_MODIFY_COUNT
:
267 printf("sam sequence update: 0x%016llx\n",
268 (unsigned long long) *u
.modified_count
);
271 /* The following types are recognised but not handled */
272 case NETR_DELTA_RENAME_GROUP
:
273 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
275 case NETR_DELTA_RENAME_USER
:
276 d_printf("NETR_DELTA_RENAME_USER not handled\n");
278 case NETR_DELTA_RENAME_ALIAS
:
279 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
281 case NETR_DELTA_POLICY
:
282 d_printf("NETR_DELTA_POLICY not handled\n");
284 case NETR_DELTA_TRUSTED_DOMAIN
:
285 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
287 case NETR_DELTA_ACCOUNT
:
288 d_printf("NETR_DELTA_ACCOUNT not handled\n");
290 case NETR_DELTA_SECRET
:
291 d_printf("NETR_DELTA_SECRET not handled\n");
293 case NETR_DELTA_DELETE_GROUP
:
294 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
296 case NETR_DELTA_DELETE_USER
:
297 d_printf("NETR_DELTA_DELETE_USER not handled\n");
299 case NETR_DELTA_MODIFY_COUNT
:
300 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
302 case NETR_DELTA_DELETE_ALIAS
:
303 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
305 case NETR_DELTA_DELETE_TRUST
:
306 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
308 case NETR_DELTA_DELETE_ACCOUNT
:
309 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
311 case NETR_DELTA_DELETE_SECRET
:
312 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
314 case NETR_DELTA_DELETE_GROUP2
:
315 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
317 case NETR_DELTA_DELETE_USER2
:
318 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
321 printf("unknown delta type 0x%02x\n",
327 static void dump_database(struct rpc_pipe_client
*pipe_hnd
,
328 enum netr_SamDatabaseID database_id
)
333 const char *logon_server
= pipe_hnd
->cli
->desthost
;
334 const char *computername
= global_myname();
335 struct netr_Authenticator credential
;
336 struct netr_Authenticator return_authenticator
;
337 uint16_t restart_state
= 0;
338 uint32_t sync_context
= 0;
339 DATA_BLOB session_key
;
341 ZERO_STRUCT(return_authenticator
);
343 if (!(mem_ctx
= talloc_init("dump_database"))) {
347 switch(database_id
) {
348 case SAM_DATABASE_DOMAIN
:
349 d_printf("Dumping DOMAIN database\n");
351 case SAM_DATABASE_BUILTIN
:
352 d_printf("Dumping BUILTIN database\n");
354 case SAM_DATABASE_PRIVS
:
355 d_printf("Dumping PRIVS databases\n");
358 d_printf("Dumping unknown database type %u\n",
364 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
366 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
368 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
372 &return_authenticator
,
379 /* Check returned credentials. */
380 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
381 &return_authenticator
.cred
)) {
382 DEBUG(0,("credentials chain check failed\n"));
386 if (NT_STATUS_IS_ERR(result
)) {
390 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
392 samsync_fix_delta_array(mem_ctx
,
398 /* Display results */
399 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
400 display_sam_entry(&delta_enum_array
->delta_enum
[i
]);
403 TALLOC_FREE(delta_enum_array
);
405 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
407 talloc_destroy(mem_ctx
);
410 /* dump sam database via samsync rpc calls */
411 NTSTATUS
rpc_samdump_internals(const DOM_SID
*domain_sid
,
412 const char *domain_name
,
413 struct cli_state
*cli
,
414 struct rpc_pipe_client
*pipe_hnd
,
420 /* net_rpc.c now always tries to create an schannel pipe.. */
422 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
423 uchar trust_password
[16];
424 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
425 uint32 sec_channel_type
= 0;
427 if (!secrets_fetch_trust_account_password(domain_name
,
429 NULL
, &sec_channel_type
)) {
430 DEBUG(0,("Could not fetch trust account password\n"));
434 nt_status
= rpccli_netlogon_setup_creds(pipe_hnd
,
442 if (!NT_STATUS_IS_OK(nt_status
)) {
443 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
448 dump_database(pipe_hnd
, SAM_DATABASE_DOMAIN
);
449 dump_database(pipe_hnd
, SAM_DATABASE_BUILTIN
);
450 dump_database(pipe_hnd
, SAM_DATABASE_PRIVS
);
455 /* Convert a struct samu_DELTA to a struct samu. */
456 #define STRING_CHANGED (old_string && !new_string) ||\
457 (!old_string && new_string) ||\
458 (old_string && new_string && (strcmp(old_string, new_string) != 0))
460 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
462 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
464 static NTSTATUS
sam_account_from_delta(struct samu
*account
,
465 struct netr_DELTA_USER
*r
)
467 const char *old_string
, *new_string
;
468 time_t unix_time
, stored_time
;
469 uchar lm_passwd
[16], nt_passwd
[16];
470 static uchar zero_buf
[16];
472 /* Username, fullname, home dir, dir drive, logon script, acct
473 desc, workstations, profile. */
475 if (r
->account_name
.string
) {
476 old_string
= pdb_get_nt_username(account
);
477 new_string
= r
->account_name
.string
;
479 if (STRING_CHANGED
) {
480 pdb_set_nt_username(account
, new_string
, PDB_CHANGED
);
483 /* Unix username is the same - for sanity */
484 old_string
= pdb_get_username( account
);
485 if (STRING_CHANGED
) {
486 pdb_set_username(account
, new_string
, PDB_CHANGED
);
490 if (r
->full_name
.string
) {
491 old_string
= pdb_get_fullname(account
);
492 new_string
= r
->full_name
.string
;
495 pdb_set_fullname(account
, new_string
, PDB_CHANGED
);
498 if (r
->home_directory
.string
) {
499 old_string
= pdb_get_homedir(account
);
500 new_string
= r
->home_directory
.string
;
503 pdb_set_homedir(account
, new_string
, PDB_CHANGED
);
506 if (r
->home_drive
.string
) {
507 old_string
= pdb_get_dir_drive(account
);
508 new_string
= r
->home_drive
.string
;
511 pdb_set_dir_drive(account
, new_string
, PDB_CHANGED
);
514 if (r
->logon_script
.string
) {
515 old_string
= pdb_get_logon_script(account
);
516 new_string
= r
->logon_script
.string
;
519 pdb_set_logon_script(account
, new_string
, PDB_CHANGED
);
522 if (r
->description
.string
) {
523 old_string
= pdb_get_acct_desc(account
);
524 new_string
= r
->description
.string
;
527 pdb_set_acct_desc(account
, new_string
, PDB_CHANGED
);
530 if (r
->workstations
.string
) {
531 old_string
= pdb_get_workstations(account
);
532 new_string
= r
->workstations
.string
;
535 pdb_set_workstations(account
, new_string
, PDB_CHANGED
);
538 if (r
->profile_path
.string
) {
539 old_string
= pdb_get_profile_path(account
);
540 new_string
= r
->profile_path
.string
;
543 pdb_set_profile_path(account
, new_string
, PDB_CHANGED
);
546 if (r
->parameters
.string
) {
549 old_string
= pdb_get_munged_dial(account
);
550 mung
.length
= r
->parameters
.length
;
551 mung
.data
= (uint8
*) r
->parameters
.string
;
552 newstr
= (mung
.length
== 0) ? NULL
:
553 base64_encode_data_blob(talloc_tos(), mung
);
555 if (STRING_CHANGED_NC(old_string
, newstr
))
556 pdb_set_munged_dial(account
, newstr
, PDB_CHANGED
);
560 /* User and group sid */
561 if (pdb_get_user_rid(account
) != r
->rid
)
562 pdb_set_user_sid_from_rid(account
, r
->rid
, PDB_CHANGED
);
563 if (pdb_get_group_rid(account
) != r
->primary_gid
)
564 pdb_set_group_sid_from_rid(account
, r
->primary_gid
, PDB_CHANGED
);
566 /* Logon and password information */
567 if (!nt_time_is_zero(&r
->last_logon
)) {
568 unix_time
= nt_time_to_unix(r
->last_logon
);
569 stored_time
= pdb_get_logon_time(account
);
570 if (stored_time
!= unix_time
)
571 pdb_set_logon_time(account
, unix_time
, PDB_CHANGED
);
574 if (!nt_time_is_zero(&r
->last_logoff
)) {
575 unix_time
= nt_time_to_unix(r
->last_logoff
);
576 stored_time
= pdb_get_logoff_time(account
);
577 if (stored_time
!= unix_time
)
578 pdb_set_logoff_time(account
, unix_time
,PDB_CHANGED
);
582 if (pdb_get_logon_divs(account
) != r
->logon_hours
.units_per_week
)
583 pdb_set_logon_divs(account
, r
->logon_hours
.units_per_week
, PDB_CHANGED
);
586 /* no idea what to do with this one - gd */
587 /* Max Logon Hours */
588 if (delta
->unknown1
!= pdb_get_unknown_6(account
)) {
589 pdb_set_unknown_6(account
, delta
->unknown1
, PDB_CHANGED
);
592 /* Logon Hours Len */
593 if (r
->logon_hours
.units_per_week
/8 != pdb_get_hours_len(account
)) {
594 pdb_set_hours_len(account
, r
->logon_hours
.units_per_week
/8, PDB_CHANGED
);
598 if (r
->logon_hours
.bits
) {
599 char oldstr
[44], newstr
[44];
600 pdb_sethexhours(oldstr
, pdb_get_hours(account
));
601 pdb_sethexhours(newstr
, r
->logon_hours
.bits
);
602 if (!strequal(oldstr
, newstr
))
603 pdb_set_hours(account
, r
->logon_hours
.bits
, PDB_CHANGED
);
606 if (pdb_get_bad_password_count(account
) != r
->bad_password_count
)
607 pdb_set_bad_password_count(account
, r
->bad_password_count
, PDB_CHANGED
);
609 if (pdb_get_logon_count(account
) != r
->logon_count
)
610 pdb_set_logon_count(account
, r
->logon_count
, PDB_CHANGED
);
612 if (!nt_time_is_zero(&r
->last_password_change
)) {
613 unix_time
= nt_time_to_unix(r
->last_password_change
);
614 stored_time
= pdb_get_pass_last_set_time(account
);
615 if (stored_time
!= unix_time
)
616 pdb_set_pass_last_set_time(account
, unix_time
, PDB_CHANGED
);
618 /* no last set time, make it now */
619 pdb_set_pass_last_set_time(account
, time(NULL
), PDB_CHANGED
);
622 if (!nt_time_is_zero(&r
->acct_expiry
)) {
623 unix_time
= nt_time_to_unix(r
->acct_expiry
);
624 stored_time
= pdb_get_kickoff_time(account
);
625 if (stored_time
!= unix_time
)
626 pdb_set_kickoff_time(account
, unix_time
, PDB_CHANGED
);
629 /* Decode hashes from password hash
630 Note that win2000 may send us all zeros for the hashes if it doesn't
631 think this channel is secure enough - don't set the passwords at all
634 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
635 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, lm_passwd
, 0);
636 pdb_set_lanman_passwd(account
, lm_passwd
, PDB_CHANGED
);
639 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
640 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, nt_passwd
, 0);
641 pdb_set_nt_passwd(account
, nt_passwd
, PDB_CHANGED
);
644 /* TODO: account expiry time */
646 pdb_set_acct_ctrl(account
, r
->acct_flags
, PDB_CHANGED
);
648 pdb_set_domain(account
, lp_workgroup(), PDB_CHANGED
);
653 static NTSTATUS
fetch_account_info(uint32_t rid
,
654 struct netr_DELTA_USER
*r
)
657 NTSTATUS nt_ret
= NT_STATUS_UNSUCCESSFUL
;
659 char *add_script
= NULL
;
660 struct samu
*sam_account
=NULL
;
665 struct passwd
*passwd
;
668 fstrcpy(account
, r
->account_name
.string
);
669 d_printf("Creating account: %s\n", account
);
671 if ( !(sam_account
= samu_new( NULL
)) ) {
672 return NT_STATUS_NO_MEMORY
;
675 if (!(passwd
= Get_Pwnam_alloc(sam_account
, account
))) {
676 /* Create appropriate user */
677 if (r
->acct_flags
& ACB_NORMAL
) {
678 add_script
= talloc_strdup(sam_account
,
679 lp_adduser_script());
680 } else if ( (r
->acct_flags
& ACB_WSTRUST
) ||
681 (r
->acct_flags
& ACB_SVRTRUST
) ||
682 (r
->acct_flags
& ACB_DOMTRUST
) ) {
683 add_script
= talloc_strdup(sam_account
,
684 lp_addmachine_script());
686 DEBUG(1, ("Unknown user type: %s\n",
687 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
688 nt_ret
= NT_STATUS_UNSUCCESSFUL
;
692 nt_ret
= NT_STATUS_NO_MEMORY
;
697 add_script
= talloc_all_string_sub(sam_account
,
702 nt_ret
= NT_STATUS_NO_MEMORY
;
705 add_ret
= smbrun(add_script
,NULL
);
706 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
707 "gave %d\n", add_script
, add_ret
));
709 smb_nscd_flush_user_cache();
713 /* try and find the possible unix account again */
714 if ( !(passwd
= Get_Pwnam_alloc(sam_account
, account
)) ) {
715 d_fprintf(stderr
, "Could not create posix account info for '%s'\n", account
);
716 nt_ret
= NT_STATUS_NO_SUCH_USER
;
721 sid_copy(&user_sid
, get_global_sam_sid());
722 sid_append_rid(&user_sid
, r
->rid
);
724 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
725 sid_to_fstring(sid_string
, &user_sid
), account
));
726 if (!pdb_getsampwsid(sam_account
, &user_sid
)) {
727 sam_account_from_delta(sam_account
, r
);
728 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
729 sid_to_fstring(sid_string
, &user_sid
),
730 pdb_get_username(sam_account
)));
731 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account
))) {
732 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
734 return NT_STATUS_ACCESS_DENIED
;
737 sam_account_from_delta(sam_account
, r
);
738 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
739 sid_to_fstring(sid_string
, &user_sid
),
740 pdb_get_username(sam_account
)));
741 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account
))) {
742 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
744 TALLOC_FREE(sam_account
);
745 return NT_STATUS_ACCESS_DENIED
;
749 if (pdb_get_group_sid(sam_account
) == NULL
) {
750 return NT_STATUS_UNSUCCESSFUL
;
753 group_sid
= *pdb_get_group_sid(sam_account
);
755 if (!pdb_getgrsid(&map
, group_sid
)) {
756 DEBUG(0, ("Primary group of %s has no mapping!\n",
757 pdb_get_username(sam_account
)));
759 if (map
.gid
!= passwd
->pw_gid
) {
760 if (!(grp
= getgrgid(map
.gid
))) {
761 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
762 (unsigned long)map
.gid
, pdb_get_username(sam_account
), sid_string_tos(&group_sid
)));
764 smb_set_primary_group(grp
->gr_name
, pdb_get_username(sam_account
));
770 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
771 pdb_get_username(sam_account
)));
775 TALLOC_FREE(sam_account
);
779 static NTSTATUS
fetch_group_info(uint32_t rid
,
780 struct netr_DELTA_GROUP
*r
)
784 struct group
*grp
= NULL
;
790 fstrcpy(name
, r
->group_name
.string
);
791 fstrcpy(comment
, r
->description
.string
);
793 /* add the group to the mapping table */
794 sid_copy(&group_sid
, get_global_sam_sid());
795 sid_append_rid(&group_sid
, rid
);
796 sid_to_fstring(sid_string
, &group_sid
);
798 if (pdb_getgrsid(&map
, group_sid
)) {
800 grp
= getgrgid(map
.gid
);
807 /* No group found from mapping, find it from its name. */
808 if ((grp
= getgrnam(name
)) == NULL
) {
810 /* No appropriate group found, create one */
812 d_printf("Creating unix group: '%s'\n", name
);
814 if (smb_create_group(name
, &gid
) != 0)
815 return NT_STATUS_ACCESS_DENIED
;
817 if ((grp
= getgrnam(name
)) == NULL
)
818 return NT_STATUS_ACCESS_DENIED
;
822 map
.gid
= grp
->gr_gid
;
824 map
.sid_name_use
= SID_NAME_DOM_GRP
;
825 fstrcpy(map
.nt_name
, name
);
826 if (r
->description
.string
) {
827 fstrcpy(map
.comment
, comment
);
829 fstrcpy(map
.comment
, "");
833 pdb_add_group_mapping_entry(&map
);
835 pdb_update_group_mapping_entry(&map
);
840 static NTSTATUS
fetch_group_mem_info(uint32_t rid
,
841 struct netr_DELTA_GROUP_MEMBER
*r
)
844 TALLOC_CTX
*t
= NULL
;
845 char **nt_members
= NULL
;
851 if (r
->num_rids
== 0) {
855 sid_copy(&group_sid
, get_global_sam_sid());
856 sid_append_rid(&group_sid
, rid
);
858 if (!get_domain_group_from_sid(group_sid
, &map
)) {
859 DEBUG(0, ("Could not find global group %d\n", rid
));
860 return NT_STATUS_NO_SUCH_GROUP
;
863 if (!(grp
= getgrgid(map
.gid
))) {
864 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map
.gid
));
865 return NT_STATUS_NO_SUCH_GROUP
;
868 d_printf("Group members of %s: ", grp
->gr_name
);
870 if (!(t
= talloc_init("fetch_group_mem_info"))) {
871 DEBUG(0, ("could not talloc_init\n"));
872 return NT_STATUS_NO_MEMORY
;
876 if ((nt_members
= TALLOC_ZERO_ARRAY(t
, char *, r
->num_rids
)) == NULL
) {
877 DEBUG(0, ("talloc failed\n"));
879 return NT_STATUS_NO_MEMORY
;
885 for (i
=0; i
< r
->num_rids
; i
++) {
886 struct samu
*member
= NULL
;
889 if ( !(member
= samu_new(t
)) ) {
891 return NT_STATUS_NO_MEMORY
;
894 sid_copy(&member_sid
, get_global_sam_sid());
895 sid_append_rid(&member_sid
, r
->rids
[i
]);
897 if (!pdb_getsampwsid(member
, &member_sid
)) {
898 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
899 r
->rids
[i
], sid_string_tos(&member_sid
), grp
->gr_name
));
904 if (pdb_get_group_rid(member
) == rid
) {
905 d_printf("%s(primary),", pdb_get_username(member
));
910 d_printf("%s,", pdb_get_username(member
));
911 nt_members
[i
] = talloc_strdup(t
, pdb_get_username(member
));
917 unix_members
= grp
->gr_mem
;
919 while (*unix_members
) {
920 bool is_nt_member
= False
;
921 for (i
=0; i
< r
->num_rids
; i
++) {
922 if (nt_members
[i
] == NULL
) {
923 /* This was a primary group */
927 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
933 /* We look at a unix group member that is not
934 an nt group member. So, remove it. NT is
936 smb_delete_user_group(grp
->gr_name
, *unix_members
);
941 for (i
=0; i
< r
->num_rids
; i
++) {
942 bool is_unix_member
= False
;
944 if (nt_members
[i
] == NULL
) {
945 /* This was the primary group */
949 unix_members
= grp
->gr_mem
;
951 while (*unix_members
) {
952 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
953 is_unix_member
= True
;
959 if (!is_unix_member
) {
960 /* We look at a nt group member that is not a
961 unix group member currently. So, add the nt
963 smb_add_user_group(grp
->gr_name
, nt_members
[i
]);
971 static NTSTATUS
fetch_alias_info(uint32_t rid
,
972 struct netr_DELTA_ALIAS
*r
,
977 struct group
*grp
= NULL
;
983 fstrcpy(name
, r
->alias_name
.string
);
984 fstrcpy(comment
, r
->description
.string
);
986 /* Find out whether the group is already mapped */
987 sid_copy(&alias_sid
, &dom_sid
);
988 sid_append_rid(&alias_sid
, rid
);
989 sid_to_fstring(sid_string
, &alias_sid
);
991 if (pdb_getgrsid(&map
, alias_sid
)) {
992 grp
= getgrgid(map
.gid
);
999 /* No group found from mapping, find it from its name. */
1000 if ((grp
= getgrnam(name
)) == NULL
) {
1001 /* No appropriate group found, create one */
1002 d_printf("Creating unix group: '%s'\n", name
);
1003 if (smb_create_group(name
, &gid
) != 0)
1004 return NT_STATUS_ACCESS_DENIED
;
1005 if ((grp
= getgrgid(gid
)) == NULL
)
1006 return NT_STATUS_ACCESS_DENIED
;
1010 map
.gid
= grp
->gr_gid
;
1011 map
.sid
= alias_sid
;
1013 if (sid_equal(&dom_sid
, &global_sid_Builtin
))
1014 map
.sid_name_use
= SID_NAME_WKN_GRP
;
1016 map
.sid_name_use
= SID_NAME_ALIAS
;
1018 fstrcpy(map
.nt_name
, name
);
1019 fstrcpy(map
.comment
, comment
);
1022 pdb_add_group_mapping_entry(&map
);
1024 pdb_update_group_mapping_entry(&map
);
1026 return NT_STATUS_OK
;
1029 static NTSTATUS
fetch_alias_mem(uint32_t rid
,
1030 struct netr_DELTA_ALIAS_MEMBER
*r
,
1033 return NT_STATUS_OK
;
1036 static NTSTATUS
fetch_domain_info(uint32_t rid
,
1037 struct netr_DELTA_DOMAIN
*r
)
1039 time_t u_max_age
, u_min_age
, u_logout
;
1040 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1041 const char *domname
;
1042 struct netr_AcctLockStr
*lockstr
= NULL
;
1044 TALLOC_CTX
*mem_ctx
= talloc_tos();
1046 status
= pull_netr_AcctLockStr(mem_ctx
, &r
->account_lockout
,
1048 if (!NT_STATUS_IS_OK(status
)) {
1049 d_printf("failed to pull account lockout string: %s\n",
1053 u_max_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->max_password_age
);
1054 u_min_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->min_password_age
);
1055 u_logout
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->force_logoff_time
);
1057 domname
= r
->domain_name
.string
;
1059 return NT_STATUS_NO_MEMORY
;
1062 /* we don't handle BUILTIN account policies */
1063 if (!strequal(domname
, get_global_sam_name())) {
1064 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname
);
1065 return NT_STATUS_OK
;
1069 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY
,
1070 r
->password_history_length
))
1073 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN
,
1074 r
->min_password_length
))
1077 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (uint32
)u_max_age
))
1080 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (uint32
)u_min_age
))
1083 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (uint32
)u_logout
))
1087 time_t u_lockoutreset
, u_lockouttime
;
1089 u_lockoutreset
= uint64s_nt_time_to_unix_abs(&lockstr
->reset_count
);
1090 u_lockouttime
= uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr
->lockout_duration
);
1092 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
1093 lockstr
->bad_attempt_lockout
))
1096 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME
, (uint32_t)u_lockoutreset
/60))
1099 if (u_lockouttime
!= -1)
1100 u_lockouttime
/= 60;
1102 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (uint32_t)u_lockouttime
))
1106 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
1107 r
->logon_to_chgpass
))
1110 return NT_STATUS_OK
;
1113 static void fetch_sam_entry(struct netr_DELTA_ENUM
*r
, DOM_SID dom_sid
)
1115 switch(r
->delta_type
) {
1116 case NETR_DELTA_USER
:
1117 fetch_account_info(r
->delta_id_union
.rid
,
1118 r
->delta_union
.user
);
1120 case NETR_DELTA_GROUP
:
1121 fetch_group_info(r
->delta_id_union
.rid
,
1122 r
->delta_union
.group
);
1124 case NETR_DELTA_GROUP_MEMBER
:
1125 fetch_group_mem_info(r
->delta_id_union
.rid
,
1126 r
->delta_union
.group_member
);
1128 case NETR_DELTA_ALIAS
:
1129 fetch_alias_info(r
->delta_id_union
.rid
,
1130 r
->delta_union
.alias
,
1133 case NETR_DELTA_ALIAS_MEMBER
:
1134 fetch_alias_mem(r
->delta_id_union
.rid
,
1135 r
->delta_union
.alias_member
,
1138 case NETR_DELTA_DOMAIN
:
1139 fetch_domain_info(r
->delta_id_union
.rid
,
1140 r
->delta_union
.domain
);
1142 /* The following types are recognised but not handled */
1143 case NETR_DELTA_RENAME_GROUP
:
1144 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1146 case NETR_DELTA_RENAME_USER
:
1147 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1149 case NETR_DELTA_RENAME_ALIAS
:
1150 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1152 case NETR_DELTA_POLICY
:
1153 d_printf("NETR_DELTA_POLICY not handled\n");
1155 case NETR_DELTA_TRUSTED_DOMAIN
:
1156 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1158 case NETR_DELTA_ACCOUNT
:
1159 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1161 case NETR_DELTA_SECRET
:
1162 d_printf("NETR_DELTA_SECRET not handled\n");
1164 case NETR_DELTA_DELETE_GROUP
:
1165 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1167 case NETR_DELTA_DELETE_USER
:
1168 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1170 case NETR_DELTA_MODIFY_COUNT
:
1171 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1173 case NETR_DELTA_DELETE_ALIAS
:
1174 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1176 case NETR_DELTA_DELETE_TRUST
:
1177 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1179 case NETR_DELTA_DELETE_ACCOUNT
:
1180 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1182 case NETR_DELTA_DELETE_SECRET
:
1183 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1185 case NETR_DELTA_DELETE_GROUP2
:
1186 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1188 case NETR_DELTA_DELETE_USER2
:
1189 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1192 d_printf("Unknown delta record type %d\n", r
->delta_type
);
1197 static NTSTATUS
fetch_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
, DOM_SID dom_sid
)
1201 TALLOC_CTX
*mem_ctx
;
1202 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1203 const char *computername
= global_myname();
1204 struct netr_Authenticator credential
;
1205 struct netr_Authenticator return_authenticator
;
1206 enum netr_SamDatabaseID database_id
= db_type
;
1207 uint16_t restart_state
= 0;
1208 uint32_t sync_context
= 0;
1209 DATA_BLOB session_key
;
1211 if (!(mem_ctx
= talloc_init("fetch_database")))
1212 return NT_STATUS_NO_MEMORY
;
1215 case SAM_DATABASE_DOMAIN
:
1216 d_printf("Fetching DOMAIN database\n");
1218 case SAM_DATABASE_BUILTIN
:
1219 d_printf("Fetching BUILTIN database\n");
1221 case SAM_DATABASE_PRIVS
:
1222 d_printf("Fetching PRIVS databases\n");
1225 d_printf("Fetching unknown database type %u\n", db_type
);
1230 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1232 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
1234 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
1238 &return_authenticator
,
1245 /* Check returned credentials. */
1246 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
1247 &return_authenticator
.cred
)) {
1248 DEBUG(0,("credentials chain check failed\n"));
1249 return NT_STATUS_ACCESS_DENIED
;
1252 if (NT_STATUS_IS_ERR(result
)) {
1256 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
1258 samsync_fix_delta_array(mem_ctx
,
1264 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
1265 fetch_sam_entry(&delta_enum_array
->delta_enum
[i
], dom_sid
);
1268 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1270 talloc_destroy(mem_ctx
);
1275 static NTSTATUS
populate_ldap_for_ldif(fstring sid
, const char *suffix
, const char
1276 *builtin_sid
, FILE *add_fd
)
1278 const char *user_suffix
, *group_suffix
, *machine_suffix
, *idmap_suffix
;
1279 char *user_attr
=NULL
, *group_attr
=NULL
;
1283 /* Get the suffix attribute */
1284 suffix_attr
= sstring_sub(suffix
, '=', ',');
1285 if (suffix_attr
== NULL
) {
1286 len
= strlen(suffix
);
1287 suffix_attr
= (char*)SMB_MALLOC(len
+1);
1288 memcpy(suffix_attr
, suffix
, len
);
1289 suffix_attr
[len
] = '\0';
1292 /* Write the base */
1293 fprintf(add_fd
, "# %s\n", suffix
);
1294 fprintf(add_fd
, "dn: %s\n", suffix
);
1295 fprintf(add_fd
, "objectClass: dcObject\n");
1296 fprintf(add_fd
, "objectClass: organization\n");
1297 fprintf(add_fd
, "o: %s\n", suffix_attr
);
1298 fprintf(add_fd
, "dc: %s\n", suffix_attr
);
1299 fprintf(add_fd
, "\n");
1302 user_suffix
= lp_ldap_user_suffix();
1303 if (user_suffix
== NULL
) {
1304 SAFE_FREE(suffix_attr
);
1305 return NT_STATUS_NO_MEMORY
;
1307 /* If it exists and is distinct from other containers,
1308 Write the Users entity */
1309 if (*user_suffix
&& strcmp(user_suffix
, suffix
)) {
1310 user_attr
= sstring_sub(lp_ldap_user_suffix(), '=', ',');
1311 fprintf(add_fd
, "# %s\n", user_suffix
);
1312 fprintf(add_fd
, "dn: %s\n", user_suffix
);
1313 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1314 fprintf(add_fd
, "ou: %s\n", user_attr
);
1315 fprintf(add_fd
, "\n");
1320 group_suffix
= lp_ldap_group_suffix();
1321 if (group_suffix
== NULL
) {
1322 SAFE_FREE(suffix_attr
);
1323 SAFE_FREE(user_attr
);
1324 return NT_STATUS_NO_MEMORY
;
1326 /* If it exists and is distinct from other containers,
1327 Write the Groups entity */
1328 if (*group_suffix
&& strcmp(group_suffix
, suffix
)) {
1329 group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1330 fprintf(add_fd
, "# %s\n", group_suffix
);
1331 fprintf(add_fd
, "dn: %s\n", group_suffix
);
1332 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1333 fprintf(add_fd
, "ou: %s\n", group_attr
);
1334 fprintf(add_fd
, "\n");
1338 /* If it exists and is distinct from other containers,
1339 Write the Computers entity */
1340 machine_suffix
= lp_ldap_machine_suffix();
1341 if (machine_suffix
== NULL
) {
1342 SAFE_FREE(suffix_attr
);
1343 SAFE_FREE(user_attr
);
1344 SAFE_FREE(group_attr
);
1345 return NT_STATUS_NO_MEMORY
;
1347 if (*machine_suffix
&& strcmp(machine_suffix
, user_suffix
) &&
1348 strcmp(machine_suffix
, suffix
)) {
1349 char *machine_ou
= NULL
;
1350 fprintf(add_fd
, "# %s\n", machine_suffix
);
1351 fprintf(add_fd
, "dn: %s\n", machine_suffix
);
1352 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1353 /* this isn't totally correct as it assumes that
1354 there _must_ be an ou. just fixing memleak now. jmcd */
1355 machine_ou
= sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1356 fprintf(add_fd
, "ou: %s\n", machine_ou
);
1357 SAFE_FREE(machine_ou
);
1358 fprintf(add_fd
, "\n");
1362 /* If it exists and is distinct from other containers,
1363 Write the IdMap entity */
1364 idmap_suffix
= lp_ldap_idmap_suffix();
1365 if (idmap_suffix
== NULL
) {
1366 SAFE_FREE(suffix_attr
);
1367 SAFE_FREE(user_attr
);
1368 SAFE_FREE(group_attr
);
1369 return NT_STATUS_NO_MEMORY
;
1371 if (*idmap_suffix
&&
1372 strcmp(idmap_suffix
, user_suffix
) &&
1373 strcmp(idmap_suffix
, suffix
)) {
1375 fprintf(add_fd
, "# %s\n", idmap_suffix
);
1376 fprintf(add_fd
, "dn: %s\n", idmap_suffix
);
1377 fprintf(add_fd
, "ObjectClass: organizationalUnit\n");
1378 s
= sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1379 fprintf(add_fd
, "ou: %s\n", s
);
1381 fprintf(add_fd
, "\n");
1385 /* Write the domain entity */
1386 fprintf(add_fd
, "# %s, %s\n", lp_workgroup(), suffix
);
1387 fprintf(add_fd
, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1389 fprintf(add_fd
, "objectClass: sambaDomain\n");
1390 fprintf(add_fd
, "objectClass: sambaUnixIdPool\n");
1391 fprintf(add_fd
, "sambaDomainName: %s\n", lp_workgroup());
1392 fprintf(add_fd
, "sambaSID: %s\n", sid
);
1393 fprintf(add_fd
, "uidNumber: %d\n", ++ldif_uid
);
1394 fprintf(add_fd
, "gidNumber: %d\n", ++ldif_gid
);
1395 fprintf(add_fd
, "\n");
1398 /* Write the Domain Admins entity */
1399 fprintf(add_fd
, "# Domain Admins, %s, %s\n", group_attr
,
1401 fprintf(add_fd
, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr
,
1403 fprintf(add_fd
, "objectClass: posixGroup\n");
1404 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1405 fprintf(add_fd
, "cn: Domain Admins\n");
1406 fprintf(add_fd
, "memberUid: Administrator\n");
1407 fprintf(add_fd
, "description: Netbios Domain Administrators\n");
1408 fprintf(add_fd
, "gidNumber: 512\n");
1409 fprintf(add_fd
, "sambaSID: %s-512\n", sid
);
1410 fprintf(add_fd
, "sambaGroupType: 2\n");
1411 fprintf(add_fd
, "displayName: Domain Admins\n");
1412 fprintf(add_fd
, "\n");
1415 /* Write the Domain Users entity */
1416 fprintf(add_fd
, "# Domain Users, %s, %s\n", group_attr
,
1418 fprintf(add_fd
, "dn: cn=Domain Users,ou=%s,%s\n", group_attr
,
1420 fprintf(add_fd
, "objectClass: posixGroup\n");
1421 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1422 fprintf(add_fd
, "cn: Domain Users\n");
1423 fprintf(add_fd
, "description: Netbios Domain Users\n");
1424 fprintf(add_fd
, "gidNumber: 513\n");
1425 fprintf(add_fd
, "sambaSID: %s-513\n", sid
);
1426 fprintf(add_fd
, "sambaGroupType: 2\n");
1427 fprintf(add_fd
, "displayName: Domain Users\n");
1428 fprintf(add_fd
, "\n");
1431 /* Write the Domain Guests entity */
1432 fprintf(add_fd
, "# Domain Guests, %s, %s\n", group_attr
,
1434 fprintf(add_fd
, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr
,
1436 fprintf(add_fd
, "objectClass: posixGroup\n");
1437 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1438 fprintf(add_fd
, "cn: Domain Guests\n");
1439 fprintf(add_fd
, "description: Netbios Domain Guests\n");
1440 fprintf(add_fd
, "gidNumber: 514\n");
1441 fprintf(add_fd
, "sambaSID: %s-514\n", sid
);
1442 fprintf(add_fd
, "sambaGroupType: 2\n");
1443 fprintf(add_fd
, "displayName: Domain Guests\n");
1444 fprintf(add_fd
, "\n");
1447 /* Write the Domain Computers entity */
1448 fprintf(add_fd
, "# Domain Computers, %s, %s\n", group_attr
,
1450 fprintf(add_fd
, "dn: cn=Domain Computers,ou=%s,%s\n",
1451 group_attr
, suffix
);
1452 fprintf(add_fd
, "objectClass: posixGroup\n");
1453 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1454 fprintf(add_fd
, "gidNumber: 515\n");
1455 fprintf(add_fd
, "cn: Domain Computers\n");
1456 fprintf(add_fd
, "description: Netbios Domain Computers accounts\n");
1457 fprintf(add_fd
, "sambaSID: %s-515\n", sid
);
1458 fprintf(add_fd
, "sambaGroupType: 2\n");
1459 fprintf(add_fd
, "displayName: Domain Computers\n");
1460 fprintf(add_fd
, "\n");
1463 /* Write the Admininistrators Groups entity */
1464 fprintf(add_fd
, "# Administrators, %s, %s\n", group_attr
,
1466 fprintf(add_fd
, "dn: cn=Administrators,ou=%s,%s\n", group_attr
,
1468 fprintf(add_fd
, "objectClass: posixGroup\n");
1469 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1470 fprintf(add_fd
, "gidNumber: 544\n");
1471 fprintf(add_fd
, "cn: Administrators\n");
1472 fprintf(add_fd
, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1473 fprintf(add_fd
, "sambaSID: %s-544\n", builtin_sid
);
1474 fprintf(add_fd
, "sambaGroupType: 5\n");
1475 fprintf(add_fd
, "displayName: Administrators\n");
1476 fprintf(add_fd
, "\n");
1478 /* Write the Print Operator entity */
1479 fprintf(add_fd
, "# Print Operators, %s, %s\n", group_attr
,
1481 fprintf(add_fd
, "dn: cn=Print Operators,ou=%s,%s\n",
1482 group_attr
, suffix
);
1483 fprintf(add_fd
, "objectClass: posixGroup\n");
1484 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1485 fprintf(add_fd
, "gidNumber: 550\n");
1486 fprintf(add_fd
, "cn: Print Operators\n");
1487 fprintf(add_fd
, "description: Netbios Domain Print Operators\n");
1488 fprintf(add_fd
, "sambaSID: %s-550\n", builtin_sid
);
1489 fprintf(add_fd
, "sambaGroupType: 5\n");
1490 fprintf(add_fd
, "displayName: Print Operators\n");
1491 fprintf(add_fd
, "\n");
1494 /* Write the Backup Operators entity */
1495 fprintf(add_fd
, "# Backup Operators, %s, %s\n", group_attr
,
1497 fprintf(add_fd
, "dn: cn=Backup Operators,ou=%s,%s\n",
1498 group_attr
, suffix
);
1499 fprintf(add_fd
, "objectClass: posixGroup\n");
1500 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1501 fprintf(add_fd
, "gidNumber: 551\n");
1502 fprintf(add_fd
, "cn: Backup Operators\n");
1503 fprintf(add_fd
, "description: Netbios Domain Members can bypass file security to back up files\n");
1504 fprintf(add_fd
, "sambaSID: %s-551\n", builtin_sid
);
1505 fprintf(add_fd
, "sambaGroupType: 5\n");
1506 fprintf(add_fd
, "displayName: Backup Operators\n");
1507 fprintf(add_fd
, "\n");
1510 /* Write the Replicators entity */
1511 fprintf(add_fd
, "# Replicators, %s, %s\n", group_attr
, suffix
);
1512 fprintf(add_fd
, "dn: cn=Replicators,ou=%s,%s\n", group_attr
,
1514 fprintf(add_fd
, "objectClass: posixGroup\n");
1515 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1516 fprintf(add_fd
, "gidNumber: 552\n");
1517 fprintf(add_fd
, "cn: Replicators\n");
1518 fprintf(add_fd
, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1519 fprintf(add_fd
, "sambaSID: %s-552\n", builtin_sid
);
1520 fprintf(add_fd
, "sambaGroupType: 5\n");
1521 fprintf(add_fd
, "displayName: Replicators\n");
1522 fprintf(add_fd
, "\n");
1525 /* Deallocate memory, and return */
1526 SAFE_FREE(suffix_attr
);
1527 SAFE_FREE(user_attr
);
1528 SAFE_FREE(group_attr
);
1529 return NT_STATUS_OK
;
1532 static NTSTATUS
map_populate_groups(GROUPMAP
*groupmap
, ACCOUNTMAP
*accountmap
, fstring sid
,
1533 const char *suffix
, const char *builtin_sid
)
1535 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1537 /* Map the groups created by populate_ldap_for_ldif */
1538 groupmap
[0].rid
= 512;
1539 groupmap
[0].gidNumber
= 512;
1540 snprintf(groupmap
[0].sambaSID
, sizeof(groupmap
[0].sambaSID
),
1542 snprintf(groupmap
[0].group_dn
, sizeof(groupmap
[0].group_dn
),
1543 "cn=Domain Admins,ou=%s,%s",
1544 group_attr
, suffix
);
1545 accountmap
[0].rid
= 512;
1546 snprintf(accountmap
[0].cn
, sizeof(accountmap
[0].cn
),
1547 "%s", "Domain Admins");
1549 groupmap
[1].rid
= 513;
1550 groupmap
[1].gidNumber
= 513;
1551 snprintf(groupmap
[1].sambaSID
, sizeof(groupmap
[1].sambaSID
),
1553 snprintf(groupmap
[1].group_dn
, sizeof(groupmap
[1].group_dn
),
1554 "cn=Domain Users,ou=%s,%s",
1555 group_attr
, suffix
);
1556 accountmap
[1].rid
= 513;
1557 snprintf(accountmap
[1].cn
, sizeof(accountmap
[1].cn
),
1558 "%s", "Domain Users");
1560 groupmap
[2].rid
= 514;
1561 groupmap
[2].gidNumber
= 514;
1562 snprintf(groupmap
[2].sambaSID
, sizeof(groupmap
[2].sambaSID
),
1564 snprintf(groupmap
[2].group_dn
, sizeof(groupmap
[2].group_dn
),
1565 "cn=Domain Guests,ou=%s,%s",
1566 group_attr
, suffix
);
1567 accountmap
[2].rid
= 514;
1568 snprintf(accountmap
[2].cn
, sizeof(accountmap
[2].cn
),
1569 "%s", "Domain Guests");
1571 groupmap
[3].rid
= 515;
1572 groupmap
[3].gidNumber
= 515;
1573 snprintf(groupmap
[3].sambaSID
, sizeof(groupmap
[3].sambaSID
),
1575 snprintf(groupmap
[3].group_dn
, sizeof(groupmap
[3].group_dn
),
1576 "cn=Domain Computers,ou=%s,%s",
1577 group_attr
, suffix
);
1578 accountmap
[3].rid
= 515;
1579 snprintf(accountmap
[3].cn
, sizeof(accountmap
[3].cn
),
1580 "%s", "Domain Computers");
1582 groupmap
[4].rid
= 544;
1583 groupmap
[4].gidNumber
= 544;
1584 snprintf(groupmap
[4].sambaSID
, sizeof(groupmap
[4].sambaSID
),
1585 "%s-544", builtin_sid
);
1586 snprintf(groupmap
[4].group_dn
, sizeof(groupmap
[4].group_dn
),
1587 "cn=Administrators,ou=%s,%s",
1588 group_attr
, suffix
);
1589 accountmap
[4].rid
= 515;
1590 snprintf(accountmap
[4].cn
, sizeof(accountmap
[4].cn
),
1591 "%s", "Administrators");
1593 groupmap
[5].rid
= 550;
1594 groupmap
[5].gidNumber
= 550;
1595 snprintf(groupmap
[5].sambaSID
, sizeof(groupmap
[5].sambaSID
),
1596 "%s-550", builtin_sid
);
1597 snprintf(groupmap
[5].group_dn
, sizeof(groupmap
[5].group_dn
),
1598 "cn=Print Operators,ou=%s,%s",
1599 group_attr
, suffix
);
1600 accountmap
[5].rid
= 550;
1601 snprintf(accountmap
[5].cn
, sizeof(accountmap
[5].cn
),
1602 "%s", "Print Operators");
1604 groupmap
[6].rid
= 551;
1605 groupmap
[6].gidNumber
= 551;
1606 snprintf(groupmap
[6].sambaSID
, sizeof(groupmap
[6].sambaSID
),
1607 "%s-551", builtin_sid
);
1608 snprintf(groupmap
[6].group_dn
, sizeof(groupmap
[6].group_dn
),
1609 "cn=Backup Operators,ou=%s,%s",
1610 group_attr
, suffix
);
1611 accountmap
[6].rid
= 551;
1612 snprintf(accountmap
[6].cn
, sizeof(accountmap
[6].cn
),
1613 "%s", "Backup Operators");
1615 groupmap
[7].rid
= 552;
1616 groupmap
[7].gidNumber
= 552;
1617 snprintf(groupmap
[7].sambaSID
, sizeof(groupmap
[7].sambaSID
),
1618 "%s-552", builtin_sid
);
1619 snprintf(groupmap
[7].group_dn
, sizeof(groupmap
[7].group_dn
),
1620 "cn=Replicators,ou=%s,%s",
1621 group_attr
, suffix
);
1622 accountmap
[7].rid
= 551;
1623 snprintf(accountmap
[7].cn
, sizeof(accountmap
[7].cn
),
1624 "%s", "Replicators");
1625 SAFE_FREE(group_attr
);
1626 return NT_STATUS_OK
;
1630 * This is a crap routine, but I think it's the quickest way to solve the
1631 * UTF8->base64 problem.
1634 static int fprintf_attr(FILE *add_fd
, const char *attr_name
,
1635 const char *fmt
, ...)
1638 char *value
, *p
, *base64
;
1639 DATA_BLOB base64_blob
;
1640 bool do_base64
= False
;
1644 value
= talloc_vasprintf(NULL
, fmt
, ap
);
1647 SMB_ASSERT(value
!= NULL
);
1649 for (p
=value
; *p
; p
++) {
1657 bool only_whitespace
= True
;
1658 for (p
=value
; *p
; p
++) {
1660 * I know that this not multibyte safe, but we break
1661 * on the first non-whitespace character anyway.
1664 only_whitespace
= False
;
1668 if (only_whitespace
) {
1674 res
= fprintf(add_fd
, "%s: %s\n", attr_name
, value
);
1679 base64_blob
.data
= (unsigned char *)value
;
1680 base64_blob
.length
= strlen(value
);
1682 base64
= base64_encode_data_blob(value
, base64_blob
);
1683 SMB_ASSERT(base64
!= NULL
);
1685 res
= fprintf(add_fd
, "%s:: %s\n", attr_name
, base64
);
1690 static NTSTATUS
fetch_group_info_to_ldif(struct netr_DELTA_GROUP
*r
, GROUPMAP
*groupmap
,
1691 FILE *add_fd
, fstring sid
, char *suffix
)
1694 uint32 grouptype
= 0, g_rid
= 0;
1695 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1697 /* Get the group name */
1698 fstrcpy(groupname
, r
->group_name
.string
);
1700 /* Set up the group type (always 2 for group info) */
1703 /* These groups are entered by populate_ldap_for_ldif */
1704 if (strcmp(groupname
, "Domain Admins") == 0 ||
1705 strcmp(groupname
, "Domain Users") == 0 ||
1706 strcmp(groupname
, "Domain Guests") == 0 ||
1707 strcmp(groupname
, "Domain Computers") == 0 ||
1708 strcmp(groupname
, "Administrators") == 0 ||
1709 strcmp(groupname
, "Print Operators") == 0 ||
1710 strcmp(groupname
, "Backup Operators") == 0 ||
1711 strcmp(groupname
, "Replicators") == 0) {
1712 SAFE_FREE(group_attr
);
1713 return NT_STATUS_OK
;
1715 /* Increment the gid for the new group */
1719 /* Map the group rid, gid, and dn */
1721 groupmap
->rid
= g_rid
;
1722 groupmap
->gidNumber
= ldif_gid
;
1723 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1724 "%s-%d", sid
, g_rid
);
1725 snprintf(groupmap
->group_dn
, sizeof(groupmap
->group_dn
),
1726 "cn=%s,ou=%s,%s", groupname
, group_attr
, suffix
);
1728 /* Write the data to the temporary add ldif file */
1729 fprintf(add_fd
, "# %s, %s, %s\n", groupname
, group_attr
,
1731 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", groupname
, group_attr
,
1733 fprintf(add_fd
, "objectClass: posixGroup\n");
1734 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1735 fprintf_attr(add_fd
, "cn", "%s", groupname
);
1736 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1737 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1738 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1739 fprintf_attr(add_fd
, "displayName", "%s", groupname
);
1740 fprintf(add_fd
, "\n");
1743 SAFE_FREE(group_attr
);
1745 return NT_STATUS_OK
;
1748 static NTSTATUS
fetch_account_info_to_ldif(struct netr_DELTA_USER
*r
,
1750 ACCOUNTMAP
*accountmap
,
1752 fstring sid
, char *suffix
,
1755 fstring username
, logonscript
, homedrive
, homepath
= "", homedir
= "";
1756 fstring hex_nt_passwd
, hex_lm_passwd
;
1757 fstring description
, profilepath
, fullname
, sambaSID
;
1758 uchar lm_passwd
[16], nt_passwd
[16];
1759 char *flags
, *user_rdn
;
1761 const char* nopasswd
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1762 static uchar zero_buf
[16];
1763 uint32 rid
= 0, group_rid
= 0, gidNumber
= 0;
1767 /* Get the username */
1768 fstrcpy(username
, r
->account_name
.string
);
1773 /* Map the rid and username for group member info later */
1774 accountmap
->rid
= rid
;
1775 snprintf(accountmap
->cn
, sizeof(accountmap
->cn
), "%s", username
);
1777 /* Get the home directory */
1778 if (r
->acct_flags
& ACB_NORMAL
) {
1779 fstrcpy(homedir
, r
->home_directory
.string
);
1781 snprintf(homedir
, sizeof(homedir
), "/home/%s", username
);
1783 snprintf(homedir
, sizeof(homedir
), "/nobodyshomedir");
1785 ou
= lp_ldap_user_suffix();
1787 ou
= lp_ldap_machine_suffix();
1788 snprintf(homedir
, sizeof(homedir
), "/machinehomedir");
1791 /* Get the logon script */
1792 fstrcpy(logonscript
, r
->logon_script
.string
);
1794 /* Get the home drive */
1795 fstrcpy(homedrive
, r
->home_drive
.string
);
1797 /* Get the home path */
1798 fstrcpy(homepath
, r
->home_directory
.string
);
1800 /* Get the description */
1801 fstrcpy(description
, r
->description
.string
);
1803 /* Get the display name */
1804 fstrcpy(fullname
, r
->full_name
.string
);
1806 /* Get the profile path */
1807 fstrcpy(profilepath
, r
->profile_path
.string
);
1809 /* Get lm and nt password data */
1810 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
1811 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
1812 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
1814 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
1816 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
1817 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
1818 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
1820 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
1822 unix_time
= nt_time_to_unix(r
->last_password_change
);
1824 /* Increment the uid for the new user */
1827 /* Set up group id and sambaSID for the user */
1828 group_rid
= r
->primary_gid
;
1829 for (i
=0; i
<alloced
; i
++) {
1830 if (groupmap
[i
].rid
== group_rid
) break;
1833 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1835 return NT_STATUS_UNSUCCESSFUL
;
1837 gidNumber
= groupmap
[i
].gidNumber
;
1838 snprintf(sambaSID
, sizeof(sambaSID
), groupmap
[i
].sambaSID
);
1840 /* Set up sambaAcctFlags */
1841 flags
= pdb_encode_acct_ctrl(r
->acct_flags
,
1842 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1844 /* Add the user to the temporary add ldif file */
1845 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1846 user_rdn
= sstring_sub(ou
, '=', ',');
1847 fprintf(add_fd
, "# %s, %s, %s\n", username
, user_rdn
, suffix
);
1848 fprintf_attr(add_fd
, "dn", "uid=%s,ou=%s,%s", username
, user_rdn
,
1850 SAFE_FREE(user_rdn
);
1851 fprintf(add_fd
, "ObjectClass: top\n");
1852 fprintf(add_fd
, "objectClass: inetOrgPerson\n");
1853 fprintf(add_fd
, "objectClass: posixAccount\n");
1854 fprintf(add_fd
, "objectClass: shadowAccount\n");
1855 fprintf(add_fd
, "objectClass: sambaSamAccount\n");
1856 fprintf_attr(add_fd
, "cn", "%s", username
);
1857 fprintf_attr(add_fd
, "sn", "%s", username
);
1858 fprintf_attr(add_fd
, "uid", "%s", username
);
1859 fprintf(add_fd
, "uidNumber: %d\n", ldif_uid
);
1860 fprintf(add_fd
, "gidNumber: %d\n", gidNumber
);
1861 fprintf_attr(add_fd
, "homeDirectory", "%s", homedir
);
1863 fprintf_attr(add_fd
, "sambaHomePath", "%s", homepath
);
1865 fprintf_attr(add_fd
, "sambaHomeDrive", "%s", homedrive
);
1867 fprintf_attr(add_fd
, "sambaLogonScript", "%s", logonscript
);
1868 fprintf(add_fd
, "loginShell: %s\n",
1869 ((r
->acct_flags
& ACB_NORMAL
) ?
1870 "/bin/bash" : "/bin/false"));
1871 fprintf(add_fd
, "gecos: System User\n");
1873 fprintf_attr(add_fd
, "description", "%s", description
);
1874 fprintf(add_fd
, "sambaSID: %s-%d\n", sid
, rid
);
1875 fprintf(add_fd
, "sambaPrimaryGroupSID: %s\n", sambaSID
);
1877 fprintf_attr(add_fd
, "displayName", "%s", fullname
);
1879 fprintf_attr(add_fd
, "sambaProfilePath", "%s", profilepath
);
1880 if (strcmp(nopasswd
, hex_lm_passwd
) != 0)
1881 fprintf(add_fd
, "sambaLMPassword: %s\n", hex_lm_passwd
);
1882 if (strcmp(nopasswd
, hex_nt_passwd
) != 0)
1883 fprintf(add_fd
, "sambaNTPassword: %s\n", hex_nt_passwd
);
1884 fprintf(add_fd
, "sambaPwdLastSet: %d\n", (int)unix_time
);
1885 fprintf(add_fd
, "sambaAcctFlags: %s\n", flags
);
1886 fprintf(add_fd
, "\n");
1890 return NT_STATUS_OK
;
1893 static NTSTATUS
fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS
*r
,
1895 FILE *add_fd
, fstring sid
,
1899 fstring aliasname
, description
;
1900 uint32 grouptype
= 0, g_rid
= 0;
1901 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1903 /* Get the alias name */
1904 fstrcpy(aliasname
, r
->alias_name
.string
);
1906 /* Get the alias description */
1907 fstrcpy(description
, r
->description
.string
);
1909 /* Set up the group type */
1911 case SAM_DATABASE_DOMAIN
:
1914 case SAM_DATABASE_BUILTIN
:
1923 These groups are entered by populate_ldap_for_ldif
1924 Note that populate creates a group called Relicators,
1925 but NT returns a group called Replicator
1927 if (strcmp(aliasname
, "Domain Admins") == 0 ||
1928 strcmp(aliasname
, "Domain Users") == 0 ||
1929 strcmp(aliasname
, "Domain Guests") == 0 ||
1930 strcmp(aliasname
, "Domain Computers") == 0 ||
1931 strcmp(aliasname
, "Administrators") == 0 ||
1932 strcmp(aliasname
, "Print Operators") == 0 ||
1933 strcmp(aliasname
, "Backup Operators") == 0 ||
1934 strcmp(aliasname
, "Replicator") == 0) {
1935 SAFE_FREE(group_attr
);
1936 return NT_STATUS_OK
;
1938 /* Increment the gid for the new group */
1942 /* Map the group rid and gid */
1944 groupmap
->gidNumber
= ldif_gid
;
1945 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1946 "%s-%d", sid
, g_rid
);
1948 /* Write the data to the temporary add ldif file */
1949 fprintf(add_fd
, "# %s, %s, %s\n", aliasname
, group_attr
,
1951 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", aliasname
, group_attr
,
1953 fprintf(add_fd
, "objectClass: posixGroup\n");
1954 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1955 fprintf(add_fd
, "cn: %s\n", aliasname
);
1956 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1957 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1958 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1959 fprintf_attr(add_fd
, "displayName", "%s", aliasname
);
1961 fprintf_attr(add_fd
, "description", "%s", description
);
1962 fprintf(add_fd
, "\n");
1965 SAFE_FREE(group_attr
);
1967 return NT_STATUS_OK
;
1970 static NTSTATUS
fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER
*r
,
1973 ACCOUNTMAP
*accountmap
,
1974 FILE *mod_fd
, int alloced
)
1977 uint32 group_rid
= 0, rid
= 0;
1980 /* Get the dn for the group */
1981 if (r
->num_rids
> 0) {
1983 for (j
=0; j
<alloced
; j
++) {
1984 if (groupmap
[j
].rid
== group_rid
) break;
1987 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1989 return NT_STATUS_UNSUCCESSFUL
;
1991 snprintf(group_dn
, sizeof(group_dn
), "%s", groupmap
[j
].group_dn
);
1992 fprintf(mod_fd
, "dn: %s\n", group_dn
);
1994 /* Get the cn for each member */
1995 for (i
=0; i
< r
->num_rids
; i
++) {
1997 for (k
=0; k
<alloced
; k
++) {
1998 if (accountmap
[k
].rid
== rid
) break;
2001 DEBUG(1, ("Could not find rid %d in "
2002 "accountmap array\n", rid
));
2003 return NT_STATUS_UNSUCCESSFUL
;
2005 fprintf(mod_fd
, "memberUid: %s\n", accountmap
[k
].cn
);
2007 fprintf(mod_fd
, "\n");
2012 return NT_STATUS_OK
;
2015 static NTSTATUS
fetch_database_to_ldif(struct rpc_pipe_client
*pipe_hnd
,
2018 const char *user_file
)
2021 const char *builtin_sid
= "S-1-5-32";
2022 char *add_name
= NULL
, *mod_filename
= NULL
;
2023 const char *add_template
= "/tmp/add.ldif.XXXXXX";
2024 const char *mod_template
= "/tmp/mod.ldif.XXXXXX";
2025 fstring sid
, domainname
;
2026 NTSTATUS ret
= NT_STATUS_OK
, result
;
2028 TALLOC_CTX
*mem_ctx
;
2030 FILE *add_file
= NULL
, *mod_file
= NULL
, *ldif_file
= NULL
;
2031 int num_alloced
= 0, g_index
= 0, a_index
= 0;
2032 const char *logon_server
= pipe_hnd
->cli
->desthost
;
2033 const char *computername
= global_myname();
2034 struct netr_Authenticator credential
;
2035 struct netr_Authenticator return_authenticator
;
2036 enum netr_SamDatabaseID database_id
= db_type
;
2037 uint16_t restart_state
= 0;
2038 uint32_t sync_context
= 0;
2039 DATA_BLOB session_key
;
2041 /* Set up array for mapping accounts to groups */
2042 /* Array element is the group rid */
2043 GROUPMAP
*groupmap
= NULL
;
2045 /* Set up array for mapping account rid's to cn's */
2046 /* Array element is the account rid */
2047 ACCOUNTMAP
*accountmap
= NULL
;
2049 if (!(mem_ctx
= talloc_init("fetch_database"))) {
2050 return NT_STATUS_NO_MEMORY
;
2053 /* Ensure we have an output file */
2055 ldif_file
= fopen(user_file
, "a");
2060 fprintf(stderr
, "Could not open %s\n", user_file
);
2061 DEBUG(1, ("Could not open %s\n", user_file
));
2062 ret
= NT_STATUS_UNSUCCESSFUL
;
2066 add_name
= talloc_strdup(mem_ctx
, add_template
);
2067 mod_filename
= talloc_strdup(mem_ctx
, mod_template
);
2068 if (!add_name
|| !mod_filename
) {
2069 ret
= NT_STATUS_NO_MEMORY
;
2073 /* Open the add and mod ldif files */
2074 if (!(add_file
= fdopen(smb_mkstemp(add_name
),"w"))) {
2075 DEBUG(1, ("Could not open %s\n", add_name
));
2076 ret
= NT_STATUS_UNSUCCESSFUL
;
2079 if (!(mod_file
= fdopen(smb_mkstemp(mod_filename
),"w"))) {
2080 DEBUG(1, ("Could not open %s\n", mod_filename
));
2081 ret
= NT_STATUS_UNSUCCESSFUL
;
2086 sid_to_fstring(sid
, &dom_sid
);
2088 /* Get the ldap suffix */
2089 suffix
= lp_ldap_suffix();
2090 if (suffix
== NULL
|| strcmp(suffix
, "") == 0) {
2091 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2095 /* Get other smb.conf data */
2096 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2097 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2101 /* Allocate initial memory for groupmap and accountmap arrays */
2102 if (init_ldap
== 1) {
2103 groupmap
= SMB_MALLOC_ARRAY(GROUPMAP
, 8);
2104 accountmap
= SMB_MALLOC_ARRAY(ACCOUNTMAP
, 8);
2105 if (groupmap
== NULL
|| accountmap
== NULL
) {
2106 DEBUG(1,("GROUPMAP malloc failed\n"));
2107 ret
= NT_STATUS_NO_MEMORY
;
2111 /* Initialize the arrays */
2112 memset(groupmap
, 0, sizeof(GROUPMAP
)*8);
2113 memset(accountmap
, 0, sizeof(ACCOUNTMAP
)*8);
2115 /* Remember how many we malloced */
2118 /* Initial database population */
2119 populate_ldap_for_ldif(sid
, suffix
, builtin_sid
, add_file
);
2120 map_populate_groups(groupmap
, accountmap
, sid
, suffix
,
2123 /* Don't do this again */
2127 /* Announce what we are doing */
2129 case SAM_DATABASE_DOMAIN
:
2130 d_fprintf(stderr
, "Fetching DOMAIN database\n");
2132 case SAM_DATABASE_BUILTIN
:
2133 d_fprintf(stderr
, "Fetching BUILTIN database\n");
2135 case SAM_DATABASE_PRIVS
:
2136 d_fprintf(stderr
, "Fetching PRIVS databases\n");
2140 "Fetching unknown database type %u\n",
2146 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2148 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
2150 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
2154 &return_authenticator
,
2161 /* Check returned credentials. */
2162 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
2163 &return_authenticator
.cred
)) {
2164 DEBUG(0,("credentials chain check failed\n"));
2165 return NT_STATUS_ACCESS_DENIED
;
2168 if (NT_STATUS_IS_ERR(result
)) {
2172 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
2174 samsync_fix_delta_array(mem_ctx
,
2180 num_deltas
= delta_enum_array
->num_deltas
;
2182 /* Re-allocate memory for groupmap and accountmap arrays */
2183 groupmap
= SMB_REALLOC_ARRAY(groupmap
, GROUPMAP
,
2184 num_deltas
+num_alloced
);
2185 accountmap
= SMB_REALLOC_ARRAY(accountmap
, ACCOUNTMAP
,
2186 num_deltas
+num_alloced
);
2187 if (groupmap
== NULL
|| accountmap
== NULL
) {
2188 DEBUG(1,("GROUPMAP malloc failed\n"));
2189 ret
= NT_STATUS_NO_MEMORY
;
2193 /* Initialize the new records */
2194 memset(&groupmap
[num_alloced
], 0,
2195 sizeof(GROUPMAP
)*num_deltas
);
2196 memset(&accountmap
[num_alloced
], 0,
2197 sizeof(ACCOUNTMAP
)*num_deltas
);
2199 /* Remember how many we alloced this time */
2200 num_alloced
+= num_deltas
;
2202 /* Loop through the deltas */
2203 for (k
=0; k
<num_deltas
; k
++) {
2205 union netr_DELTA_UNION u
=
2206 delta_enum_array
->delta_enum
[k
].delta_union
;
2207 union netr_DELTA_ID_UNION id
=
2208 delta_enum_array
->delta_enum
[k
].delta_id_union
;
2210 switch(delta_enum_array
->delta_enum
[k
].delta_type
) {
2211 case NETR_DELTA_DOMAIN
:
2212 /* Is this case needed? */
2214 u
.domain
->domain_name
.string
);
2217 case NETR_DELTA_GROUP
:
2218 fetch_group_info_to_ldif(
2221 add_file
, sid
, suffix
);
2225 case NETR_DELTA_USER
:
2226 fetch_account_info_to_ldif(
2228 &accountmap
[a_index
], add_file
,
2229 sid
, suffix
, num_alloced
);
2233 case NETR_DELTA_ALIAS
:
2234 fetch_alias_info_to_ldif(
2235 u
.alias
, &groupmap
[g_index
],
2236 add_file
, sid
, suffix
, db_type
);
2240 case NETR_DELTA_GROUP_MEMBER
:
2241 fetch_groupmem_info_to_ldif(
2242 u
.group_member
, id
.rid
,
2243 groupmap
, accountmap
,
2244 mod_file
, num_alloced
);
2247 case NETR_DELTA_ALIAS_MEMBER
:
2248 case NETR_DELTA_POLICY
:
2249 case NETR_DELTA_ACCOUNT
:
2250 case NETR_DELTA_TRUSTED_DOMAIN
:
2251 case NETR_DELTA_SECRET
:
2252 case NETR_DELTA_RENAME_GROUP
:
2253 case NETR_DELTA_RENAME_USER
:
2254 case NETR_DELTA_RENAME_ALIAS
:
2255 case NETR_DELTA_DELETE_GROUP
:
2256 case NETR_DELTA_DELETE_USER
:
2257 case NETR_DELTA_MODIFY_COUNT
:
2260 } /* end of switch */
2261 } /* end of for loop */
2263 /* Increment sync_context */
2266 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2268 /* Write ldif data to the user's file */
2269 if (db_type
== SAM_DATABASE_DOMAIN
) {
2271 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2273 "# =================================\n\n");
2275 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2277 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2279 "# ==================================\n\n");
2282 fseek(add_file
, 0, SEEK_SET
);
2283 transfer_file(fileno(add_file
), fileno(ldif_file
), (size_t) -1);
2285 if (db_type
== SAM_DATABASE_DOMAIN
) {
2287 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2289 "# ====================================\n\n");
2291 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2293 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2295 "# =====================================\n\n");
2298 fseek(mod_file
, 0, SEEK_SET
);
2299 transfer_file(fileno(mod_file
), fileno(ldif_file
), (size_t) -1);
2303 /* Close and delete the ldif files */
2308 if ((add_name
!= NULL
) &&
2309 strcmp(add_name
, add_template
) && (unlink(add_name
))) {
2310 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2311 add_name
, strerror(errno
)));
2318 if ((mod_filename
!= NULL
) &&
2319 strcmp(mod_filename
, mod_template
) && (unlink(mod_filename
))) {
2320 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2321 mod_filename
, strerror(errno
)));
2324 if (ldif_file
&& (ldif_file
!= stdout
)) {
2328 /* Deallocate memory for the mapping arrays */
2329 SAFE_FREE(groupmap
);
2330 SAFE_FREE(accountmap
);
2333 talloc_destroy(mem_ctx
);
2338 * Basic usage function for 'net rpc vampire'
2339 * @param argc Standard main() style argc
2340 * @param argc Standard main() style argv. Initial components are already
2344 int rpc_vampire_usage(int argc
, const char **argv
)
2346 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2347 "\t to pull accounts from a remote PDC where we are a BDC\n"
2348 "\t\t no args puts accounts in local passdb from smb.conf\n"
2349 "\t\t ldif - put accounts in ldif format (file defaults to "
2352 net_common_flags_usage(argc
, argv
);
2357 /* dump sam database via samsync rpc calls */
2358 NTSTATUS
rpc_vampire_internals(const DOM_SID
*domain_sid
,
2359 const char *domain_name
,
2360 struct cli_state
*cli
,
2361 struct rpc_pipe_client
*pipe_hnd
,
2362 TALLOC_CTX
*mem_ctx
,
2367 fstring my_dom_sid_str
;
2368 fstring rem_dom_sid_str
;
2370 if (!sid_equal(domain_sid
, get_global_sam_sid())) {
2371 d_printf("Cannot import users from %s at this time, "
2372 "as the current domain:\n\t%s: %s\nconflicts "
2373 "with the remote domain\n\t%s: %s\n"
2374 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2375 "workgroup=%s\n\n in your smb.conf?\n",
2377 get_global_sam_name(),
2378 sid_to_fstring(my_dom_sid_str
,
2379 get_global_sam_sid()),
2380 domain_name
, sid_to_fstring(rem_dom_sid_str
,
2383 return NT_STATUS_UNSUCCESSFUL
;
2386 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2387 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2388 *domain_sid
, argv
[1]);
2390 result
= fetch_database(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2394 if (!NT_STATUS_IS_OK(result
)) {
2395 d_fprintf(stderr
, "Failed to fetch domain database: %s\n",
2397 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOT_SUPPORTED
))
2398 d_fprintf(stderr
, "Perhaps %s is a Windows 2000 "
2399 "native mode domain?\n", domain_name
);
2403 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2404 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2405 global_sid_Builtin
, argv
[1]);
2407 result
= fetch_database(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2408 global_sid_Builtin
);
2411 if (!NT_STATUS_IS_OK(result
)) {
2412 d_fprintf(stderr
, "Failed to fetch builtin database: %s\n",
2417 /* Currently we crash on PRIVS somewhere in unmarshalling */
2418 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */