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;
340 ZERO_STRUCT(return_authenticator
);
342 if (!(mem_ctx
= talloc_init("dump_database"))) {
346 switch(database_id
) {
347 case SAM_DATABASE_DOMAIN
:
348 d_printf("Dumping DOMAIN database\n");
350 case SAM_DATABASE_BUILTIN
:
351 d_printf("Dumping BUILTIN database\n");
353 case SAM_DATABASE_PRIVS
:
354 d_printf("Dumping PRIVS databases\n");
357 d_printf("Dumping unknown database type %u\n",
363 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
365 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
367 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
371 &return_authenticator
,
378 /* Check returned credentials. */
379 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
380 &return_authenticator
.cred
)) {
381 DEBUG(0,("credentials chain check failed\n"));
385 if (NT_STATUS_IS_ERR(result
)) {
389 /* Display results */
390 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
391 display_sam_entry(&delta_enum_array
->delta_enum
[i
]);
394 TALLOC_FREE(delta_enum_array
);
396 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
398 talloc_destroy(mem_ctx
);
401 /* dump sam database via samsync rpc calls */
402 NTSTATUS
rpc_samdump_internals(const DOM_SID
*domain_sid
,
403 const char *domain_name
,
404 struct cli_state
*cli
,
405 struct rpc_pipe_client
*pipe_hnd
,
411 /* net_rpc.c now always tries to create an schannel pipe.. */
413 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
414 uchar trust_password
[16];
415 uint32_t neg_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
;
416 uint32 sec_channel_type
= 0;
418 if (!secrets_fetch_trust_account_password(domain_name
,
420 NULL
, &sec_channel_type
)) {
421 DEBUG(0,("Could not fetch trust account password\n"));
425 nt_status
= rpccli_netlogon_setup_creds(pipe_hnd
,
433 if (!NT_STATUS_IS_OK(nt_status
)) {
434 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
439 dump_database(pipe_hnd
, SAM_DATABASE_DOMAIN
);
440 dump_database(pipe_hnd
, SAM_DATABASE_BUILTIN
);
441 dump_database(pipe_hnd
, SAM_DATABASE_PRIVS
);
446 /* Convert a struct samu_DELTA to a struct samu. */
447 #define STRING_CHANGED (old_string && !new_string) ||\
448 (!old_string && new_string) ||\
449 (old_string && new_string && (strcmp(old_string, new_string) != 0))
451 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
453 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
455 static NTSTATUS
sam_account_from_delta(struct samu
*account
,
456 struct netr_DELTA_USER
*r
)
458 const char *old_string
, *new_string
;
459 time_t unix_time
, stored_time
;
460 uchar lm_passwd
[16], nt_passwd
[16];
461 static uchar zero_buf
[16];
463 /* Username, fullname, home dir, dir drive, logon script, acct
464 desc, workstations, profile. */
466 if (r
->account_name
.string
) {
467 old_string
= pdb_get_nt_username(account
);
468 new_string
= r
->account_name
.string
;
470 if (STRING_CHANGED
) {
471 pdb_set_nt_username(account
, new_string
, PDB_CHANGED
);
474 /* Unix username is the same - for sanity */
475 old_string
= pdb_get_username( account
);
476 if (STRING_CHANGED
) {
477 pdb_set_username(account
, new_string
, PDB_CHANGED
);
481 if (r
->full_name
.string
) {
482 old_string
= pdb_get_fullname(account
);
483 new_string
= r
->full_name
.string
;
486 pdb_set_fullname(account
, new_string
, PDB_CHANGED
);
489 if (r
->home_directory
.string
) {
490 old_string
= pdb_get_homedir(account
);
491 new_string
= r
->home_directory
.string
;
494 pdb_set_homedir(account
, new_string
, PDB_CHANGED
);
497 if (r
->home_drive
.string
) {
498 old_string
= pdb_get_dir_drive(account
);
499 new_string
= r
->home_drive
.string
;
502 pdb_set_dir_drive(account
, new_string
, PDB_CHANGED
);
505 if (r
->logon_script
.string
) {
506 old_string
= pdb_get_logon_script(account
);
507 new_string
= r
->logon_script
.string
;
510 pdb_set_logon_script(account
, new_string
, PDB_CHANGED
);
513 if (r
->description
.string
) {
514 old_string
= pdb_get_acct_desc(account
);
515 new_string
= r
->description
.string
;
518 pdb_set_acct_desc(account
, new_string
, PDB_CHANGED
);
521 if (r
->workstations
.string
) {
522 old_string
= pdb_get_workstations(account
);
523 new_string
= r
->workstations
.string
;
526 pdb_set_workstations(account
, new_string
, PDB_CHANGED
);
529 if (r
->profile_path
.string
) {
530 old_string
= pdb_get_profile_path(account
);
531 new_string
= r
->profile_path
.string
;
534 pdb_set_profile_path(account
, new_string
, PDB_CHANGED
);
537 if (r
->parameters
.string
) {
540 old_string
= pdb_get_munged_dial(account
);
541 mung
.length
= r
->parameters
.length
;
542 mung
.data
= (uint8
*) r
->parameters
.string
;
543 newstr
= (mung
.length
== 0) ? NULL
:
544 base64_encode_data_blob(talloc_tos(), mung
);
546 if (STRING_CHANGED_NC(old_string
, newstr
))
547 pdb_set_munged_dial(account
, newstr
, PDB_CHANGED
);
551 /* User and group sid */
552 if (pdb_get_user_rid(account
) != r
->rid
)
553 pdb_set_user_sid_from_rid(account
, r
->rid
, PDB_CHANGED
);
554 if (pdb_get_group_rid(account
) != r
->primary_gid
)
555 pdb_set_group_sid_from_rid(account
, r
->primary_gid
, PDB_CHANGED
);
557 /* Logon and password information */
558 if (!nt_time_is_zero(&r
->last_logon
)) {
559 unix_time
= nt_time_to_unix(r
->last_logon
);
560 stored_time
= pdb_get_logon_time(account
);
561 if (stored_time
!= unix_time
)
562 pdb_set_logon_time(account
, unix_time
, PDB_CHANGED
);
565 if (!nt_time_is_zero(&r
->last_logoff
)) {
566 unix_time
= nt_time_to_unix(r
->last_logoff
);
567 stored_time
= pdb_get_logoff_time(account
);
568 if (stored_time
!= unix_time
)
569 pdb_set_logoff_time(account
, unix_time
,PDB_CHANGED
);
573 if (pdb_get_logon_divs(account
) != r
->logon_hours
.units_per_week
)
574 pdb_set_logon_divs(account
, r
->logon_hours
.units_per_week
, PDB_CHANGED
);
577 /* no idea what to do with this one - gd */
578 /* Max Logon Hours */
579 if (delta
->unknown1
!= pdb_get_unknown_6(account
)) {
580 pdb_set_unknown_6(account
, delta
->unknown1
, PDB_CHANGED
);
583 /* Logon Hours Len */
584 if (r
->logon_hours
.units_per_week
/8 != pdb_get_hours_len(account
)) {
585 pdb_set_hours_len(account
, r
->logon_hours
.units_per_week
/8, PDB_CHANGED
);
589 if (r
->logon_hours
.bits
) {
590 char oldstr
[44], newstr
[44];
591 pdb_sethexhours(oldstr
, pdb_get_hours(account
));
592 pdb_sethexhours(newstr
, r
->logon_hours
.bits
);
593 if (!strequal(oldstr
, newstr
))
594 pdb_set_hours(account
, r
->logon_hours
.bits
, PDB_CHANGED
);
597 if (pdb_get_bad_password_count(account
) != r
->bad_password_count
)
598 pdb_set_bad_password_count(account
, r
->bad_password_count
, PDB_CHANGED
);
600 if (pdb_get_logon_count(account
) != r
->logon_count
)
601 pdb_set_logon_count(account
, r
->logon_count
, PDB_CHANGED
);
603 if (!nt_time_is_zero(&r
->last_password_change
)) {
604 unix_time
= nt_time_to_unix(r
->last_password_change
);
605 stored_time
= pdb_get_pass_last_set_time(account
);
606 if (stored_time
!= unix_time
)
607 pdb_set_pass_last_set_time(account
, unix_time
, PDB_CHANGED
);
609 /* no last set time, make it now */
610 pdb_set_pass_last_set_time(account
, time(NULL
), PDB_CHANGED
);
613 if (!nt_time_is_zero(&r
->acct_expiry
)) {
614 unix_time
= nt_time_to_unix(r
->acct_expiry
);
615 stored_time
= pdb_get_kickoff_time(account
);
616 if (stored_time
!= unix_time
)
617 pdb_set_kickoff_time(account
, unix_time
, PDB_CHANGED
);
620 /* Decode hashes from password hash
621 Note that win2000 may send us all zeros for the hashes if it doesn't
622 think this channel is secure enough - don't set the passwords at all
625 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
626 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, lm_passwd
, 0);
627 pdb_set_lanman_passwd(account
, lm_passwd
, PDB_CHANGED
);
630 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
631 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, nt_passwd
, 0);
632 pdb_set_nt_passwd(account
, nt_passwd
, PDB_CHANGED
);
635 /* TODO: account expiry time */
637 pdb_set_acct_ctrl(account
, r
->acct_flags
, PDB_CHANGED
);
639 pdb_set_domain(account
, lp_workgroup(), PDB_CHANGED
);
644 static NTSTATUS
fetch_account_info(uint32_t rid
,
645 struct netr_DELTA_USER
*r
)
648 NTSTATUS nt_ret
= NT_STATUS_UNSUCCESSFUL
;
650 char *add_script
= NULL
;
651 struct samu
*sam_account
=NULL
;
656 struct passwd
*passwd
;
659 fstrcpy(account
, r
->account_name
.string
);
660 d_printf("Creating account: %s\n", account
);
662 if ( !(sam_account
= samu_new( NULL
)) ) {
663 return NT_STATUS_NO_MEMORY
;
666 if (!(passwd
= Get_Pwnam_alloc(sam_account
, account
))) {
667 /* Create appropriate user */
668 if (r
->acct_flags
& ACB_NORMAL
) {
669 add_script
= talloc_strdup(sam_account
,
670 lp_adduser_script());
671 } else if ( (r
->acct_flags
& ACB_WSTRUST
) ||
672 (r
->acct_flags
& ACB_SVRTRUST
) ||
673 (r
->acct_flags
& ACB_DOMTRUST
) ) {
674 add_script
= talloc_strdup(sam_account
,
675 lp_addmachine_script());
677 DEBUG(1, ("Unknown user type: %s\n",
678 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
679 nt_ret
= NT_STATUS_UNSUCCESSFUL
;
683 nt_ret
= NT_STATUS_NO_MEMORY
;
688 add_script
= talloc_all_string_sub(sam_account
,
693 nt_ret
= NT_STATUS_NO_MEMORY
;
696 add_ret
= smbrun(add_script
,NULL
);
697 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
698 "gave %d\n", add_script
, add_ret
));
700 smb_nscd_flush_user_cache();
704 /* try and find the possible unix account again */
705 if ( !(passwd
= Get_Pwnam_alloc(sam_account
, account
)) ) {
706 d_fprintf(stderr
, "Could not create posix account info for '%s'\n", account
);
707 nt_ret
= NT_STATUS_NO_SUCH_USER
;
712 sid_copy(&user_sid
, get_global_sam_sid());
713 sid_append_rid(&user_sid
, r
->rid
);
715 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
716 sid_to_fstring(sid_string
, &user_sid
), account
));
717 if (!pdb_getsampwsid(sam_account
, &user_sid
)) {
718 sam_account_from_delta(sam_account
, r
);
719 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
720 sid_to_fstring(sid_string
, &user_sid
),
721 pdb_get_username(sam_account
)));
722 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account
))) {
723 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
725 return NT_STATUS_ACCESS_DENIED
;
728 sam_account_from_delta(sam_account
, r
);
729 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
730 sid_to_fstring(sid_string
, &user_sid
),
731 pdb_get_username(sam_account
)));
732 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account
))) {
733 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
735 TALLOC_FREE(sam_account
);
736 return NT_STATUS_ACCESS_DENIED
;
740 if (pdb_get_group_sid(sam_account
) == NULL
) {
741 return NT_STATUS_UNSUCCESSFUL
;
744 group_sid
= *pdb_get_group_sid(sam_account
);
746 if (!pdb_getgrsid(&map
, group_sid
)) {
747 DEBUG(0, ("Primary group of %s has no mapping!\n",
748 pdb_get_username(sam_account
)));
750 if (map
.gid
!= passwd
->pw_gid
) {
751 if (!(grp
= getgrgid(map
.gid
))) {
752 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
753 (unsigned long)map
.gid
, pdb_get_username(sam_account
), sid_string_tos(&group_sid
)));
755 smb_set_primary_group(grp
->gr_name
, pdb_get_username(sam_account
));
761 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
762 pdb_get_username(sam_account
)));
766 TALLOC_FREE(sam_account
);
770 static NTSTATUS
fetch_group_info(uint32_t rid
,
771 struct netr_DELTA_GROUP
*r
)
775 struct group
*grp
= NULL
;
781 fstrcpy(name
, r
->group_name
.string
);
782 fstrcpy(comment
, r
->description
.string
);
784 /* add the group to the mapping table */
785 sid_copy(&group_sid
, get_global_sam_sid());
786 sid_append_rid(&group_sid
, rid
);
787 sid_to_fstring(sid_string
, &group_sid
);
789 if (pdb_getgrsid(&map
, group_sid
)) {
791 grp
= getgrgid(map
.gid
);
798 /* No group found from mapping, find it from its name. */
799 if ((grp
= getgrnam(name
)) == NULL
) {
801 /* No appropriate group found, create one */
803 d_printf("Creating unix group: '%s'\n", name
);
805 if (smb_create_group(name
, &gid
) != 0)
806 return NT_STATUS_ACCESS_DENIED
;
808 if ((grp
= getgrnam(name
)) == NULL
)
809 return NT_STATUS_ACCESS_DENIED
;
813 map
.gid
= grp
->gr_gid
;
815 map
.sid_name_use
= SID_NAME_DOM_GRP
;
816 fstrcpy(map
.nt_name
, name
);
817 if (r
->description
.string
) {
818 fstrcpy(map
.comment
, comment
);
820 fstrcpy(map
.comment
, "");
824 pdb_add_group_mapping_entry(&map
);
826 pdb_update_group_mapping_entry(&map
);
831 static NTSTATUS
fetch_group_mem_info(uint32_t rid
,
832 struct netr_DELTA_GROUP_MEMBER
*r
)
835 TALLOC_CTX
*t
= NULL
;
836 char **nt_members
= NULL
;
842 if (r
->num_rids
== 0) {
846 sid_copy(&group_sid
, get_global_sam_sid());
847 sid_append_rid(&group_sid
, rid
);
849 if (!get_domain_group_from_sid(group_sid
, &map
)) {
850 DEBUG(0, ("Could not find global group %d\n", rid
));
851 return NT_STATUS_NO_SUCH_GROUP
;
854 if (!(grp
= getgrgid(map
.gid
))) {
855 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map
.gid
));
856 return NT_STATUS_NO_SUCH_GROUP
;
859 d_printf("Group members of %s: ", grp
->gr_name
);
861 if (!(t
= talloc_init("fetch_group_mem_info"))) {
862 DEBUG(0, ("could not talloc_init\n"));
863 return NT_STATUS_NO_MEMORY
;
867 if ((nt_members
= TALLOC_ZERO_ARRAY(t
, char *, r
->num_rids
)) == NULL
) {
868 DEBUG(0, ("talloc failed\n"));
870 return NT_STATUS_NO_MEMORY
;
876 for (i
=0; i
< r
->num_rids
; i
++) {
877 struct samu
*member
= NULL
;
880 if ( !(member
= samu_new(t
)) ) {
882 return NT_STATUS_NO_MEMORY
;
885 sid_copy(&member_sid
, get_global_sam_sid());
886 sid_append_rid(&member_sid
, r
->rids
[i
]);
888 if (!pdb_getsampwsid(member
, &member_sid
)) {
889 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
890 r
->rids
[i
], sid_string_tos(&member_sid
), grp
->gr_name
));
895 if (pdb_get_group_rid(member
) == rid
) {
896 d_printf("%s(primary),", pdb_get_username(member
));
901 d_printf("%s,", pdb_get_username(member
));
902 nt_members
[i
] = talloc_strdup(t
, pdb_get_username(member
));
908 unix_members
= grp
->gr_mem
;
910 while (*unix_members
) {
911 bool is_nt_member
= False
;
912 for (i
=0; i
< r
->num_rids
; i
++) {
913 if (nt_members
[i
] == NULL
) {
914 /* This was a primary group */
918 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
924 /* We look at a unix group member that is not
925 an nt group member. So, remove it. NT is
927 smb_delete_user_group(grp
->gr_name
, *unix_members
);
932 for (i
=0; i
< r
->num_rids
; i
++) {
933 bool is_unix_member
= False
;
935 if (nt_members
[i
] == NULL
) {
936 /* This was the primary group */
940 unix_members
= grp
->gr_mem
;
942 while (*unix_members
) {
943 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
944 is_unix_member
= True
;
950 if (!is_unix_member
) {
951 /* We look at a nt group member that is not a
952 unix group member currently. So, add the nt
954 smb_add_user_group(grp
->gr_name
, nt_members
[i
]);
962 static NTSTATUS
fetch_alias_info(uint32_t rid
,
963 struct netr_DELTA_ALIAS
*r
,
968 struct group
*grp
= NULL
;
974 fstrcpy(name
, r
->alias_name
.string
);
975 fstrcpy(comment
, r
->description
.string
);
977 /* Find out whether the group is already mapped */
978 sid_copy(&alias_sid
, &dom_sid
);
979 sid_append_rid(&alias_sid
, rid
);
980 sid_to_fstring(sid_string
, &alias_sid
);
982 if (pdb_getgrsid(&map
, alias_sid
)) {
983 grp
= getgrgid(map
.gid
);
990 /* No group found from mapping, find it from its name. */
991 if ((grp
= getgrnam(name
)) == NULL
) {
992 /* No appropriate group found, create one */
993 d_printf("Creating unix group: '%s'\n", name
);
994 if (smb_create_group(name
, &gid
) != 0)
995 return NT_STATUS_ACCESS_DENIED
;
996 if ((grp
= getgrgid(gid
)) == NULL
)
997 return NT_STATUS_ACCESS_DENIED
;
1001 map
.gid
= grp
->gr_gid
;
1002 map
.sid
= alias_sid
;
1004 if (sid_equal(&dom_sid
, &global_sid_Builtin
))
1005 map
.sid_name_use
= SID_NAME_WKN_GRP
;
1007 map
.sid_name_use
= SID_NAME_ALIAS
;
1009 fstrcpy(map
.nt_name
, name
);
1010 fstrcpy(map
.comment
, comment
);
1013 pdb_add_group_mapping_entry(&map
);
1015 pdb_update_group_mapping_entry(&map
);
1017 return NT_STATUS_OK
;
1020 static NTSTATUS
fetch_alias_mem(uint32_t rid
,
1021 struct netr_DELTA_ALIAS_MEMBER
*r
,
1024 return NT_STATUS_OK
;
1027 static NTSTATUS
fetch_domain_info(uint32_t rid
,
1028 struct netr_DELTA_DOMAIN
*r
)
1030 time_t u_max_age
, u_min_age
, u_logout
;
1031 time_t u_lockoutreset
, u_lockouttime
;
1032 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1033 const char *domname
;
1034 struct netr_AcctLockStr
*lockstr
= NULL
;
1036 TALLOC_CTX
*mem_ctx
= talloc_tos();
1038 status
= pull_netr_AcctLockStr(mem_ctx
, &r
->account_lockout
,
1040 if (!NT_STATUS_IS_OK(status
)) {
1041 d_printf("failed to pull account lockout string: %s\n",
1045 u_max_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->max_password_age
);
1046 u_min_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->min_password_age
);
1047 u_logout
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->force_logoff_time
);
1050 u_lockoutreset
= uint64s_nt_time_to_unix_abs(&lockstr
->reset_count
);
1051 u_lockouttime
= uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr
->lockout_duration
);
1054 domname
= r
->domain_name
.string
;
1056 return NT_STATUS_NO_MEMORY
;
1059 /* we don't handle BUILTIN account policies */
1060 if (!strequal(domname
, get_global_sam_name())) {
1061 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname
);
1062 return NT_STATUS_OK
;
1066 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY
,
1067 r
->password_history_length
))
1070 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN
,
1071 r
->min_password_length
))
1074 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (uint32
)u_max_age
))
1077 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (uint32
)u_min_age
))
1080 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (uint32
)u_logout
))
1084 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
1085 lockstr
->bad_attempt_lockout
))
1088 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME
, (uint32_t)u_lockoutreset
/60))
1091 if (u_lockouttime
!= -1)
1092 u_lockouttime
/= 60;
1094 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (uint32_t)u_lockouttime
))
1098 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
1099 r
->logon_to_chgpass
))
1102 return NT_STATUS_OK
;
1105 static void fetch_sam_entry(struct netr_DELTA_ENUM
*r
, DOM_SID dom_sid
)
1107 switch(r
->delta_type
) {
1108 case NETR_DELTA_USER
:
1109 fetch_account_info(r
->delta_id_union
.rid
,
1110 r
->delta_union
.user
);
1112 case NETR_DELTA_GROUP
:
1113 fetch_group_info(r
->delta_id_union
.rid
,
1114 r
->delta_union
.group
);
1116 case NETR_DELTA_GROUP_MEMBER
:
1117 fetch_group_mem_info(r
->delta_id_union
.rid
,
1118 r
->delta_union
.group_member
);
1120 case NETR_DELTA_ALIAS
:
1121 fetch_alias_info(r
->delta_id_union
.rid
,
1122 r
->delta_union
.alias
,
1125 case NETR_DELTA_ALIAS_MEMBER
:
1126 fetch_alias_mem(r
->delta_id_union
.rid
,
1127 r
->delta_union
.alias_member
,
1130 case NETR_DELTA_DOMAIN
:
1131 fetch_domain_info(r
->delta_id_union
.rid
,
1132 r
->delta_union
.domain
);
1134 /* The following types are recognised but not handled */
1135 case NETR_DELTA_RENAME_GROUP
:
1136 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1138 case NETR_DELTA_RENAME_USER
:
1139 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1141 case NETR_DELTA_RENAME_ALIAS
:
1142 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1144 case NETR_DELTA_POLICY
:
1145 d_printf("NETR_DELTA_POLICY not handled\n");
1147 case NETR_DELTA_TRUSTED_DOMAIN
:
1148 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1150 case NETR_DELTA_ACCOUNT
:
1151 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1153 case NETR_DELTA_SECRET
:
1154 d_printf("NETR_DELTA_SECRET not handled\n");
1156 case NETR_DELTA_DELETE_GROUP
:
1157 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1159 case NETR_DELTA_DELETE_USER
:
1160 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1162 case NETR_DELTA_MODIFY_COUNT
:
1163 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1165 case NETR_DELTA_DELETE_ALIAS
:
1166 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1168 case NETR_DELTA_DELETE_TRUST
:
1169 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1171 case NETR_DELTA_DELETE_ACCOUNT
:
1172 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1174 case NETR_DELTA_DELETE_SECRET
:
1175 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1177 case NETR_DELTA_DELETE_GROUP2
:
1178 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1180 case NETR_DELTA_DELETE_USER2
:
1181 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1184 d_printf("Unknown delta record type %d\n", r
->delta_type
);
1189 static NTSTATUS
fetch_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
, DOM_SID dom_sid
)
1193 TALLOC_CTX
*mem_ctx
;
1194 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1195 const char *computername
= global_myname();
1196 struct netr_Authenticator credential
;
1197 struct netr_Authenticator return_authenticator
;
1198 enum netr_SamDatabaseID database_id
= db_type
;
1199 uint16_t restart_state
= 0;
1200 uint32_t sync_context
= 0;
1202 if (!(mem_ctx
= talloc_init("fetch_database")))
1203 return NT_STATUS_NO_MEMORY
;
1206 case SAM_DATABASE_DOMAIN
:
1207 d_printf("Fetching DOMAIN database\n");
1209 case SAM_DATABASE_BUILTIN
:
1210 d_printf("Fetching BUILTIN database\n");
1212 case SAM_DATABASE_PRIVS
:
1213 d_printf("Fetching PRIVS databases\n");
1216 d_printf("Fetching unknown database type %u\n", db_type
);
1221 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1223 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
1225 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
1229 &return_authenticator
,
1236 /* Check returned credentials. */
1237 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
1238 &return_authenticator
.cred
)) {
1239 DEBUG(0,("credentials chain check failed\n"));
1240 return NT_STATUS_ACCESS_DENIED
;
1243 if (NT_STATUS_IS_ERR(result
)) {
1247 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
1248 fetch_sam_entry(&delta_enum_array
->delta_enum
[i
], dom_sid
);
1251 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1253 talloc_destroy(mem_ctx
);
1258 static NTSTATUS
populate_ldap_for_ldif(fstring sid
, const char *suffix
, const char
1259 *builtin_sid
, FILE *add_fd
)
1261 const char *user_suffix
, *group_suffix
, *machine_suffix
, *idmap_suffix
;
1262 char *user_attr
=NULL
, *group_attr
=NULL
;
1266 /* Get the suffix attribute */
1267 suffix_attr
= sstring_sub(suffix
, '=', ',');
1268 if (suffix_attr
== NULL
) {
1269 len
= strlen(suffix
);
1270 suffix_attr
= (char*)SMB_MALLOC(len
+1);
1271 memcpy(suffix_attr
, suffix
, len
);
1272 suffix_attr
[len
] = '\0';
1275 /* Write the base */
1276 fprintf(add_fd
, "# %s\n", suffix
);
1277 fprintf(add_fd
, "dn: %s\n", suffix
);
1278 fprintf(add_fd
, "objectClass: dcObject\n");
1279 fprintf(add_fd
, "objectClass: organization\n");
1280 fprintf(add_fd
, "o: %s\n", suffix_attr
);
1281 fprintf(add_fd
, "dc: %s\n", suffix_attr
);
1282 fprintf(add_fd
, "\n");
1285 user_suffix
= lp_ldap_user_suffix();
1286 if (user_suffix
== NULL
) {
1287 SAFE_FREE(suffix_attr
);
1288 return NT_STATUS_NO_MEMORY
;
1290 /* If it exists and is distinct from other containers,
1291 Write the Users entity */
1292 if (*user_suffix
&& strcmp(user_suffix
, suffix
)) {
1293 user_attr
= sstring_sub(lp_ldap_user_suffix(), '=', ',');
1294 fprintf(add_fd
, "# %s\n", user_suffix
);
1295 fprintf(add_fd
, "dn: %s\n", user_suffix
);
1296 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1297 fprintf(add_fd
, "ou: %s\n", user_attr
);
1298 fprintf(add_fd
, "\n");
1303 group_suffix
= lp_ldap_group_suffix();
1304 if (group_suffix
== NULL
) {
1305 SAFE_FREE(suffix_attr
);
1306 SAFE_FREE(user_attr
);
1307 return NT_STATUS_NO_MEMORY
;
1309 /* If it exists and is distinct from other containers,
1310 Write the Groups entity */
1311 if (*group_suffix
&& strcmp(group_suffix
, suffix
)) {
1312 group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1313 fprintf(add_fd
, "# %s\n", group_suffix
);
1314 fprintf(add_fd
, "dn: %s\n", group_suffix
);
1315 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1316 fprintf(add_fd
, "ou: %s\n", group_attr
);
1317 fprintf(add_fd
, "\n");
1321 /* If it exists and is distinct from other containers,
1322 Write the Computers entity */
1323 machine_suffix
= lp_ldap_machine_suffix();
1324 if (machine_suffix
== NULL
) {
1325 SAFE_FREE(suffix_attr
);
1326 SAFE_FREE(user_attr
);
1327 SAFE_FREE(group_attr
);
1328 return NT_STATUS_NO_MEMORY
;
1330 if (*machine_suffix
&& strcmp(machine_suffix
, user_suffix
) &&
1331 strcmp(machine_suffix
, suffix
)) {
1332 char *machine_ou
= NULL
;
1333 fprintf(add_fd
, "# %s\n", machine_suffix
);
1334 fprintf(add_fd
, "dn: %s\n", machine_suffix
);
1335 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1336 /* this isn't totally correct as it assumes that
1337 there _must_ be an ou. just fixing memleak now. jmcd */
1338 machine_ou
= sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1339 fprintf(add_fd
, "ou: %s\n", machine_ou
);
1340 SAFE_FREE(machine_ou
);
1341 fprintf(add_fd
, "\n");
1345 /* If it exists and is distinct from other containers,
1346 Write the IdMap entity */
1347 idmap_suffix
= lp_ldap_idmap_suffix();
1348 if (idmap_suffix
== NULL
) {
1349 SAFE_FREE(suffix_attr
);
1350 SAFE_FREE(user_attr
);
1351 SAFE_FREE(group_attr
);
1352 return NT_STATUS_NO_MEMORY
;
1354 if (*idmap_suffix
&&
1355 strcmp(idmap_suffix
, user_suffix
) &&
1356 strcmp(idmap_suffix
, suffix
)) {
1358 fprintf(add_fd
, "# %s\n", idmap_suffix
);
1359 fprintf(add_fd
, "dn: %s\n", idmap_suffix
);
1360 fprintf(add_fd
, "ObjectClass: organizationalUnit\n");
1361 s
= sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1362 fprintf(add_fd
, "ou: %s\n", s
);
1364 fprintf(add_fd
, "\n");
1368 /* Write the domain entity */
1369 fprintf(add_fd
, "# %s, %s\n", lp_workgroup(), suffix
);
1370 fprintf(add_fd
, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1372 fprintf(add_fd
, "objectClass: sambaDomain\n");
1373 fprintf(add_fd
, "objectClass: sambaUnixIdPool\n");
1374 fprintf(add_fd
, "sambaDomainName: %s\n", lp_workgroup());
1375 fprintf(add_fd
, "sambaSID: %s\n", sid
);
1376 fprintf(add_fd
, "uidNumber: %d\n", ++ldif_uid
);
1377 fprintf(add_fd
, "gidNumber: %d\n", ++ldif_gid
);
1378 fprintf(add_fd
, "\n");
1381 /* Write the Domain Admins entity */
1382 fprintf(add_fd
, "# Domain Admins, %s, %s\n", group_attr
,
1384 fprintf(add_fd
, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr
,
1386 fprintf(add_fd
, "objectClass: posixGroup\n");
1387 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1388 fprintf(add_fd
, "cn: Domain Admins\n");
1389 fprintf(add_fd
, "memberUid: Administrator\n");
1390 fprintf(add_fd
, "description: Netbios Domain Administrators\n");
1391 fprintf(add_fd
, "gidNumber: 512\n");
1392 fprintf(add_fd
, "sambaSID: %s-512\n", sid
);
1393 fprintf(add_fd
, "sambaGroupType: 2\n");
1394 fprintf(add_fd
, "displayName: Domain Admins\n");
1395 fprintf(add_fd
, "\n");
1398 /* Write the Domain Users entity */
1399 fprintf(add_fd
, "# Domain Users, %s, %s\n", group_attr
,
1401 fprintf(add_fd
, "dn: cn=Domain Users,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 Users\n");
1406 fprintf(add_fd
, "description: Netbios Domain Users\n");
1407 fprintf(add_fd
, "gidNumber: 513\n");
1408 fprintf(add_fd
, "sambaSID: %s-513\n", sid
);
1409 fprintf(add_fd
, "sambaGroupType: 2\n");
1410 fprintf(add_fd
, "displayName: Domain Users\n");
1411 fprintf(add_fd
, "\n");
1414 /* Write the Domain Guests entity */
1415 fprintf(add_fd
, "# Domain Guests, %s, %s\n", group_attr
,
1417 fprintf(add_fd
, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr
,
1419 fprintf(add_fd
, "objectClass: posixGroup\n");
1420 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1421 fprintf(add_fd
, "cn: Domain Guests\n");
1422 fprintf(add_fd
, "description: Netbios Domain Guests\n");
1423 fprintf(add_fd
, "gidNumber: 514\n");
1424 fprintf(add_fd
, "sambaSID: %s-514\n", sid
);
1425 fprintf(add_fd
, "sambaGroupType: 2\n");
1426 fprintf(add_fd
, "displayName: Domain Guests\n");
1427 fprintf(add_fd
, "\n");
1430 /* Write the Domain Computers entity */
1431 fprintf(add_fd
, "# Domain Computers, %s, %s\n", group_attr
,
1433 fprintf(add_fd
, "dn: cn=Domain Computers,ou=%s,%s\n",
1434 group_attr
, suffix
);
1435 fprintf(add_fd
, "objectClass: posixGroup\n");
1436 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1437 fprintf(add_fd
, "gidNumber: 515\n");
1438 fprintf(add_fd
, "cn: Domain Computers\n");
1439 fprintf(add_fd
, "description: Netbios Domain Computers accounts\n");
1440 fprintf(add_fd
, "sambaSID: %s-515\n", sid
);
1441 fprintf(add_fd
, "sambaGroupType: 2\n");
1442 fprintf(add_fd
, "displayName: Domain Computers\n");
1443 fprintf(add_fd
, "\n");
1446 /* Write the Admininistrators Groups entity */
1447 fprintf(add_fd
, "# Administrators, %s, %s\n", group_attr
,
1449 fprintf(add_fd
, "dn: cn=Administrators,ou=%s,%s\n", group_attr
,
1451 fprintf(add_fd
, "objectClass: posixGroup\n");
1452 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1453 fprintf(add_fd
, "gidNumber: 544\n");
1454 fprintf(add_fd
, "cn: Administrators\n");
1455 fprintf(add_fd
, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1456 fprintf(add_fd
, "sambaSID: %s-544\n", builtin_sid
);
1457 fprintf(add_fd
, "sambaGroupType: 5\n");
1458 fprintf(add_fd
, "displayName: Administrators\n");
1459 fprintf(add_fd
, "\n");
1461 /* Write the Print Operator entity */
1462 fprintf(add_fd
, "# Print Operators, %s, %s\n", group_attr
,
1464 fprintf(add_fd
, "dn: cn=Print Operators,ou=%s,%s\n",
1465 group_attr
, suffix
);
1466 fprintf(add_fd
, "objectClass: posixGroup\n");
1467 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1468 fprintf(add_fd
, "gidNumber: 550\n");
1469 fprintf(add_fd
, "cn: Print Operators\n");
1470 fprintf(add_fd
, "description: Netbios Domain Print Operators\n");
1471 fprintf(add_fd
, "sambaSID: %s-550\n", builtin_sid
);
1472 fprintf(add_fd
, "sambaGroupType: 5\n");
1473 fprintf(add_fd
, "displayName: Print Operators\n");
1474 fprintf(add_fd
, "\n");
1477 /* Write the Backup Operators entity */
1478 fprintf(add_fd
, "# Backup Operators, %s, %s\n", group_attr
,
1480 fprintf(add_fd
, "dn: cn=Backup Operators,ou=%s,%s\n",
1481 group_attr
, suffix
);
1482 fprintf(add_fd
, "objectClass: posixGroup\n");
1483 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1484 fprintf(add_fd
, "gidNumber: 551\n");
1485 fprintf(add_fd
, "cn: Backup Operators\n");
1486 fprintf(add_fd
, "description: Netbios Domain Members can bypass file security to back up files\n");
1487 fprintf(add_fd
, "sambaSID: %s-551\n", builtin_sid
);
1488 fprintf(add_fd
, "sambaGroupType: 5\n");
1489 fprintf(add_fd
, "displayName: Backup Operators\n");
1490 fprintf(add_fd
, "\n");
1493 /* Write the Replicators entity */
1494 fprintf(add_fd
, "# Replicators, %s, %s\n", group_attr
, suffix
);
1495 fprintf(add_fd
, "dn: cn=Replicators,ou=%s,%s\n", group_attr
,
1497 fprintf(add_fd
, "objectClass: posixGroup\n");
1498 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1499 fprintf(add_fd
, "gidNumber: 552\n");
1500 fprintf(add_fd
, "cn: Replicators\n");
1501 fprintf(add_fd
, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1502 fprintf(add_fd
, "sambaSID: %s-552\n", builtin_sid
);
1503 fprintf(add_fd
, "sambaGroupType: 5\n");
1504 fprintf(add_fd
, "displayName: Replicators\n");
1505 fprintf(add_fd
, "\n");
1508 /* Deallocate memory, and return */
1509 SAFE_FREE(suffix_attr
);
1510 SAFE_FREE(user_attr
);
1511 SAFE_FREE(group_attr
);
1512 return NT_STATUS_OK
;
1515 static NTSTATUS
map_populate_groups(GROUPMAP
*groupmap
, ACCOUNTMAP
*accountmap
, fstring sid
,
1516 const char *suffix
, const char *builtin_sid
)
1518 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1520 /* Map the groups created by populate_ldap_for_ldif */
1521 groupmap
[0].rid
= 512;
1522 groupmap
[0].gidNumber
= 512;
1523 snprintf(groupmap
[0].sambaSID
, sizeof(groupmap
[0].sambaSID
),
1525 snprintf(groupmap
[0].group_dn
, sizeof(groupmap
[0].group_dn
),
1526 "cn=Domain Admins,ou=%s,%s",
1527 group_attr
, suffix
);
1528 accountmap
[0].rid
= 512;
1529 snprintf(accountmap
[0].cn
, sizeof(accountmap
[0].cn
),
1530 "%s", "Domain Admins");
1532 groupmap
[1].rid
= 513;
1533 groupmap
[1].gidNumber
= 513;
1534 snprintf(groupmap
[1].sambaSID
, sizeof(groupmap
[1].sambaSID
),
1536 snprintf(groupmap
[1].group_dn
, sizeof(groupmap
[1].group_dn
),
1537 "cn=Domain Users,ou=%s,%s",
1538 group_attr
, suffix
);
1539 accountmap
[1].rid
= 513;
1540 snprintf(accountmap
[1].cn
, sizeof(accountmap
[1].cn
),
1541 "%s", "Domain Users");
1543 groupmap
[2].rid
= 514;
1544 groupmap
[2].gidNumber
= 514;
1545 snprintf(groupmap
[2].sambaSID
, sizeof(groupmap
[2].sambaSID
),
1547 snprintf(groupmap
[2].group_dn
, sizeof(groupmap
[2].group_dn
),
1548 "cn=Domain Guests,ou=%s,%s",
1549 group_attr
, suffix
);
1550 accountmap
[2].rid
= 514;
1551 snprintf(accountmap
[2].cn
, sizeof(accountmap
[2].cn
),
1552 "%s", "Domain Guests");
1554 groupmap
[3].rid
= 515;
1555 groupmap
[3].gidNumber
= 515;
1556 snprintf(groupmap
[3].sambaSID
, sizeof(groupmap
[3].sambaSID
),
1558 snprintf(groupmap
[3].group_dn
, sizeof(groupmap
[3].group_dn
),
1559 "cn=Domain Computers,ou=%s,%s",
1560 group_attr
, suffix
);
1561 accountmap
[3].rid
= 515;
1562 snprintf(accountmap
[3].cn
, sizeof(accountmap
[3].cn
),
1563 "%s", "Domain Computers");
1565 groupmap
[4].rid
= 544;
1566 groupmap
[4].gidNumber
= 544;
1567 snprintf(groupmap
[4].sambaSID
, sizeof(groupmap
[4].sambaSID
),
1568 "%s-544", builtin_sid
);
1569 snprintf(groupmap
[4].group_dn
, sizeof(groupmap
[4].group_dn
),
1570 "cn=Administrators,ou=%s,%s",
1571 group_attr
, suffix
);
1572 accountmap
[4].rid
= 515;
1573 snprintf(accountmap
[4].cn
, sizeof(accountmap
[4].cn
),
1574 "%s", "Administrators");
1576 groupmap
[5].rid
= 550;
1577 groupmap
[5].gidNumber
= 550;
1578 snprintf(groupmap
[5].sambaSID
, sizeof(groupmap
[5].sambaSID
),
1579 "%s-550", builtin_sid
);
1580 snprintf(groupmap
[5].group_dn
, sizeof(groupmap
[5].group_dn
),
1581 "cn=Print Operators,ou=%s,%s",
1582 group_attr
, suffix
);
1583 accountmap
[5].rid
= 550;
1584 snprintf(accountmap
[5].cn
, sizeof(accountmap
[5].cn
),
1585 "%s", "Print Operators");
1587 groupmap
[6].rid
= 551;
1588 groupmap
[6].gidNumber
= 551;
1589 snprintf(groupmap
[6].sambaSID
, sizeof(groupmap
[6].sambaSID
),
1590 "%s-551", builtin_sid
);
1591 snprintf(groupmap
[6].group_dn
, sizeof(groupmap
[6].group_dn
),
1592 "cn=Backup Operators,ou=%s,%s",
1593 group_attr
, suffix
);
1594 accountmap
[6].rid
= 551;
1595 snprintf(accountmap
[6].cn
, sizeof(accountmap
[6].cn
),
1596 "%s", "Backup Operators");
1598 groupmap
[7].rid
= 552;
1599 groupmap
[7].gidNumber
= 552;
1600 snprintf(groupmap
[7].sambaSID
, sizeof(groupmap
[7].sambaSID
),
1601 "%s-552", builtin_sid
);
1602 snprintf(groupmap
[7].group_dn
, sizeof(groupmap
[7].group_dn
),
1603 "cn=Replicators,ou=%s,%s",
1604 group_attr
, suffix
);
1605 accountmap
[7].rid
= 551;
1606 snprintf(accountmap
[7].cn
, sizeof(accountmap
[7].cn
),
1607 "%s", "Replicators");
1608 SAFE_FREE(group_attr
);
1609 return NT_STATUS_OK
;
1613 * This is a crap routine, but I think it's the quickest way to solve the
1614 * UTF8->base64 problem.
1617 static int fprintf_attr(FILE *add_fd
, const char *attr_name
,
1618 const char *fmt
, ...)
1621 char *value
, *p
, *base64
;
1622 DATA_BLOB base64_blob
;
1623 bool do_base64
= False
;
1627 value
= talloc_vasprintf(NULL
, fmt
, ap
);
1630 SMB_ASSERT(value
!= NULL
);
1632 for (p
=value
; *p
; p
++) {
1640 bool only_whitespace
= True
;
1641 for (p
=value
; *p
; p
++) {
1643 * I know that this not multibyte safe, but we break
1644 * on the first non-whitespace character anyway.
1647 only_whitespace
= False
;
1651 if (only_whitespace
) {
1657 res
= fprintf(add_fd
, "%s: %s\n", attr_name
, value
);
1662 base64_blob
.data
= (unsigned char *)value
;
1663 base64_blob
.length
= strlen(value
);
1665 base64
= base64_encode_data_blob(value
, base64_blob
);
1666 SMB_ASSERT(base64
!= NULL
);
1668 res
= fprintf(add_fd
, "%s:: %s\n", attr_name
, base64
);
1673 static NTSTATUS
fetch_group_info_to_ldif(struct netr_DELTA_GROUP
*r
, GROUPMAP
*groupmap
,
1674 FILE *add_fd
, fstring sid
, char *suffix
)
1677 uint32 grouptype
= 0, g_rid
= 0;
1678 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1680 /* Get the group name */
1681 fstrcpy(groupname
, r
->group_name
.string
);
1683 /* Set up the group type (always 2 for group info) */
1686 /* These groups are entered by populate_ldap_for_ldif */
1687 if (strcmp(groupname
, "Domain Admins") == 0 ||
1688 strcmp(groupname
, "Domain Users") == 0 ||
1689 strcmp(groupname
, "Domain Guests") == 0 ||
1690 strcmp(groupname
, "Domain Computers") == 0 ||
1691 strcmp(groupname
, "Administrators") == 0 ||
1692 strcmp(groupname
, "Print Operators") == 0 ||
1693 strcmp(groupname
, "Backup Operators") == 0 ||
1694 strcmp(groupname
, "Replicators") == 0) {
1695 SAFE_FREE(group_attr
);
1696 return NT_STATUS_OK
;
1698 /* Increment the gid for the new group */
1702 /* Map the group rid, gid, and dn */
1704 groupmap
->rid
= g_rid
;
1705 groupmap
->gidNumber
= ldif_gid
;
1706 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1707 "%s-%d", sid
, g_rid
);
1708 snprintf(groupmap
->group_dn
, sizeof(groupmap
->group_dn
),
1709 "cn=%s,ou=%s,%s", groupname
, group_attr
, suffix
);
1711 /* Write the data to the temporary add ldif file */
1712 fprintf(add_fd
, "# %s, %s, %s\n", groupname
, group_attr
,
1714 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", groupname
, group_attr
,
1716 fprintf(add_fd
, "objectClass: posixGroup\n");
1717 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1718 fprintf_attr(add_fd
, "cn", "%s", groupname
);
1719 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1720 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1721 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1722 fprintf_attr(add_fd
, "displayName", "%s", groupname
);
1723 fprintf(add_fd
, "\n");
1726 SAFE_FREE(group_attr
);
1728 return NT_STATUS_OK
;
1731 static NTSTATUS
fetch_account_info_to_ldif(struct netr_DELTA_USER
*r
,
1733 ACCOUNTMAP
*accountmap
,
1735 fstring sid
, char *suffix
,
1738 fstring username
, logonscript
, homedrive
, homepath
= "", homedir
= "";
1739 fstring hex_nt_passwd
, hex_lm_passwd
;
1740 fstring description
, profilepath
, fullname
, sambaSID
;
1741 uchar lm_passwd
[16], nt_passwd
[16];
1742 char *flags
, *user_rdn
;
1744 const char* nopasswd
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1745 static uchar zero_buf
[16];
1746 uint32 rid
= 0, group_rid
= 0, gidNumber
= 0;
1750 /* Get the username */
1751 fstrcpy(username
, r
->account_name
.string
);
1756 /* Map the rid and username for group member info later */
1757 accountmap
->rid
= rid
;
1758 snprintf(accountmap
->cn
, sizeof(accountmap
->cn
), "%s", username
);
1760 /* Get the home directory */
1761 if (r
->acct_flags
& ACB_NORMAL
) {
1762 fstrcpy(homedir
, r
->home_directory
.string
);
1764 snprintf(homedir
, sizeof(homedir
), "/home/%s", username
);
1766 snprintf(homedir
, sizeof(homedir
), "/nobodyshomedir");
1768 ou
= lp_ldap_user_suffix();
1770 ou
= lp_ldap_machine_suffix();
1771 snprintf(homedir
, sizeof(homedir
), "/machinehomedir");
1774 /* Get the logon script */
1775 fstrcpy(logonscript
, r
->logon_script
.string
);
1777 /* Get the home drive */
1778 fstrcpy(homedrive
, r
->home_drive
.string
);
1780 /* Get the home path */
1781 fstrcpy(homepath
, r
->home_directory
.string
);
1783 /* Get the description */
1784 fstrcpy(description
, r
->description
.string
);
1786 /* Get the display name */
1787 fstrcpy(fullname
, r
->full_name
.string
);
1789 /* Get the profile path */
1790 fstrcpy(profilepath
, r
->profile_path
.string
);
1792 /* Get lm and nt password data */
1793 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
1794 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
1795 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
1797 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
1799 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
1800 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
1801 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
1803 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
1805 unix_time
= nt_time_to_unix(r
->last_password_change
);
1807 /* Increment the uid for the new user */
1810 /* Set up group id and sambaSID for the user */
1811 group_rid
= r
->primary_gid
;
1812 for (i
=0; i
<alloced
; i
++) {
1813 if (groupmap
[i
].rid
== group_rid
) break;
1816 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1818 return NT_STATUS_UNSUCCESSFUL
;
1820 gidNumber
= groupmap
[i
].gidNumber
;
1821 snprintf(sambaSID
, sizeof(sambaSID
), groupmap
[i
].sambaSID
);
1823 /* Set up sambaAcctFlags */
1824 flags
= pdb_encode_acct_ctrl(r
->acct_flags
,
1825 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1827 /* Add the user to the temporary add ldif file */
1828 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1829 user_rdn
= sstring_sub(ou
, '=', ',');
1830 fprintf(add_fd
, "# %s, %s, %s\n", username
, user_rdn
, suffix
);
1831 fprintf_attr(add_fd
, "dn", "uid=%s,ou=%s,%s", username
, user_rdn
,
1833 SAFE_FREE(user_rdn
);
1834 fprintf(add_fd
, "ObjectClass: top\n");
1835 fprintf(add_fd
, "objectClass: inetOrgPerson\n");
1836 fprintf(add_fd
, "objectClass: posixAccount\n");
1837 fprintf(add_fd
, "objectClass: shadowAccount\n");
1838 fprintf(add_fd
, "objectClass: sambaSamAccount\n");
1839 fprintf_attr(add_fd
, "cn", "%s", username
);
1840 fprintf_attr(add_fd
, "sn", "%s", username
);
1841 fprintf_attr(add_fd
, "uid", "%s", username
);
1842 fprintf(add_fd
, "uidNumber: %d\n", ldif_uid
);
1843 fprintf(add_fd
, "gidNumber: %d\n", gidNumber
);
1844 fprintf_attr(add_fd
, "homeDirectory", "%s", homedir
);
1846 fprintf_attr(add_fd
, "sambaHomePath", "%s", homepath
);
1848 fprintf_attr(add_fd
, "sambaHomeDrive", "%s", homedrive
);
1850 fprintf_attr(add_fd
, "sambaLogonScript", "%s", logonscript
);
1851 fprintf(add_fd
, "loginShell: %s\n",
1852 ((r
->acct_flags
& ACB_NORMAL
) ?
1853 "/bin/bash" : "/bin/false"));
1854 fprintf(add_fd
, "gecos: System User\n");
1856 fprintf_attr(add_fd
, "description", "%s", description
);
1857 fprintf(add_fd
, "sambaSID: %s-%d\n", sid
, rid
);
1858 fprintf(add_fd
, "sambaPrimaryGroupSID: %s\n", sambaSID
);
1860 fprintf_attr(add_fd
, "displayName", "%s", fullname
);
1862 fprintf_attr(add_fd
, "sambaProfilePath", "%s", profilepath
);
1863 if (strcmp(nopasswd
, hex_lm_passwd
) != 0)
1864 fprintf(add_fd
, "sambaLMPassword: %s\n", hex_lm_passwd
);
1865 if (strcmp(nopasswd
, hex_nt_passwd
) != 0)
1866 fprintf(add_fd
, "sambaNTPassword: %s\n", hex_nt_passwd
);
1867 fprintf(add_fd
, "sambaPwdLastSet: %d\n", (int)unix_time
);
1868 fprintf(add_fd
, "sambaAcctFlags: %s\n", flags
);
1869 fprintf(add_fd
, "\n");
1873 return NT_STATUS_OK
;
1876 static NTSTATUS
fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS
*r
,
1878 FILE *add_fd
, fstring sid
,
1882 fstring aliasname
, description
;
1883 uint32 grouptype
= 0, g_rid
= 0;
1884 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1886 /* Get the alias name */
1887 fstrcpy(aliasname
, r
->alias_name
.string
);
1889 /* Get the alias description */
1890 fstrcpy(description
, r
->description
.string
);
1892 /* Set up the group type */
1894 case SAM_DATABASE_DOMAIN
:
1897 case SAM_DATABASE_BUILTIN
:
1906 These groups are entered by populate_ldap_for_ldif
1907 Note that populate creates a group called Relicators,
1908 but NT returns a group called Replicator
1910 if (strcmp(aliasname
, "Domain Admins") == 0 ||
1911 strcmp(aliasname
, "Domain Users") == 0 ||
1912 strcmp(aliasname
, "Domain Guests") == 0 ||
1913 strcmp(aliasname
, "Domain Computers") == 0 ||
1914 strcmp(aliasname
, "Administrators") == 0 ||
1915 strcmp(aliasname
, "Print Operators") == 0 ||
1916 strcmp(aliasname
, "Backup Operators") == 0 ||
1917 strcmp(aliasname
, "Replicator") == 0) {
1918 SAFE_FREE(group_attr
);
1919 return NT_STATUS_OK
;
1921 /* Increment the gid for the new group */
1925 /* Map the group rid and gid */
1927 groupmap
->gidNumber
= ldif_gid
;
1928 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1929 "%s-%d", sid
, g_rid
);
1931 /* Write the data to the temporary add ldif file */
1932 fprintf(add_fd
, "# %s, %s, %s\n", aliasname
, group_attr
,
1934 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", aliasname
, group_attr
,
1936 fprintf(add_fd
, "objectClass: posixGroup\n");
1937 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1938 fprintf(add_fd
, "cn: %s\n", aliasname
);
1939 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1940 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1941 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1942 fprintf_attr(add_fd
, "displayName", "%s", aliasname
);
1944 fprintf_attr(add_fd
, "description", "%s", description
);
1945 fprintf(add_fd
, "\n");
1948 SAFE_FREE(group_attr
);
1950 return NT_STATUS_OK
;
1953 static NTSTATUS
fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER
*r
,
1956 ACCOUNTMAP
*accountmap
,
1957 FILE *mod_fd
, int alloced
)
1960 uint32 group_rid
= 0, rid
= 0;
1963 /* Get the dn for the group */
1964 if (r
->num_rids
> 0) {
1966 for (j
=0; j
<alloced
; j
++) {
1967 if (groupmap
[j
].rid
== group_rid
) break;
1970 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1972 return NT_STATUS_UNSUCCESSFUL
;
1974 snprintf(group_dn
, sizeof(group_dn
), "%s", groupmap
[j
].group_dn
);
1975 fprintf(mod_fd
, "dn: %s\n", group_dn
);
1977 /* Get the cn for each member */
1978 for (i
=0; i
< r
->num_rids
; i
++) {
1980 for (k
=0; k
<alloced
; k
++) {
1981 if (accountmap
[k
].rid
== rid
) break;
1984 DEBUG(1, ("Could not find rid %d in "
1985 "accountmap array\n", rid
));
1986 return NT_STATUS_UNSUCCESSFUL
;
1988 fprintf(mod_fd
, "memberUid: %s\n", accountmap
[k
].cn
);
1990 fprintf(mod_fd
, "\n");
1995 return NT_STATUS_OK
;
1998 static NTSTATUS
fetch_database_to_ldif(struct rpc_pipe_client
*pipe_hnd
,
2001 const char *user_file
)
2004 const char *builtin_sid
= "S-1-5-32";
2005 char *add_name
= NULL
, *mod_name
= NULL
;
2006 const char *add_template
= "/tmp/add.ldif.XXXXXX";
2007 const char *mod_template
= "/tmp/mod.ldif.XXXXXX";
2008 fstring sid
, domainname
;
2009 NTSTATUS ret
= NT_STATUS_OK
, result
;
2011 TALLOC_CTX
*mem_ctx
;
2013 FILE *add_file
= NULL
, *mod_file
= NULL
, *ldif_file
= NULL
;
2014 int num_alloced
= 0, g_index
= 0, a_index
= 0;
2015 const char *logon_server
= pipe_hnd
->cli
->desthost
;
2016 const char *computername
= global_myname();
2017 struct netr_Authenticator credential
;
2018 struct netr_Authenticator return_authenticator
;
2019 enum netr_SamDatabaseID database_id
= db_type
;
2020 uint16_t restart_state
= 0;
2021 uint32_t sync_context
= 0;
2023 /* Set up array for mapping accounts to groups */
2024 /* Array element is the group rid */
2025 GROUPMAP
*groupmap
= NULL
;
2027 /* Set up array for mapping account rid's to cn's */
2028 /* Array element is the account rid */
2029 ACCOUNTMAP
*accountmap
= NULL
;
2031 if (!(mem_ctx
= talloc_init("fetch_database"))) {
2032 return NT_STATUS_NO_MEMORY
;
2035 /* Ensure we have an output file */
2037 ldif_file
= fopen(user_file
, "a");
2042 fprintf(stderr
, "Could not open %s\n", user_file
);
2043 DEBUG(1, ("Could not open %s\n", user_file
));
2044 ret
= NT_STATUS_UNSUCCESSFUL
;
2048 add_name
= talloc_strdup(mem_ctx
, add_template
);
2049 mod_name
= talloc_strdup(mem_ctx
, mod_template
);
2050 if (!add_name
|| !mod_name
) {
2051 ret
= NT_STATUS_NO_MEMORY
;
2055 /* Open the add and mod ldif files */
2056 if (!(add_file
= fdopen(smb_mkstemp(add_name
),"w"))) {
2057 DEBUG(1, ("Could not open %s\n", add_name
));
2058 ret
= NT_STATUS_UNSUCCESSFUL
;
2061 if (!(mod_file
= fdopen(smb_mkstemp(mod_name
),"w"))) {
2062 DEBUG(1, ("Could not open %s\n", mod_name
));
2063 ret
= NT_STATUS_UNSUCCESSFUL
;
2068 sid_to_fstring(sid
, &dom_sid
);
2070 /* Get the ldap suffix */
2071 suffix
= lp_ldap_suffix();
2072 if (suffix
== NULL
|| strcmp(suffix
, "") == 0) {
2073 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2077 /* Get other smb.conf data */
2078 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2079 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2083 /* Allocate initial memory for groupmap and accountmap arrays */
2084 if (init_ldap
== 1) {
2085 groupmap
= SMB_MALLOC_ARRAY(GROUPMAP
, 8);
2086 accountmap
= SMB_MALLOC_ARRAY(ACCOUNTMAP
, 8);
2087 if (groupmap
== NULL
|| accountmap
== NULL
) {
2088 DEBUG(1,("GROUPMAP malloc failed\n"));
2089 ret
= NT_STATUS_NO_MEMORY
;
2093 /* Initialize the arrays */
2094 memset(groupmap
, 0, sizeof(GROUPMAP
)*8);
2095 memset(accountmap
, 0, sizeof(ACCOUNTMAP
)*8);
2097 /* Remember how many we malloced */
2100 /* Initial database population */
2101 populate_ldap_for_ldif(sid
, suffix
, builtin_sid
, add_file
);
2102 map_populate_groups(groupmap
, accountmap
, sid
, suffix
,
2105 /* Don't do this again */
2109 /* Announce what we are doing */
2111 case SAM_DATABASE_DOMAIN
:
2112 d_fprintf(stderr
, "Fetching DOMAIN database\n");
2114 case SAM_DATABASE_BUILTIN
:
2115 d_fprintf(stderr
, "Fetching BUILTIN database\n");
2117 case SAM_DATABASE_PRIVS
:
2118 d_fprintf(stderr
, "Fetching PRIVS databases\n");
2122 "Fetching unknown database type %u\n",
2128 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2130 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
2132 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
2136 &return_authenticator
,
2143 /* Check returned credentials. */
2144 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
2145 &return_authenticator
.cred
)) {
2146 DEBUG(0,("credentials chain check failed\n"));
2147 return NT_STATUS_ACCESS_DENIED
;
2150 if (NT_STATUS_IS_ERR(result
)) {
2154 num_deltas
= delta_enum_array
->num_deltas
;
2156 /* Re-allocate memory for groupmap and accountmap arrays */
2157 groupmap
= SMB_REALLOC_ARRAY(groupmap
, GROUPMAP
,
2158 num_deltas
+num_alloced
);
2159 accountmap
= SMB_REALLOC_ARRAY(accountmap
, ACCOUNTMAP
,
2160 num_deltas
+num_alloced
);
2161 if (groupmap
== NULL
|| accountmap
== NULL
) {
2162 DEBUG(1,("GROUPMAP malloc failed\n"));
2163 ret
= NT_STATUS_NO_MEMORY
;
2167 /* Initialize the new records */
2168 memset(&groupmap
[num_alloced
], 0,
2169 sizeof(GROUPMAP
)*num_deltas
);
2170 memset(&accountmap
[num_alloced
], 0,
2171 sizeof(ACCOUNTMAP
)*num_deltas
);
2173 /* Remember how many we alloced this time */
2174 num_alloced
+= num_deltas
;
2176 /* Loop through the deltas */
2177 for (k
=0; k
<num_deltas
; k
++) {
2179 union netr_DELTA_UNION u
=
2180 delta_enum_array
->delta_enum
[k
].delta_union
;
2181 union netr_DELTA_ID_UNION id
=
2182 delta_enum_array
->delta_enum
[k
].delta_id_union
;
2184 switch(delta_enum_array
->delta_enum
[k
].delta_type
) {
2185 case NETR_DELTA_DOMAIN
:
2186 /* Is this case needed? */
2188 u
.domain
->domain_name
.string
);
2191 case NETR_DELTA_GROUP
:
2192 fetch_group_info_to_ldif(
2195 add_file
, sid
, suffix
);
2199 case NETR_DELTA_USER
:
2200 fetch_account_info_to_ldif(
2202 &accountmap
[a_index
], add_file
,
2203 sid
, suffix
, num_alloced
);
2207 case NETR_DELTA_ALIAS
:
2208 fetch_alias_info_to_ldif(
2209 u
.alias
, &groupmap
[g_index
],
2210 add_file
, sid
, suffix
, db_type
);
2214 case NETR_DELTA_GROUP_MEMBER
:
2215 fetch_groupmem_info_to_ldif(
2216 u
.group_member
, id
.rid
,
2217 groupmap
, accountmap
,
2218 mod_file
, num_alloced
);
2221 case NETR_DELTA_ALIAS_MEMBER
:
2222 case NETR_DELTA_POLICY
:
2223 case NETR_DELTA_ACCOUNT
:
2224 case NETR_DELTA_TRUSTED_DOMAIN
:
2225 case NETR_DELTA_SECRET
:
2226 case NETR_DELTA_RENAME_GROUP
:
2227 case NETR_DELTA_RENAME_USER
:
2228 case NETR_DELTA_RENAME_ALIAS
:
2229 case NETR_DELTA_DELETE_GROUP
:
2230 case NETR_DELTA_DELETE_USER
:
2231 case NETR_DELTA_MODIFY_COUNT
:
2234 } /* end of switch */
2235 } /* end of for loop */
2237 /* Increment sync_context */
2240 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2242 /* Write ldif data to the user's file */
2243 if (db_type
== SAM_DATABASE_DOMAIN
) {
2245 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2247 "# =================================\n\n");
2249 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2251 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2253 "# ==================================\n\n");
2256 fseek(add_file
, 0, SEEK_SET
);
2257 transfer_file(fileno(add_file
), fileno(ldif_file
), (size_t) -1);
2259 if (db_type
== SAM_DATABASE_DOMAIN
) {
2261 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2263 "# ====================================\n\n");
2265 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2267 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2269 "# =====================================\n\n");
2272 fseek(mod_file
, 0, SEEK_SET
);
2273 transfer_file(fileno(mod_file
), fileno(ldif_file
), (size_t) -1);
2277 /* Close and delete the ldif files */
2282 if ((add_name
!= NULL
) &&
2283 strcmp(add_name
, add_template
) && (unlink(add_name
))) {
2284 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2285 add_name
, strerror(errno
)));
2292 if ((mod_name
!= NULL
) &&
2293 strcmp(mod_name
, mod_template
) && (unlink(mod_name
))) {
2294 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2295 mod_name
, strerror(errno
)));
2298 if (ldif_file
&& (ldif_file
!= stdout
)) {
2302 /* Deallocate memory for the mapping arrays */
2303 SAFE_FREE(groupmap
);
2304 SAFE_FREE(accountmap
);
2307 talloc_destroy(mem_ctx
);
2312 * Basic usage function for 'net rpc vampire'
2313 * @param argc Standard main() style argc
2314 * @param argc Standard main() style argv. Initial components are already
2318 int rpc_vampire_usage(int argc
, const char **argv
)
2320 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2321 "\t to pull accounts from a remote PDC where we are a BDC\n"
2322 "\t\t no args puts accounts in local passdb from smb.conf\n"
2323 "\t\t ldif - put accounts in ldif format (file defaults to "
2326 net_common_flags_usage(argc
, argv
);
2331 /* dump sam database via samsync rpc calls */
2332 NTSTATUS
rpc_vampire_internals(const DOM_SID
*domain_sid
,
2333 const char *domain_name
,
2334 struct cli_state
*cli
,
2335 struct rpc_pipe_client
*pipe_hnd
,
2336 TALLOC_CTX
*mem_ctx
,
2341 fstring my_dom_sid_str
;
2342 fstring rem_dom_sid_str
;
2344 if (!sid_equal(domain_sid
, get_global_sam_sid())) {
2345 d_printf("Cannot import users from %s at this time, "
2346 "as the current domain:\n\t%s: %s\nconflicts "
2347 "with the remote domain\n\t%s: %s\n"
2348 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2349 "workgroup=%s\n\n in your smb.conf?\n",
2351 get_global_sam_name(),
2352 sid_to_fstring(my_dom_sid_str
,
2353 get_global_sam_sid()),
2354 domain_name
, sid_to_fstring(rem_dom_sid_str
,
2357 return NT_STATUS_UNSUCCESSFUL
;
2360 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2361 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2362 *domain_sid
, argv
[1]);
2364 result
= fetch_database(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2368 if (!NT_STATUS_IS_OK(result
)) {
2369 d_fprintf(stderr
, "Failed to fetch domain database: %s\n",
2371 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOT_SUPPORTED
))
2372 d_fprintf(stderr
, "Perhaps %s is a Windows 2000 "
2373 "native mode domain?\n", domain_name
);
2377 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2378 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2379 global_sid_Builtin
, argv
[1]);
2381 result
= fetch_database(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2382 global_sid_Builtin
);
2385 if (!NT_STATUS_IS_OK(result
)) {
2386 d_fprintf(stderr
, "Failed to fetch builtin database: %s\n",
2391 /* Currently we crash on PRIVS somewhere in unmarshalling */
2392 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */