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
;
70 memset(zero_buf
, '\0', sizeof(zero_buf
));
71 /* Decode hashes from password hash (if they are not NULL) */
73 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
74 pdb_sethexpwd(hex_lm_passwd
, r
->lmpassword
.hash
, r
->acct_flags
);
76 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
79 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
80 pdb_sethexpwd(hex_nt_passwd
, r
->ntpassword
.hash
, 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 void display_sam_entry(struct netr_DELTA_ENUM
*r
)
175 union netr_DELTA_UNION u
= r
->delta_union
;
176 union netr_DELTA_ID_UNION id
= r
->delta_id_union
;
178 switch (r
->delta_type
) {
179 case NETR_DELTA_DOMAIN
:
180 display_domain_info(u
.domain
);
182 case NETR_DELTA_GROUP
:
183 display_group_info(id
.rid
, u
.group
);
186 case NETR_DELTA_DELETE_GROUP
:
187 printf("Delete Group: %d\n",
188 u
.delete_account
.unknown
);
190 case NETR_DELTA_RENAME_GROUP
:
191 printf("Rename Group: %s -> %s\n",
192 u
.rename_group
->OldName
.string
,
193 u
.rename_group
->NewName
.string
);
196 case NETR_DELTA_USER
:
197 display_account_info(id
.rid
, u
.user
);
200 case NETR_DELTA_DELETE_USER
:
201 printf("Delete User: %d\n",
204 case NETR_DELTA_RENAME_USER
:
205 printf("Rename user: %s -> %s\n",
206 u
.rename_user
->OldName
.string
,
207 u
.rename_user
->NewName
.string
);
210 case NETR_DELTA_GROUP_MEMBER
:
211 display_group_mem_info(id
.rid
, u
.group_member
);
213 case NETR_DELTA_ALIAS
:
214 display_alias_info(id
.rid
, u
.alias
);
217 case NETR_DELTA_DELETE_ALIAS
:
218 printf("Delete Alias: %d\n",
221 case NETR_DELTA_RENAME_ALIAS
:
222 printf("Rename alias: %s -> %s\n",
223 u
.rename_alias
->OldName
.string
,
224 u
.rename_alias
->NewName
.string
);
227 case NETR_DELTA_ALIAS_MEMBER
:
228 display_alias_mem(id
.rid
, u
.alias_member
);
231 case NETR_DELTA_POLICY
:
234 case NETR_DELTA_TRUSTED_DOMAIN
:
235 printf("Trusted Domain: %s\n",
236 u
.trusted_domain
->domain_name
.string
);
238 case NETR_DELTA_DELETE_TRUST
:
239 printf("Delete Trust: %d\n",
240 u
.delete_trust
.unknown
);
242 case NETR_DELTA_ACCOUNT
:
245 case NETR_DELTA_DELETE_ACCOUNT
:
246 printf("Delete Account: %d\n",
247 u
.delete_account
.unknown
);
249 case NETR_DELTA_SECRET
:
252 case NETR_DELTA_DELETE_SECRET
:
253 printf("Delete Secret: %d\n",
254 u
.delete_secret
.unknown
);
256 case NETR_DELTA_DELETE_GROUP2
:
257 printf("Delete Group2: %s\n",
258 u
.delete_group
->account_name
);
260 case NETR_DELTA_DELETE_USER2
:
261 printf("Delete User2: %s\n",
262 u
.delete_user
->account_name
);
264 case NETR_DELTA_MODIFY_COUNT
:
265 printf("sam sequence update: 0x%016llx\n",
266 (unsigned long long) *u
.modified_count
);
269 /* The following types are recognised but not handled */
270 case NETR_DELTA_RENAME_GROUP
:
271 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
273 case NETR_DELTA_RENAME_USER
:
274 d_printf("NETR_DELTA_RENAME_USER not handled\n");
276 case NETR_DELTA_RENAME_ALIAS
:
277 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
279 case NETR_DELTA_POLICY
:
280 d_printf("NETR_DELTA_POLICY not handled\n");
282 case NETR_DELTA_TRUSTED_DOMAIN
:
283 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
285 case NETR_DELTA_ACCOUNT
:
286 d_printf("NETR_DELTA_ACCOUNT not handled\n");
288 case NETR_DELTA_SECRET
:
289 d_printf("NETR_DELTA_SECRET not handled\n");
291 case NETR_DELTA_DELETE_GROUP
:
292 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
294 case NETR_DELTA_DELETE_USER
:
295 d_printf("NETR_DELTA_DELETE_USER not handled\n");
297 case NETR_DELTA_MODIFY_COUNT
:
298 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
300 case NETR_DELTA_DELETE_ALIAS
:
301 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
303 case NETR_DELTA_DELETE_TRUST
:
304 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
306 case NETR_DELTA_DELETE_ACCOUNT
:
307 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
309 case NETR_DELTA_DELETE_SECRET
:
310 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
312 case NETR_DELTA_DELETE_GROUP2
:
313 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
315 case NETR_DELTA_DELETE_USER2
:
316 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
319 printf("unknown delta type 0x%02x\n",
325 static void dump_database(struct rpc_pipe_client
*pipe_hnd
,
326 enum netr_SamDatabaseID database_id
)
331 const char *logon_server
= pipe_hnd
->cli
->desthost
;
332 const char *computername
= global_myname();
333 struct netr_Authenticator credential
;
334 struct netr_Authenticator return_authenticator
;
335 uint16_t restart_state
= 0;
336 uint32_t sync_context
= 0;
337 DATA_BLOB session_key
;
339 ZERO_STRUCT(return_authenticator
);
341 if (!(mem_ctx
= talloc_init("dump_database"))) {
345 switch(database_id
) {
346 case SAM_DATABASE_DOMAIN
:
347 d_printf("Dumping DOMAIN database\n");
349 case SAM_DATABASE_BUILTIN
:
350 d_printf("Dumping BUILTIN database\n");
352 case SAM_DATABASE_PRIVS
:
353 d_printf("Dumping PRIVS databases\n");
356 d_printf("Dumping unknown database type %u\n",
362 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
364 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
366 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
370 &return_authenticator
,
377 /* Check returned credentials. */
378 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
379 &return_authenticator
.cred
)) {
380 DEBUG(0,("credentials chain check failed\n"));
384 if (NT_STATUS_IS_ERR(result
)) {
388 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
390 samsync_fix_delta_array(mem_ctx
,
395 /* Display results */
396 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
397 display_sam_entry(&delta_enum_array
->delta_enum
[i
]);
400 TALLOC_FREE(delta_enum_array
);
402 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
404 talloc_destroy(mem_ctx
);
407 /* dump sam database via samsync rpc calls */
408 NTSTATUS
rpc_samdump_internals(const DOM_SID
*domain_sid
,
409 const char *domain_name
,
410 struct cli_state
*cli
,
411 struct rpc_pipe_client
*pipe_hnd
,
417 /* net_rpc.c now always tries to create an schannel pipe.. */
419 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
420 uchar trust_password
[16];
421 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
422 uint32 sec_channel_type
= 0;
424 if (!secrets_fetch_trust_account_password(domain_name
,
426 NULL
, &sec_channel_type
)) {
427 DEBUG(0,("Could not fetch trust account password\n"));
431 nt_status
= rpccli_netlogon_setup_creds(pipe_hnd
,
439 if (!NT_STATUS_IS_OK(nt_status
)) {
440 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
445 dump_database(pipe_hnd
, SAM_DATABASE_DOMAIN
);
446 dump_database(pipe_hnd
, SAM_DATABASE_BUILTIN
);
447 dump_database(pipe_hnd
, SAM_DATABASE_PRIVS
);
452 /* Convert a struct samu_DELTA to a struct samu. */
453 #define STRING_CHANGED (old_string && !new_string) ||\
454 (!old_string && new_string) ||\
455 (old_string && new_string && (strcmp(old_string, new_string) != 0))
457 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
459 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
461 static NTSTATUS
sam_account_from_delta(struct samu
*account
,
462 struct netr_DELTA_USER
*r
)
464 const char *old_string
, *new_string
;
465 time_t unix_time
, stored_time
;
468 memset(zero_buf
, '\0', sizeof(zero_buf
));
470 /* Username, fullname, home dir, dir drive, logon script, acct
471 desc, workstations, profile. */
473 if (r
->account_name
.string
) {
474 old_string
= pdb_get_nt_username(account
);
475 new_string
= r
->account_name
.string
;
477 if (STRING_CHANGED
) {
478 pdb_set_nt_username(account
, new_string
, PDB_CHANGED
);
481 /* Unix username is the same - for sanity */
482 old_string
= pdb_get_username( account
);
483 if (STRING_CHANGED
) {
484 pdb_set_username(account
, new_string
, PDB_CHANGED
);
488 if (r
->full_name
.string
) {
489 old_string
= pdb_get_fullname(account
);
490 new_string
= r
->full_name
.string
;
493 pdb_set_fullname(account
, new_string
, PDB_CHANGED
);
496 if (r
->home_directory
.string
) {
497 old_string
= pdb_get_homedir(account
);
498 new_string
= r
->home_directory
.string
;
501 pdb_set_homedir(account
, new_string
, PDB_CHANGED
);
504 if (r
->home_drive
.string
) {
505 old_string
= pdb_get_dir_drive(account
);
506 new_string
= r
->home_drive
.string
;
509 pdb_set_dir_drive(account
, new_string
, PDB_CHANGED
);
512 if (r
->logon_script
.string
) {
513 old_string
= pdb_get_logon_script(account
);
514 new_string
= r
->logon_script
.string
;
517 pdb_set_logon_script(account
, new_string
, PDB_CHANGED
);
520 if (r
->description
.string
) {
521 old_string
= pdb_get_acct_desc(account
);
522 new_string
= r
->description
.string
;
525 pdb_set_acct_desc(account
, new_string
, PDB_CHANGED
);
528 if (r
->workstations
.string
) {
529 old_string
= pdb_get_workstations(account
);
530 new_string
= r
->workstations
.string
;
533 pdb_set_workstations(account
, new_string
, PDB_CHANGED
);
536 if (r
->profile_path
.string
) {
537 old_string
= pdb_get_profile_path(account
);
538 new_string
= r
->profile_path
.string
;
541 pdb_set_profile_path(account
, new_string
, PDB_CHANGED
);
544 if (r
->parameters
.string
) {
547 old_string
= pdb_get_munged_dial(account
);
548 mung
.length
= r
->parameters
.length
;
549 mung
.data
= (uint8
*) r
->parameters
.string
;
550 newstr
= (mung
.length
== 0) ? NULL
:
551 base64_encode_data_blob(talloc_tos(), mung
);
553 if (STRING_CHANGED_NC(old_string
, newstr
))
554 pdb_set_munged_dial(account
, newstr
, PDB_CHANGED
);
558 /* User and group sid */
559 if (pdb_get_user_rid(account
) != r
->rid
)
560 pdb_set_user_sid_from_rid(account
, r
->rid
, PDB_CHANGED
);
561 if (pdb_get_group_rid(account
) != r
->primary_gid
)
562 pdb_set_group_sid_from_rid(account
, r
->primary_gid
, PDB_CHANGED
);
564 /* Logon and password information */
565 if (!nt_time_is_zero(&r
->last_logon
)) {
566 unix_time
= nt_time_to_unix(r
->last_logon
);
567 stored_time
= pdb_get_logon_time(account
);
568 if (stored_time
!= unix_time
)
569 pdb_set_logon_time(account
, unix_time
, PDB_CHANGED
);
572 if (!nt_time_is_zero(&r
->last_logoff
)) {
573 unix_time
= nt_time_to_unix(r
->last_logoff
);
574 stored_time
= pdb_get_logoff_time(account
);
575 if (stored_time
!= unix_time
)
576 pdb_set_logoff_time(account
, unix_time
,PDB_CHANGED
);
580 if (pdb_get_logon_divs(account
) != r
->logon_hours
.units_per_week
)
581 pdb_set_logon_divs(account
, r
->logon_hours
.units_per_week
, PDB_CHANGED
);
584 /* no idea what to do with this one - gd */
585 /* Max Logon Hours */
586 if (delta
->unknown1
!= pdb_get_unknown_6(account
)) {
587 pdb_set_unknown_6(account
, delta
->unknown1
, PDB_CHANGED
);
590 /* Logon Hours Len */
591 if (r
->logon_hours
.units_per_week
/8 != pdb_get_hours_len(account
)) {
592 pdb_set_hours_len(account
, r
->logon_hours
.units_per_week
/8, PDB_CHANGED
);
596 if (r
->logon_hours
.bits
) {
597 char oldstr
[44], newstr
[44];
598 pdb_sethexhours(oldstr
, pdb_get_hours(account
));
599 pdb_sethexhours(newstr
, r
->logon_hours
.bits
);
600 if (!strequal(oldstr
, newstr
))
601 pdb_set_hours(account
, r
->logon_hours
.bits
, PDB_CHANGED
);
604 if (pdb_get_bad_password_count(account
) != r
->bad_password_count
)
605 pdb_set_bad_password_count(account
, r
->bad_password_count
, PDB_CHANGED
);
607 if (pdb_get_logon_count(account
) != r
->logon_count
)
608 pdb_set_logon_count(account
, r
->logon_count
, PDB_CHANGED
);
610 if (!nt_time_is_zero(&r
->last_password_change
)) {
611 unix_time
= nt_time_to_unix(r
->last_password_change
);
612 stored_time
= pdb_get_pass_last_set_time(account
);
613 if (stored_time
!= unix_time
)
614 pdb_set_pass_last_set_time(account
, unix_time
, PDB_CHANGED
);
616 /* no last set time, make it now */
617 pdb_set_pass_last_set_time(account
, time(NULL
), PDB_CHANGED
);
620 if (!nt_time_is_zero(&r
->acct_expiry
)) {
621 unix_time
= nt_time_to_unix(r
->acct_expiry
);
622 stored_time
= pdb_get_kickoff_time(account
);
623 if (stored_time
!= unix_time
)
624 pdb_set_kickoff_time(account
, unix_time
, PDB_CHANGED
);
627 /* Decode hashes from password hash
628 Note that win2000 may send us all zeros for the hashes if it doesn't
629 think this channel is secure enough - don't set the passwords at all
632 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
633 pdb_set_lanman_passwd(account
, r
->lmpassword
.hash
, PDB_CHANGED
);
636 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
637 pdb_set_nt_passwd(account
, r
->ntpassword
.hash
, PDB_CHANGED
);
640 /* TODO: account expiry time */
642 pdb_set_acct_ctrl(account
, r
->acct_flags
, PDB_CHANGED
);
644 pdb_set_domain(account
, lp_workgroup(), PDB_CHANGED
);
649 static NTSTATUS
fetch_account_info(uint32_t rid
,
650 struct netr_DELTA_USER
*r
)
653 NTSTATUS nt_ret
= NT_STATUS_UNSUCCESSFUL
;
655 char *add_script
= NULL
;
656 struct samu
*sam_account
=NULL
;
661 struct passwd
*passwd
;
664 fstrcpy(account
, r
->account_name
.string
);
665 d_printf("Creating account: %s\n", account
);
667 if ( !(sam_account
= samu_new( NULL
)) ) {
668 return NT_STATUS_NO_MEMORY
;
671 if (!(passwd
= Get_Pwnam_alloc(sam_account
, account
))) {
672 /* Create appropriate user */
673 if (r
->acct_flags
& ACB_NORMAL
) {
674 add_script
= talloc_strdup(sam_account
,
675 lp_adduser_script());
676 } else if ( (r
->acct_flags
& ACB_WSTRUST
) ||
677 (r
->acct_flags
& ACB_SVRTRUST
) ||
678 (r
->acct_flags
& ACB_DOMTRUST
) ) {
679 add_script
= talloc_strdup(sam_account
,
680 lp_addmachine_script());
682 DEBUG(1, ("Unknown user type: %s\n",
683 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
684 nt_ret
= NT_STATUS_UNSUCCESSFUL
;
688 nt_ret
= NT_STATUS_NO_MEMORY
;
693 add_script
= talloc_all_string_sub(sam_account
,
698 nt_ret
= NT_STATUS_NO_MEMORY
;
701 add_ret
= smbrun(add_script
,NULL
);
702 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
703 "gave %d\n", add_script
, add_ret
));
705 smb_nscd_flush_user_cache();
709 /* try and find the possible unix account again */
710 if ( !(passwd
= Get_Pwnam_alloc(sam_account
, account
)) ) {
711 d_fprintf(stderr
, "Could not create posix account info for '%s'\n", account
);
712 nt_ret
= NT_STATUS_NO_SUCH_USER
;
717 sid_copy(&user_sid
, get_global_sam_sid());
718 sid_append_rid(&user_sid
, r
->rid
);
720 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
721 sid_to_fstring(sid_string
, &user_sid
), account
));
722 if (!pdb_getsampwsid(sam_account
, &user_sid
)) {
723 sam_account_from_delta(sam_account
, r
);
724 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
725 sid_to_fstring(sid_string
, &user_sid
),
726 pdb_get_username(sam_account
)));
727 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account
))) {
728 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
730 return NT_STATUS_ACCESS_DENIED
;
733 sam_account_from_delta(sam_account
, r
);
734 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
735 sid_to_fstring(sid_string
, &user_sid
),
736 pdb_get_username(sam_account
)));
737 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account
))) {
738 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
740 TALLOC_FREE(sam_account
);
741 return NT_STATUS_ACCESS_DENIED
;
745 if (pdb_get_group_sid(sam_account
) == NULL
) {
746 return NT_STATUS_UNSUCCESSFUL
;
749 group_sid
= *pdb_get_group_sid(sam_account
);
751 if (!pdb_getgrsid(&map
, group_sid
)) {
752 DEBUG(0, ("Primary group of %s has no mapping!\n",
753 pdb_get_username(sam_account
)));
755 if (map
.gid
!= passwd
->pw_gid
) {
756 if (!(grp
= getgrgid(map
.gid
))) {
757 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
758 (unsigned long)map
.gid
, pdb_get_username(sam_account
), sid_string_tos(&group_sid
)));
760 smb_set_primary_group(grp
->gr_name
, pdb_get_username(sam_account
));
766 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
767 pdb_get_username(sam_account
)));
771 TALLOC_FREE(sam_account
);
775 static NTSTATUS
fetch_group_info(uint32_t rid
,
776 struct netr_DELTA_GROUP
*r
)
780 struct group
*grp
= NULL
;
786 fstrcpy(name
, r
->group_name
.string
);
787 fstrcpy(comment
, r
->description
.string
);
789 /* add the group to the mapping table */
790 sid_copy(&group_sid
, get_global_sam_sid());
791 sid_append_rid(&group_sid
, rid
);
792 sid_to_fstring(sid_string
, &group_sid
);
794 if (pdb_getgrsid(&map
, group_sid
)) {
796 grp
= getgrgid(map
.gid
);
803 /* No group found from mapping, find it from its name. */
804 if ((grp
= getgrnam(name
)) == NULL
) {
806 /* No appropriate group found, create one */
808 d_printf("Creating unix group: '%s'\n", name
);
810 if (smb_create_group(name
, &gid
) != 0)
811 return NT_STATUS_ACCESS_DENIED
;
813 if ((grp
= getgrnam(name
)) == NULL
)
814 return NT_STATUS_ACCESS_DENIED
;
818 map
.gid
= grp
->gr_gid
;
820 map
.sid_name_use
= SID_NAME_DOM_GRP
;
821 fstrcpy(map
.nt_name
, name
);
822 if (r
->description
.string
) {
823 fstrcpy(map
.comment
, comment
);
825 fstrcpy(map
.comment
, "");
829 pdb_add_group_mapping_entry(&map
);
831 pdb_update_group_mapping_entry(&map
);
836 static NTSTATUS
fetch_group_mem_info(uint32_t rid
,
837 struct netr_DELTA_GROUP_MEMBER
*r
)
840 TALLOC_CTX
*t
= NULL
;
841 char **nt_members
= NULL
;
847 if (r
->num_rids
== 0) {
851 sid_copy(&group_sid
, get_global_sam_sid());
852 sid_append_rid(&group_sid
, rid
);
854 if (!get_domain_group_from_sid(group_sid
, &map
)) {
855 DEBUG(0, ("Could not find global group %d\n", rid
));
856 return NT_STATUS_NO_SUCH_GROUP
;
859 if (!(grp
= getgrgid(map
.gid
))) {
860 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map
.gid
));
861 return NT_STATUS_NO_SUCH_GROUP
;
864 d_printf("Group members of %s: ", grp
->gr_name
);
866 if (!(t
= talloc_init("fetch_group_mem_info"))) {
867 DEBUG(0, ("could not talloc_init\n"));
868 return NT_STATUS_NO_MEMORY
;
872 if ((nt_members
= TALLOC_ZERO_ARRAY(t
, char *, r
->num_rids
)) == NULL
) {
873 DEBUG(0, ("talloc failed\n"));
875 return NT_STATUS_NO_MEMORY
;
881 for (i
=0; i
< r
->num_rids
; i
++) {
882 struct samu
*member
= NULL
;
885 if ( !(member
= samu_new(t
)) ) {
887 return NT_STATUS_NO_MEMORY
;
890 sid_copy(&member_sid
, get_global_sam_sid());
891 sid_append_rid(&member_sid
, r
->rids
[i
]);
893 if (!pdb_getsampwsid(member
, &member_sid
)) {
894 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
895 r
->rids
[i
], sid_string_tos(&member_sid
), grp
->gr_name
));
900 if (pdb_get_group_rid(member
) == rid
) {
901 d_printf("%s(primary),", pdb_get_username(member
));
906 d_printf("%s,", pdb_get_username(member
));
907 nt_members
[i
] = talloc_strdup(t
, pdb_get_username(member
));
913 unix_members
= grp
->gr_mem
;
915 while (*unix_members
) {
916 bool is_nt_member
= False
;
917 for (i
=0; i
< r
->num_rids
; i
++) {
918 if (nt_members
[i
] == NULL
) {
919 /* This was a primary group */
923 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
929 /* We look at a unix group member that is not
930 an nt group member. So, remove it. NT is
932 smb_delete_user_group(grp
->gr_name
, *unix_members
);
937 for (i
=0; i
< r
->num_rids
; i
++) {
938 bool is_unix_member
= False
;
940 if (nt_members
[i
] == NULL
) {
941 /* This was the primary group */
945 unix_members
= grp
->gr_mem
;
947 while (*unix_members
) {
948 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
949 is_unix_member
= True
;
955 if (!is_unix_member
) {
956 /* We look at a nt group member that is not a
957 unix group member currently. So, add the nt
959 smb_add_user_group(grp
->gr_name
, nt_members
[i
]);
967 static NTSTATUS
fetch_alias_info(uint32_t rid
,
968 struct netr_DELTA_ALIAS
*r
,
973 struct group
*grp
= NULL
;
979 fstrcpy(name
, r
->alias_name
.string
);
980 fstrcpy(comment
, r
->description
.string
);
982 /* Find out whether the group is already mapped */
983 sid_copy(&alias_sid
, &dom_sid
);
984 sid_append_rid(&alias_sid
, rid
);
985 sid_to_fstring(sid_string
, &alias_sid
);
987 if (pdb_getgrsid(&map
, alias_sid
)) {
988 grp
= getgrgid(map
.gid
);
995 /* No group found from mapping, find it from its name. */
996 if ((grp
= getgrnam(name
)) == NULL
) {
997 /* No appropriate group found, create one */
998 d_printf("Creating unix group: '%s'\n", name
);
999 if (smb_create_group(name
, &gid
) != 0)
1000 return NT_STATUS_ACCESS_DENIED
;
1001 if ((grp
= getgrgid(gid
)) == NULL
)
1002 return NT_STATUS_ACCESS_DENIED
;
1006 map
.gid
= grp
->gr_gid
;
1007 map
.sid
= alias_sid
;
1009 if (sid_equal(&dom_sid
, &global_sid_Builtin
))
1010 map
.sid_name_use
= SID_NAME_WKN_GRP
;
1012 map
.sid_name_use
= SID_NAME_ALIAS
;
1014 fstrcpy(map
.nt_name
, name
);
1015 fstrcpy(map
.comment
, comment
);
1018 pdb_add_group_mapping_entry(&map
);
1020 pdb_update_group_mapping_entry(&map
);
1022 return NT_STATUS_OK
;
1025 static NTSTATUS
fetch_alias_mem(uint32_t rid
,
1026 struct netr_DELTA_ALIAS_MEMBER
*r
,
1029 return NT_STATUS_OK
;
1032 static NTSTATUS
fetch_domain_info(uint32_t rid
,
1033 struct netr_DELTA_DOMAIN
*r
)
1035 time_t u_max_age
, u_min_age
, u_logout
;
1036 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1037 const char *domname
;
1038 struct netr_AcctLockStr
*lockstr
= NULL
;
1040 TALLOC_CTX
*mem_ctx
= talloc_tos();
1042 status
= pull_netr_AcctLockStr(mem_ctx
, &r
->account_lockout
,
1044 if (!NT_STATUS_IS_OK(status
)) {
1045 d_printf("failed to pull account lockout string: %s\n",
1049 u_max_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->max_password_age
);
1050 u_min_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->min_password_age
);
1051 u_logout
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->force_logoff_time
);
1053 domname
= r
->domain_name
.string
;
1055 return NT_STATUS_NO_MEMORY
;
1058 /* we don't handle BUILTIN account policies */
1059 if (!strequal(domname
, get_global_sam_name())) {
1060 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname
);
1061 return NT_STATUS_OK
;
1065 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY
,
1066 r
->password_history_length
))
1069 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN
,
1070 r
->min_password_length
))
1073 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (uint32
)u_max_age
))
1076 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (uint32
)u_min_age
))
1079 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (uint32
)u_logout
))
1083 time_t u_lockoutreset
, u_lockouttime
;
1085 u_lockoutreset
= uint64s_nt_time_to_unix_abs(&lockstr
->reset_count
);
1086 u_lockouttime
= uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr
->lockout_duration
);
1088 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
1089 lockstr
->bad_attempt_lockout
))
1092 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME
, (uint32_t)u_lockoutreset
/60))
1095 if (u_lockouttime
!= -1)
1096 u_lockouttime
/= 60;
1098 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (uint32_t)u_lockouttime
))
1102 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
1103 r
->logon_to_chgpass
))
1106 return NT_STATUS_OK
;
1109 static void fetch_sam_entry(struct netr_DELTA_ENUM
*r
, DOM_SID dom_sid
)
1111 switch(r
->delta_type
) {
1112 case NETR_DELTA_USER
:
1113 fetch_account_info(r
->delta_id_union
.rid
,
1114 r
->delta_union
.user
);
1116 case NETR_DELTA_GROUP
:
1117 fetch_group_info(r
->delta_id_union
.rid
,
1118 r
->delta_union
.group
);
1120 case NETR_DELTA_GROUP_MEMBER
:
1121 fetch_group_mem_info(r
->delta_id_union
.rid
,
1122 r
->delta_union
.group_member
);
1124 case NETR_DELTA_ALIAS
:
1125 fetch_alias_info(r
->delta_id_union
.rid
,
1126 r
->delta_union
.alias
,
1129 case NETR_DELTA_ALIAS_MEMBER
:
1130 fetch_alias_mem(r
->delta_id_union
.rid
,
1131 r
->delta_union
.alias_member
,
1134 case NETR_DELTA_DOMAIN
:
1135 fetch_domain_info(r
->delta_id_union
.rid
,
1136 r
->delta_union
.domain
);
1138 /* The following types are recognised but not handled */
1139 case NETR_DELTA_RENAME_GROUP
:
1140 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1142 case NETR_DELTA_RENAME_USER
:
1143 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1145 case NETR_DELTA_RENAME_ALIAS
:
1146 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1148 case NETR_DELTA_POLICY
:
1149 d_printf("NETR_DELTA_POLICY not handled\n");
1151 case NETR_DELTA_TRUSTED_DOMAIN
:
1152 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1154 case NETR_DELTA_ACCOUNT
:
1155 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1157 case NETR_DELTA_SECRET
:
1158 d_printf("NETR_DELTA_SECRET not handled\n");
1160 case NETR_DELTA_DELETE_GROUP
:
1161 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1163 case NETR_DELTA_DELETE_USER
:
1164 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1166 case NETR_DELTA_MODIFY_COUNT
:
1167 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1169 case NETR_DELTA_DELETE_ALIAS
:
1170 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1172 case NETR_DELTA_DELETE_TRUST
:
1173 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1175 case NETR_DELTA_DELETE_ACCOUNT
:
1176 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1178 case NETR_DELTA_DELETE_SECRET
:
1179 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1181 case NETR_DELTA_DELETE_GROUP2
:
1182 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1184 case NETR_DELTA_DELETE_USER2
:
1185 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1188 d_printf("Unknown delta record type %d\n", r
->delta_type
);
1193 static NTSTATUS
fetch_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
, DOM_SID dom_sid
)
1197 TALLOC_CTX
*mem_ctx
;
1198 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1199 const char *computername
= global_myname();
1200 struct netr_Authenticator credential
;
1201 struct netr_Authenticator return_authenticator
;
1202 enum netr_SamDatabaseID database_id
= db_type
;
1203 uint16_t restart_state
= 0;
1204 uint32_t sync_context
= 0;
1205 DATA_BLOB session_key
;
1207 if (!(mem_ctx
= talloc_init("fetch_database")))
1208 return NT_STATUS_NO_MEMORY
;
1211 case SAM_DATABASE_DOMAIN
:
1212 d_printf("Fetching DOMAIN database\n");
1214 case SAM_DATABASE_BUILTIN
:
1215 d_printf("Fetching BUILTIN database\n");
1217 case SAM_DATABASE_PRIVS
:
1218 d_printf("Fetching PRIVS databases\n");
1221 d_printf("Fetching unknown database type %u\n", db_type
);
1226 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1228 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
1230 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
1234 &return_authenticator
,
1241 /* Check returned credentials. */
1242 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
1243 &return_authenticator
.cred
)) {
1244 DEBUG(0,("credentials chain check failed\n"));
1245 return NT_STATUS_ACCESS_DENIED
;
1248 if (NT_STATUS_IS_ERR(result
)) {
1252 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
1254 samsync_fix_delta_array(mem_ctx
,
1259 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
1260 fetch_sam_entry(&delta_enum_array
->delta_enum
[i
], dom_sid
);
1263 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1265 talloc_destroy(mem_ctx
);
1270 static NTSTATUS
populate_ldap_for_ldif(fstring sid
, const char *suffix
, const char
1271 *builtin_sid
, FILE *add_fd
)
1273 const char *user_suffix
, *group_suffix
, *machine_suffix
, *idmap_suffix
;
1274 char *user_attr
=NULL
, *group_attr
=NULL
;
1278 /* Get the suffix attribute */
1279 suffix_attr
= sstring_sub(suffix
, '=', ',');
1280 if (suffix_attr
== NULL
) {
1281 len
= strlen(suffix
);
1282 suffix_attr
= (char*)SMB_MALLOC(len
+1);
1283 memcpy(suffix_attr
, suffix
, len
);
1284 suffix_attr
[len
] = '\0';
1287 /* Write the base */
1288 fprintf(add_fd
, "# %s\n", suffix
);
1289 fprintf(add_fd
, "dn: %s\n", suffix
);
1290 fprintf(add_fd
, "objectClass: dcObject\n");
1291 fprintf(add_fd
, "objectClass: organization\n");
1292 fprintf(add_fd
, "o: %s\n", suffix_attr
);
1293 fprintf(add_fd
, "dc: %s\n", suffix_attr
);
1294 fprintf(add_fd
, "\n");
1297 user_suffix
= lp_ldap_user_suffix();
1298 if (user_suffix
== NULL
) {
1299 SAFE_FREE(suffix_attr
);
1300 return NT_STATUS_NO_MEMORY
;
1302 /* If it exists and is distinct from other containers,
1303 Write the Users entity */
1304 if (*user_suffix
&& strcmp(user_suffix
, suffix
)) {
1305 user_attr
= sstring_sub(lp_ldap_user_suffix(), '=', ',');
1306 fprintf(add_fd
, "# %s\n", user_suffix
);
1307 fprintf(add_fd
, "dn: %s\n", user_suffix
);
1308 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1309 fprintf(add_fd
, "ou: %s\n", user_attr
);
1310 fprintf(add_fd
, "\n");
1315 group_suffix
= lp_ldap_group_suffix();
1316 if (group_suffix
== NULL
) {
1317 SAFE_FREE(suffix_attr
);
1318 SAFE_FREE(user_attr
);
1319 return NT_STATUS_NO_MEMORY
;
1321 /* If it exists and is distinct from other containers,
1322 Write the Groups entity */
1323 if (*group_suffix
&& strcmp(group_suffix
, suffix
)) {
1324 group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1325 fprintf(add_fd
, "# %s\n", group_suffix
);
1326 fprintf(add_fd
, "dn: %s\n", group_suffix
);
1327 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1328 fprintf(add_fd
, "ou: %s\n", group_attr
);
1329 fprintf(add_fd
, "\n");
1333 /* If it exists and is distinct from other containers,
1334 Write the Computers entity */
1335 machine_suffix
= lp_ldap_machine_suffix();
1336 if (machine_suffix
== NULL
) {
1337 SAFE_FREE(suffix_attr
);
1338 SAFE_FREE(user_attr
);
1339 SAFE_FREE(group_attr
);
1340 return NT_STATUS_NO_MEMORY
;
1342 if (*machine_suffix
&& strcmp(machine_suffix
, user_suffix
) &&
1343 strcmp(machine_suffix
, suffix
)) {
1344 char *machine_ou
= NULL
;
1345 fprintf(add_fd
, "# %s\n", machine_suffix
);
1346 fprintf(add_fd
, "dn: %s\n", machine_suffix
);
1347 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1348 /* this isn't totally correct as it assumes that
1349 there _must_ be an ou. just fixing memleak now. jmcd */
1350 machine_ou
= sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1351 fprintf(add_fd
, "ou: %s\n", machine_ou
);
1352 SAFE_FREE(machine_ou
);
1353 fprintf(add_fd
, "\n");
1357 /* If it exists and is distinct from other containers,
1358 Write the IdMap entity */
1359 idmap_suffix
= lp_ldap_idmap_suffix();
1360 if (idmap_suffix
== NULL
) {
1361 SAFE_FREE(suffix_attr
);
1362 SAFE_FREE(user_attr
);
1363 SAFE_FREE(group_attr
);
1364 return NT_STATUS_NO_MEMORY
;
1366 if (*idmap_suffix
&&
1367 strcmp(idmap_suffix
, user_suffix
) &&
1368 strcmp(idmap_suffix
, suffix
)) {
1370 fprintf(add_fd
, "# %s\n", idmap_suffix
);
1371 fprintf(add_fd
, "dn: %s\n", idmap_suffix
);
1372 fprintf(add_fd
, "ObjectClass: organizationalUnit\n");
1373 s
= sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1374 fprintf(add_fd
, "ou: %s\n", s
);
1376 fprintf(add_fd
, "\n");
1380 /* Write the domain entity */
1381 fprintf(add_fd
, "# %s, %s\n", lp_workgroup(), suffix
);
1382 fprintf(add_fd
, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1384 fprintf(add_fd
, "objectClass: sambaDomain\n");
1385 fprintf(add_fd
, "objectClass: sambaUnixIdPool\n");
1386 fprintf(add_fd
, "sambaDomainName: %s\n", lp_workgroup());
1387 fprintf(add_fd
, "sambaSID: %s\n", sid
);
1388 fprintf(add_fd
, "uidNumber: %d\n", ++ldif_uid
);
1389 fprintf(add_fd
, "gidNumber: %d\n", ++ldif_gid
);
1390 fprintf(add_fd
, "\n");
1393 /* Write the Domain Admins entity */
1394 fprintf(add_fd
, "# Domain Admins, %s, %s\n", group_attr
,
1396 fprintf(add_fd
, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr
,
1398 fprintf(add_fd
, "objectClass: posixGroup\n");
1399 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1400 fprintf(add_fd
, "cn: Domain Admins\n");
1401 fprintf(add_fd
, "memberUid: Administrator\n");
1402 fprintf(add_fd
, "description: Netbios Domain Administrators\n");
1403 fprintf(add_fd
, "gidNumber: 512\n");
1404 fprintf(add_fd
, "sambaSID: %s-512\n", sid
);
1405 fprintf(add_fd
, "sambaGroupType: 2\n");
1406 fprintf(add_fd
, "displayName: Domain Admins\n");
1407 fprintf(add_fd
, "\n");
1410 /* Write the Domain Users entity */
1411 fprintf(add_fd
, "# Domain Users, %s, %s\n", group_attr
,
1413 fprintf(add_fd
, "dn: cn=Domain Users,ou=%s,%s\n", group_attr
,
1415 fprintf(add_fd
, "objectClass: posixGroup\n");
1416 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1417 fprintf(add_fd
, "cn: Domain Users\n");
1418 fprintf(add_fd
, "description: Netbios Domain Users\n");
1419 fprintf(add_fd
, "gidNumber: 513\n");
1420 fprintf(add_fd
, "sambaSID: %s-513\n", sid
);
1421 fprintf(add_fd
, "sambaGroupType: 2\n");
1422 fprintf(add_fd
, "displayName: Domain Users\n");
1423 fprintf(add_fd
, "\n");
1426 /* Write the Domain Guests entity */
1427 fprintf(add_fd
, "# Domain Guests, %s, %s\n", group_attr
,
1429 fprintf(add_fd
, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr
,
1431 fprintf(add_fd
, "objectClass: posixGroup\n");
1432 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1433 fprintf(add_fd
, "cn: Domain Guests\n");
1434 fprintf(add_fd
, "description: Netbios Domain Guests\n");
1435 fprintf(add_fd
, "gidNumber: 514\n");
1436 fprintf(add_fd
, "sambaSID: %s-514\n", sid
);
1437 fprintf(add_fd
, "sambaGroupType: 2\n");
1438 fprintf(add_fd
, "displayName: Domain Guests\n");
1439 fprintf(add_fd
, "\n");
1442 /* Write the Domain Computers entity */
1443 fprintf(add_fd
, "# Domain Computers, %s, %s\n", group_attr
,
1445 fprintf(add_fd
, "dn: cn=Domain Computers,ou=%s,%s\n",
1446 group_attr
, suffix
);
1447 fprintf(add_fd
, "objectClass: posixGroup\n");
1448 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1449 fprintf(add_fd
, "gidNumber: 515\n");
1450 fprintf(add_fd
, "cn: Domain Computers\n");
1451 fprintf(add_fd
, "description: Netbios Domain Computers accounts\n");
1452 fprintf(add_fd
, "sambaSID: %s-515\n", sid
);
1453 fprintf(add_fd
, "sambaGroupType: 2\n");
1454 fprintf(add_fd
, "displayName: Domain Computers\n");
1455 fprintf(add_fd
, "\n");
1458 /* Write the Admininistrators Groups entity */
1459 fprintf(add_fd
, "# Administrators, %s, %s\n", group_attr
,
1461 fprintf(add_fd
, "dn: cn=Administrators,ou=%s,%s\n", group_attr
,
1463 fprintf(add_fd
, "objectClass: posixGroup\n");
1464 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1465 fprintf(add_fd
, "gidNumber: 544\n");
1466 fprintf(add_fd
, "cn: Administrators\n");
1467 fprintf(add_fd
, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1468 fprintf(add_fd
, "sambaSID: %s-544\n", builtin_sid
);
1469 fprintf(add_fd
, "sambaGroupType: 5\n");
1470 fprintf(add_fd
, "displayName: Administrators\n");
1471 fprintf(add_fd
, "\n");
1473 /* Write the Print Operator entity */
1474 fprintf(add_fd
, "# Print Operators, %s, %s\n", group_attr
,
1476 fprintf(add_fd
, "dn: cn=Print Operators,ou=%s,%s\n",
1477 group_attr
, suffix
);
1478 fprintf(add_fd
, "objectClass: posixGroup\n");
1479 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1480 fprintf(add_fd
, "gidNumber: 550\n");
1481 fprintf(add_fd
, "cn: Print Operators\n");
1482 fprintf(add_fd
, "description: Netbios Domain Print Operators\n");
1483 fprintf(add_fd
, "sambaSID: %s-550\n", builtin_sid
);
1484 fprintf(add_fd
, "sambaGroupType: 5\n");
1485 fprintf(add_fd
, "displayName: Print Operators\n");
1486 fprintf(add_fd
, "\n");
1489 /* Write the Backup Operators entity */
1490 fprintf(add_fd
, "# Backup Operators, %s, %s\n", group_attr
,
1492 fprintf(add_fd
, "dn: cn=Backup Operators,ou=%s,%s\n",
1493 group_attr
, suffix
);
1494 fprintf(add_fd
, "objectClass: posixGroup\n");
1495 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1496 fprintf(add_fd
, "gidNumber: 551\n");
1497 fprintf(add_fd
, "cn: Backup Operators\n");
1498 fprintf(add_fd
, "description: Netbios Domain Members can bypass file security to back up files\n");
1499 fprintf(add_fd
, "sambaSID: %s-551\n", builtin_sid
);
1500 fprintf(add_fd
, "sambaGroupType: 5\n");
1501 fprintf(add_fd
, "displayName: Backup Operators\n");
1502 fprintf(add_fd
, "\n");
1505 /* Write the Replicators entity */
1506 fprintf(add_fd
, "# Replicators, %s, %s\n", group_attr
, suffix
);
1507 fprintf(add_fd
, "dn: cn=Replicators,ou=%s,%s\n", group_attr
,
1509 fprintf(add_fd
, "objectClass: posixGroup\n");
1510 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1511 fprintf(add_fd
, "gidNumber: 552\n");
1512 fprintf(add_fd
, "cn: Replicators\n");
1513 fprintf(add_fd
, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1514 fprintf(add_fd
, "sambaSID: %s-552\n", builtin_sid
);
1515 fprintf(add_fd
, "sambaGroupType: 5\n");
1516 fprintf(add_fd
, "displayName: Replicators\n");
1517 fprintf(add_fd
, "\n");
1520 /* Deallocate memory, and return */
1521 SAFE_FREE(suffix_attr
);
1522 SAFE_FREE(user_attr
);
1523 SAFE_FREE(group_attr
);
1524 return NT_STATUS_OK
;
1527 static NTSTATUS
map_populate_groups(GROUPMAP
*groupmap
, ACCOUNTMAP
*accountmap
, fstring sid
,
1528 const char *suffix
, const char *builtin_sid
)
1530 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1532 /* Map the groups created by populate_ldap_for_ldif */
1533 groupmap
[0].rid
= 512;
1534 groupmap
[0].gidNumber
= 512;
1535 snprintf(groupmap
[0].sambaSID
, sizeof(groupmap
[0].sambaSID
),
1537 snprintf(groupmap
[0].group_dn
, sizeof(groupmap
[0].group_dn
),
1538 "cn=Domain Admins,ou=%s,%s",
1539 group_attr
, suffix
);
1540 accountmap
[0].rid
= 512;
1541 snprintf(accountmap
[0].cn
, sizeof(accountmap
[0].cn
),
1542 "%s", "Domain Admins");
1544 groupmap
[1].rid
= 513;
1545 groupmap
[1].gidNumber
= 513;
1546 snprintf(groupmap
[1].sambaSID
, sizeof(groupmap
[1].sambaSID
),
1548 snprintf(groupmap
[1].group_dn
, sizeof(groupmap
[1].group_dn
),
1549 "cn=Domain Users,ou=%s,%s",
1550 group_attr
, suffix
);
1551 accountmap
[1].rid
= 513;
1552 snprintf(accountmap
[1].cn
, sizeof(accountmap
[1].cn
),
1553 "%s", "Domain Users");
1555 groupmap
[2].rid
= 514;
1556 groupmap
[2].gidNumber
= 514;
1557 snprintf(groupmap
[2].sambaSID
, sizeof(groupmap
[2].sambaSID
),
1559 snprintf(groupmap
[2].group_dn
, sizeof(groupmap
[2].group_dn
),
1560 "cn=Domain Guests,ou=%s,%s",
1561 group_attr
, suffix
);
1562 accountmap
[2].rid
= 514;
1563 snprintf(accountmap
[2].cn
, sizeof(accountmap
[2].cn
),
1564 "%s", "Domain Guests");
1566 groupmap
[3].rid
= 515;
1567 groupmap
[3].gidNumber
= 515;
1568 snprintf(groupmap
[3].sambaSID
, sizeof(groupmap
[3].sambaSID
),
1570 snprintf(groupmap
[3].group_dn
, sizeof(groupmap
[3].group_dn
),
1571 "cn=Domain Computers,ou=%s,%s",
1572 group_attr
, suffix
);
1573 accountmap
[3].rid
= 515;
1574 snprintf(accountmap
[3].cn
, sizeof(accountmap
[3].cn
),
1575 "%s", "Domain Computers");
1577 groupmap
[4].rid
= 544;
1578 groupmap
[4].gidNumber
= 544;
1579 snprintf(groupmap
[4].sambaSID
, sizeof(groupmap
[4].sambaSID
),
1580 "%s-544", builtin_sid
);
1581 snprintf(groupmap
[4].group_dn
, sizeof(groupmap
[4].group_dn
),
1582 "cn=Administrators,ou=%s,%s",
1583 group_attr
, suffix
);
1584 accountmap
[4].rid
= 515;
1585 snprintf(accountmap
[4].cn
, sizeof(accountmap
[4].cn
),
1586 "%s", "Administrators");
1588 groupmap
[5].rid
= 550;
1589 groupmap
[5].gidNumber
= 550;
1590 snprintf(groupmap
[5].sambaSID
, sizeof(groupmap
[5].sambaSID
),
1591 "%s-550", builtin_sid
);
1592 snprintf(groupmap
[5].group_dn
, sizeof(groupmap
[5].group_dn
),
1593 "cn=Print Operators,ou=%s,%s",
1594 group_attr
, suffix
);
1595 accountmap
[5].rid
= 550;
1596 snprintf(accountmap
[5].cn
, sizeof(accountmap
[5].cn
),
1597 "%s", "Print Operators");
1599 groupmap
[6].rid
= 551;
1600 groupmap
[6].gidNumber
= 551;
1601 snprintf(groupmap
[6].sambaSID
, sizeof(groupmap
[6].sambaSID
),
1602 "%s-551", builtin_sid
);
1603 snprintf(groupmap
[6].group_dn
, sizeof(groupmap
[6].group_dn
),
1604 "cn=Backup Operators,ou=%s,%s",
1605 group_attr
, suffix
);
1606 accountmap
[6].rid
= 551;
1607 snprintf(accountmap
[6].cn
, sizeof(accountmap
[6].cn
),
1608 "%s", "Backup Operators");
1610 groupmap
[7].rid
= 552;
1611 groupmap
[7].gidNumber
= 552;
1612 snprintf(groupmap
[7].sambaSID
, sizeof(groupmap
[7].sambaSID
),
1613 "%s-552", builtin_sid
);
1614 snprintf(groupmap
[7].group_dn
, sizeof(groupmap
[7].group_dn
),
1615 "cn=Replicators,ou=%s,%s",
1616 group_attr
, suffix
);
1617 accountmap
[7].rid
= 551;
1618 snprintf(accountmap
[7].cn
, sizeof(accountmap
[7].cn
),
1619 "%s", "Replicators");
1620 SAFE_FREE(group_attr
);
1621 return NT_STATUS_OK
;
1625 * This is a crap routine, but I think it's the quickest way to solve the
1626 * UTF8->base64 problem.
1629 static int fprintf_attr(FILE *add_fd
, const char *attr_name
,
1630 const char *fmt
, ...)
1633 char *value
, *p
, *base64
;
1634 DATA_BLOB base64_blob
;
1635 bool do_base64
= False
;
1639 value
= talloc_vasprintf(NULL
, fmt
, ap
);
1642 SMB_ASSERT(value
!= NULL
);
1644 for (p
=value
; *p
; p
++) {
1652 bool only_whitespace
= True
;
1653 for (p
=value
; *p
; p
++) {
1655 * I know that this not multibyte safe, but we break
1656 * on the first non-whitespace character anyway.
1659 only_whitespace
= False
;
1663 if (only_whitespace
) {
1669 res
= fprintf(add_fd
, "%s: %s\n", attr_name
, value
);
1674 base64_blob
.data
= (unsigned char *)value
;
1675 base64_blob
.length
= strlen(value
);
1677 base64
= base64_encode_data_blob(value
, base64_blob
);
1678 SMB_ASSERT(base64
!= NULL
);
1680 res
= fprintf(add_fd
, "%s:: %s\n", attr_name
, base64
);
1685 static NTSTATUS
fetch_group_info_to_ldif(struct netr_DELTA_GROUP
*r
, GROUPMAP
*groupmap
,
1686 FILE *add_fd
, fstring sid
, char *suffix
)
1689 uint32 grouptype
= 0, g_rid
= 0;
1690 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1692 /* Get the group name */
1693 fstrcpy(groupname
, r
->group_name
.string
);
1695 /* Set up the group type (always 2 for group info) */
1698 /* These groups are entered by populate_ldap_for_ldif */
1699 if (strcmp(groupname
, "Domain Admins") == 0 ||
1700 strcmp(groupname
, "Domain Users") == 0 ||
1701 strcmp(groupname
, "Domain Guests") == 0 ||
1702 strcmp(groupname
, "Domain Computers") == 0 ||
1703 strcmp(groupname
, "Administrators") == 0 ||
1704 strcmp(groupname
, "Print Operators") == 0 ||
1705 strcmp(groupname
, "Backup Operators") == 0 ||
1706 strcmp(groupname
, "Replicators") == 0) {
1707 SAFE_FREE(group_attr
);
1708 return NT_STATUS_OK
;
1710 /* Increment the gid for the new group */
1714 /* Map the group rid, gid, and dn */
1716 groupmap
->rid
= g_rid
;
1717 groupmap
->gidNumber
= ldif_gid
;
1718 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1719 "%s-%d", sid
, g_rid
);
1720 snprintf(groupmap
->group_dn
, sizeof(groupmap
->group_dn
),
1721 "cn=%s,ou=%s,%s", groupname
, group_attr
, suffix
);
1723 /* Write the data to the temporary add ldif file */
1724 fprintf(add_fd
, "# %s, %s, %s\n", groupname
, group_attr
,
1726 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", groupname
, group_attr
,
1728 fprintf(add_fd
, "objectClass: posixGroup\n");
1729 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1730 fprintf_attr(add_fd
, "cn", "%s", groupname
);
1731 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1732 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1733 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1734 fprintf_attr(add_fd
, "displayName", "%s", groupname
);
1735 fprintf(add_fd
, "\n");
1738 SAFE_FREE(group_attr
);
1740 return NT_STATUS_OK
;
1743 static NTSTATUS
fetch_account_info_to_ldif(struct netr_DELTA_USER
*r
,
1745 ACCOUNTMAP
*accountmap
,
1747 fstring sid
, char *suffix
,
1750 fstring username
, logonscript
, homedrive
, homepath
= "", homedir
= "";
1751 fstring hex_nt_passwd
, hex_lm_passwd
;
1752 fstring description
, profilepath
, fullname
, sambaSID
;
1753 char *flags
, *user_rdn
;
1755 const char* nopasswd
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1757 uint32 rid
= 0, group_rid
= 0, gidNumber
= 0;
1761 memset(zero_buf
, '\0', sizeof(zero_buf
));
1763 /* Get the username */
1764 fstrcpy(username
, r
->account_name
.string
);
1769 /* Map the rid and username for group member info later */
1770 accountmap
->rid
= rid
;
1771 snprintf(accountmap
->cn
, sizeof(accountmap
->cn
), "%s", username
);
1773 /* Get the home directory */
1774 if (r
->acct_flags
& ACB_NORMAL
) {
1775 fstrcpy(homedir
, r
->home_directory
.string
);
1777 snprintf(homedir
, sizeof(homedir
), "/home/%s", username
);
1779 snprintf(homedir
, sizeof(homedir
), "/nobodyshomedir");
1781 ou
= lp_ldap_user_suffix();
1783 ou
= lp_ldap_machine_suffix();
1784 snprintf(homedir
, sizeof(homedir
), "/machinehomedir");
1787 /* Get the logon script */
1788 fstrcpy(logonscript
, r
->logon_script
.string
);
1790 /* Get the home drive */
1791 fstrcpy(homedrive
, r
->home_drive
.string
);
1793 /* Get the home path */
1794 fstrcpy(homepath
, r
->home_directory
.string
);
1796 /* Get the description */
1797 fstrcpy(description
, r
->description
.string
);
1799 /* Get the display name */
1800 fstrcpy(fullname
, r
->full_name
.string
);
1802 /* Get the profile path */
1803 fstrcpy(profilepath
, r
->profile_path
.string
);
1805 /* Get lm and nt password data */
1806 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
1807 pdb_sethexpwd(hex_lm_passwd
, r
->lmpassword
.hash
, r
->acct_flags
);
1809 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
1811 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
1812 pdb_sethexpwd(hex_nt_passwd
, r
->ntpassword
.hash
, r
->acct_flags
);
1814 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
1816 unix_time
= nt_time_to_unix(r
->last_password_change
);
1818 /* Increment the uid for the new user */
1821 /* Set up group id and sambaSID for the user */
1822 group_rid
= r
->primary_gid
;
1823 for (i
=0; i
<alloced
; i
++) {
1824 if (groupmap
[i
].rid
== group_rid
) break;
1827 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1829 return NT_STATUS_UNSUCCESSFUL
;
1831 gidNumber
= groupmap
[i
].gidNumber
;
1832 snprintf(sambaSID
, sizeof(sambaSID
), groupmap
[i
].sambaSID
);
1834 /* Set up sambaAcctFlags */
1835 flags
= pdb_encode_acct_ctrl(r
->acct_flags
,
1836 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1838 /* Add the user to the temporary add ldif file */
1839 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1840 user_rdn
= sstring_sub(ou
, '=', ',');
1841 fprintf(add_fd
, "# %s, %s, %s\n", username
, user_rdn
, suffix
);
1842 fprintf_attr(add_fd
, "dn", "uid=%s,ou=%s,%s", username
, user_rdn
,
1844 SAFE_FREE(user_rdn
);
1845 fprintf(add_fd
, "ObjectClass: top\n");
1846 fprintf(add_fd
, "objectClass: inetOrgPerson\n");
1847 fprintf(add_fd
, "objectClass: posixAccount\n");
1848 fprintf(add_fd
, "objectClass: shadowAccount\n");
1849 fprintf(add_fd
, "objectClass: sambaSamAccount\n");
1850 fprintf_attr(add_fd
, "cn", "%s", username
);
1851 fprintf_attr(add_fd
, "sn", "%s", username
);
1852 fprintf_attr(add_fd
, "uid", "%s", username
);
1853 fprintf(add_fd
, "uidNumber: %d\n", ldif_uid
);
1854 fprintf(add_fd
, "gidNumber: %d\n", gidNumber
);
1855 fprintf_attr(add_fd
, "homeDirectory", "%s", homedir
);
1857 fprintf_attr(add_fd
, "sambaHomePath", "%s", homepath
);
1859 fprintf_attr(add_fd
, "sambaHomeDrive", "%s", homedrive
);
1861 fprintf_attr(add_fd
, "sambaLogonScript", "%s", logonscript
);
1862 fprintf(add_fd
, "loginShell: %s\n",
1863 ((r
->acct_flags
& ACB_NORMAL
) ?
1864 "/bin/bash" : "/bin/false"));
1865 fprintf(add_fd
, "gecos: System User\n");
1867 fprintf_attr(add_fd
, "description", "%s", description
);
1868 fprintf(add_fd
, "sambaSID: %s-%d\n", sid
, rid
);
1869 fprintf(add_fd
, "sambaPrimaryGroupSID: %s\n", sambaSID
);
1871 fprintf_attr(add_fd
, "displayName", "%s", fullname
);
1873 fprintf_attr(add_fd
, "sambaProfilePath", "%s", profilepath
);
1874 if (strcmp(nopasswd
, hex_lm_passwd
) != 0)
1875 fprintf(add_fd
, "sambaLMPassword: %s\n", hex_lm_passwd
);
1876 if (strcmp(nopasswd
, hex_nt_passwd
) != 0)
1877 fprintf(add_fd
, "sambaNTPassword: %s\n", hex_nt_passwd
);
1878 fprintf(add_fd
, "sambaPwdLastSet: %d\n", (int)unix_time
);
1879 fprintf(add_fd
, "sambaAcctFlags: %s\n", flags
);
1880 fprintf(add_fd
, "\n");
1884 return NT_STATUS_OK
;
1887 static NTSTATUS
fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS
*r
,
1889 FILE *add_fd
, fstring sid
,
1893 fstring aliasname
, description
;
1894 uint32 grouptype
= 0, g_rid
= 0;
1895 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1897 /* Get the alias name */
1898 fstrcpy(aliasname
, r
->alias_name
.string
);
1900 /* Get the alias description */
1901 fstrcpy(description
, r
->description
.string
);
1903 /* Set up the group type */
1905 case SAM_DATABASE_DOMAIN
:
1908 case SAM_DATABASE_BUILTIN
:
1917 These groups are entered by populate_ldap_for_ldif
1918 Note that populate creates a group called Relicators,
1919 but NT returns a group called Replicator
1921 if (strcmp(aliasname
, "Domain Admins") == 0 ||
1922 strcmp(aliasname
, "Domain Users") == 0 ||
1923 strcmp(aliasname
, "Domain Guests") == 0 ||
1924 strcmp(aliasname
, "Domain Computers") == 0 ||
1925 strcmp(aliasname
, "Administrators") == 0 ||
1926 strcmp(aliasname
, "Print Operators") == 0 ||
1927 strcmp(aliasname
, "Backup Operators") == 0 ||
1928 strcmp(aliasname
, "Replicator") == 0) {
1929 SAFE_FREE(group_attr
);
1930 return NT_STATUS_OK
;
1932 /* Increment the gid for the new group */
1936 /* Map the group rid and gid */
1938 groupmap
->gidNumber
= ldif_gid
;
1939 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1940 "%s-%d", sid
, g_rid
);
1942 /* Write the data to the temporary add ldif file */
1943 fprintf(add_fd
, "# %s, %s, %s\n", aliasname
, group_attr
,
1945 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", aliasname
, group_attr
,
1947 fprintf(add_fd
, "objectClass: posixGroup\n");
1948 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1949 fprintf(add_fd
, "cn: %s\n", aliasname
);
1950 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1951 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1952 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1953 fprintf_attr(add_fd
, "displayName", "%s", aliasname
);
1955 fprintf_attr(add_fd
, "description", "%s", description
);
1956 fprintf(add_fd
, "\n");
1959 SAFE_FREE(group_attr
);
1961 return NT_STATUS_OK
;
1964 static NTSTATUS
fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER
*r
,
1967 ACCOUNTMAP
*accountmap
,
1968 FILE *mod_fd
, int alloced
)
1971 uint32 group_rid
= 0, rid
= 0;
1974 /* Get the dn for the group */
1975 if (r
->num_rids
> 0) {
1977 for (j
=0; j
<alloced
; j
++) {
1978 if (groupmap
[j
].rid
== group_rid
) break;
1981 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1983 return NT_STATUS_UNSUCCESSFUL
;
1985 snprintf(group_dn
, sizeof(group_dn
), "%s", groupmap
[j
].group_dn
);
1986 fprintf(mod_fd
, "dn: %s\n", group_dn
);
1988 /* Get the cn for each member */
1989 for (i
=0; i
< r
->num_rids
; i
++) {
1991 for (k
=0; k
<alloced
; k
++) {
1992 if (accountmap
[k
].rid
== rid
) break;
1995 DEBUG(1, ("Could not find rid %d in "
1996 "accountmap array\n", rid
));
1997 return NT_STATUS_UNSUCCESSFUL
;
1999 fprintf(mod_fd
, "memberUid: %s\n", accountmap
[k
].cn
);
2001 fprintf(mod_fd
, "\n");
2006 return NT_STATUS_OK
;
2009 static NTSTATUS
fetch_database_to_ldif(struct rpc_pipe_client
*pipe_hnd
,
2012 const char *user_file
)
2015 const char *builtin_sid
= "S-1-5-32";
2016 char *add_name
= NULL
, *mod_filename
= NULL
;
2017 const char *add_template
= "/tmp/add.ldif.XXXXXX";
2018 const char *mod_template
= "/tmp/mod.ldif.XXXXXX";
2019 fstring sid
, domainname
;
2020 NTSTATUS ret
= NT_STATUS_OK
, result
;
2022 TALLOC_CTX
*mem_ctx
;
2024 FILE *add_file
= NULL
, *mod_file
= NULL
, *ldif_file
= NULL
;
2025 int num_alloced
= 0, g_index
= 0, a_index
= 0;
2026 const char *logon_server
= pipe_hnd
->cli
->desthost
;
2027 const char *computername
= global_myname();
2028 struct netr_Authenticator credential
;
2029 struct netr_Authenticator return_authenticator
;
2030 enum netr_SamDatabaseID database_id
= db_type
;
2031 uint16_t restart_state
= 0;
2032 uint32_t sync_context
= 0;
2033 DATA_BLOB session_key
;
2035 /* Set up array for mapping accounts to groups */
2036 /* Array element is the group rid */
2037 GROUPMAP
*groupmap
= NULL
;
2039 /* Set up array for mapping account rid's to cn's */
2040 /* Array element is the account rid */
2041 ACCOUNTMAP
*accountmap
= NULL
;
2043 if (!(mem_ctx
= talloc_init("fetch_database"))) {
2044 return NT_STATUS_NO_MEMORY
;
2047 /* Ensure we have an output file */
2049 ldif_file
= fopen(user_file
, "a");
2054 fprintf(stderr
, "Could not open %s\n", user_file
);
2055 DEBUG(1, ("Could not open %s\n", user_file
));
2056 ret
= NT_STATUS_UNSUCCESSFUL
;
2060 add_name
= talloc_strdup(mem_ctx
, add_template
);
2061 mod_filename
= talloc_strdup(mem_ctx
, mod_template
);
2062 if (!add_name
|| !mod_filename
) {
2063 ret
= NT_STATUS_NO_MEMORY
;
2067 /* Open the add and mod ldif files */
2068 if (!(add_file
= fdopen(smb_mkstemp(add_name
),"w"))) {
2069 DEBUG(1, ("Could not open %s\n", add_name
));
2070 ret
= NT_STATUS_UNSUCCESSFUL
;
2073 if (!(mod_file
= fdopen(smb_mkstemp(mod_filename
),"w"))) {
2074 DEBUG(1, ("Could not open %s\n", mod_filename
));
2075 ret
= NT_STATUS_UNSUCCESSFUL
;
2080 sid_to_fstring(sid
, &dom_sid
);
2082 /* Get the ldap suffix */
2083 suffix
= lp_ldap_suffix();
2084 if (suffix
== NULL
|| strcmp(suffix
, "") == 0) {
2085 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2089 /* Get other smb.conf data */
2090 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2091 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2095 /* Allocate initial memory for groupmap and accountmap arrays */
2096 if (init_ldap
== 1) {
2097 groupmap
= SMB_MALLOC_ARRAY(GROUPMAP
, 8);
2098 accountmap
= SMB_MALLOC_ARRAY(ACCOUNTMAP
, 8);
2099 if (groupmap
== NULL
|| accountmap
== NULL
) {
2100 DEBUG(1,("GROUPMAP malloc failed\n"));
2101 ret
= NT_STATUS_NO_MEMORY
;
2105 /* Initialize the arrays */
2106 memset(groupmap
, 0, sizeof(GROUPMAP
)*8);
2107 memset(accountmap
, 0, sizeof(ACCOUNTMAP
)*8);
2109 /* Remember how many we malloced */
2112 /* Initial database population */
2113 populate_ldap_for_ldif(sid
, suffix
, builtin_sid
, add_file
);
2114 map_populate_groups(groupmap
, accountmap
, sid
, suffix
,
2117 /* Don't do this again */
2121 /* Announce what we are doing */
2123 case SAM_DATABASE_DOMAIN
:
2124 d_fprintf(stderr
, "Fetching DOMAIN database\n");
2126 case SAM_DATABASE_BUILTIN
:
2127 d_fprintf(stderr
, "Fetching BUILTIN database\n");
2129 case SAM_DATABASE_PRIVS
:
2130 d_fprintf(stderr
, "Fetching PRIVS databases\n");
2134 "Fetching unknown database type %u\n",
2140 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2142 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
2144 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
2148 &return_authenticator
,
2155 /* Check returned credentials. */
2156 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
2157 &return_authenticator
.cred
)) {
2158 DEBUG(0,("credentials chain check failed\n"));
2159 return NT_STATUS_ACCESS_DENIED
;
2162 if (NT_STATUS_IS_ERR(result
)) {
2166 session_key
= data_blob_const(pipe_hnd
->dc
->sess_key
, 16);
2168 samsync_fix_delta_array(mem_ctx
,
2173 num_deltas
= delta_enum_array
->num_deltas
;
2175 /* Re-allocate memory for groupmap and accountmap arrays */
2176 groupmap
= SMB_REALLOC_ARRAY(groupmap
, GROUPMAP
,
2177 num_deltas
+num_alloced
);
2178 accountmap
= SMB_REALLOC_ARRAY(accountmap
, ACCOUNTMAP
,
2179 num_deltas
+num_alloced
);
2180 if (groupmap
== NULL
|| accountmap
== NULL
) {
2181 DEBUG(1,("GROUPMAP malloc failed\n"));
2182 ret
= NT_STATUS_NO_MEMORY
;
2186 /* Initialize the new records */
2187 memset(&groupmap
[num_alloced
], 0,
2188 sizeof(GROUPMAP
)*num_deltas
);
2189 memset(&accountmap
[num_alloced
], 0,
2190 sizeof(ACCOUNTMAP
)*num_deltas
);
2192 /* Remember how many we alloced this time */
2193 num_alloced
+= num_deltas
;
2195 /* Loop through the deltas */
2196 for (k
=0; k
<num_deltas
; k
++) {
2198 union netr_DELTA_UNION u
=
2199 delta_enum_array
->delta_enum
[k
].delta_union
;
2200 union netr_DELTA_ID_UNION id
=
2201 delta_enum_array
->delta_enum
[k
].delta_id_union
;
2203 switch(delta_enum_array
->delta_enum
[k
].delta_type
) {
2204 case NETR_DELTA_DOMAIN
:
2205 /* Is this case needed? */
2207 u
.domain
->domain_name
.string
);
2210 case NETR_DELTA_GROUP
:
2211 fetch_group_info_to_ldif(
2214 add_file
, sid
, suffix
);
2218 case NETR_DELTA_USER
:
2219 fetch_account_info_to_ldif(
2221 &accountmap
[a_index
], add_file
,
2222 sid
, suffix
, num_alloced
);
2226 case NETR_DELTA_ALIAS
:
2227 fetch_alias_info_to_ldif(
2228 u
.alias
, &groupmap
[g_index
],
2229 add_file
, sid
, suffix
, db_type
);
2233 case NETR_DELTA_GROUP_MEMBER
:
2234 fetch_groupmem_info_to_ldif(
2235 u
.group_member
, id
.rid
,
2236 groupmap
, accountmap
,
2237 mod_file
, num_alloced
);
2240 case NETR_DELTA_ALIAS_MEMBER
:
2241 case NETR_DELTA_POLICY
:
2242 case NETR_DELTA_ACCOUNT
:
2243 case NETR_DELTA_TRUSTED_DOMAIN
:
2244 case NETR_DELTA_SECRET
:
2245 case NETR_DELTA_RENAME_GROUP
:
2246 case NETR_DELTA_RENAME_USER
:
2247 case NETR_DELTA_RENAME_ALIAS
:
2248 case NETR_DELTA_DELETE_GROUP
:
2249 case NETR_DELTA_DELETE_USER
:
2250 case NETR_DELTA_MODIFY_COUNT
:
2253 } /* end of switch */
2254 } /* end of for loop */
2256 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2258 /* Write ldif data to the user's file */
2259 if (db_type
== SAM_DATABASE_DOMAIN
) {
2261 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2263 "# =================================\n\n");
2265 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2267 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2269 "# ==================================\n\n");
2272 fseek(add_file
, 0, SEEK_SET
);
2273 transfer_file(fileno(add_file
), fileno(ldif_file
), (size_t) -1);
2275 if (db_type
== SAM_DATABASE_DOMAIN
) {
2277 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2279 "# ====================================\n\n");
2281 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2283 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2285 "# =====================================\n\n");
2288 fseek(mod_file
, 0, SEEK_SET
);
2289 transfer_file(fileno(mod_file
), fileno(ldif_file
), (size_t) -1);
2293 /* Close and delete the ldif files */
2298 if ((add_name
!= NULL
) &&
2299 strcmp(add_name
, add_template
) && (unlink(add_name
))) {
2300 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2301 add_name
, strerror(errno
)));
2308 if ((mod_filename
!= NULL
) &&
2309 strcmp(mod_filename
, mod_template
) && (unlink(mod_filename
))) {
2310 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2311 mod_filename
, strerror(errno
)));
2314 if (ldif_file
&& (ldif_file
!= stdout
)) {
2318 /* Deallocate memory for the mapping arrays */
2319 SAFE_FREE(groupmap
);
2320 SAFE_FREE(accountmap
);
2323 talloc_destroy(mem_ctx
);
2328 * Basic usage function for 'net rpc vampire'
2329 * @param argc Standard main() style argc
2330 * @param argc Standard main() style argv. Initial components are already
2334 int rpc_vampire_usage(int argc
, const char **argv
)
2336 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2337 "\t to pull accounts from a remote PDC where we are a BDC\n"
2338 "\t\t no args puts accounts in local passdb from smb.conf\n"
2339 "\t\t ldif - put accounts in ldif format (file defaults to "
2342 net_common_flags_usage(argc
, argv
);
2347 /* dump sam database via samsync rpc calls */
2348 NTSTATUS
rpc_vampire_internals(const DOM_SID
*domain_sid
,
2349 const char *domain_name
,
2350 struct cli_state
*cli
,
2351 struct rpc_pipe_client
*pipe_hnd
,
2352 TALLOC_CTX
*mem_ctx
,
2357 fstring my_dom_sid_str
;
2358 fstring rem_dom_sid_str
;
2360 if (!sid_equal(domain_sid
, get_global_sam_sid())) {
2361 d_printf("Cannot import users from %s at this time, "
2362 "as the current domain:\n\t%s: %s\nconflicts "
2363 "with the remote domain\n\t%s: %s\n"
2364 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2365 "workgroup=%s\n\n in your smb.conf?\n",
2367 get_global_sam_name(),
2368 sid_to_fstring(my_dom_sid_str
,
2369 get_global_sam_sid()),
2370 domain_name
, sid_to_fstring(rem_dom_sid_str
,
2373 return NT_STATUS_UNSUCCESSFUL
;
2376 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2377 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2378 *domain_sid
, argv
[1]);
2380 result
= fetch_database(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2384 if (!NT_STATUS_IS_OK(result
)) {
2385 d_fprintf(stderr
, "Failed to fetch domain database: %s\n",
2387 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOT_SUPPORTED
))
2388 d_fprintf(stderr
, "Perhaps %s is a Windows 2000 "
2389 "native mode domain?\n", domain_name
);
2393 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2394 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2395 global_sid_Builtin
, argv
[1]);
2397 result
= fetch_database(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2398 global_sid_Builtin
);
2401 if (!NT_STATUS_IS_OK(result
)) {
2402 d_fprintf(stderr
, "Failed to fetch builtin database: %s\n",
2407 /* Currently we crash on PRIVS somewhere in unmarshalling */
2408 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */