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.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "utils/net.h"
28 /* uid's and gid's for writing deltas to ldif */
29 static uint32 ldif_gid
= 999;
30 static uint32 ldif_uid
= 999;
31 /* Keep track of ldap initialization */
32 static int init_ldap
= 1;
34 static void display_group_mem_info(uint32_t rid
,
35 struct netr_DELTA_GROUP_MEMBER
*r
)
38 d_printf("Group mem %u: ", rid
);
39 for (i
=0; i
< r
->num_rids
; i
++) {
40 d_printf("%u ", r
->rids
[i
]);
45 static void display_alias_info(uint32_t rid
,
46 struct netr_DELTA_ALIAS
*r
)
48 d_printf("Alias '%s' ", r
->alias_name
.string
);
49 d_printf("desc='%s' rid=%u\n", r
->description
.string
, r
->rid
);
52 static void display_alias_mem(uint32_t rid
,
53 struct netr_DELTA_ALIAS_MEMBER
*r
)
56 d_printf("Alias rid %u: ", rid
);
57 for (i
=0; i
< r
->sids
.num_sids
; i
++) {
58 d_printf("%s ", sid_string_tos(r
->sids
.sids
[i
].sid
));
63 static void display_account_info(uint32_t rid
,
64 struct netr_DELTA_USER
*r
)
66 fstring hex_nt_passwd
, hex_lm_passwd
;
67 uchar lm_passwd
[16], nt_passwd
[16];
68 static uchar zero_buf
[16];
70 /* Decode hashes from password hash (if they are not NULL) */
72 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
73 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
74 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
76 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
79 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
80 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
81 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
83 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
86 printf("%s:%d:%s:%s:%s:LCT-0\n",
87 r
->account_name
.string
,
88 r
->rid
, hex_lm_passwd
, hex_nt_passwd
,
89 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
));
92 static time_t uint64s_nt_time_to_unix_abs(const uint64
*src
)
96 return nt_time_to_unix_abs(&nttime
);
99 static void display_domain_info(struct netr_DELTA_DOMAIN
*r
)
103 u_logout
= uint64s_nt_time_to_unix_abs((const uint64
*)&r
->force_logoff_time
);
105 d_printf("Domain name: %s\n", r
->domain_name
.string
);
107 d_printf("Minimal Password Length: %d\n", r
->min_password_length
);
108 d_printf("Password History Length: %d\n", r
->password_history_length
);
110 d_printf("Force Logoff: %d\n", (int)u_logout
);
112 d_printf("Max Password Age: %s\n", display_time(r
->max_password_age
));
113 d_printf("Min Password Age: %s\n", display_time(r
->min_password_age
));
117 d_printf("Lockout Time: %s\n", display_time(a
->account_lockout
.lockout_duration
));
118 d_printf("Lockout Reset Time: %s\n", display_time(a
->account_lockout
.reset_count
));
119 d_printf("Bad Attempt Lockout: %d\n", a
->account_lockout
.bad_attempt_lockout
);
121 d_printf("User must logon to change password: %d\n", r
->logon_to_chgpass
);
124 static void display_group_info(uint32_t rid
, struct netr_DELTA_GROUP
*r
)
126 d_printf("Group '%s' ", r
->group_name
.string
);
127 d_printf("desc='%s', rid=%u\n", r
->description
.string
, rid
);
130 static void display_sam_entry(struct netr_DELTA_ENUM
*r
)
132 union netr_DELTA_UNION u
= r
->delta_union
;
133 union netr_DELTA_ID_UNION id
= r
->delta_id_union
;
135 switch (r
->delta_type
) {
136 case NETR_DELTA_DOMAIN
:
137 display_domain_info(u
.domain
);
139 case NETR_DELTA_GROUP
:
140 display_group_info(id
.rid
, u
.group
);
143 case NETR_DELTA_DELETE_GROUP
:
144 printf("Delete Group: %d\n",
145 u
.delete_account
.unknown
);
147 case NETR_DELTA_RENAME_GROUP
:
148 printf("Rename Group: %s -> %s\n",
149 u
.rename_group
->OldName
.string
,
150 u
.rename_group
->NewName
.string
);
153 case NETR_DELTA_USER
:
154 display_account_info(id
.rid
, u
.user
);
157 case NETR_DELTA_DELETE_USER
:
158 printf("Delete User: %d\n",
161 case NETR_DELTA_RENAME_USER
:
162 printf("Rename user: %s -> %s\n",
163 u
.rename_user
->OldName
.string
,
164 u
.rename_user
->NewName
.string
);
167 case NETR_DELTA_GROUP_MEMBER
:
168 display_group_mem_info(id
.rid
, u
.group_member
);
170 case NETR_DELTA_ALIAS
:
171 display_alias_info(id
.rid
, u
.alias
);
174 case NETR_DELTA_DELETE_ALIAS
:
175 printf("Delete Alias: %d\n",
178 case NETR_DELTA_RENAME_ALIAS
:
179 printf("Rename alias: %s -> %s\n",
180 u
.rename_alias
->OldName
.string
,
181 u
.rename_alias
->NewName
.string
);
184 case NETR_DELTA_ALIAS_MEMBER
:
185 display_alias_mem(id
.rid
, u
.alias_member
);
188 case NETR_DELTA_POLICY
:
191 case NETR_DELTA_TRUSTED_DOMAIN
:
192 printf("Trusted Domain: %s\n",
193 u
.trusted_domain
->domain_name
.string
);
195 case NETR_DELTA_DELETE_TRUST
:
196 printf("Delete Trust: %d\n",
197 u
.delete_trust
.unknown
);
199 case NETR_DELTA_ACCOUNT
:
202 case NETR_DELTA_DELETE_ACCOUNT
:
203 printf("Delete Account: %d\n",
204 u
.delete_account
.unknown
);
206 case NETR_DELTA_SECRET
:
209 case NETR_DELTA_DELETE_SECRET
:
210 printf("Delete Secret: %d\n",
211 u
.delete_secret
.unknown
);
213 case NETR_DELTA_DELETE_GROUP2
:
214 printf("Delete Group2: %s\n",
215 u
.delete_group
->account_name
);
217 case NETR_DELTA_DELETE_USER2
:
218 printf("Delete User2: %s\n",
219 u
.delete_user
->account_name
);
221 case NETR_DELTA_MODIFY_COUNT
:
222 printf("sam sequence update: 0x%016llx\n",
223 (unsigned long long) *u
.modified_count
);
226 /* The following types are recognised but not handled */
227 case NETR_DELTA_RENAME_GROUP
:
228 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
230 case NETR_DELTA_RENAME_USER
:
231 d_printf("NETR_DELTA_RENAME_USER not handled\n");
233 case NETR_DELTA_RENAME_ALIAS
:
234 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
236 case NETR_DELTA_POLICY
:
237 d_printf("NETR_DELTA_POLICY not handled\n");
239 case NETR_DELTA_TRUSTED_DOMAIN
:
240 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
242 case NETR_DELTA_ACCOUNT
:
243 d_printf("NETR_DELTA_ACCOUNT not handled\n");
245 case NETR_DELTA_SECRET
:
246 d_printf("NETR_DELTA_SECRET not handled\n");
248 case NETR_DELTA_DELETE_GROUP
:
249 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
251 case NETR_DELTA_DELETE_USER
:
252 d_printf("NETR_DELTA_DELETE_USER not handled\n");
254 case NETR_DELTA_MODIFY_COUNT
:
255 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
257 case NETR_DELTA_DELETE_ALIAS
:
258 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
260 case NETR_DELTA_DELETE_TRUST
:
261 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
263 case NETR_DELTA_DELETE_ACCOUNT
:
264 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
266 case NETR_DELTA_DELETE_SECRET
:
267 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
269 case NETR_DELTA_DELETE_GROUP2
:
270 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
272 case NETR_DELTA_DELETE_USER2
:
273 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
276 printf("unknown delta type 0x%02x\n",
282 static void dump_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
)
287 const char *logon_server
= pipe_hnd
->cli
->desthost
;
288 const char *computername
= global_myname();
289 struct netr_Authenticator credential
;
290 struct netr_Authenticator return_authenticator
;
291 enum netr_SamDatabaseID database_id
= db_type
;
292 uint16_t restart_state
= 0;
293 uint32_t sync_context
= 0;
295 if (!(mem_ctx
= talloc_init("dump_database"))) {
300 case SAM_DATABASE_DOMAIN
:
301 d_printf("Dumping DOMAIN database\n");
303 case SAM_DATABASE_BUILTIN
:
304 d_printf("Dumping BUILTIN database\n");
306 case SAM_DATABASE_PRIVS
:
307 d_printf("Dumping PRIVS databases\n");
310 d_printf("Dumping unknown database type %u\n", db_type
);
315 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
317 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
319 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
323 &return_authenticator
,
330 /* Check returned credentials. */
331 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
332 &return_authenticator
.cred
)) {
333 DEBUG(0,("credentials chain check failed\n"));
337 if (NT_STATUS_IS_ERR(result
)) {
341 /* Display results */
342 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
343 display_sam_entry(&delta_enum_array
->delta_enum
[i
]);
346 TALLOC_FREE(delta_enum_array
);
348 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
350 talloc_destroy(mem_ctx
);
353 /* dump sam database via samsync rpc calls */
354 NTSTATUS
rpc_samdump_internals(const DOM_SID
*domain_sid
,
355 const char *domain_name
,
356 struct cli_state
*cli
,
357 struct rpc_pipe_client
*pipe_hnd
,
363 /* net_rpc.c now always tries to create an schannel pipe.. */
365 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
366 uchar trust_password
[16];
367 uint32 neg_flags
= NETLOGON_NEG_SELECT_AUTH2_FLAGS
;
368 uint32 sec_channel_type
= 0;
370 if (!secrets_fetch_trust_account_password(domain_name
,
372 NULL
, &sec_channel_type
)) {
373 DEBUG(0,("Could not fetch trust account password\n"));
377 nt_status
= rpccli_netlogon_setup_creds(pipe_hnd
,
385 if (!NT_STATUS_IS_OK(nt_status
)) {
386 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
391 dump_database(pipe_hnd
, SAM_DATABASE_DOMAIN
);
392 dump_database(pipe_hnd
, SAM_DATABASE_BUILTIN
);
393 dump_database(pipe_hnd
, SAM_DATABASE_PRIVS
);
398 /* Convert a struct samu_DELTA to a struct samu. */
399 #define STRING_CHANGED (old_string && !new_string) ||\
400 (!old_string && new_string) ||\
401 (old_string && new_string && (strcmp(old_string, new_string) != 0))
403 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
405 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
407 static NTSTATUS
sam_account_from_delta(struct samu
*account
,
408 struct netr_DELTA_USER
*r
)
410 const char *old_string
, *new_string
;
411 time_t unix_time
, stored_time
;
412 uchar lm_passwd
[16], nt_passwd
[16];
413 static uchar zero_buf
[16];
415 /* Username, fullname, home dir, dir drive, logon script, acct
416 desc, workstations, profile. */
418 if (r
->account_name
.string
) {
419 old_string
= pdb_get_nt_username(account
);
420 new_string
= r
->account_name
.string
;
422 if (STRING_CHANGED
) {
423 pdb_set_nt_username(account
, new_string
, PDB_CHANGED
);
426 /* Unix username is the same - for sanity */
427 old_string
= pdb_get_username( account
);
428 if (STRING_CHANGED
) {
429 pdb_set_username(account
, new_string
, PDB_CHANGED
);
433 if (r
->full_name
.string
) {
434 old_string
= pdb_get_fullname(account
);
435 new_string
= r
->full_name
.string
;
438 pdb_set_fullname(account
, new_string
, PDB_CHANGED
);
441 if (r
->home_directory
.string
) {
442 old_string
= pdb_get_homedir(account
);
443 new_string
= r
->home_directory
.string
;
446 pdb_set_homedir(account
, new_string
, PDB_CHANGED
);
449 if (r
->home_drive
.string
) {
450 old_string
= pdb_get_dir_drive(account
);
451 new_string
= r
->home_drive
.string
;
454 pdb_set_dir_drive(account
, new_string
, PDB_CHANGED
);
457 if (r
->logon_script
.string
) {
458 old_string
= pdb_get_logon_script(account
);
459 new_string
= r
->logon_script
.string
;
462 pdb_set_logon_script(account
, new_string
, PDB_CHANGED
);
465 if (r
->description
.string
) {
466 old_string
= pdb_get_acct_desc(account
);
467 new_string
= r
->description
.string
;
470 pdb_set_acct_desc(account
, new_string
, PDB_CHANGED
);
473 if (r
->workstations
.string
) {
474 old_string
= pdb_get_workstations(account
);
475 new_string
= r
->workstations
.string
;
478 pdb_set_workstations(account
, new_string
, PDB_CHANGED
);
481 if (r
->profile_path
.string
) {
482 old_string
= pdb_get_profile_path(account
);
483 new_string
= r
->profile_path
.string
;
486 pdb_set_profile_path(account
, new_string
, PDB_CHANGED
);
489 if (r
->parameters
.string
) {
492 old_string
= pdb_get_munged_dial(account
);
493 mung
.length
= r
->parameters
.length
;
494 mung
.data
= (uint8
*) r
->parameters
.string
;
495 newstr
= (mung
.length
== 0) ? NULL
:
496 base64_encode_data_blob(talloc_tos(), mung
);
498 if (STRING_CHANGED_NC(old_string
, newstr
))
499 pdb_set_munged_dial(account
, newstr
, PDB_CHANGED
);
503 /* User and group sid */
504 if (pdb_get_user_rid(account
) != r
->rid
)
505 pdb_set_user_sid_from_rid(account
, r
->rid
, PDB_CHANGED
);
506 if (pdb_get_group_rid(account
) != r
->primary_gid
)
507 pdb_set_group_sid_from_rid(account
, r
->primary_gid
, PDB_CHANGED
);
509 /* Logon and password information */
510 if (!nt_time_is_zero(&r
->last_logon
)) {
511 unix_time
= nt_time_to_unix(r
->last_logon
);
512 stored_time
= pdb_get_logon_time(account
);
513 if (stored_time
!= unix_time
)
514 pdb_set_logon_time(account
, unix_time
, PDB_CHANGED
);
517 if (!nt_time_is_zero(&r
->last_logoff
)) {
518 unix_time
= nt_time_to_unix(r
->last_logoff
);
519 stored_time
= pdb_get_logoff_time(account
);
520 if (stored_time
!= unix_time
)
521 pdb_set_logoff_time(account
, unix_time
,PDB_CHANGED
);
525 if (pdb_get_logon_divs(account
) != r
->logon_hours
.units_per_week
)
526 pdb_set_logon_divs(account
, r
->logon_hours
.units_per_week
, PDB_CHANGED
);
529 /* no idea what to do with this one - gd */
530 /* Max Logon Hours */
531 if (delta
->unknown1
!= pdb_get_unknown_6(account
)) {
532 pdb_set_unknown_6(account
, delta
->unknown1
, PDB_CHANGED
);
535 /* Logon Hours Len */
536 if (r
->logon_hours
.units_per_week
/8 != pdb_get_hours_len(account
)) {
537 pdb_set_hours_len(account
, r
->logon_hours
.units_per_week
/8, PDB_CHANGED
);
541 if (r
->logon_hours
.bits
) {
542 char oldstr
[44], newstr
[44];
543 pdb_sethexhours(oldstr
, pdb_get_hours(account
));
544 pdb_sethexhours(newstr
, r
->logon_hours
.bits
);
545 if (!strequal(oldstr
, newstr
))
546 pdb_set_hours(account
, r
->logon_hours
.bits
, PDB_CHANGED
);
549 if (pdb_get_bad_password_count(account
) != r
->bad_password_count
)
550 pdb_set_bad_password_count(account
, r
->bad_password_count
, PDB_CHANGED
);
552 if (pdb_get_logon_count(account
) != r
->logon_count
)
553 pdb_set_logon_count(account
, r
->logon_count
, PDB_CHANGED
);
555 if (!nt_time_is_zero(&r
->last_password_change
)) {
556 unix_time
= nt_time_to_unix(r
->last_password_change
);
557 stored_time
= pdb_get_pass_last_set_time(account
);
558 if (stored_time
!= unix_time
)
559 pdb_set_pass_last_set_time(account
, unix_time
, PDB_CHANGED
);
561 /* no last set time, make it now */
562 pdb_set_pass_last_set_time(account
, time(NULL
), PDB_CHANGED
);
565 if (!nt_time_is_zero(&r
->acct_expiry
)) {
566 unix_time
= nt_time_to_unix(r
->acct_expiry
);
567 stored_time
= pdb_get_kickoff_time(account
);
568 if (stored_time
!= unix_time
)
569 pdb_set_kickoff_time(account
, unix_time
, PDB_CHANGED
);
572 /* Decode hashes from password hash
573 Note that win2000 may send us all zeros for the hashes if it doesn't
574 think this channel is secure enough - don't set the passwords at all
577 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
578 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, lm_passwd
, 0);
579 pdb_set_lanman_passwd(account
, lm_passwd
, PDB_CHANGED
);
582 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
583 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, nt_passwd
, 0);
584 pdb_set_nt_passwd(account
, nt_passwd
, PDB_CHANGED
);
587 /* TODO: account expiry time */
589 pdb_set_acct_ctrl(account
, r
->acct_flags
, PDB_CHANGED
);
591 pdb_set_domain(account
, lp_workgroup(), PDB_CHANGED
);
596 static NTSTATUS
fetch_account_info(uint32_t rid
,
597 struct netr_DELTA_USER
*r
)
600 NTSTATUS nt_ret
= NT_STATUS_UNSUCCESSFUL
;
602 char *add_script
= NULL
;
603 struct samu
*sam_account
=NULL
;
608 struct passwd
*passwd
;
611 fstrcpy(account
, r
->account_name
.string
);
612 d_printf("Creating account: %s\n", account
);
614 if ( !(sam_account
= samu_new( NULL
)) ) {
615 return NT_STATUS_NO_MEMORY
;
618 if (!(passwd
= Get_Pwnam_alloc(sam_account
, account
))) {
619 /* Create appropriate user */
620 if (r
->acct_flags
& ACB_NORMAL
) {
621 add_script
= talloc_strdup(sam_account
,
622 lp_adduser_script());
623 } else if ( (r
->acct_flags
& ACB_WSTRUST
) ||
624 (r
->acct_flags
& ACB_SVRTRUST
) ||
625 (r
->acct_flags
& ACB_DOMTRUST
) ) {
626 add_script
= talloc_strdup(sam_account
,
627 lp_addmachine_script());
629 DEBUG(1, ("Unknown user type: %s\n",
630 pdb_encode_acct_ctrl(r
->acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
631 nt_ret
= NT_STATUS_UNSUCCESSFUL
;
635 nt_ret
= NT_STATUS_NO_MEMORY
;
640 add_script
= talloc_all_string_sub(sam_account
,
645 nt_ret
= NT_STATUS_NO_MEMORY
;
648 add_ret
= smbrun(add_script
,NULL
);
649 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
650 "gave %d\n", add_script
, add_ret
));
652 smb_nscd_flush_user_cache();
656 /* try and find the possible unix account again */
657 if ( !(passwd
= Get_Pwnam_alloc(sam_account
, account
)) ) {
658 d_fprintf(stderr
, "Could not create posix account info for '%s'\n", account
);
659 nt_ret
= NT_STATUS_NO_SUCH_USER
;
664 sid_copy(&user_sid
, get_global_sam_sid());
665 sid_append_rid(&user_sid
, r
->rid
);
667 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
668 sid_to_fstring(sid_string
, &user_sid
), account
));
669 if (!pdb_getsampwsid(sam_account
, &user_sid
)) {
670 sam_account_from_delta(sam_account
, r
);
671 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
672 sid_to_fstring(sid_string
, &user_sid
),
673 pdb_get_username(sam_account
)));
674 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account
))) {
675 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
677 return NT_STATUS_ACCESS_DENIED
;
680 sam_account_from_delta(sam_account
, r
);
681 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n",
682 sid_to_fstring(sid_string
, &user_sid
),
683 pdb_get_username(sam_account
)));
684 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account
))) {
685 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
687 TALLOC_FREE(sam_account
);
688 return NT_STATUS_ACCESS_DENIED
;
692 if (pdb_get_group_sid(sam_account
) == NULL
) {
693 return NT_STATUS_UNSUCCESSFUL
;
696 group_sid
= *pdb_get_group_sid(sam_account
);
698 if (!pdb_getgrsid(&map
, group_sid
)) {
699 DEBUG(0, ("Primary group of %s has no mapping!\n",
700 pdb_get_username(sam_account
)));
702 if (map
.gid
!= passwd
->pw_gid
) {
703 if (!(grp
= getgrgid(map
.gid
))) {
704 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
705 (unsigned long)map
.gid
, pdb_get_username(sam_account
), sid_string_tos(&group_sid
)));
707 smb_set_primary_group(grp
->gr_name
, pdb_get_username(sam_account
));
713 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n",
714 pdb_get_username(sam_account
)));
718 TALLOC_FREE(sam_account
);
722 static NTSTATUS
fetch_group_info(uint32_t rid
,
723 struct netr_DELTA_GROUP
*r
)
727 struct group
*grp
= NULL
;
733 fstrcpy(name
, r
->group_name
.string
);
734 fstrcpy(comment
, r
->description
.string
);
736 /* add the group to the mapping table */
737 sid_copy(&group_sid
, get_global_sam_sid());
738 sid_append_rid(&group_sid
, rid
);
739 sid_to_fstring(sid_string
, &group_sid
);
741 if (pdb_getgrsid(&map
, group_sid
)) {
743 grp
= getgrgid(map
.gid
);
750 /* No group found from mapping, find it from its name. */
751 if ((grp
= getgrnam(name
)) == NULL
) {
753 /* No appropriate group found, create one */
755 d_printf("Creating unix group: '%s'\n", name
);
757 if (smb_create_group(name
, &gid
) != 0)
758 return NT_STATUS_ACCESS_DENIED
;
760 if ((grp
= getgrnam(name
)) == NULL
)
761 return NT_STATUS_ACCESS_DENIED
;
765 map
.gid
= grp
->gr_gid
;
767 map
.sid_name_use
= SID_NAME_DOM_GRP
;
768 fstrcpy(map
.nt_name
, name
);
769 if (r
->description
.string
) {
770 fstrcpy(map
.comment
, comment
);
772 fstrcpy(map
.comment
, "");
776 pdb_add_group_mapping_entry(&map
);
778 pdb_update_group_mapping_entry(&map
);
783 static NTSTATUS
fetch_group_mem_info(uint32_t rid
,
784 struct netr_DELTA_GROUP_MEMBER
*r
)
787 TALLOC_CTX
*t
= NULL
;
788 char **nt_members
= NULL
;
794 if (r
->num_rids
== 0) {
798 sid_copy(&group_sid
, get_global_sam_sid());
799 sid_append_rid(&group_sid
, rid
);
801 if (!get_domain_group_from_sid(group_sid
, &map
)) {
802 DEBUG(0, ("Could not find global group %d\n", rid
));
803 return NT_STATUS_NO_SUCH_GROUP
;
806 if (!(grp
= getgrgid(map
.gid
))) {
807 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map
.gid
));
808 return NT_STATUS_NO_SUCH_GROUP
;
811 d_printf("Group members of %s: ", grp
->gr_name
);
813 if (!(t
= talloc_init("fetch_group_mem_info"))) {
814 DEBUG(0, ("could not talloc_init\n"));
815 return NT_STATUS_NO_MEMORY
;
819 if ((nt_members
= TALLOC_ZERO_ARRAY(t
, char *, r
->num_rids
)) == NULL
) {
820 DEBUG(0, ("talloc failed\n"));
822 return NT_STATUS_NO_MEMORY
;
828 for (i
=0; i
< r
->num_rids
; i
++) {
829 struct samu
*member
= NULL
;
832 if ( !(member
= samu_new(t
)) ) {
834 return NT_STATUS_NO_MEMORY
;
837 sid_copy(&member_sid
, get_global_sam_sid());
838 sid_append_rid(&member_sid
, r
->rids
[i
]);
840 if (!pdb_getsampwsid(member
, &member_sid
)) {
841 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
842 r
->rids
[i
], sid_string_tos(&member_sid
), grp
->gr_name
));
847 if (pdb_get_group_rid(member
) == rid
) {
848 d_printf("%s(primary),", pdb_get_username(member
));
853 d_printf("%s,", pdb_get_username(member
));
854 nt_members
[i
] = talloc_strdup(t
, pdb_get_username(member
));
860 unix_members
= grp
->gr_mem
;
862 while (*unix_members
) {
863 bool is_nt_member
= False
;
864 for (i
=0; i
< r
->num_rids
; i
++) {
865 if (nt_members
[i
] == NULL
) {
866 /* This was a primary group */
870 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
876 /* We look at a unix group member that is not
877 an nt group member. So, remove it. NT is
879 smb_delete_user_group(grp
->gr_name
, *unix_members
);
884 for (i
=0; i
< r
->num_rids
; i
++) {
885 bool is_unix_member
= False
;
887 if (nt_members
[i
] == NULL
) {
888 /* This was the primary group */
892 unix_members
= grp
->gr_mem
;
894 while (*unix_members
) {
895 if (strcmp(*unix_members
, nt_members
[i
]) == 0) {
896 is_unix_member
= True
;
902 if (!is_unix_member
) {
903 /* We look at a nt group member that is not a
904 unix group member currently. So, add the nt
906 smb_add_user_group(grp
->gr_name
, nt_members
[i
]);
914 static NTSTATUS
fetch_alias_info(uint32_t rid
,
915 struct netr_DELTA_ALIAS
*r
,
920 struct group
*grp
= NULL
;
926 fstrcpy(name
, r
->alias_name
.string
);
927 fstrcpy(comment
, r
->description
.string
);
929 /* Find out whether the group is already mapped */
930 sid_copy(&alias_sid
, &dom_sid
);
931 sid_append_rid(&alias_sid
, rid
);
932 sid_to_fstring(sid_string
, &alias_sid
);
934 if (pdb_getgrsid(&map
, alias_sid
)) {
935 grp
= getgrgid(map
.gid
);
942 /* No group found from mapping, find it from its name. */
943 if ((grp
= getgrnam(name
)) == NULL
) {
944 /* No appropriate group found, create one */
945 d_printf("Creating unix group: '%s'\n", name
);
946 if (smb_create_group(name
, &gid
) != 0)
947 return NT_STATUS_ACCESS_DENIED
;
948 if ((grp
= getgrgid(gid
)) == NULL
)
949 return NT_STATUS_ACCESS_DENIED
;
953 map
.gid
= grp
->gr_gid
;
956 if (sid_equal(&dom_sid
, &global_sid_Builtin
))
957 map
.sid_name_use
= SID_NAME_WKN_GRP
;
959 map
.sid_name_use
= SID_NAME_ALIAS
;
961 fstrcpy(map
.nt_name
, name
);
962 fstrcpy(map
.comment
, comment
);
965 pdb_add_group_mapping_entry(&map
);
967 pdb_update_group_mapping_entry(&map
);
972 static NTSTATUS
fetch_alias_mem(uint32_t rid
,
973 struct netr_DELTA_ALIAS_MEMBER
*r
,
979 static NTSTATUS
fetch_domain_info(uint32_t rid
,
980 struct netr_DELTA_DOMAIN
*r
)
982 time_t u_max_age
, u_min_age
, u_logout
;
985 time_t u_lockoutreset
, u_lockouttime
;
987 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
990 u_max_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->max_password_age
);
991 u_min_age
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->min_password_age
);
992 u_logout
= uint64s_nt_time_to_unix_abs((uint64
*)&r
->force_logoff_time
);
995 u_lockoutreset
= uint64s_nt_time_to_unix_abs(&delta
->account_lockout
.reset_count
);
996 u_lockouttime
= uint64s_nt_time_to_unix_abs(&delta
->account_lockout
.lockout_duration
);
998 domname
= r
->domain_name
.string
;
1000 return NT_STATUS_NO_MEMORY
;
1003 /* we don't handle BUILTIN account policies */
1004 if (!strequal(domname
, get_global_sam_name())) {
1005 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname
);
1006 return NT_STATUS_OK
;
1010 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY
,
1011 r
->password_history_length
))
1014 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN
,
1015 r
->min_password_length
))
1018 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (uint32
)u_max_age
))
1021 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (uint32
)u_min_age
))
1024 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (uint32
)u_logout
))
1028 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, delta
->account_lockout
.bad_attempt_lockout
))
1031 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME
, (uint32
)u_lockoutreset
/60))
1034 if (u_lockouttime
!= -1)
1035 u_lockouttime
/= 60;
1037 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (uint32
)u_lockouttime
))
1041 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
1042 r
->logon_to_chgpass
))
1045 return NT_STATUS_OK
;
1048 static void fetch_sam_entry(struct netr_DELTA_ENUM
*r
, DOM_SID dom_sid
)
1050 switch(r
->delta_type
) {
1051 case NETR_DELTA_USER
:
1052 fetch_account_info(r
->delta_id_union
.rid
,
1053 r
->delta_union
.user
);
1055 case NETR_DELTA_GROUP
:
1056 fetch_group_info(r
->delta_id_union
.rid
,
1057 r
->delta_union
.group
);
1059 case NETR_DELTA_GROUP_MEMBER
:
1060 fetch_group_mem_info(r
->delta_id_union
.rid
,
1061 r
->delta_union
.group_member
);
1063 case NETR_DELTA_ALIAS
:
1064 fetch_alias_info(r
->delta_id_union
.rid
,
1065 r
->delta_union
.alias
,
1068 case NETR_DELTA_ALIAS_MEMBER
:
1069 fetch_alias_mem(r
->delta_id_union
.rid
,
1070 r
->delta_union
.alias_member
,
1073 case NETR_DELTA_DOMAIN
:
1074 fetch_domain_info(r
->delta_id_union
.rid
,
1075 r
->delta_union
.domain
);
1077 /* The following types are recognised but not handled */
1078 case NETR_DELTA_RENAME_GROUP
:
1079 d_printf("NETR_DELTA_RENAME_GROUP not handled\n");
1081 case NETR_DELTA_RENAME_USER
:
1082 d_printf("NETR_DELTA_RENAME_USER not handled\n");
1084 case NETR_DELTA_RENAME_ALIAS
:
1085 d_printf("NETR_DELTA_RENAME_ALIAS not handled\n");
1087 case NETR_DELTA_POLICY
:
1088 d_printf("NETR_DELTA_POLICY not handled\n");
1090 case NETR_DELTA_TRUSTED_DOMAIN
:
1091 d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
1093 case NETR_DELTA_ACCOUNT
:
1094 d_printf("NETR_DELTA_ACCOUNT not handled\n");
1096 case NETR_DELTA_SECRET
:
1097 d_printf("NETR_DELTA_SECRET not handled\n");
1099 case NETR_DELTA_DELETE_GROUP
:
1100 d_printf("NETR_DELTA_DELETE_GROUP not handled\n");
1102 case NETR_DELTA_DELETE_USER
:
1103 d_printf("NETR_DELTA_DELETE_USER not handled\n");
1105 case NETR_DELTA_MODIFY_COUNT
:
1106 d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
1108 case NETR_DELTA_DELETE_ALIAS
:
1109 d_printf("NETR_DELTA_DELETE_ALIAS not handled\n");
1111 case NETR_DELTA_DELETE_TRUST
:
1112 d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
1114 case NETR_DELTA_DELETE_ACCOUNT
:
1115 d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
1117 case NETR_DELTA_DELETE_SECRET
:
1118 d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
1120 case NETR_DELTA_DELETE_GROUP2
:
1121 d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
1123 case NETR_DELTA_DELETE_USER2
:
1124 d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
1127 d_printf("Unknown delta record type %d\n", r
->delta_type
);
1132 static NTSTATUS
fetch_database(struct rpc_pipe_client
*pipe_hnd
, uint32 db_type
, DOM_SID dom_sid
)
1136 TALLOC_CTX
*mem_ctx
;
1137 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1138 const char *computername
= global_myname();
1139 struct netr_Authenticator credential
;
1140 struct netr_Authenticator return_authenticator
;
1141 enum netr_SamDatabaseID database_id
= db_type
;
1142 uint16_t restart_state
= 0;
1143 uint32_t sync_context
= 0;
1145 if (!(mem_ctx
= talloc_init("fetch_database")))
1146 return NT_STATUS_NO_MEMORY
;
1149 case SAM_DATABASE_DOMAIN
:
1150 d_printf("Fetching DOMAIN database\n");
1152 case SAM_DATABASE_BUILTIN
:
1153 d_printf("Fetching BUILTIN database\n");
1155 case SAM_DATABASE_PRIVS
:
1156 d_printf("Fetching PRIVS databases\n");
1159 d_printf("Fetching unknown database type %u\n", db_type
);
1164 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1166 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
1168 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
1172 &return_authenticator
,
1179 /* Check returned credentials. */
1180 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
1181 &return_authenticator
.cred
)) {
1182 DEBUG(0,("credentials chain check failed\n"));
1183 return NT_STATUS_ACCESS_DENIED
;
1186 if (NT_STATUS_IS_ERR(result
)) {
1190 for (i
= 0; i
< delta_enum_array
->num_deltas
; i
++) {
1191 fetch_sam_entry(&delta_enum_array
->delta_enum
[i
], dom_sid
);
1194 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1196 talloc_destroy(mem_ctx
);
1201 static NTSTATUS
populate_ldap_for_ldif(fstring sid
, const char *suffix
, const char
1202 *builtin_sid
, FILE *add_fd
)
1204 const char *user_suffix
, *group_suffix
, *machine_suffix
, *idmap_suffix
;
1205 char *user_attr
=NULL
, *group_attr
=NULL
;
1209 /* Get the suffix attribute */
1210 suffix_attr
= sstring_sub(suffix
, '=', ',');
1211 if (suffix_attr
== NULL
) {
1212 len
= strlen(suffix
);
1213 suffix_attr
= (char*)SMB_MALLOC(len
+1);
1214 memcpy(suffix_attr
, suffix
, len
);
1215 suffix_attr
[len
] = '\0';
1218 /* Write the base */
1219 fprintf(add_fd
, "# %s\n", suffix
);
1220 fprintf(add_fd
, "dn: %s\n", suffix
);
1221 fprintf(add_fd
, "objectClass: dcObject\n");
1222 fprintf(add_fd
, "objectClass: organization\n");
1223 fprintf(add_fd
, "o: %s\n", suffix_attr
);
1224 fprintf(add_fd
, "dc: %s\n", suffix_attr
);
1225 fprintf(add_fd
, "\n");
1228 user_suffix
= lp_ldap_user_suffix();
1229 if (user_suffix
== NULL
) {
1230 SAFE_FREE(suffix_attr
);
1231 return NT_STATUS_NO_MEMORY
;
1233 /* If it exists and is distinct from other containers,
1234 Write the Users entity */
1235 if (*user_suffix
&& strcmp(user_suffix
, suffix
)) {
1236 user_attr
= sstring_sub(lp_ldap_user_suffix(), '=', ',');
1237 fprintf(add_fd
, "# %s\n", user_suffix
);
1238 fprintf(add_fd
, "dn: %s\n", user_suffix
);
1239 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1240 fprintf(add_fd
, "ou: %s\n", user_attr
);
1241 fprintf(add_fd
, "\n");
1246 group_suffix
= lp_ldap_group_suffix();
1247 if (group_suffix
== NULL
) {
1248 SAFE_FREE(suffix_attr
);
1249 SAFE_FREE(user_attr
);
1250 return NT_STATUS_NO_MEMORY
;
1252 /* If it exists and is distinct from other containers,
1253 Write the Groups entity */
1254 if (*group_suffix
&& strcmp(group_suffix
, suffix
)) {
1255 group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1256 fprintf(add_fd
, "# %s\n", group_suffix
);
1257 fprintf(add_fd
, "dn: %s\n", group_suffix
);
1258 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1259 fprintf(add_fd
, "ou: %s\n", group_attr
);
1260 fprintf(add_fd
, "\n");
1264 /* If it exists and is distinct from other containers,
1265 Write the Computers entity */
1266 machine_suffix
= lp_ldap_machine_suffix();
1267 if (machine_suffix
== NULL
) {
1268 SAFE_FREE(suffix_attr
);
1269 SAFE_FREE(user_attr
);
1270 SAFE_FREE(group_attr
);
1271 return NT_STATUS_NO_MEMORY
;
1273 if (*machine_suffix
&& strcmp(machine_suffix
, user_suffix
) &&
1274 strcmp(machine_suffix
, suffix
)) {
1275 char *machine_ou
= NULL
;
1276 fprintf(add_fd
, "# %s\n", machine_suffix
);
1277 fprintf(add_fd
, "dn: %s\n", machine_suffix
);
1278 fprintf(add_fd
, "objectClass: organizationalUnit\n");
1279 /* this isn't totally correct as it assumes that
1280 there _must_ be an ou. just fixing memleak now. jmcd */
1281 machine_ou
= sstring_sub(lp_ldap_machine_suffix(), '=', ',');
1282 fprintf(add_fd
, "ou: %s\n", machine_ou
);
1283 SAFE_FREE(machine_ou
);
1284 fprintf(add_fd
, "\n");
1288 /* If it exists and is distinct from other containers,
1289 Write the IdMap entity */
1290 idmap_suffix
= lp_ldap_idmap_suffix();
1291 if (idmap_suffix
== NULL
) {
1292 SAFE_FREE(suffix_attr
);
1293 SAFE_FREE(user_attr
);
1294 SAFE_FREE(group_attr
);
1295 return NT_STATUS_NO_MEMORY
;
1297 if (*idmap_suffix
&&
1298 strcmp(idmap_suffix
, user_suffix
) &&
1299 strcmp(idmap_suffix
, suffix
)) {
1301 fprintf(add_fd
, "# %s\n", idmap_suffix
);
1302 fprintf(add_fd
, "dn: %s\n", idmap_suffix
);
1303 fprintf(add_fd
, "ObjectClass: organizationalUnit\n");
1304 s
= sstring_sub(lp_ldap_idmap_suffix(), '=', ',');
1305 fprintf(add_fd
, "ou: %s\n", s
);
1307 fprintf(add_fd
, "\n");
1311 /* Write the domain entity */
1312 fprintf(add_fd
, "# %s, %s\n", lp_workgroup(), suffix
);
1313 fprintf(add_fd
, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
1315 fprintf(add_fd
, "objectClass: sambaDomain\n");
1316 fprintf(add_fd
, "objectClass: sambaUnixIdPool\n");
1317 fprintf(add_fd
, "sambaDomainName: %s\n", lp_workgroup());
1318 fprintf(add_fd
, "sambaSID: %s\n", sid
);
1319 fprintf(add_fd
, "uidNumber: %d\n", ++ldif_uid
);
1320 fprintf(add_fd
, "gidNumber: %d\n", ++ldif_gid
);
1321 fprintf(add_fd
, "\n");
1324 /* Write the Domain Admins entity */
1325 fprintf(add_fd
, "# Domain Admins, %s, %s\n", group_attr
,
1327 fprintf(add_fd
, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr
,
1329 fprintf(add_fd
, "objectClass: posixGroup\n");
1330 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1331 fprintf(add_fd
, "cn: Domain Admins\n");
1332 fprintf(add_fd
, "memberUid: Administrator\n");
1333 fprintf(add_fd
, "description: Netbios Domain Administrators\n");
1334 fprintf(add_fd
, "gidNumber: 512\n");
1335 fprintf(add_fd
, "sambaSID: %s-512\n", sid
);
1336 fprintf(add_fd
, "sambaGroupType: 2\n");
1337 fprintf(add_fd
, "displayName: Domain Admins\n");
1338 fprintf(add_fd
, "\n");
1341 /* Write the Domain Users entity */
1342 fprintf(add_fd
, "# Domain Users, %s, %s\n", group_attr
,
1344 fprintf(add_fd
, "dn: cn=Domain Users,ou=%s,%s\n", group_attr
,
1346 fprintf(add_fd
, "objectClass: posixGroup\n");
1347 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1348 fprintf(add_fd
, "cn: Domain Users\n");
1349 fprintf(add_fd
, "description: Netbios Domain Users\n");
1350 fprintf(add_fd
, "gidNumber: 513\n");
1351 fprintf(add_fd
, "sambaSID: %s-513\n", sid
);
1352 fprintf(add_fd
, "sambaGroupType: 2\n");
1353 fprintf(add_fd
, "displayName: Domain Users\n");
1354 fprintf(add_fd
, "\n");
1357 /* Write the Domain Guests entity */
1358 fprintf(add_fd
, "# Domain Guests, %s, %s\n", group_attr
,
1360 fprintf(add_fd
, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr
,
1362 fprintf(add_fd
, "objectClass: posixGroup\n");
1363 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1364 fprintf(add_fd
, "cn: Domain Guests\n");
1365 fprintf(add_fd
, "description: Netbios Domain Guests\n");
1366 fprintf(add_fd
, "gidNumber: 514\n");
1367 fprintf(add_fd
, "sambaSID: %s-514\n", sid
);
1368 fprintf(add_fd
, "sambaGroupType: 2\n");
1369 fprintf(add_fd
, "displayName: Domain Guests\n");
1370 fprintf(add_fd
, "\n");
1373 /* Write the Domain Computers entity */
1374 fprintf(add_fd
, "# Domain Computers, %s, %s\n", group_attr
,
1376 fprintf(add_fd
, "dn: cn=Domain Computers,ou=%s,%s\n",
1377 group_attr
, suffix
);
1378 fprintf(add_fd
, "objectClass: posixGroup\n");
1379 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1380 fprintf(add_fd
, "gidNumber: 515\n");
1381 fprintf(add_fd
, "cn: Domain Computers\n");
1382 fprintf(add_fd
, "description: Netbios Domain Computers accounts\n");
1383 fprintf(add_fd
, "sambaSID: %s-515\n", sid
);
1384 fprintf(add_fd
, "sambaGroupType: 2\n");
1385 fprintf(add_fd
, "displayName: Domain Computers\n");
1386 fprintf(add_fd
, "\n");
1389 /* Write the Admininistrators Groups entity */
1390 fprintf(add_fd
, "# Administrators, %s, %s\n", group_attr
,
1392 fprintf(add_fd
, "dn: cn=Administrators,ou=%s,%s\n", group_attr
,
1394 fprintf(add_fd
, "objectClass: posixGroup\n");
1395 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1396 fprintf(add_fd
, "gidNumber: 544\n");
1397 fprintf(add_fd
, "cn: Administrators\n");
1398 fprintf(add_fd
, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n");
1399 fprintf(add_fd
, "sambaSID: %s-544\n", builtin_sid
);
1400 fprintf(add_fd
, "sambaGroupType: 5\n");
1401 fprintf(add_fd
, "displayName: Administrators\n");
1402 fprintf(add_fd
, "\n");
1404 /* Write the Print Operator entity */
1405 fprintf(add_fd
, "# Print Operators, %s, %s\n", group_attr
,
1407 fprintf(add_fd
, "dn: cn=Print Operators,ou=%s,%s\n",
1408 group_attr
, suffix
);
1409 fprintf(add_fd
, "objectClass: posixGroup\n");
1410 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1411 fprintf(add_fd
, "gidNumber: 550\n");
1412 fprintf(add_fd
, "cn: Print Operators\n");
1413 fprintf(add_fd
, "description: Netbios Domain Print Operators\n");
1414 fprintf(add_fd
, "sambaSID: %s-550\n", builtin_sid
);
1415 fprintf(add_fd
, "sambaGroupType: 5\n");
1416 fprintf(add_fd
, "displayName: Print Operators\n");
1417 fprintf(add_fd
, "\n");
1420 /* Write the Backup Operators entity */
1421 fprintf(add_fd
, "# Backup Operators, %s, %s\n", group_attr
,
1423 fprintf(add_fd
, "dn: cn=Backup Operators,ou=%s,%s\n",
1424 group_attr
, suffix
);
1425 fprintf(add_fd
, "objectClass: posixGroup\n");
1426 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1427 fprintf(add_fd
, "gidNumber: 551\n");
1428 fprintf(add_fd
, "cn: Backup Operators\n");
1429 fprintf(add_fd
, "description: Netbios Domain Members can bypass file security to back up files\n");
1430 fprintf(add_fd
, "sambaSID: %s-551\n", builtin_sid
);
1431 fprintf(add_fd
, "sambaGroupType: 5\n");
1432 fprintf(add_fd
, "displayName: Backup Operators\n");
1433 fprintf(add_fd
, "\n");
1436 /* Write the Replicators entity */
1437 fprintf(add_fd
, "# Replicators, %s, %s\n", group_attr
, suffix
);
1438 fprintf(add_fd
, "dn: cn=Replicators,ou=%s,%s\n", group_attr
,
1440 fprintf(add_fd
, "objectClass: posixGroup\n");
1441 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1442 fprintf(add_fd
, "gidNumber: 552\n");
1443 fprintf(add_fd
, "cn: Replicators\n");
1444 fprintf(add_fd
, "description: Netbios Domain Supports file replication in a sambaDomainName\n");
1445 fprintf(add_fd
, "sambaSID: %s-552\n", builtin_sid
);
1446 fprintf(add_fd
, "sambaGroupType: 5\n");
1447 fprintf(add_fd
, "displayName: Replicators\n");
1448 fprintf(add_fd
, "\n");
1451 /* Deallocate memory, and return */
1452 SAFE_FREE(suffix_attr
);
1453 SAFE_FREE(user_attr
);
1454 SAFE_FREE(group_attr
);
1455 return NT_STATUS_OK
;
1458 static NTSTATUS
map_populate_groups(GROUPMAP
*groupmap
, ACCOUNTMAP
*accountmap
, fstring sid
,
1459 const char *suffix
, const char *builtin_sid
)
1461 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1463 /* Map the groups created by populate_ldap_for_ldif */
1464 groupmap
[0].rid
= 512;
1465 groupmap
[0].gidNumber
= 512;
1466 snprintf(groupmap
[0].sambaSID
, sizeof(groupmap
[0].sambaSID
),
1468 snprintf(groupmap
[0].group_dn
, sizeof(groupmap
[0].group_dn
),
1469 "cn=Domain Admins,ou=%s,%s",
1470 group_attr
, suffix
);
1471 accountmap
[0].rid
= 512;
1472 snprintf(accountmap
[0].cn
, sizeof(accountmap
[0].cn
),
1473 "%s", "Domain Admins");
1475 groupmap
[1].rid
= 513;
1476 groupmap
[1].gidNumber
= 513;
1477 snprintf(groupmap
[1].sambaSID
, sizeof(groupmap
[1].sambaSID
),
1479 snprintf(groupmap
[1].group_dn
, sizeof(groupmap
[1].group_dn
),
1480 "cn=Domain Users,ou=%s,%s",
1481 group_attr
, suffix
);
1482 accountmap
[1].rid
= 513;
1483 snprintf(accountmap
[1].cn
, sizeof(accountmap
[1].cn
),
1484 "%s", "Domain Users");
1486 groupmap
[2].rid
= 514;
1487 groupmap
[2].gidNumber
= 514;
1488 snprintf(groupmap
[2].sambaSID
, sizeof(groupmap
[2].sambaSID
),
1490 snprintf(groupmap
[2].group_dn
, sizeof(groupmap
[2].group_dn
),
1491 "cn=Domain Guests,ou=%s,%s",
1492 group_attr
, suffix
);
1493 accountmap
[2].rid
= 514;
1494 snprintf(accountmap
[2].cn
, sizeof(accountmap
[2].cn
),
1495 "%s", "Domain Guests");
1497 groupmap
[3].rid
= 515;
1498 groupmap
[3].gidNumber
= 515;
1499 snprintf(groupmap
[3].sambaSID
, sizeof(groupmap
[3].sambaSID
),
1501 snprintf(groupmap
[3].group_dn
, sizeof(groupmap
[3].group_dn
),
1502 "cn=Domain Computers,ou=%s,%s",
1503 group_attr
, suffix
);
1504 accountmap
[3].rid
= 515;
1505 snprintf(accountmap
[3].cn
, sizeof(accountmap
[3].cn
),
1506 "%s", "Domain Computers");
1508 groupmap
[4].rid
= 544;
1509 groupmap
[4].gidNumber
= 544;
1510 snprintf(groupmap
[4].sambaSID
, sizeof(groupmap
[4].sambaSID
),
1511 "%s-544", builtin_sid
);
1512 snprintf(groupmap
[4].group_dn
, sizeof(groupmap
[4].group_dn
),
1513 "cn=Administrators,ou=%s,%s",
1514 group_attr
, suffix
);
1515 accountmap
[4].rid
= 515;
1516 snprintf(accountmap
[4].cn
, sizeof(accountmap
[4].cn
),
1517 "%s", "Administrators");
1519 groupmap
[5].rid
= 550;
1520 groupmap
[5].gidNumber
= 550;
1521 snprintf(groupmap
[5].sambaSID
, sizeof(groupmap
[5].sambaSID
),
1522 "%s-550", builtin_sid
);
1523 snprintf(groupmap
[5].group_dn
, sizeof(groupmap
[5].group_dn
),
1524 "cn=Print Operators,ou=%s,%s",
1525 group_attr
, suffix
);
1526 accountmap
[5].rid
= 550;
1527 snprintf(accountmap
[5].cn
, sizeof(accountmap
[5].cn
),
1528 "%s", "Print Operators");
1530 groupmap
[6].rid
= 551;
1531 groupmap
[6].gidNumber
= 551;
1532 snprintf(groupmap
[6].sambaSID
, sizeof(groupmap
[6].sambaSID
),
1533 "%s-551", builtin_sid
);
1534 snprintf(groupmap
[6].group_dn
, sizeof(groupmap
[6].group_dn
),
1535 "cn=Backup Operators,ou=%s,%s",
1536 group_attr
, suffix
);
1537 accountmap
[6].rid
= 551;
1538 snprintf(accountmap
[6].cn
, sizeof(accountmap
[6].cn
),
1539 "%s", "Backup Operators");
1541 groupmap
[7].rid
= 552;
1542 groupmap
[7].gidNumber
= 552;
1543 snprintf(groupmap
[7].sambaSID
, sizeof(groupmap
[7].sambaSID
),
1544 "%s-552", builtin_sid
);
1545 snprintf(groupmap
[7].group_dn
, sizeof(groupmap
[7].group_dn
),
1546 "cn=Replicators,ou=%s,%s",
1547 group_attr
, suffix
);
1548 accountmap
[7].rid
= 551;
1549 snprintf(accountmap
[7].cn
, sizeof(accountmap
[7].cn
),
1550 "%s", "Replicators");
1551 SAFE_FREE(group_attr
);
1552 return NT_STATUS_OK
;
1556 * This is a crap routine, but I think it's the quickest way to solve the
1557 * UTF8->base64 problem.
1560 static int fprintf_attr(FILE *add_fd
, const char *attr_name
,
1561 const char *fmt
, ...)
1564 char *value
, *p
, *base64
;
1565 DATA_BLOB base64_blob
;
1566 bool do_base64
= False
;
1570 value
= talloc_vasprintf(NULL
, fmt
, ap
);
1573 SMB_ASSERT(value
!= NULL
);
1575 for (p
=value
; *p
; p
++) {
1583 bool only_whitespace
= True
;
1584 for (p
=value
; *p
; p
++) {
1586 * I know that this not multibyte safe, but we break
1587 * on the first non-whitespace character anyway.
1590 only_whitespace
= False
;
1594 if (only_whitespace
) {
1600 res
= fprintf(add_fd
, "%s: %s\n", attr_name
, value
);
1605 base64_blob
.data
= (unsigned char *)value
;
1606 base64_blob
.length
= strlen(value
);
1608 base64
= base64_encode_data_blob(value
, base64_blob
);
1609 SMB_ASSERT(base64
!= NULL
);
1611 res
= fprintf(add_fd
, "%s:: %s\n", attr_name
, base64
);
1616 static NTSTATUS
fetch_group_info_to_ldif(struct netr_DELTA_GROUP
*r
, GROUPMAP
*groupmap
,
1617 FILE *add_fd
, fstring sid
, char *suffix
)
1620 uint32 grouptype
= 0, g_rid
= 0;
1621 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1623 /* Get the group name */
1624 fstrcpy(groupname
, r
->group_name
.string
);
1626 /* Set up the group type (always 2 for group info) */
1629 /* These groups are entered by populate_ldap_for_ldif */
1630 if (strcmp(groupname
, "Domain Admins") == 0 ||
1631 strcmp(groupname
, "Domain Users") == 0 ||
1632 strcmp(groupname
, "Domain Guests") == 0 ||
1633 strcmp(groupname
, "Domain Computers") == 0 ||
1634 strcmp(groupname
, "Administrators") == 0 ||
1635 strcmp(groupname
, "Print Operators") == 0 ||
1636 strcmp(groupname
, "Backup Operators") == 0 ||
1637 strcmp(groupname
, "Replicators") == 0) {
1638 SAFE_FREE(group_attr
);
1639 return NT_STATUS_OK
;
1641 /* Increment the gid for the new group */
1645 /* Map the group rid, gid, and dn */
1647 groupmap
->rid
= g_rid
;
1648 groupmap
->gidNumber
= ldif_gid
;
1649 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1650 "%s-%d", sid
, g_rid
);
1651 snprintf(groupmap
->group_dn
, sizeof(groupmap
->group_dn
),
1652 "cn=%s,ou=%s,%s", groupname
, group_attr
, suffix
);
1654 /* Write the data to the temporary add ldif file */
1655 fprintf(add_fd
, "# %s, %s, %s\n", groupname
, group_attr
,
1657 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", groupname
, group_attr
,
1659 fprintf(add_fd
, "objectClass: posixGroup\n");
1660 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1661 fprintf_attr(add_fd
, "cn", "%s", groupname
);
1662 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1663 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1664 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1665 fprintf_attr(add_fd
, "displayName", "%s", groupname
);
1666 fprintf(add_fd
, "\n");
1669 SAFE_FREE(group_attr
);
1671 return NT_STATUS_OK
;
1674 static NTSTATUS
fetch_account_info_to_ldif(struct netr_DELTA_USER
*r
,
1676 ACCOUNTMAP
*accountmap
,
1678 fstring sid
, char *suffix
,
1681 fstring username
, logonscript
, homedrive
, homepath
= "", homedir
= "";
1682 fstring hex_nt_passwd
, hex_lm_passwd
;
1683 fstring description
, profilepath
, fullname
, sambaSID
;
1684 uchar lm_passwd
[16], nt_passwd
[16];
1685 char *flags
, *user_rdn
;
1687 const char* nopasswd
= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
1688 static uchar zero_buf
[16];
1689 uint32 rid
= 0, group_rid
= 0, gidNumber
= 0;
1693 /* Get the username */
1694 fstrcpy(username
, r
->account_name
.string
);
1699 /* Map the rid and username for group member info later */
1700 accountmap
->rid
= rid
;
1701 snprintf(accountmap
->cn
, sizeof(accountmap
->cn
), "%s", username
);
1703 /* Get the home directory */
1704 if (r
->acct_flags
& ACB_NORMAL
) {
1705 fstrcpy(homedir
, r
->home_directory
.string
);
1707 snprintf(homedir
, sizeof(homedir
), "/home/%s", username
);
1709 snprintf(homedir
, sizeof(homedir
), "/nobodyshomedir");
1711 ou
= lp_ldap_user_suffix();
1713 ou
= lp_ldap_machine_suffix();
1714 snprintf(homedir
, sizeof(homedir
), "/machinehomedir");
1717 /* Get the logon script */
1718 fstrcpy(logonscript
, r
->logon_script
.string
);
1720 /* Get the home drive */
1721 fstrcpy(homedrive
, r
->home_drive
.string
);
1723 /* Get the home path */
1724 fstrcpy(homepath
, r
->home_directory
.string
);
1726 /* Get the description */
1727 fstrcpy(description
, r
->description
.string
);
1729 /* Get the display name */
1730 fstrcpy(fullname
, r
->full_name
.string
);
1732 /* Get the profile path */
1733 fstrcpy(profilepath
, r
->profile_path
.string
);
1735 /* Get lm and nt password data */
1736 if (memcmp(r
->lmpassword
.hash
, zero_buf
, 16) != 0) {
1737 sam_pwd_hash(r
->rid
, r
->lmpassword
.hash
, lm_passwd
, 0);
1738 pdb_sethexpwd(hex_lm_passwd
, lm_passwd
, r
->acct_flags
);
1740 pdb_sethexpwd(hex_lm_passwd
, NULL
, 0);
1742 if (memcmp(r
->ntpassword
.hash
, zero_buf
, 16) != 0) {
1743 sam_pwd_hash(r
->rid
, r
->ntpassword
.hash
, nt_passwd
, 0);
1744 pdb_sethexpwd(hex_nt_passwd
, nt_passwd
, r
->acct_flags
);
1746 pdb_sethexpwd(hex_nt_passwd
, NULL
, 0);
1748 unix_time
= nt_time_to_unix(r
->last_password_change
);
1750 /* Increment the uid for the new user */
1753 /* Set up group id and sambaSID for the user */
1754 group_rid
= r
->primary_gid
;
1755 for (i
=0; i
<alloced
; i
++) {
1756 if (groupmap
[i
].rid
== group_rid
) break;
1759 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1761 return NT_STATUS_UNSUCCESSFUL
;
1763 gidNumber
= groupmap
[i
].gidNumber
;
1764 snprintf(sambaSID
, sizeof(sambaSID
), groupmap
[i
].sambaSID
);
1766 /* Set up sambaAcctFlags */
1767 flags
= pdb_encode_acct_ctrl(r
->acct_flags
,
1768 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1770 /* Add the user to the temporary add ldif file */
1771 /* this isn't quite right...we can't assume there's just OU=. jmcd */
1772 user_rdn
= sstring_sub(ou
, '=', ',');
1773 fprintf(add_fd
, "# %s, %s, %s\n", username
, user_rdn
, suffix
);
1774 fprintf_attr(add_fd
, "dn", "uid=%s,ou=%s,%s", username
, user_rdn
,
1776 SAFE_FREE(user_rdn
);
1777 fprintf(add_fd
, "ObjectClass: top\n");
1778 fprintf(add_fd
, "objectClass: inetOrgPerson\n");
1779 fprintf(add_fd
, "objectClass: posixAccount\n");
1780 fprintf(add_fd
, "objectClass: shadowAccount\n");
1781 fprintf(add_fd
, "objectClass: sambaSamAccount\n");
1782 fprintf_attr(add_fd
, "cn", "%s", username
);
1783 fprintf_attr(add_fd
, "sn", "%s", username
);
1784 fprintf_attr(add_fd
, "uid", "%s", username
);
1785 fprintf(add_fd
, "uidNumber: %d\n", ldif_uid
);
1786 fprintf(add_fd
, "gidNumber: %d\n", gidNumber
);
1787 fprintf_attr(add_fd
, "homeDirectory", "%s", homedir
);
1789 fprintf_attr(add_fd
, "sambaHomePath", "%s", homepath
);
1791 fprintf_attr(add_fd
, "sambaHomeDrive", "%s", homedrive
);
1793 fprintf_attr(add_fd
, "sambaLogonScript", "%s", logonscript
);
1794 fprintf(add_fd
, "loginShell: %s\n",
1795 ((r
->acct_flags
& ACB_NORMAL
) ?
1796 "/bin/bash" : "/bin/false"));
1797 fprintf(add_fd
, "gecos: System User\n");
1799 fprintf_attr(add_fd
, "description", "%s", description
);
1800 fprintf(add_fd
, "sambaSID: %s-%d\n", sid
, rid
);
1801 fprintf(add_fd
, "sambaPrimaryGroupSID: %s\n", sambaSID
);
1803 fprintf_attr(add_fd
, "displayName", "%s", fullname
);
1805 fprintf_attr(add_fd
, "sambaProfilePath", "%s", profilepath
);
1806 if (strcmp(nopasswd
, hex_lm_passwd
) != 0)
1807 fprintf(add_fd
, "sambaLMPassword: %s\n", hex_lm_passwd
);
1808 if (strcmp(nopasswd
, hex_nt_passwd
) != 0)
1809 fprintf(add_fd
, "sambaNTPassword: %s\n", hex_nt_passwd
);
1810 fprintf(add_fd
, "sambaPwdLastSet: %d\n", (int)unix_time
);
1811 fprintf(add_fd
, "sambaAcctFlags: %s\n", flags
);
1812 fprintf(add_fd
, "\n");
1816 return NT_STATUS_OK
;
1819 static NTSTATUS
fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS
*r
,
1821 FILE *add_fd
, fstring sid
,
1825 fstring aliasname
, description
;
1826 uint32 grouptype
= 0, g_rid
= 0;
1827 char *group_attr
= sstring_sub(lp_ldap_group_suffix(), '=', ',');
1829 /* Get the alias name */
1830 fstrcpy(aliasname
, r
->alias_name
.string
);
1832 /* Get the alias description */
1833 fstrcpy(description
, r
->description
.string
);
1835 /* Set up the group type */
1837 case SAM_DATABASE_DOMAIN
:
1840 case SAM_DATABASE_BUILTIN
:
1849 These groups are entered by populate_ldap_for_ldif
1850 Note that populate creates a group called Relicators,
1851 but NT returns a group called Replicator
1853 if (strcmp(aliasname
, "Domain Admins") == 0 ||
1854 strcmp(aliasname
, "Domain Users") == 0 ||
1855 strcmp(aliasname
, "Domain Guests") == 0 ||
1856 strcmp(aliasname
, "Domain Computers") == 0 ||
1857 strcmp(aliasname
, "Administrators") == 0 ||
1858 strcmp(aliasname
, "Print Operators") == 0 ||
1859 strcmp(aliasname
, "Backup Operators") == 0 ||
1860 strcmp(aliasname
, "Replicator") == 0) {
1861 SAFE_FREE(group_attr
);
1862 return NT_STATUS_OK
;
1864 /* Increment the gid for the new group */
1868 /* Map the group rid and gid */
1870 groupmap
->gidNumber
= ldif_gid
;
1871 snprintf(groupmap
->sambaSID
, sizeof(groupmap
->sambaSID
),
1872 "%s-%d", sid
, g_rid
);
1874 /* Write the data to the temporary add ldif file */
1875 fprintf(add_fd
, "# %s, %s, %s\n", aliasname
, group_attr
,
1877 fprintf_attr(add_fd
, "dn", "cn=%s,ou=%s,%s", aliasname
, group_attr
,
1879 fprintf(add_fd
, "objectClass: posixGroup\n");
1880 fprintf(add_fd
, "objectClass: sambaGroupMapping\n");
1881 fprintf(add_fd
, "cn: %s\n", aliasname
);
1882 fprintf(add_fd
, "gidNumber: %d\n", ldif_gid
);
1883 fprintf(add_fd
, "sambaSID: %s\n", groupmap
->sambaSID
);
1884 fprintf(add_fd
, "sambaGroupType: %d\n", grouptype
);
1885 fprintf_attr(add_fd
, "displayName", "%s", aliasname
);
1887 fprintf_attr(add_fd
, "description", "%s", description
);
1888 fprintf(add_fd
, "\n");
1891 SAFE_FREE(group_attr
);
1893 return NT_STATUS_OK
;
1896 static NTSTATUS
fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER
*r
,
1899 ACCOUNTMAP
*accountmap
,
1900 FILE *mod_fd
, int alloced
)
1903 uint32 group_rid
= 0, rid
= 0;
1906 /* Get the dn for the group */
1907 if (r
->num_rids
> 0) {
1909 for (j
=0; j
<alloced
; j
++) {
1910 if (groupmap
[j
].rid
== group_rid
) break;
1913 DEBUG(1, ("Could not find rid %d in groupmap array\n",
1915 return NT_STATUS_UNSUCCESSFUL
;
1917 snprintf(group_dn
, sizeof(group_dn
), "%s", groupmap
[j
].group_dn
);
1918 fprintf(mod_fd
, "dn: %s\n", group_dn
);
1920 /* Get the cn for each member */
1921 for (i
=0; i
< r
->num_rids
; i
++) {
1923 for (k
=0; k
<alloced
; k
++) {
1924 if (accountmap
[k
].rid
== rid
) break;
1927 DEBUG(1, ("Could not find rid %d in "
1928 "accountmap array\n", rid
));
1929 return NT_STATUS_UNSUCCESSFUL
;
1931 fprintf(mod_fd
, "memberUid: %s\n", accountmap
[k
].cn
);
1933 fprintf(mod_fd
, "\n");
1938 return NT_STATUS_OK
;
1941 static NTSTATUS
fetch_database_to_ldif(struct rpc_pipe_client
*pipe_hnd
,
1944 const char *user_file
)
1947 const char *builtin_sid
= "S-1-5-32";
1948 char *add_name
= NULL
, *mod_name
= NULL
;
1949 const char *add_template
= "/tmp/add.ldif.XXXXXX";
1950 const char *mod_template
= "/tmp/mod.ldif.XXXXXX";
1951 fstring sid
, domainname
;
1952 NTSTATUS ret
= NT_STATUS_OK
, result
;
1954 TALLOC_CTX
*mem_ctx
;
1956 FILE *add_file
= NULL
, *mod_file
= NULL
, *ldif_file
= NULL
;
1957 int num_alloced
= 0, g_index
= 0, a_index
= 0;
1958 const char *logon_server
= pipe_hnd
->cli
->desthost
;
1959 const char *computername
= global_myname();
1960 struct netr_Authenticator credential
;
1961 struct netr_Authenticator return_authenticator
;
1962 enum netr_SamDatabaseID database_id
= db_type
;
1963 uint16_t restart_state
= 0;
1964 uint32_t sync_context
= 0;
1966 /* Set up array for mapping accounts to groups */
1967 /* Array element is the group rid */
1968 GROUPMAP
*groupmap
= NULL
;
1970 /* Set up array for mapping account rid's to cn's */
1971 /* Array element is the account rid */
1972 ACCOUNTMAP
*accountmap
= NULL
;
1974 if (!(mem_ctx
= talloc_init("fetch_database"))) {
1975 return NT_STATUS_NO_MEMORY
;
1978 /* Ensure we have an output file */
1980 ldif_file
= fopen(user_file
, "a");
1985 fprintf(stderr
, "Could not open %s\n", user_file
);
1986 DEBUG(1, ("Could not open %s\n", user_file
));
1987 ret
= NT_STATUS_UNSUCCESSFUL
;
1991 add_name
= talloc_strdup(mem_ctx
, add_template
);
1992 mod_name
= talloc_strdup(mem_ctx
, mod_template
);
1993 if (!add_name
|| !mod_name
) {
1994 ret
= NT_STATUS_NO_MEMORY
;
1998 /* Open the add and mod ldif files */
1999 if (!(add_file
= fdopen(smb_mkstemp(add_name
),"w"))) {
2000 DEBUG(1, ("Could not open %s\n", add_name
));
2001 ret
= NT_STATUS_UNSUCCESSFUL
;
2004 if (!(mod_file
= fdopen(smb_mkstemp(mod_name
),"w"))) {
2005 DEBUG(1, ("Could not open %s\n", mod_name
));
2006 ret
= NT_STATUS_UNSUCCESSFUL
;
2011 sid_to_fstring(sid
, &dom_sid
);
2013 /* Get the ldap suffix */
2014 suffix
= lp_ldap_suffix();
2015 if (suffix
== NULL
|| strcmp(suffix
, "") == 0) {
2016 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n"));
2020 /* Get other smb.conf data */
2021 if (!(lp_workgroup()) || !*(lp_workgroup())) {
2022 DEBUG(0,("workgroup missing from smb.conf--exiting\n"));
2026 /* Allocate initial memory for groupmap and accountmap arrays */
2027 if (init_ldap
== 1) {
2028 groupmap
= SMB_MALLOC_ARRAY(GROUPMAP
, 8);
2029 accountmap
= SMB_MALLOC_ARRAY(ACCOUNTMAP
, 8);
2030 if (groupmap
== NULL
|| accountmap
== NULL
) {
2031 DEBUG(1,("GROUPMAP malloc failed\n"));
2032 ret
= NT_STATUS_NO_MEMORY
;
2036 /* Initialize the arrays */
2037 memset(groupmap
, 0, sizeof(GROUPMAP
)*8);
2038 memset(accountmap
, 0, sizeof(ACCOUNTMAP
)*8);
2040 /* Remember how many we malloced */
2043 /* Initial database population */
2044 populate_ldap_for_ldif(sid
, suffix
, builtin_sid
, add_file
);
2045 map_populate_groups(groupmap
, accountmap
, sid
, suffix
,
2048 /* Don't do this again */
2052 /* Announce what we are doing */
2054 case SAM_DATABASE_DOMAIN
:
2055 d_fprintf(stderr
, "Fetching DOMAIN database\n");
2057 case SAM_DATABASE_BUILTIN
:
2058 d_fprintf(stderr
, "Fetching BUILTIN database\n");
2060 case SAM_DATABASE_PRIVS
:
2061 d_fprintf(stderr
, "Fetching PRIVS databases\n");
2065 "Fetching unknown database type %u\n",
2071 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2073 netlogon_creds_client_step(pipe_hnd
->dc
, &credential
);
2075 result
= rpccli_netr_DatabaseSync2(pipe_hnd
, mem_ctx
,
2079 &return_authenticator
,
2086 /* Check returned credentials. */
2087 if (!netlogon_creds_client_check(pipe_hnd
->dc
,
2088 &return_authenticator
.cred
)) {
2089 DEBUG(0,("credentials chain check failed\n"));
2090 return NT_STATUS_ACCESS_DENIED
;
2093 if (NT_STATUS_IS_ERR(result
)) {
2097 num_deltas
= delta_enum_array
->num_deltas
;
2099 /* Re-allocate memory for groupmap and accountmap arrays */
2100 groupmap
= SMB_REALLOC_ARRAY(groupmap
, GROUPMAP
,
2101 num_deltas
+num_alloced
);
2102 accountmap
= SMB_REALLOC_ARRAY(accountmap
, ACCOUNTMAP
,
2103 num_deltas
+num_alloced
);
2104 if (groupmap
== NULL
|| accountmap
== NULL
) {
2105 DEBUG(1,("GROUPMAP malloc failed\n"));
2106 ret
= NT_STATUS_NO_MEMORY
;
2110 /* Initialize the new records */
2111 memset(&groupmap
[num_alloced
], 0,
2112 sizeof(GROUPMAP
)*num_deltas
);
2113 memset(&accountmap
[num_alloced
], 0,
2114 sizeof(ACCOUNTMAP
)*num_deltas
);
2116 /* Remember how many we alloced this time */
2117 num_alloced
+= num_deltas
;
2119 /* Loop through the deltas */
2120 for (k
=0; k
<num_deltas
; k
++) {
2122 union netr_DELTA_UNION u
=
2123 delta_enum_array
->delta_enum
[k
].delta_union
;
2124 union netr_DELTA_ID_UNION id
=
2125 delta_enum_array
->delta_enum
[k
].delta_id_union
;
2127 switch(delta_enum_array
->delta_enum
[k
].delta_type
) {
2128 case NETR_DELTA_DOMAIN
:
2129 /* Is this case needed? */
2131 u
.domain
->domain_name
.string
);
2134 case NETR_DELTA_GROUP
:
2135 fetch_group_info_to_ldif(
2138 add_file
, sid
, suffix
);
2142 case NETR_DELTA_USER
:
2143 fetch_account_info_to_ldif(
2145 &accountmap
[a_index
], add_file
,
2146 sid
, suffix
, num_alloced
);
2150 case NETR_DELTA_ALIAS
:
2151 fetch_alias_info_to_ldif(
2152 u
.alias
, &groupmap
[g_index
],
2153 add_file
, sid
, suffix
, db_type
);
2157 case NETR_DELTA_GROUP_MEMBER
:
2158 fetch_groupmem_info_to_ldif(
2159 u
.group_member
, id
.rid
,
2160 groupmap
, accountmap
,
2161 mod_file
, num_alloced
);
2164 case NETR_DELTA_ALIAS_MEMBER
:
2165 case NETR_DELTA_POLICY
:
2166 case NETR_DELTA_ACCOUNT
:
2167 case NETR_DELTA_TRUSTED_DOMAIN
:
2168 case NETR_DELTA_SECRET
:
2169 case NETR_DELTA_RENAME_GROUP
:
2170 case NETR_DELTA_RENAME_USER
:
2171 case NETR_DELTA_RENAME_ALIAS
:
2172 case NETR_DELTA_DELETE_GROUP
:
2173 case NETR_DELTA_DELETE_USER
:
2174 case NETR_DELTA_MODIFY_COUNT
:
2177 } /* end of switch */
2178 } /* end of for loop */
2180 /* Increment sync_context */
2183 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
2185 /* Write ldif data to the user's file */
2186 if (db_type
== SAM_DATABASE_DOMAIN
) {
2188 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n");
2190 "# =================================\n\n");
2192 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2194 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n");
2196 "# ==================================\n\n");
2199 fseek(add_file
, 0, SEEK_SET
);
2200 transfer_file(fileno(add_file
), fileno(ldif_file
), (size_t) -1);
2202 if (db_type
== SAM_DATABASE_DOMAIN
) {
2204 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n");
2206 "# ====================================\n\n");
2208 } else if (db_type
== SAM_DATABASE_BUILTIN
) {
2210 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n");
2212 "# =====================================\n\n");
2215 fseek(mod_file
, 0, SEEK_SET
);
2216 transfer_file(fileno(mod_file
), fileno(ldif_file
), (size_t) -1);
2220 /* Close and delete the ldif files */
2225 if ((add_name
!= NULL
) &&
2226 strcmp(add_name
, add_template
) && (unlink(add_name
))) {
2227 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2228 add_name
, strerror(errno
)));
2235 if ((mod_name
!= NULL
) &&
2236 strcmp(mod_name
, mod_template
) && (unlink(mod_name
))) {
2237 DEBUG(1,("unlink(%s) failed, error was (%s)\n",
2238 mod_name
, strerror(errno
)));
2241 if (ldif_file
&& (ldif_file
!= stdout
)) {
2245 /* Deallocate memory for the mapping arrays */
2246 SAFE_FREE(groupmap
);
2247 SAFE_FREE(accountmap
);
2250 talloc_destroy(mem_ctx
);
2255 * Basic usage function for 'net rpc vampire'
2256 * @param argc Standard main() style argc
2257 * @param argc Standard main() style argv. Initial components are already
2261 int rpc_vampire_usage(int argc
, const char **argv
)
2263 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n"
2264 "\t to pull accounts from a remote PDC where we are a BDC\n"
2265 "\t\t no args puts accounts in local passdb from smb.conf\n"
2266 "\t\t ldif - put accounts in ldif format (file defaults to "
2269 net_common_flags_usage(argc
, argv
);
2274 /* dump sam database via samsync rpc calls */
2275 NTSTATUS
rpc_vampire_internals(const DOM_SID
*domain_sid
,
2276 const char *domain_name
,
2277 struct cli_state
*cli
,
2278 struct rpc_pipe_client
*pipe_hnd
,
2279 TALLOC_CTX
*mem_ctx
,
2284 fstring my_dom_sid_str
;
2285 fstring rem_dom_sid_str
;
2287 if (!sid_equal(domain_sid
, get_global_sam_sid())) {
2288 d_printf("Cannot import users from %s at this time, "
2289 "as the current domain:\n\t%s: %s\nconflicts "
2290 "with the remote domain\n\t%s: %s\n"
2291 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
2292 "workgroup=%s\n\n in your smb.conf?\n",
2294 get_global_sam_name(),
2295 sid_to_fstring(my_dom_sid_str
,
2296 get_global_sam_sid()),
2297 domain_name
, sid_to_fstring(rem_dom_sid_str
,
2300 return NT_STATUS_UNSUCCESSFUL
;
2303 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2304 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2305 *domain_sid
, argv
[1]);
2307 result
= fetch_database(pipe_hnd
, SAM_DATABASE_DOMAIN
,
2311 if (!NT_STATUS_IS_OK(result
)) {
2312 d_fprintf(stderr
, "Failed to fetch domain database: %s\n",
2314 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOT_SUPPORTED
))
2315 d_fprintf(stderr
, "Perhaps %s is a Windows 2000 "
2316 "native mode domain?\n", domain_name
);
2320 if (argc
>= 1 && (strcmp(argv
[0], "ldif") == 0)) {
2321 result
= fetch_database_to_ldif(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2322 global_sid_Builtin
, argv
[1]);
2324 result
= fetch_database(pipe_hnd
, SAM_DATABASE_BUILTIN
,
2325 global_sid_Builtin
);
2328 if (!NT_STATUS_IS_OK(result
)) {
2329 d_fprintf(stderr
, "Failed to fetch builtin database: %s\n",
2334 /* Currently we crash on PRIVS somewhere in unmarshalling */
2335 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */