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 void display_domain_info(struct netr_DELTA_DOMAIN
*r
)
104 u_logout
= uint64s_nt_time_to_unix_abs((const uint64
*)&r
->force_logoff_time
);
106 d_printf("Domain name: %s\n", r
->domain_name
.string
);
108 d_printf("Minimal Password Length: %d\n", r
->min_password_length
);
109 d_printf("Password History Length: %d\n", r
->password_history_length
);
111 d_printf("Force Logoff: %d\n", (int)u_logout
);
113 d_printf("Max Password Age: %s\n", display_time(r
->max_password_age
));
114 d_printf("Min Password Age: %s\n", display_time(r
->min_password_age
));
118 d_printf("Lockout Time: %s\n", display_time(a
->account_lockout
.lockout_duration
));
119 d_printf("Lockout Reset Time: %s\n", display_time(a
->account_lockout
.reset_count
));
120 d_printf("Bad Attempt Lockout: %d\n", a
->account_lockout
.bad_attempt_lockout
);
122 d_printf("User must logon to change password: %d\n", r
->logon_to_chgpass
);
125 static void display_group_info(uint32_t rid
, struct netr_DELTA_GROUP
*r
)
127 d_printf("Group '%s' ", r
->group_name
.string
);
128 d_printf("desc='%s', rid=%u\n", r
->description
.string
, rid
);
131 static void display_sam_entry(struct netr_DELTA_ENUM
*r
)
133 union netr_DELTA_UNION u
= r
->delta_union
;
134 union netr_DELTA_ID_UNION id
= r
->delta_id_union
;
136 switch (r
->delta_type
) {
137 case NETR_DELTA_DOMAIN
:
138 display_domain_info(u
.domain
);
140 case NETR_DELTA_GROUP
:
141 display_group_info(id
.rid
, u
.group
);
144 case NETR_DELTA_DELETE_GROUP
:
145 printf("Delete Group: %d\n",
146 u
.delete_account
.unknown
);
148 case NETR_DELTA_RENAME_GROUP
:
149 printf("Rename Group: %s -> %s\n",
150 u
.rename_group
->OldName
.string
,
151 u
.rename_group
->NewName
.string
);
154 case NETR_DELTA_USER
:
155 display_account_info(id
.rid
, u
.user
);
158 case NETR_DELTA_DELETE_USER
:
159 printf("Delete User: %d\n",
162 case NETR_DELTA_RENAME_USER
:
163 printf("Rename user: %s -> %s\n",
164 u
.rename_user
->OldName
.string
,
165 u
.rename_user
->NewName
.string
);
168 case NETR_DELTA_GROUP_MEMBER
:
169 display_group_mem_info(id
.rid
, u
.group_member
);
171 case NETR_DELTA_ALIAS
:
172 display_alias_info(id
.rid
, u
.alias
);
175 case NETR_DELTA_DELETE_ALIAS
:
176 printf("Delete Alias: %d\n",
179 case NETR_DELTA_RENAME_ALIAS
:
180 printf("Rename alias: %s -> %s\n",
181 u
.rename_alias
->OldName
.string
,
182 u
.rename_alias
->NewName
.string
);
185 case NETR_DELTA_ALIAS_MEMBER
:
186 display_alias_mem(id
.rid
, u
.alias_member
);
189 case NETR_DELTA_POLICY
:
192 case NETR_DELTA_TRUSTED_DOMAIN
:
193 printf("Trusted Domain: %s\n",
194 u
.trusted_domain
->domain_name
.string
);
196 case NETR_DELTA_DELETE_TRUST
:
197 printf("Delete Trust: %d\n",
198 u
.delete_trust
.unknown
);
200 case NETR_DELTA_ACCOUNT
:
203 case NETR_DELTA_DELETE_ACCOUNT
:
204 printf("Delete Account: %d\n",
205 u
.delete_account
.unknown
);
207 case NETR_DELTA_SECRET
:
210 case NETR_DELTA_DELETE_SECRET
:
211 printf("Delete Secret: %d\n",
212 u
.delete_secret
.unknown
);
214 case NETR_DELTA_DELETE_GROUP2
:
215 printf("Delete Group2: %s\n",
216 u
.delete_group
->account_name
);
218 case NETR_DELTA_DELETE_USER2
:
219 printf("Delete User2: %s\n",
220 u
.delete_user
->account_name
);
222 case NETR_DELTA_MODIFY_COUNT
:
223 printf("sam sequence update: 0x%016llx\n",
224 (unsigned long long) *u
.modified_count
);
227 /* The following types are recognised but not handled */
228 case NETR_DELTA_RENAME_GROUP
:
229 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
231 case NETR_DELTA_RENAME_USER
:
232 d_printf("NETR_DELTA_RENAME_USER not handled\n");
234 case NETR_DELTA_RENAME_ALIAS
:
235 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
237 case NETR_DELTA_POLICY
:
238 d_printf("NETR_DELTA_POLICY not handled\n");
240 case NETR_DELTA_TRUSTED_DOMAIN
:
241 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
243 case NETR_DELTA_ACCOUNT
:
244 d_printf("NETR_DELTA_ACCOUNT not handled\n");
246 case NETR_DELTA_SECRET
:
247 d_printf("NETR_DELTA_SECRET not handled\n");
249 case NETR_DELTA_DELETE_GROUP
:
250 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
252 case NETR_DELTA_DELETE_USER
:
253 d_printf("NETR_DELTA_DELETE_USER not handled\n");
255 case NETR_DELTA_MODIFY_COUNT
:
256 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
258 case NETR_DELTA_DELETE_ALIAS
:
259 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
261 case NETR_DELTA_DELETE_TRUST
:
262 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
264 case NETR_DELTA_DELETE_ACCOUNT
:
265 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
267 case NETR_DELTA_DELETE_SECRET
:
268 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
270 case NETR_DELTA_DELETE_GROUP2
:
271 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
273 case NETR_DELTA_DELETE_USER2
:
274 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
277 printf("unknown delta type 0x%02x\n",
283 static void dump_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
)
288 const char *logon_server
= pipe_hnd
->cli
->desthost
;
289 const char *computername
= global_myname();
290 struct netr_Authenticator credential
;
291 struct netr_Authenticator return_authenticator
;
292 enum netr_SamDatabaseID database_id
= db_type
;
293 uint16_t restart_state
= 0;
294 uint32_t sync_context
= 0;
296 if (!(mem_ctx
= talloc_init("dump_database"))) {
301 case SAM_DATABASE_DOMAIN
:
302 d_printf("Dumping DOMAIN database\n");
304 case SAM_DATABASE_BUILTIN
:
305 d_printf("Dumping BUILTIN database\n");
307 case SAM_DATABASE_PRIVS
:
308 d_printf("Dumping PRIVS databases\n");
311 d_printf("Dumping unknown database type %u\n", db_type
);
316 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
318 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
320 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
324 &return_authenticator
,
331 /* Check returned credentials. */
332 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
333 &return_authenticator
.cred
)) {
334 DEBUG(0,("credentials chain check failed\n"));
338 if (NT_STATUS_IS_ERR(result
)) {
342 /* Display results */
343 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
344 display_sam_entry(&delta_enum_array
->delta_enum
[i
]);
347 TALLOC_FREE(delta_enum_array
);
349 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
351 talloc_destroy(mem_ctx
);
354 /* dump sam database via samsync rpc calls */
355 NTSTATUS
rpc_samdump_internals(const DOM_SID
*domain_sid
,
356 const char *domain_name
,
357 struct cli_state
*cli
,
358 struct rpc_pipe_client
*pipe_hnd
,
364 /* net_rpc.c now always tries to create an schannel pipe.. */
366 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
367 uchar trust_password
[16];
368 uint32 neg_flags
= NETLOGON_NEG_SELECT_AUTH2_FLAGS
;
369 uint32 sec_channel_type
= 0;
371 if (!secrets_fetch_trust_account_password(domain_name
,
373 NULL
, &sec_channel_type
)) {
374 DEBUG(0,("Could not fetch trust account password\n"));
378 nt_status
= rpccli_netlogon_setup_creds(pipe_hnd
,
386 if (!NT_STATUS_IS_OK(nt_status
)) {
387 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
392 dump_database(pipe_hnd
, SAM_DATABASE_DOMAIN
);
393 dump_database(pipe_hnd
, SAM_DATABASE_BUILTIN
);
394 dump_database(pipe_hnd
, SAM_DATABASE_PRIVS
);
399 /* Convert a struct samu_DELTA to a struct samu. */
400 #define STRING_CHANGED (old_string && !new_string) ||\
401 (!old_string && new_string) ||\
402 (old_string && new_string && (strcmp(old_string, new_string) != 0))
404 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
406 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
408 static NTSTATUS
sam_account_from_delta(struct samu
*account
,
409 struct netr_DELTA_USER
*r
)
411 const char *old_string
, *new_string
;
412 time_t unix_time
, stored_time
;
413 uchar lm_passwd
[16], nt_passwd
[16];
414 static uchar zero_buf
[16];
416 /* Username, fullname, home dir, dir drive, logon script, acct
417 desc, workstations, profile. */
419 if (r
->account_name
.string
) {
420 old_string
= pdb_get_nt_username(account
);
421 new_string
= r
->account_name
.string
;
423 if (STRING_CHANGED
) {
424 pdb_set_nt_username(account
, new_string
, PDB_CHANGED
);
427 /* Unix username is the same - for sanity */
428 old_string
= pdb_get_username( account
);
429 if (STRING_CHANGED
) {
430 pdb_set_username(account
, new_string
, PDB_CHANGED
);
434 if (r
->full_name
.string
) {
435 old_string
= pdb_get_fullname(account
);
436 new_string
= r
->full_name
.string
;
439 pdb_set_fullname(account
, new_string
, PDB_CHANGED
);
442 if (r
->home_directory
.string
) {
443 old_string
= pdb_get_homedir(account
);
444 new_string
= r
->home_directory
.string
;
447 pdb_set_homedir(account
, new_string
, PDB_CHANGED
);
450 if (r
->home_drive
.string
) {
451 old_string
= pdb_get_dir_drive(account
);
452 new_string
= r
->home_drive
.string
;
455 pdb_set_dir_drive(account
, new_string
, PDB_CHANGED
);
458 if (r
->logon_script
.string
) {
459 old_string
= pdb_get_logon_script(account
);
460 new_string
= r
->logon_script
.string
;
463 pdb_set_logon_script(account
, new_string
, PDB_CHANGED
);
466 if (r
->description
.string
) {
467 old_string
= pdb_get_acct_desc(account
);
468 new_string
= r
->description
.string
;
471 pdb_set_acct_desc(account
, new_string
, PDB_CHANGED
);
474 if (r
->workstations
.string
) {
475 old_string
= pdb_get_workstations(account
);
476 new_string
= r
->workstations
.string
;
479 pdb_set_workstations(account
, new_string
, PDB_CHANGED
);
482 if (r
->profile_path
.string
) {
483 old_string
= pdb_get_profile_path(account
);
484 new_string
= r
->profile_path
.string
;
487 pdb_set_profile_path(account
, new_string
, PDB_CHANGED
);
490 if (r
->parameters
.string
) {
493 old_string
= pdb_get_munged_dial(account
);
494 mung
.length
= r
->parameters
.length
;
495 mung
.data
= (uint8
*) r
->parameters
.string
;
496 newstr
= (mung
.length
== 0) ? NULL
:
497 base64_encode_data_blob(talloc_tos(), mung
);
499 if (STRING_CHANGED_NC(old_string
, newstr
))
500 pdb_set_munged_dial(account
, newstr
, PDB_CHANGED
);
504 /* User and group sid */
505 if (pdb_get_user_rid(account
) != r
->rid
)
506 pdb_set_user_sid_from_rid(account
, r
->rid
, PDB_CHANGED
);
507 if (pdb_get_group_rid(account
) != r
->primary_gid
)
508 pdb_set_group_sid_from_rid(account
, r
->primary_gid
, PDB_CHANGED
);
510 /* Logon and password information */
511 if (!nt_time_is_zero(&r
->last_logon
)) {
512 unix_time
= nt_time_to_unix(r
->last_logon
);
513 stored_time
= pdb_get_logon_time(account
);
514 if (stored_time
!= unix_time
)
515 pdb_set_logon_time(account
, unix_time
, PDB_CHANGED
);
518 if (!nt_time_is_zero(&r
->last_logoff
)) {
519 unix_time
= nt_time_to_unix(r
->last_logoff
);
520 stored_time
= pdb_get_logoff_time(account
);
521 if (stored_time
!= unix_time
)
522 pdb_set_logoff_time(account
, unix_time
,PDB_CHANGED
);
526 if (pdb_get_logon_divs(account
) != r
->logon_hours
.units_per_week
)
527 pdb_set_logon_divs(account
, r
->logon_hours
.units_per_week
, PDB_CHANGED
);
530 /* no idea what to do with this one - gd */
531 /* Max Logon Hours */
532 if (delta
->unknown1
!= pdb_get_unknown_6(account
)) {
533 pdb_set_unknown_6(account
, delta
->unknown1
, PDB_CHANGED
);
536 /* Logon Hours Len */
537 if (r
->logon_hours
.units_per_week
/8 != pdb_get_hours_len(account
)) {
538 pdb_set_hours_len(account
, r
->logon_hours
.units_per_week
/8, PDB_CHANGED
);
542 if (r
->logon_hours
.bits
) {
543 char oldstr
[44], newstr
[44];
544 pdb_sethexhours(oldstr
, pdb_get_hours(account
));
545 pdb_sethexhours(newstr
, r
->logon_hours
.bits
);
546 if (!strequal(oldstr
, newstr
))
547 pdb_set_hours(account
, r
->logon_hours
.bits
, PDB_CHANGED
);
550 if (pdb_get_bad_password_count(account
) != r
->bad_password_count
)
551 pdb_set_bad_password_count(account
, r
->bad_password_count
, PDB_CHANGED
);
553 if (pdb_get_logon_count(account
) != r
->logon_count
)
554 pdb_set_logon_count(account
, r
->logon_count
, PDB_CHANGED
);
556 if (!nt_time_is_zero(&r
->last_password_change
)) {
557 unix_time
= nt_time_to_unix(r
->last_password_change
);
558 stored_time
= pdb_get_pass_last_set_time(account
);
559 if (stored_time
!= unix_time
)
560 pdb_set_pass_last_set_time(account
, unix_time
, PDB_CHANGED
);
562 /* no last set time, make it now */
563 pdb_set_pass_last_set_time(account
, time(NULL
), PDB_CHANGED
);
566 if (!nt_time_is_zero(&r
->acct_expiry
)) {
567 unix_time
= nt_time_to_unix(r
->acct_expiry
);
568 stored_time
= pdb_get_kickoff_time(account
);
569 if (stored_time
!= unix_time
)
570 pdb_set_kickoff_time(account
, unix_time
, PDB_CHANGED
);
573 /* Decode hashes from password hash
574 Note that win2000 may send us all zeros for the hashes if it doesn't
575 think this channel is secure enough - don't set the passwords at all
578 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
579 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, lm_passwd
, 0);
580 pdb_set_lanman_passwd(account
, lm_passwd
, PDB_CHANGED
);
583 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
584 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, nt_passwd
, 0);
585 pdb_set_nt_passwd(account
, nt_passwd
, PDB_CHANGED
);
588 /* TODO: account expiry time */
590 pdb_set_acct_ctrl(account
, r
->acct_flags
, PDB_CHANGED
);
592 pdb_set_domain(account
, lp_workgroup(), PDB_CHANGED
);
597 static NTSTATUS
fetch_account_info(uint32_t rid
,
598 struct netr_DELTA_USER
*r
)
601 NTSTATUS nt_ret
= NT_STATUS_UNSUCCESSFUL
;
603 char *add_script
= NULL
;
604 struct samu
*sam_account
=NULL
;
609 struct passwd
*passwd
;
612 fstrcpy(account
, r
->account_name
.string
);
613 d_printf("Creating account: %s\n", account
);
615 if ( !(sam_account
= samu_new( NULL
)) ) {
616 return NT_STATUS_NO_MEMORY
;
619 if (!(passwd
= Get_Pwnam_alloc(sam_account
, account
))) {
620 /* Create appropriate user */
621 if (r
->acct_flags
& ACB_NORMAL
) {
622 add_script
= talloc_strdup(sam_account
,
623 lp_adduser_script());
624 } else if ( (r
->acct_flags
& ACB_WSTRUST
) ||
625 (r
->acct_flags
& ACB_SVRTRUST
) ||
626 (r
->acct_flags
& ACB_DOMTRUST
) ) {
627 add_script
= talloc_strdup(sam_account
,
628 lp_addmachine_script());
630 DEBUG(1, ("Unknown user type: %s\n",
631 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
632 nt_ret
= NT_STATUS_UNSUCCESSFUL
;
636 nt_ret
= NT_STATUS_NO_MEMORY
;
641 add_script
= talloc_all_string_sub(sam_account
,
646 nt_ret
= NT_STATUS_NO_MEMORY
;
649 add_ret
= smbrun(add_script
,NULL
);
650 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
651 "gave %d\n", add_script
, add_ret
));
653 smb_nscd_flush_user_cache();
657 /* try and find the possible unix account again */
658 if ( !(passwd
= Get_Pwnam_alloc(sam_account
, account
)) ) {
659 d_fprintf(stderr
, "Could not create posix account info for '%s'\n", account
);
660 nt_ret
= NT_STATUS_NO_SUCH_USER
;
665 sid_copy(&user_sid
, get_global_sam_sid());
666 sid_append_rid(&user_sid
, r
->rid
);
668 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
669 sid_to_fstring(sid_string
, &user_sid
), account
));
670 if (!pdb_getsampwsid(sam_account
, &user_sid
)) {
671 sam_account_from_delta(sam_account
, r
);
672 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
673 sid_to_fstring(sid_string
, &user_sid
),
674 pdb_get_username(sam_account
)));
675 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account
))) {
676 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
678 return NT_STATUS_ACCESS_DENIED
;
681 sam_account_from_delta(sam_account
, r
);
682 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
683 sid_to_fstring(sid_string
, &user_sid
),
684 pdb_get_username(sam_account
)));
685 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account
))) {
686 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
688 TALLOC_FREE(sam_account
);
689 return NT_STATUS_ACCESS_DENIED
;
693 if (pdb_get_group_sid(sam_account
) == NULL
) {
694 return NT_STATUS_UNSUCCESSFUL
;
697 group_sid
= *pdb_get_group_sid(sam_account
);
699 if (!pdb_getgrsid(&map
, group_sid
)) {
700 DEBUG(0, ("Primary group of %s has no mapping!\n",
701 pdb_get_username(sam_account
)));
703 if (map
.gid
!= passwd
->pw_gid
) {
704 if (!(grp
= getgrgid(map
.gid
))) {
705 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
706 (unsigned long)map
.gid
, pdb_get_username(sam_account
), sid_string_tos(&group_sid
)));
708 smb_set_primary_group(grp
->gr_name
, pdb_get_username(sam_account
));
714 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
715 pdb_get_username(sam_account
)));
719 TALLOC_FREE(sam_account
);
723 static NTSTATUS
fetch_group_info(uint32_t rid
,
724 struct netr_DELTA_GROUP
*r
)
728 struct group
*grp
= NULL
;
734 fstrcpy(name
, r
->group_name
.string
);
735 fstrcpy(comment
, r
->description
.string
);
737 /* add the group to the mapping table */
738 sid_copy(&group_sid
, get_global_sam_sid());
739 sid_append_rid(&group_sid
, rid
);
740 sid_to_fstring(sid_string
, &group_sid
);
742 if (pdb_getgrsid(&map
, group_sid
)) {
744 grp
= getgrgid(map
.gid
);
751 /* No group found from mapping, find it from its name. */
752 if ((grp
= getgrnam(name
)) == NULL
) {
754 /* No appropriate group found, create one */
756 d_printf("Creating unix group: '%s'\n", name
);
758 if (smb_create_group(name
, &gid
) != 0)
759 return NT_STATUS_ACCESS_DENIED
;
761 if ((grp
= getgrnam(name
)) == NULL
)
762 return NT_STATUS_ACCESS_DENIED
;
766 map
.gid
= grp
->gr_gid
;
768 map
.sid_name_use
= SID_NAME_DOM_GRP
;
769 fstrcpy(map
.nt_name
, name
);
770 if (r
->description
.string
) {
771 fstrcpy(map
.comment
, comment
);
773 fstrcpy(map
.comment
, "");
777 pdb_add_group_mapping_entry(&map
);
779 pdb_update_group_mapping_entry(&map
);
784 static NTSTATUS
fetch_group_mem_info(uint32_t rid
,
785 struct netr_DELTA_GROUP_MEMBER
*r
)
788 TALLOC_CTX
*t
= NULL
;
789 char **nt_members
= NULL
;
795 if (r
->num_rids
== 0) {
799 sid_copy(&group_sid
, get_global_sam_sid());
800 sid_append_rid(&group_sid
, rid
);
802 if (!get_domain_group_from_sid(group_sid
, &map
)) {
803 DEBUG(0, ("Could not find global group %d\n", rid
));
804 return NT_STATUS_NO_SUCH_GROUP
;
807 if (!(grp
= getgrgid(map
.gid
))) {
808 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map
.gid
));
809 return NT_STATUS_NO_SUCH_GROUP
;
812 d_printf("Group members of %s: ", grp
->gr_name
);
814 if (!(t
= talloc_init("fetch_group_mem_info"))) {
815 DEBUG(0, ("could not talloc_init\n"));
816 return NT_STATUS_NO_MEMORY
;
820 if ((nt_members
= TALLOC_ZERO_ARRAY(t
, char *, r
->num_rids
)) == NULL
) {
821 DEBUG(0, ("talloc failed\n"));
823 return NT_STATUS_NO_MEMORY
;
829 for (i
=0; i
< r
->num_rids
; i
++) {
830 struct samu
*member
= NULL
;
833 if ( !(member
= samu_new(t
)) ) {
835 return NT_STATUS_NO_MEMORY
;
838 sid_copy(&member_sid
, get_global_sam_sid());
839 sid_append_rid(&member_sid
, r
->rids
[i
]);
841 if (!pdb_getsampwsid(member
, &member_sid
)) {
842 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
843 r
->rids
[i
], sid_string_tos(&member_sid
), grp
->gr_name
));
848 if (pdb_get_group_rid(member
) == rid
) {
849 d_printf("%s(primary),", pdb_get_username(member
));
854 d_printf("%s,", pdb_get_username(member
));
855 nt_members
[i
] = talloc_strdup(t
, pdb_get_username(member
));
861 unix_members
= grp
->gr_mem
;
863 while (*unix_members
) {
864 bool is_nt_member
= False
;
865 for (i
=0; i
< r
->num_rids
; i
++) {
866 if (nt_members
[i
] == NULL
) {
867 /* This was a primary group */
871 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
877 /* We look at a unix group member that is not
878 an nt group member. So, remove it. NT is
880 smb_delete_user_group(grp
->gr_name
, *unix_members
);
885 for (i
=0; i
< r
->num_rids
; i
++) {
886 bool is_unix_member
= False
;
888 if (nt_members
[i
] == NULL
) {
889 /* This was the primary group */
893 unix_members
= grp
->gr_mem
;
895 while (*unix_members
) {
896 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
897 is_unix_member
= True
;
903 if (!is_unix_member
) {
904 /* We look at a nt group member that is not a
905 unix group member currently. So, add the nt
907 smb_add_user_group(grp
->gr_name
, nt_members
[i
]);
915 static NTSTATUS
fetch_alias_info(uint32_t rid
,
916 struct netr_DELTA_ALIAS
*r
,
921 struct group
*grp
= NULL
;
927 fstrcpy(name
, r
->alias_name
.string
);
928 fstrcpy(comment
, r
->description
.string
);
930 /* Find out whether the group is already mapped */
931 sid_copy(&alias_sid
, &dom_sid
);
932 sid_append_rid(&alias_sid
, rid
);
933 sid_to_fstring(sid_string
, &alias_sid
);
935 if (pdb_getgrsid(&map
, alias_sid
)) {
936 grp
= getgrgid(map
.gid
);
943 /* No group found from mapping, find it from its name. */
944 if ((grp
= getgrnam(name
)) == NULL
) {
945 /* No appropriate group found, create one */
946 d_printf("Creating unix group: '%s'\n", name
);
947 if (smb_create_group(name
, &gid
) != 0)
948 return NT_STATUS_ACCESS_DENIED
;
949 if ((grp
= getgrgid(gid
)) == NULL
)
950 return NT_STATUS_ACCESS_DENIED
;
954 map
.gid
= grp
->gr_gid
;
957 if (sid_equal(&dom_sid
, &global_sid_Builtin
))
958 map
.sid_name_use
= SID_NAME_WKN_GRP
;
960 map
.sid_name_use
= SID_NAME_ALIAS
;
962 fstrcpy(map
.nt_name
, name
);
963 fstrcpy(map
.comment
, comment
);
966 pdb_add_group_mapping_entry(&map
);
968 pdb_update_group_mapping_entry(&map
);
973 static NTSTATUS
fetch_alias_mem(uint32_t rid
,
974 struct netr_DELTA_ALIAS_MEMBER
*r
,
980 static NTSTATUS
fetch_domain_info(uint32_t rid
,
981 struct netr_DELTA_DOMAIN
*r
)
983 time_t u_max_age
, u_min_age
, u_logout
;
986 time_t u_lockoutreset
, u_lockouttime
;
988 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
991 u_max_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->max_password_age
);
992 u_min_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->min_password_age
);
993 u_logout
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->force_logoff_time
);
996 u_lockoutreset
= uint64s_nt_time_to_unix_abs(&delta
->account_lockout
.reset_count
);
997 u_lockouttime
= uint64s_nt_time_to_unix_abs(&delta
->account_lockout
.lockout_duration
);
999 domname
= r
->domain_name
.string
;
1001 return NT_STATUS_NO_MEMORY
;
1004 /* we don't handle BUILTIN account policies */
1005 if (!strequal(domname
, get_global_sam_name())) {
1006 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname
);
1007 return NT_STATUS_OK
;
1011 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY
,
1012 r
->password_history_length
))
1015 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN
,
1016 r
->min_password_length
))
1019 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (uint32
)u_max_age
))
1022 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (uint32
)u_min_age
))
1025 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (uint32
)u_logout
))
1029 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, delta
->account_lockout
.bad_attempt_lockout
))
1032 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME
, (uint32
)u_lockoutreset
/60))
1035 if (u_lockouttime
!= -1)
1036 u_lockouttime
/= 60;
1038 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (uint32
)u_lockouttime
))
1042 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
1043 r
->logon_to_chgpass
))
1046 return NT_STATUS_OK
;
1049 static void fetch_sam_entry(struct netr_DELTA_ENUM
*r
, DOM_SID dom_sid
)
1051 switch(r
->delta_type
) {
1052 case NETR_DELTA_USER
:
1053 fetch_account_info(r
->delta_id_union
.rid
,
1054 r
->delta_union
.user
);
1056 case NETR_DELTA_GROUP
:
1057 fetch_group_info(r
->delta_id_union
.rid
,
1058 r
->delta_union
.group
);
1060 case NETR_DELTA_GROUP_MEMBER
:
1061 fetch_group_mem_info(r
->delta_id_union
.rid
,
1062 r
->delta_union
.group_member
);
1064 case NETR_DELTA_ALIAS
:
1065 fetch_alias_info(r
->delta_id_union
.rid
,
1066 r
->delta_union
.alias
,
1069 case NETR_DELTA_ALIAS_MEMBER
:
1070 fetch_alias_mem(r
->delta_id_union
.rid
,
1071 r
->delta_union
.alias_member
,
1074 case NETR_DELTA_DOMAIN
:
1075 fetch_domain_info(r
->delta_id_union
.rid
,
1076 r
->delta_union
.domain
);
1078 /* The following types are recognised but not handled */
1079 case NETR_DELTA_RENAME_GROUP
:
1080 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1082 case NETR_DELTA_RENAME_USER
:
1083 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1085 case NETR_DELTA_RENAME_ALIAS
:
1086 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1088 case NETR_DELTA_POLICY
:
1089 d_printf("NETR_DELTA_POLICY not handled\n");
1091 case NETR_DELTA_TRUSTED_DOMAIN
:
1092 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1094 case NETR_DELTA_ACCOUNT
:
1095 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1097 case NETR_DELTA_SECRET
:
1098 d_printf("NETR_DELTA_SECRET not handled\n");
1100 case NETR_DELTA_DELETE_GROUP
:
1101 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1103 case NETR_DELTA_DELETE_USER
:
1104 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1106 case NETR_DELTA_MODIFY_COUNT
:
1107 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1109 case NETR_DELTA_DELETE_ALIAS
:
1110 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1112 case NETR_DELTA_DELETE_TRUST
:
1113 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1115 case NETR_DELTA_DELETE_ACCOUNT
:
1116 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1118 case NETR_DELTA_DELETE_SECRET
:
1119 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1121 case NETR_DELTA_DELETE_GROUP2
:
1122 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1124 case NETR_DELTA_DELETE_USER2
:
1125 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1128 d_printf("Unknown delta record type %d\n", r
->delta_type
);
1133 static NTSTATUS
fetch_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
, DOM_SID dom_sid
)
1137 TALLOC_CTX
*mem_ctx
;
1138 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1139 const char *computername
= global_myname();
1140 struct netr_Authenticator credential
;
1141 struct netr_Authenticator return_authenticator
;
1142 enum netr_SamDatabaseID database_id
= db_type
;
1143 uint16_t restart_state
= 0;
1144 uint32_t sync_context
= 0;
1146 if (!(mem_ctx
= talloc_init("fetch_database")))
1147 return NT_STATUS_NO_MEMORY
;
1150 case SAM_DATABASE_DOMAIN
:
1151 d_printf("Fetching DOMAIN database\n");
1153 case SAM_DATABASE_BUILTIN
:
1154 d_printf("Fetching BUILTIN database\n");
1156 case SAM_DATABASE_PRIVS
:
1157 d_printf("Fetching PRIVS databases\n");
1160 d_printf("Fetching unknown database type %u\n", db_type
);
1165 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1167 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
1169 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
1173 &return_authenticator
,
1180 /* Check returned credentials. */
1181 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
1182 &return_authenticator
.cred
)) {
1183 DEBUG(0,("credentials chain check failed\n"));
1184 return NT_STATUS_ACCESS_DENIED
;
1187 if (NT_STATUS_IS_ERR(result
)) {
1191 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
1192 fetch_sam_entry(&delta_enum_array
->delta_enum
[i
], dom_sid
);
1195 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1197 talloc_destroy(mem_ctx
);
1202 static NTSTATUS
populate_ldap_for_ldif(fstring sid
, const char *suffix
, const char
1203 *builtin_sid
, FILE *add_fd
)
1205 const char *user_suffix
, *group_suffix
, *machine_suffix
, *idmap_suffix
;
1206 char *user_attr
=NULL
, *group_attr
=NULL
;
1210 /* Get the suffix attribute */
1211 suffix_attr
= sstring_sub(suffix
, '=', ',');
1212 if (suffix_attr
== NULL
) {
1213 len
= strlen(suffix
);
1214 suffix_attr
= (char*)SMB_MALLOC(len
+1);
1215 memcpy(suffix_attr
, suffix
, len
);
1216 suffix_attr
[len
] = '\0';
1219 /* Write the base */
1220 fprintf(add_fd
, "# %s\n", suffix
);
1221 fprintf(add_fd
, "dn: %s\n", suffix
);
1222 fprintf(add_fd
, "objectClass: dcObject\n");
1223 fprintf(add_fd
, "objectClass: organization\n");
1224 fprintf(add_fd
, "o: %s\n", suffix_attr
);
1225 fprintf(add_fd
, "dc: %s\n", suffix_attr
);
1226 fprintf(add_fd
, "\n");
1229 user_suffix
= lp_ldap_user_suffix();
1230 if (user_suffix
== NULL
) {
1231 SAFE_FREE(suffix_attr
);
1232 return NT_STATUS_NO_MEMORY
;
1234 /* If it exists and is distinct from other containers,
1235 Write the Users entity */
1236 if (*user_suffix
&& strcmp(user_suffix
, suffix
)) {
1237 user_attr
= sstring_sub(lp_ldap_user_suffix(), '=', ',');
1238 fprintf(add_fd
, "# %s\n", user_suffix
);
1239 fprintf(add_fd
, "dn: %s\n", user_suffix
);
1240 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1241 fprintf(add_fd
, "ou: %s\n", user_attr
);
1242 fprintf(add_fd
, "\n");
1247 group_suffix
= lp_ldap_group_suffix();
1248 if (group_suffix
== NULL
) {
1249 SAFE_FREE(suffix_attr
);
1250 SAFE_FREE(user_attr
);
1251 return NT_STATUS_NO_MEMORY
;
1253 /* If it exists and is distinct from other containers,
1254 Write the Groups entity */
1255 if (*group_suffix
&& strcmp(group_suffix
, suffix
)) {
1256 group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1257 fprintf(add_fd
, "# %s\n", group_suffix
);
1258 fprintf(add_fd
, "dn: %s\n", group_suffix
);
1259 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1260 fprintf(add_fd
, "ou: %s\n", group_attr
);
1261 fprintf(add_fd
, "\n");
1265 /* If it exists and is distinct from other containers,
1266 Write the Computers entity */
1267 machine_suffix
= lp_ldap_machine_suffix();
1268 if (machine_suffix
== NULL
) {
1269 SAFE_FREE(suffix_attr
);
1270 SAFE_FREE(user_attr
);
1271 SAFE_FREE(group_attr
);
1272 return NT_STATUS_NO_MEMORY
;
1274 if (*machine_suffix
&& strcmp(machine_suffix
, user_suffix
) &&
1275 strcmp(machine_suffix
, suffix
)) {
1276 char *machine_ou
= NULL
;
1277 fprintf(add_fd
, "# %s\n", machine_suffix
);
1278 fprintf(add_fd
, "dn: %s\n", machine_suffix
);
1279 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1280 /* this isn't totally correct as it assumes that
1281 there _must_ be an ou. just fixing memleak now. jmcd */
1282 machine_ou
= sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1283 fprintf(add_fd
, "ou: %s\n", machine_ou
);
1284 SAFE_FREE(machine_ou
);
1285 fprintf(add_fd
, "\n");
1289 /* If it exists and is distinct from other containers,
1290 Write the IdMap entity */
1291 idmap_suffix
= lp_ldap_idmap_suffix();
1292 if (idmap_suffix
== NULL
) {
1293 SAFE_FREE(suffix_attr
);
1294 SAFE_FREE(user_attr
);
1295 SAFE_FREE(group_attr
);
1296 return NT_STATUS_NO_MEMORY
;
1298 if (*idmap_suffix
&&
1299 strcmp(idmap_suffix
, user_suffix
) &&
1300 strcmp(idmap_suffix
, suffix
)) {
1302 fprintf(add_fd
, "# %s\n", idmap_suffix
);
1303 fprintf(add_fd
, "dn: %s\n", idmap_suffix
);
1304 fprintf(add_fd
, "ObjectClass: organizationalUnit\n");
1305 s
= sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1306 fprintf(add_fd
, "ou: %s\n", s
);
1308 fprintf(add_fd
, "\n");
1312 /* Write the domain entity */
1313 fprintf(add_fd
, "# %s, %s\n", lp_workgroup(), suffix
);
1314 fprintf(add_fd
, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1316 fprintf(add_fd
, "objectClass: sambaDomain\n");
1317 fprintf(add_fd
, "objectClass: sambaUnixIdPool\n");
1318 fprintf(add_fd
, "sambaDomainName: %s\n", lp_workgroup());
1319 fprintf(add_fd
, "sambaSID: %s\n", sid
);
1320 fprintf(add_fd
, "uidNumber: %d\n", ++ldif_uid
);
1321 fprintf(add_fd
, "gidNumber: %d\n", ++ldif_gid
);
1322 fprintf(add_fd
, "\n");
1325 /* Write the Domain Admins entity */
1326 fprintf(add_fd
, "# Domain Admins, %s, %s\n", group_attr
,
1328 fprintf(add_fd
, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr
,
1330 fprintf(add_fd
, "objectClass: posixGroup\n");
1331 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1332 fprintf(add_fd
, "cn: Domain Admins\n");
1333 fprintf(add_fd
, "memberUid: Administrator\n");
1334 fprintf(add_fd
, "description: Netbios Domain Administrators\n");
1335 fprintf(add_fd
, "gidNumber: 512\n");
1336 fprintf(add_fd
, "sambaSID: %s-512\n", sid
);
1337 fprintf(add_fd
, "sambaGroupType: 2\n");
1338 fprintf(add_fd
, "displayName: Domain Admins\n");
1339 fprintf(add_fd
, "\n");
1342 /* Write the Domain Users entity */
1343 fprintf(add_fd
, "# Domain Users, %s, %s\n", group_attr
,
1345 fprintf(add_fd
, "dn: cn=Domain Users,ou=%s,%s\n", group_attr
,
1347 fprintf(add_fd
, "objectClass: posixGroup\n");
1348 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1349 fprintf(add_fd
, "cn: Domain Users\n");
1350 fprintf(add_fd
, "description: Netbios Domain Users\n");
1351 fprintf(add_fd
, "gidNumber: 513\n");
1352 fprintf(add_fd
, "sambaSID: %s-513\n", sid
);
1353 fprintf(add_fd
, "sambaGroupType: 2\n");
1354 fprintf(add_fd
, "displayName: Domain Users\n");
1355 fprintf(add_fd
, "\n");
1358 /* Write the Domain Guests entity */
1359 fprintf(add_fd
, "# Domain Guests, %s, %s\n", group_attr
,
1361 fprintf(add_fd
, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr
,
1363 fprintf(add_fd
, "objectClass: posixGroup\n");
1364 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1365 fprintf(add_fd
, "cn: Domain Guests\n");
1366 fprintf(add_fd
, "description: Netbios Domain Guests\n");
1367 fprintf(add_fd
, "gidNumber: 514\n");
1368 fprintf(add_fd
, "sambaSID: %s-514\n", sid
);
1369 fprintf(add_fd
, "sambaGroupType: 2\n");
1370 fprintf(add_fd
, "displayName: Domain Guests\n");
1371 fprintf(add_fd
, "\n");
1374 /* Write the Domain Computers entity */
1375 fprintf(add_fd
, "# Domain Computers, %s, %s\n", group_attr
,
1377 fprintf(add_fd
, "dn: cn=Domain Computers,ou=%s,%s\n",
1378 group_attr
, suffix
);
1379 fprintf(add_fd
, "objectClass: posixGroup\n");
1380 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1381 fprintf(add_fd
, "gidNumber: 515\n");
1382 fprintf(add_fd
, "cn: Domain Computers\n");
1383 fprintf(add_fd
, "description: Netbios Domain Computers accounts\n");
1384 fprintf(add_fd
, "sambaSID: %s-515\n", sid
);
1385 fprintf(add_fd
, "sambaGroupType: 2\n");
1386 fprintf(add_fd
, "displayName: Domain Computers\n");
1387 fprintf(add_fd
, "\n");
1390 /* Write the Admininistrators Groups entity */
1391 fprintf(add_fd
, "# Administrators, %s, %s\n", group_attr
,
1393 fprintf(add_fd
, "dn: cn=Administrators,ou=%s,%s\n", group_attr
,
1395 fprintf(add_fd
, "objectClass: posixGroup\n");
1396 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1397 fprintf(add_fd
, "gidNumber: 544\n");
1398 fprintf(add_fd
, "cn: Administrators\n");
1399 fprintf(add_fd
, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1400 fprintf(add_fd
, "sambaSID: %s-544\n", builtin_sid
);
1401 fprintf(add_fd
, "sambaGroupType: 5\n");
1402 fprintf(add_fd
, "displayName: Administrators\n");
1403 fprintf(add_fd
, "\n");
1405 /* Write the Print Operator entity */
1406 fprintf(add_fd
, "# Print Operators, %s, %s\n", group_attr
,
1408 fprintf(add_fd
, "dn: cn=Print Operators,ou=%s,%s\n",
1409 group_attr
, suffix
);
1410 fprintf(add_fd
, "objectClass: posixGroup\n");
1411 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1412 fprintf(add_fd
, "gidNumber: 550\n");
1413 fprintf(add_fd
, "cn: Print Operators\n");
1414 fprintf(add_fd
, "description: Netbios Domain Print Operators\n");
1415 fprintf(add_fd
, "sambaSID: %s-550\n", builtin_sid
);
1416 fprintf(add_fd
, "sambaGroupType: 5\n");
1417 fprintf(add_fd
, "displayName: Print Operators\n");
1418 fprintf(add_fd
, "\n");
1421 /* Write the Backup Operators entity */
1422 fprintf(add_fd
, "# Backup Operators, %s, %s\n", group_attr
,
1424 fprintf(add_fd
, "dn: cn=Backup Operators,ou=%s,%s\n",
1425 group_attr
, suffix
);
1426 fprintf(add_fd
, "objectClass: posixGroup\n");
1427 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1428 fprintf(add_fd
, "gidNumber: 551\n");
1429 fprintf(add_fd
, "cn: Backup Operators\n");
1430 fprintf(add_fd
, "description: Netbios Domain Members can bypass file security to back up files\n");
1431 fprintf(add_fd
, "sambaSID: %s-551\n", builtin_sid
);
1432 fprintf(add_fd
, "sambaGroupType: 5\n");
1433 fprintf(add_fd
, "displayName: Backup Operators\n");
1434 fprintf(add_fd
, "\n");
1437 /* Write the Replicators entity */
1438 fprintf(add_fd
, "# Replicators, %s, %s\n", group_attr
, suffix
);
1439 fprintf(add_fd
, "dn: cn=Replicators,ou=%s,%s\n", group_attr
,
1441 fprintf(add_fd
, "objectClass: posixGroup\n");
1442 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1443 fprintf(add_fd
, "gidNumber: 552\n");
1444 fprintf(add_fd
, "cn: Replicators\n");
1445 fprintf(add_fd
, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1446 fprintf(add_fd
, "sambaSID: %s-552\n", builtin_sid
);
1447 fprintf(add_fd
, "sambaGroupType: 5\n");
1448 fprintf(add_fd
, "displayName: Replicators\n");
1449 fprintf(add_fd
, "\n");
1452 /* Deallocate memory, and return */
1453 SAFE_FREE(suffix_attr
);
1454 SAFE_FREE(user_attr
);
1455 SAFE_FREE(group_attr
);
1456 return NT_STATUS_OK
;
1459 static NTSTATUS
map_populate_groups(GROUPMAP
*groupmap
, ACCOUNTMAP
*accountmap
, fstring sid
,
1460 const char *suffix
, const char *builtin_sid
)
1462 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1464 /* Map the groups created by populate_ldap_for_ldif */
1465 groupmap
[0].rid
= 512;
1466 groupmap
[0].gidNumber
= 512;
1467 snprintf(groupmap
[0].sambaSID
, sizeof(groupmap
[0].sambaSID
),
1469 snprintf(groupmap
[0].group_dn
, sizeof(groupmap
[0].group_dn
),
1470 "cn=Domain Admins,ou=%s,%s",
1471 group_attr
, suffix
);
1472 accountmap
[0].rid
= 512;
1473 snprintf(accountmap
[0].cn
, sizeof(accountmap
[0].cn
),
1474 "%s", "Domain Admins");
1476 groupmap
[1].rid
= 513;
1477 groupmap
[1].gidNumber
= 513;
1478 snprintf(groupmap
[1].sambaSID
, sizeof(groupmap
[1].sambaSID
),
1480 snprintf(groupmap
[1].group_dn
, sizeof(groupmap
[1].group_dn
),
1481 "cn=Domain Users,ou=%s,%s",
1482 group_attr
, suffix
);
1483 accountmap
[1].rid
= 513;
1484 snprintf(accountmap
[1].cn
, sizeof(accountmap
[1].cn
),
1485 "%s", "Domain Users");
1487 groupmap
[2].rid
= 514;
1488 groupmap
[2].gidNumber
= 514;
1489 snprintf(groupmap
[2].sambaSID
, sizeof(groupmap
[2].sambaSID
),
1491 snprintf(groupmap
[2].group_dn
, sizeof(groupmap
[2].group_dn
),
1492 "cn=Domain Guests,ou=%s,%s",
1493 group_attr
, suffix
);
1494 accountmap
[2].rid
= 514;
1495 snprintf(accountmap
[2].cn
, sizeof(accountmap
[2].cn
),
1496 "%s", "Domain Guests");
1498 groupmap
[3].rid
= 515;
1499 groupmap
[3].gidNumber
= 515;
1500 snprintf(groupmap
[3].sambaSID
, sizeof(groupmap
[3].sambaSID
),
1502 snprintf(groupmap
[3].group_dn
, sizeof(groupmap
[3].group_dn
),
1503 "cn=Domain Computers,ou=%s,%s",
1504 group_attr
, suffix
);
1505 accountmap
[3].rid
= 515;
1506 snprintf(accountmap
[3].cn
, sizeof(accountmap
[3].cn
),
1507 "%s", "Domain Computers");
1509 groupmap
[4].rid
= 544;
1510 groupmap
[4].gidNumber
= 544;
1511 snprintf(groupmap
[4].sambaSID
, sizeof(groupmap
[4].sambaSID
),
1512 "%s-544", builtin_sid
);
1513 snprintf(groupmap
[4].group_dn
, sizeof(groupmap
[4].group_dn
),
1514 "cn=Administrators,ou=%s,%s",
1515 group_attr
, suffix
);
1516 accountmap
[4].rid
= 515;
1517 snprintf(accountmap
[4].cn
, sizeof(accountmap
[4].cn
),
1518 "%s", "Administrators");
1520 groupmap
[5].rid
= 550;
1521 groupmap
[5].gidNumber
= 550;
1522 snprintf(groupmap
[5].sambaSID
, sizeof(groupmap
[5].sambaSID
),
1523 "%s-550", builtin_sid
);
1524 snprintf(groupmap
[5].group_dn
, sizeof(groupmap
[5].group_dn
),
1525 "cn=Print Operators,ou=%s,%s",
1526 group_attr
, suffix
);
1527 accountmap
[5].rid
= 550;
1528 snprintf(accountmap
[5].cn
, sizeof(accountmap
[5].cn
),
1529 "%s", "Print Operators");
1531 groupmap
[6].rid
= 551;
1532 groupmap
[6].gidNumber
= 551;
1533 snprintf(groupmap
[6].sambaSID
, sizeof(groupmap
[6].sambaSID
),
1534 "%s-551", builtin_sid
);
1535 snprintf(groupmap
[6].group_dn
, sizeof(groupmap
[6].group_dn
),
1536 "cn=Backup Operators,ou=%s,%s",
1537 group_attr
, suffix
);
1538 accountmap
[6].rid
= 551;
1539 snprintf(accountmap
[6].cn
, sizeof(accountmap
[6].cn
),
1540 "%s", "Backup Operators");
1542 groupmap
[7].rid
= 552;
1543 groupmap
[7].gidNumber
= 552;
1544 snprintf(groupmap
[7].sambaSID
, sizeof(groupmap
[7].sambaSID
),
1545 "%s-552", builtin_sid
);
1546 snprintf(groupmap
[7].group_dn
, sizeof(groupmap
[7].group_dn
),
1547 "cn=Replicators,ou=%s,%s",
1548 group_attr
, suffix
);
1549 accountmap
[7].rid
= 551;
1550 snprintf(accountmap
[7].cn
, sizeof(accountmap
[7].cn
),
1551 "%s", "Replicators");
1552 SAFE_FREE(group_attr
);
1553 return NT_STATUS_OK
;
1557 * This is a crap routine, but I think it's the quickest way to solve the
1558 * UTF8->base64 problem.
1561 static int fprintf_attr(FILE *add_fd
, const char *attr_name
,
1562 const char *fmt
, ...)
1565 char *value
, *p
, *base64
;
1566 DATA_BLOB base64_blob
;
1567 bool do_base64
= False
;
1571 value
= talloc_vasprintf(NULL
, fmt
, ap
);
1574 SMB_ASSERT(value
!= NULL
);
1576 for (p
=value
; *p
; p
++) {
1584 bool only_whitespace
= True
;
1585 for (p
=value
; *p
; p
++) {
1587 * I know that this not multibyte safe, but we break
1588 * on the first non-whitespace character anyway.
1591 only_whitespace
= False
;
1595 if (only_whitespace
) {
1601 res
= fprintf(add_fd
, "%s: %s\n", attr_name
, value
);
1606 base64_blob
.data
= (unsigned char *)value
;
1607 base64_blob
.length
= strlen(value
);
1609 base64
= base64_encode_data_blob(value
, base64_blob
);
1610 SMB_ASSERT(base64
!= NULL
);
1612 res
= fprintf(add_fd
, "%s:: %s\n", attr_name
, base64
);
1617 static NTSTATUS
fetch_group_info_to_ldif(struct netr_DELTA_GROUP
*r
, GROUPMAP
*groupmap
,
1618 FILE *add_fd
, fstring sid
, char *suffix
)
1621 uint32 grouptype
= 0, g_rid
= 0;
1622 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1624 /* Get the group name */
1625 fstrcpy(groupname
, r
->group_name
.string
);
1627 /* Set up the group type (always 2 for group info) */
1630 /* These groups are entered by populate_ldap_for_ldif */
1631 if (strcmp(groupname
, "Domain Admins") == 0 ||
1632 strcmp(groupname
, "Domain Users") == 0 ||
1633 strcmp(groupname
, "Domain Guests") == 0 ||
1634 strcmp(groupname
, "Domain Computers") == 0 ||
1635 strcmp(groupname
, "Administrators") == 0 ||
1636 strcmp(groupname
, "Print Operators") == 0 ||
1637 strcmp(groupname
, "Backup Operators") == 0 ||
1638 strcmp(groupname
, "Replicators") == 0) {
1639 SAFE_FREE(group_attr
);
1640 return NT_STATUS_OK
;
1642 /* Increment the gid for the new group */
1646 /* Map the group rid, gid, and dn */
1648 groupmap
->rid
= g_rid
;
1649 groupmap
->gidNumber
= ldif_gid
;
1650 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1651 "%s-%d", sid
, g_rid
);
1652 snprintf(groupmap
->group_dn
, sizeof(groupmap
->group_dn
),
1653 "cn=%s,ou=%s,%s", groupname
, group_attr
, suffix
);
1655 /* Write the data to the temporary add ldif file */
1656 fprintf(add_fd
, "# %s, %s, %s\n", groupname
, group_attr
,
1658 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", groupname
, group_attr
,
1660 fprintf(add_fd
, "objectClass: posixGroup\n");
1661 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1662 fprintf_attr(add_fd
, "cn", "%s", groupname
);
1663 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1664 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1665 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1666 fprintf_attr(add_fd
, "displayName", "%s", groupname
);
1667 fprintf(add_fd
, "\n");
1670 SAFE_FREE(group_attr
);
1672 return NT_STATUS_OK
;
1675 static NTSTATUS
fetch_account_info_to_ldif(struct netr_DELTA_USER
*r
,
1677 ACCOUNTMAP
*accountmap
,
1679 fstring sid
, char *suffix
,
1682 fstring username
, logonscript
, homedrive
, homepath
= "", homedir
= "";
1683 fstring hex_nt_passwd
, hex_lm_passwd
;
1684 fstring description
, profilepath
, fullname
, sambaSID
;
1685 uchar lm_passwd
[16], nt_passwd
[16];
1686 char *flags
, *user_rdn
;
1688 const char* nopasswd
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1689 static uchar zero_buf
[16];
1690 uint32 rid
= 0, group_rid
= 0, gidNumber
= 0;
1694 /* Get the username */
1695 fstrcpy(username
, r
->account_name
.string
);
1700 /* Map the rid and username for group member info later */
1701 accountmap
->rid
= rid
;
1702 snprintf(accountmap
->cn
, sizeof(accountmap
->cn
), "%s", username
);
1704 /* Get the home directory */
1705 if (r
->acct_flags
& ACB_NORMAL
) {
1706 fstrcpy(homedir
, r
->home_directory
.string
);
1708 snprintf(homedir
, sizeof(homedir
), "/home/%s", username
);
1710 snprintf(homedir
, sizeof(homedir
), "/nobodyshomedir");
1712 ou
= lp_ldap_user_suffix();
1714 ou
= lp_ldap_machine_suffix();
1715 snprintf(homedir
, sizeof(homedir
), "/machinehomedir");
1718 /* Get the logon script */
1719 fstrcpy(logonscript
, r
->logon_script
.string
);
1721 /* Get the home drive */
1722 fstrcpy(homedrive
, r
->home_drive
.string
);
1724 /* Get the home path */
1725 fstrcpy(homepath
, r
->home_directory
.string
);
1727 /* Get the description */
1728 fstrcpy(description
, r
->description
.string
);
1730 /* Get the display name */
1731 fstrcpy(fullname
, r
->full_name
.string
);
1733 /* Get the profile path */
1734 fstrcpy(profilepath
, r
->profile_path
.string
);
1736 /* Get lm and nt password data */
1737 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
1738 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
1739 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
1741 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
1743 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
1744 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
1745 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
1747 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
1749 unix_time
= nt_time_to_unix(r
->last_password_change
);
1751 /* Increment the uid for the new user */
1754 /* Set up group id and sambaSID for the user */
1755 group_rid
= r
->primary_gid
;
1756 for (i
=0; i
<alloced
; i
++) {
1757 if (groupmap
[i
].rid
== group_rid
) break;
1760 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1762 return NT_STATUS_UNSUCCESSFUL
;
1764 gidNumber
= groupmap
[i
].gidNumber
;
1765 snprintf(sambaSID
, sizeof(sambaSID
), groupmap
[i
].sambaSID
);
1767 /* Set up sambaAcctFlags */
1768 flags
= pdb_encode_acct_ctrl(r
->acct_flags
,
1769 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1771 /* Add the user to the temporary add ldif file */
1772 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1773 user_rdn
= sstring_sub(ou
, '=', ',');
1774 fprintf(add_fd
, "# %s, %s, %s\n", username
, user_rdn
, suffix
);
1775 fprintf_attr(add_fd
, "dn", "uid=%s,ou=%s,%s", username
, user_rdn
,
1777 SAFE_FREE(user_rdn
);
1778 fprintf(add_fd
, "ObjectClass: top\n");
1779 fprintf(add_fd
, "objectClass: inetOrgPerson\n");
1780 fprintf(add_fd
, "objectClass: posixAccount\n");
1781 fprintf(add_fd
, "objectClass: shadowAccount\n");
1782 fprintf(add_fd
, "objectClass: sambaSamAccount\n");
1783 fprintf_attr(add_fd
, "cn", "%s", username
);
1784 fprintf_attr(add_fd
, "sn", "%s", username
);
1785 fprintf_attr(add_fd
, "uid", "%s", username
);
1786 fprintf(add_fd
, "uidNumber: %d\n", ldif_uid
);
1787 fprintf(add_fd
, "gidNumber: %d\n", gidNumber
);
1788 fprintf_attr(add_fd
, "homeDirectory", "%s", homedir
);
1790 fprintf_attr(add_fd
, "sambaHomePath", "%s", homepath
);
1792 fprintf_attr(add_fd
, "sambaHomeDrive", "%s", homedrive
);
1794 fprintf_attr(add_fd
, "sambaLogonScript", "%s", logonscript
);
1795 fprintf(add_fd
, "loginShell: %s\n",
1796 ((r
->acct_flags
& ACB_NORMAL
) ?
1797 "/bin/bash" : "/bin/false"));
1798 fprintf(add_fd
, "gecos: System User\n");
1800 fprintf_attr(add_fd
, "description", "%s", description
);
1801 fprintf(add_fd
, "sambaSID: %s-%d\n", sid
, rid
);
1802 fprintf(add_fd
, "sambaPrimaryGroupSID: %s\n", sambaSID
);
1804 fprintf_attr(add_fd
, "displayName", "%s", fullname
);
1806 fprintf_attr(add_fd
, "sambaProfilePath", "%s", profilepath
);
1807 if (strcmp(nopasswd
, hex_lm_passwd
) != 0)
1808 fprintf(add_fd
, "sambaLMPassword: %s\n", hex_lm_passwd
);
1809 if (strcmp(nopasswd
, hex_nt_passwd
) != 0)
1810 fprintf(add_fd
, "sambaNTPassword: %s\n", hex_nt_passwd
);
1811 fprintf(add_fd
, "sambaPwdLastSet: %d\n", (int)unix_time
);
1812 fprintf(add_fd
, "sambaAcctFlags: %s\n", flags
);
1813 fprintf(add_fd
, "\n");
1817 return NT_STATUS_OK
;
1820 static NTSTATUS
fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS
*r
,
1822 FILE *add_fd
, fstring sid
,
1826 fstring aliasname
, description
;
1827 uint32 grouptype
= 0, g_rid
= 0;
1828 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1830 /* Get the alias name */
1831 fstrcpy(aliasname
, r
->alias_name
.string
);
1833 /* Get the alias description */
1834 fstrcpy(description
, r
->description
.string
);
1836 /* Set up the group type */
1838 case SAM_DATABASE_DOMAIN
:
1841 case SAM_DATABASE_BUILTIN
:
1850 These groups are entered by populate_ldap_for_ldif
1851 Note that populate creates a group called Relicators,
1852 but NT returns a group called Replicator
1854 if (strcmp(aliasname
, "Domain Admins") == 0 ||
1855 strcmp(aliasname
, "Domain Users") == 0 ||
1856 strcmp(aliasname
, "Domain Guests") == 0 ||
1857 strcmp(aliasname
, "Domain Computers") == 0 ||
1858 strcmp(aliasname
, "Administrators") == 0 ||
1859 strcmp(aliasname
, "Print Operators") == 0 ||
1860 strcmp(aliasname
, "Backup Operators") == 0 ||
1861 strcmp(aliasname
, "Replicator") == 0) {
1862 SAFE_FREE(group_attr
);
1863 return NT_STATUS_OK
;
1865 /* Increment the gid for the new group */
1869 /* Map the group rid and gid */
1871 groupmap
->gidNumber
= ldif_gid
;
1872 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1873 "%s-%d", sid
, g_rid
);
1875 /* Write the data to the temporary add ldif file */
1876 fprintf(add_fd
, "# %s, %s, %s\n", aliasname
, group_attr
,
1878 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", aliasname
, group_attr
,
1880 fprintf(add_fd
, "objectClass: posixGroup\n");
1881 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1882 fprintf(add_fd
, "cn: %s\n", aliasname
);
1883 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1884 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1885 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1886 fprintf_attr(add_fd
, "displayName", "%s", aliasname
);
1888 fprintf_attr(add_fd
, "description", "%s", description
);
1889 fprintf(add_fd
, "\n");
1892 SAFE_FREE(group_attr
);
1894 return NT_STATUS_OK
;
1897 static NTSTATUS
fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER
*r
,
1900 ACCOUNTMAP
*accountmap
,
1901 FILE *mod_fd
, int alloced
)
1904 uint32 group_rid
= 0, rid
= 0;
1907 /* Get the dn for the group */
1908 if (r
->num_rids
> 0) {
1910 for (j
=0; j
<alloced
; j
++) {
1911 if (groupmap
[j
].rid
== group_rid
) break;
1914 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1916 return NT_STATUS_UNSUCCESSFUL
;
1918 snprintf(group_dn
, sizeof(group_dn
), "%s", groupmap
[j
].group_dn
);
1919 fprintf(mod_fd
, "dn: %s\n", group_dn
);
1921 /* Get the cn for each member */
1922 for (i
=0; i
< r
->num_rids
; i
++) {
1924 for (k
=0; k
<alloced
; k
++) {
1925 if (accountmap
[k
].rid
== rid
) break;
1928 DEBUG(1, ("Could not find rid %d in "
1929 "accountmap array\n", rid
));
1930 return NT_STATUS_UNSUCCESSFUL
;
1932 fprintf(mod_fd
, "memberUid: %s\n", accountmap
[k
].cn
);
1934 fprintf(mod_fd
, "\n");
1939 return NT_STATUS_OK
;
1942 static NTSTATUS
fetch_database_to_ldif(struct rpc_pipe_client
*pipe_hnd
,
1945 const char *user_file
)
1948 const char *builtin_sid
= "S-1-5-32";
1949 char *add_name
= NULL
, *mod_name
= NULL
;
1950 const char *add_template
= "/tmp/add.ldif.XXXXXX";
1951 const char *mod_template
= "/tmp/mod.ldif.XXXXXX";
1952 fstring sid
, domainname
;
1953 NTSTATUS ret
= NT_STATUS_OK
, result
;
1955 TALLOC_CTX
*mem_ctx
;
1957 FILE *add_file
= NULL
, *mod_file
= NULL
, *ldif_file
= NULL
;
1958 int num_alloced
= 0, g_index
= 0, a_index
= 0;
1959 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1960 const char *computername
= global_myname();
1961 struct netr_Authenticator credential
;
1962 struct netr_Authenticator return_authenticator
;
1963 enum netr_SamDatabaseID database_id
= db_type
;
1964 uint16_t restart_state
= 0;
1965 uint32_t sync_context
= 0;
1967 /* Set up array for mapping accounts to groups */
1968 /* Array element is the group rid */
1969 GROUPMAP
*groupmap
= NULL
;
1971 /* Set up array for mapping account rid's to cn's */
1972 /* Array element is the account rid */
1973 ACCOUNTMAP
*accountmap
= NULL
;
1975 if (!(mem_ctx
= talloc_init("fetch_database"))) {
1976 return NT_STATUS_NO_MEMORY
;
1979 /* Ensure we have an output file */
1981 ldif_file
= fopen(user_file
, "a");
1986 fprintf(stderr
, "Could not open %s\n", user_file
);
1987 DEBUG(1, ("Could not open %s\n", user_file
));
1988 ret
= NT_STATUS_UNSUCCESSFUL
;
1992 add_name
= talloc_strdup(mem_ctx
, add_template
);
1993 mod_name
= talloc_strdup(mem_ctx
, mod_template
);
1994 if (!add_name
|| !mod_name
) {
1995 ret
= NT_STATUS_NO_MEMORY
;
1999 /* Open the add and mod ldif files */
2000 if (!(add_file
= fdopen(smb_mkstemp(add_name
),"w"))) {
2001 DEBUG(1, ("Could not open %s\n", add_name
));
2002 ret
= NT_STATUS_UNSUCCESSFUL
;
2005 if (!(mod_file
= fdopen(smb_mkstemp(mod_name
),"w"))) {
2006 DEBUG(1, ("Could not open %s\n", mod_name
));
2007 ret
= NT_STATUS_UNSUCCESSFUL
;
2012 sid_to_fstring(sid
, &dom_sid
);
2014 /* Get the ldap suffix */
2015 suffix
= lp_ldap_suffix();
2016 if (suffix
== NULL
|| strcmp(suffix
, "") == 0) {
2017 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2021 /* Get other smb.conf data */
2022 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2023 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2027 /* Allocate initial memory for groupmap and accountmap arrays */
2028 if (init_ldap
== 1) {
2029 groupmap
= SMB_MALLOC_ARRAY(GROUPMAP
, 8);
2030 accountmap
= SMB_MALLOC_ARRAY(ACCOUNTMAP
, 8);
2031 if (groupmap
== NULL
|| accountmap
== NULL
) {
2032 DEBUG(1,("GROUPMAP malloc failed\n"));
2033 ret
= NT_STATUS_NO_MEMORY
;
2037 /* Initialize the arrays */
2038 memset(groupmap
, 0, sizeof(GROUPMAP
)*8);
2039 memset(accountmap
, 0, sizeof(ACCOUNTMAP
)*8);
2041 /* Remember how many we malloced */
2044 /* Initial database population */
2045 populate_ldap_for_ldif(sid
, suffix
, builtin_sid
, add_file
);
2046 map_populate_groups(groupmap
, accountmap
, sid
, suffix
,
2049 /* Don't do this again */
2053 /* Announce what we are doing */
2055 case SAM_DATABASE_DOMAIN
:
2056 d_fprintf(stderr
, "Fetching DOMAIN database\n");
2058 case SAM_DATABASE_BUILTIN
:
2059 d_fprintf(stderr
, "Fetching BUILTIN database\n");
2061 case SAM_DATABASE_PRIVS
:
2062 d_fprintf(stderr
, "Fetching PRIVS databases\n");
2066 "Fetching unknown database type %u\n",
2072 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2074 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
2076 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
2080 &return_authenticator
,
2087 /* Check returned credentials. */
2088 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
2089 &return_authenticator
.cred
)) {
2090 DEBUG(0,("credentials chain check failed\n"));
2091 return NT_STATUS_ACCESS_DENIED
;
2094 if (NT_STATUS_IS_ERR(result
)) {
2098 num_deltas
= delta_enum_array
->num_deltas
;
2100 /* Re-allocate memory for groupmap and accountmap arrays */
2101 groupmap
= SMB_REALLOC_ARRAY(groupmap
, GROUPMAP
,
2102 num_deltas
+num_alloced
);
2103 accountmap
= SMB_REALLOC_ARRAY(accountmap
, ACCOUNTMAP
,
2104 num_deltas
+num_alloced
);
2105 if (groupmap
== NULL
|| accountmap
== NULL
) {
2106 DEBUG(1,("GROUPMAP malloc failed\n"));
2107 ret
= NT_STATUS_NO_MEMORY
;
2111 /* Initialize the new records */
2112 memset(&groupmap
[num_alloced
], 0,
2113 sizeof(GROUPMAP
)*num_deltas
);
2114 memset(&accountmap
[num_alloced
], 0,
2115 sizeof(ACCOUNTMAP
)*num_deltas
);
2117 /* Remember how many we alloced this time */
2118 num_alloced
+= num_deltas
;
2120 /* Loop through the deltas */
2121 for (k
=0; k
<num_deltas
; k
++) {
2123 union netr_DELTA_UNION u
=
2124 delta_enum_array
->delta_enum
[k
].delta_union
;
2125 union netr_DELTA_ID_UNION id
=
2126 delta_enum_array
->delta_enum
[k
].delta_id_union
;
2128 switch(delta_enum_array
->delta_enum
[k
].delta_type
) {
2129 case NETR_DELTA_DOMAIN
:
2130 /* Is this case needed? */
2132 u
.domain
->domain_name
.string
);
2135 case NETR_DELTA_GROUP
:
2136 fetch_group_info_to_ldif(
2139 add_file
, sid
, suffix
);
2143 case NETR_DELTA_USER
:
2144 fetch_account_info_to_ldif(
2146 &accountmap
[a_index
], add_file
,
2147 sid
, suffix
, num_alloced
);
2151 case NETR_DELTA_ALIAS
:
2152 fetch_alias_info_to_ldif(
2153 u
.alias
, &groupmap
[g_index
],
2154 add_file
, sid
, suffix
, db_type
);
2158 case NETR_DELTA_GROUP_MEMBER
:
2159 fetch_groupmem_info_to_ldif(
2160 u
.group_member
, id
.rid
,
2161 groupmap
, accountmap
,
2162 mod_file
, num_alloced
);
2165 case NETR_DELTA_ALIAS_MEMBER
:
2166 case NETR_DELTA_POLICY
:
2167 case NETR_DELTA_ACCOUNT
:
2168 case NETR_DELTA_TRUSTED_DOMAIN
:
2169 case NETR_DELTA_SECRET
:
2170 case NETR_DELTA_RENAME_GROUP
:
2171 case NETR_DELTA_RENAME_USER
:
2172 case NETR_DELTA_RENAME_ALIAS
:
2173 case NETR_DELTA_DELETE_GROUP
:
2174 case NETR_DELTA_DELETE_USER
:
2175 case NETR_DELTA_MODIFY_COUNT
:
2178 } /* end of switch */
2179 } /* end of for loop */
2181 /* Increment sync_context */
2184 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2186 /* Write ldif data to the user's file */
2187 if (db_type
== SAM_DATABASE_DOMAIN
) {
2189 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2191 "# =================================\n\n");
2193 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2195 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2197 "# ==================================\n\n");
2200 fseek(add_file
, 0, SEEK_SET
);
2201 transfer_file(fileno(add_file
), fileno(ldif_file
), (size_t) -1);
2203 if (db_type
== SAM_DATABASE_DOMAIN
) {
2205 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2207 "# ====================================\n\n");
2209 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2211 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2213 "# =====================================\n\n");
2216 fseek(mod_file
, 0, SEEK_SET
);
2217 transfer_file(fileno(mod_file
), fileno(ldif_file
), (size_t) -1);
2221 /* Close and delete the ldif files */
2226 if ((add_name
!= NULL
) &&
2227 strcmp(add_name
, add_template
) && (unlink(add_name
))) {
2228 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2229 add_name
, strerror(errno
)));
2236 if ((mod_name
!= NULL
) &&
2237 strcmp(mod_name
, mod_template
) && (unlink(mod_name
))) {
2238 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2239 mod_name
, strerror(errno
)));
2242 if (ldif_file
&& (ldif_file
!= stdout
)) {
2246 /* Deallocate memory for the mapping arrays */
2247 SAFE_FREE(groupmap
);
2248 SAFE_FREE(accountmap
);
2251 talloc_destroy(mem_ctx
);
2256 * Basic usage function for 'net rpc vampire'
2257 * @param argc Standard main() style argc
2258 * @param argc Standard main() style argv. Initial components are already
2262 int rpc_vampire_usage(int argc
, const char **argv
)
2264 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2265 "\t to pull accounts from a remote PDC where we are a BDC\n"
2266 "\t\t no args puts accounts in local passdb from smb.conf\n"
2267 "\t\t ldif - put accounts in ldif format (file defaults to "
2270 net_common_flags_usage(argc
, argv
);
2275 /* dump sam database via samsync rpc calls */
2276 NTSTATUS
rpc_vampire_internals(const DOM_SID
*domain_sid
,
2277 const char *domain_name
,
2278 struct cli_state
*cli
,
2279 struct rpc_pipe_client
*pipe_hnd
,
2280 TALLOC_CTX
*mem_ctx
,
2285 fstring my_dom_sid_str
;
2286 fstring rem_dom_sid_str
;
2288 if (!sid_equal(domain_sid
, get_global_sam_sid())) {
2289 d_printf("Cannot import users from %s at this time, "
2290 "as the current domain:\n\t%s: %s\nconflicts "
2291 "with the remote domain\n\t%s: %s\n"
2292 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2293 "workgroup=%s\n\n in your smb.conf?\n",
2295 get_global_sam_name(),
2296 sid_to_fstring(my_dom_sid_str
,
2297 get_global_sam_sid()),
2298 domain_name
, sid_to_fstring(rem_dom_sid_str
,
2301 return NT_STATUS_UNSUCCESSFUL
;
2304 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2305 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2306 *domain_sid
, argv
[1]);
2308 result
= fetch_database(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2312 if (!NT_STATUS_IS_OK(result
)) {
2313 d_fprintf(stderr
, "Failed to fetch domain database: %s\n",
2315 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOT_SUPPORTED
))
2316 d_fprintf(stderr
, "Perhaps %s is a Windows 2000 "
2317 "native mode domain?\n", domain_name
);
2321 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2322 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2323 global_sid_Builtin
, argv
[1]);
2325 result
= fetch_database(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2326 global_sid_Builtin
);
2329 if (!NT_STATUS_IS_OK(result
)) {
2330 d_fprintf(stderr
, "Failed to fetch builtin database: %s\n",
2335 /* Currently we crash on PRIVS somewhere in unmarshalling */
2336 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */