1/* 2 Unix SMB/CIFS implementation. 3 dump the remote SAM using rpc samsync operations 4 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 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 2 of the License, or 14 (at your option) any later version. 15 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. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24*/ 25 26#include "includes.h" 27#include "utils/net.h" 28 29/* uid's and gid's for writing deltas to ldif */ 30static uint32 ldif_gid = 999; 31static uint32 ldif_uid = 999; 32/* Keep track of ldap initialization */ 33static int init_ldap = 1; 34 35static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) 36{ 37 int i; 38 d_printf("Group mem %u: ", rid); 39 for (i=0;i<g->num_members;i++) { 40 d_printf("%u ", g->rids[i]); 41 } 42 d_printf("\n"); 43} 44 45static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a) 46{ 47 d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name)); 48 d_printf("desc='%s' rid=%u\n", unistr2_static(&a->uni_als_desc), a->als_rid); 49} 50 51static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a) 52{ 53 int i; 54 d_printf("Alias rid %u: ", rid); 55 for (i=0;i<a->num_members;i++) { 56 d_printf("%s ", sid_string_static(&a->sids[i].sid)); 57 } 58 d_printf("\n"); 59} 60 61static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) 62{ 63 fstring hex_nt_passwd, hex_lm_passwd; 64 uchar lm_passwd[16], nt_passwd[16]; 65 static uchar zero_buf[16]; 66 67 /* Decode hashes from password hash (if they are not NULL) */ 68 69 if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) { 70 sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0); 71 pdb_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); 72 } else { 73 pdb_sethexpwd(hex_lm_passwd, NULL, 0); 74 } 75 76 if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) { 77 sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0); 78 pdb_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); 79 } else { 80 pdb_sethexpwd(hex_nt_passwd, NULL, 0); 81 } 82 83 printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name), 84 a->user_rid, hex_lm_passwd, hex_nt_passwd, 85 pdb_encode_acct_ctrl(a->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN)); 86} 87 88static time_t uint64s_nt_time_to_unix_abs(const uint64 *src) 89{ 90 NTTIME nttime; 91 nttime = *src; 92 return nt_time_to_unix_abs(&nttime); 93} 94 95static void display_domain_info(SAM_DOMAIN_INFO *a) 96{ 97 time_t u_logout; 98 99 u_logout = uint64s_nt_time_to_unix_abs(&a->force_logoff); 100 101 d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name)); 102 103 d_printf("Minimal Password Length: %d\n", a->min_pwd_len); 104 d_printf("Password History Length: %d\n", a->pwd_history_len); 105 106 d_printf("Force Logoff: %d\n", (int)u_logout); 107 108 d_printf("Max Password Age: %s\n", display_time(a->max_pwd_age)); 109 d_printf("Min Password Age: %s\n", display_time(a->min_pwd_age)); 110 111 d_printf("Lockout Time: %s\n", display_time(a->account_lockout.lockout_duration)); 112 d_printf("Lockout Reset Time: %s\n", display_time(a->account_lockout.reset_count)); 113 114 d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout); 115 d_printf("User must logon to change password: %d\n", a->logon_chgpass); 116} 117 118static void display_group_info(uint32 rid, SAM_GROUP_INFO *a) 119{ 120 d_printf("Group '%s' ", unistr2_static(&a->uni_grp_name)); 121 d_printf("desc='%s', rid=%u\n", unistr2_static(&a->uni_grp_desc), rid); 122} 123 124static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) 125{ 126 switch (hdr_delta->type) { 127 case SAM_DELTA_ACCOUNT_INFO: 128 display_account_info(hdr_delta->target_rid, &delta->account_info); 129 break; 130 case SAM_DELTA_GROUP_MEM: 131 display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info); 132 break; 133 case SAM_DELTA_ALIAS_INFO: 134 display_alias_info(hdr_delta->target_rid, &delta->alias_info); 135 break; 136 case SAM_DELTA_ALIAS_MEM: 137 display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info); 138 break; 139 case SAM_DELTA_DOMAIN_INFO: 140 display_domain_info(&delta->domain_info); 141 break; 142 case SAM_DELTA_GROUP_INFO: 143 display_group_info(hdr_delta->target_rid, &delta->group_info); 144 break; 145 /* The following types are recognised but not handled */ 146 case SAM_DELTA_RENAME_GROUP: 147 d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); 148 break; 149 case SAM_DELTA_RENAME_USER: 150 d_printf("SAM_DELTA_RENAME_USER not handled\n"); 151 break; 152 case SAM_DELTA_RENAME_ALIAS: 153 d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); 154 break; 155 case SAM_DELTA_POLICY_INFO: 156 d_printf("SAM_DELTA_POLICY_INFO not handled\n"); 157 break; 158 case SAM_DELTA_TRUST_DOMS: 159 d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); 160 break; 161 case SAM_DELTA_PRIVS_INFO: 162 d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); 163 break; 164 case SAM_DELTA_SECRET_INFO: 165 d_printf("SAM_DELTA_SECRET_INFO not handled\n"); 166 break; 167 case SAM_DELTA_DELETE_GROUP: 168 d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); 169 break; 170 case SAM_DELTA_DELETE_USER: 171 d_printf("SAM_DELTA_DELETE_USER not handled\n"); 172 break; 173 case SAM_DELTA_MODIFIED_COUNT: 174 d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); 175 break; 176 default: 177 d_printf("Unknown delta record type %d\n", hdr_delta->type); 178 break; 179 } 180} 181 182static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type) 183{ 184 uint32 sync_context = 0; 185 NTSTATUS result; 186 int i; 187 TALLOC_CTX *mem_ctx; 188 SAM_DELTA_HDR *hdr_deltas; 189 SAM_DELTA_CTR *deltas; 190 uint32 num_deltas; 191 192 if (!(mem_ctx = talloc_init("dump_database"))) { 193 return; 194 } 195 196 switch( db_type ) { 197 case SAM_DATABASE_DOMAIN: 198 d_printf("Dumping DOMAIN database\n"); 199 break; 200 case SAM_DATABASE_BUILTIN: 201 d_printf("Dumping BUILTIN database\n"); 202 break; 203 case SAM_DATABASE_PRIVS: 204 d_printf("Dumping PRIVS databases\n"); 205 break; 206 default: 207 d_printf("Dumping unknown database type %u\n", db_type ); 208 break; 209 } 210 211 do { 212 result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, db_type, 213 sync_context, 214 &num_deltas, &hdr_deltas, &deltas); 215 if (!NT_STATUS_IS_OK(result)) 216 break; 217 218 for (i = 0; i < num_deltas; i++) { 219 display_sam_entry(&hdr_deltas[i], &deltas[i]); 220 } 221 sync_context += 1; 222 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 223 224 talloc_destroy(mem_ctx); 225} 226 227/* dump sam database via samsync rpc calls */ 228NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, 229 const char *domain_name, 230 struct cli_state *cli, 231 struct rpc_pipe_client *pipe_hnd, 232 TALLOC_CTX *mem_ctx, 233 int argc, 234 const char **argv) 235{ 236#if 0 237 /* net_rpc.c now always tries to create an schannel pipe.. */ 238 239 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 240 uchar trust_password[16]; 241 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; 242 uint32 sec_channel_type = 0; 243 244 if (!secrets_fetch_trust_account_password(domain_name, 245 trust_password, 246 NULL, &sec_channel_type)) { 247 DEBUG(0,("Could not fetch trust account password\n")); 248 goto fail; 249 } 250 251 nt_status = rpccli_netlogon_setup_creds(pipe_hnd, 252 cli->desthost, 253 domain_name, 254 global_myname(), 255 trust_password, 256 sec_channel_type, 257 &neg_flags); 258 259 if (!NT_STATUS_IS_OK(nt_status)) { 260 DEBUG(0,("Error connecting to NETLOGON pipe\n")); 261 goto fail; 262 } 263#endif 264 265 dump_database(pipe_hnd, SAM_DATABASE_DOMAIN); 266 dump_database(pipe_hnd, SAM_DATABASE_BUILTIN); 267 dump_database(pipe_hnd, SAM_DATABASE_PRIVS); 268 269 return NT_STATUS_OK; 270} 271 272/* Convert a struct samu_DELTA to a struct samu. */ 273#define STRING_CHANGED (old_string && !new_string) ||\ 274 (!old_string && new_string) ||\ 275 (old_string && new_string && (strcmp(old_string, new_string) != 0)) 276 277#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\ 278 (!(s1) && (s2)) ||\ 279 ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) 280 281static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *delta) 282{ 283 const char *old_string, *new_string; 284 time_t unix_time, stored_time; 285 uchar lm_passwd[16], nt_passwd[16]; 286 static uchar zero_buf[16]; 287 288 /* Username, fullname, home dir, dir drive, logon script, acct 289 desc, workstations, profile. */ 290 291 if (delta->hdr_acct_name.buffer) { 292 old_string = pdb_get_nt_username(account); 293 new_string = unistr2_static(&delta->uni_acct_name); 294 295 if (STRING_CHANGED) { 296 pdb_set_nt_username(account, new_string, PDB_CHANGED); 297 298 } 299 300 /* Unix username is the same - for sanity */ 301 old_string = pdb_get_username( account ); 302 if (STRING_CHANGED) { 303 pdb_set_username(account, new_string, PDB_CHANGED); 304 } 305 } 306 307 if (delta->hdr_full_name.buffer) { 308 old_string = pdb_get_fullname(account); 309 new_string = unistr2_static(&delta->uni_full_name); 310 311 if (STRING_CHANGED) 312 pdb_set_fullname(account, new_string, PDB_CHANGED); 313 } 314 315 if (delta->hdr_home_dir.buffer) { 316 old_string = pdb_get_homedir(account); 317 new_string = unistr2_static(&delta->uni_home_dir); 318 319 if (STRING_CHANGED) 320 pdb_set_homedir(account, new_string, PDB_CHANGED); 321 } 322 323 if (delta->hdr_dir_drive.buffer) { 324 old_string = pdb_get_dir_drive(account); 325 new_string = unistr2_static(&delta->uni_dir_drive); 326 327 if (STRING_CHANGED) 328 pdb_set_dir_drive(account, new_string, PDB_CHANGED); 329 } 330 331 if (delta->hdr_logon_script.buffer) { 332 old_string = pdb_get_logon_script(account); 333 new_string = unistr2_static(&delta->uni_logon_script); 334 335 if (STRING_CHANGED) 336 pdb_set_logon_script(account, new_string, PDB_CHANGED); 337 } 338 339 if (delta->hdr_acct_desc.buffer) { 340 old_string = pdb_get_acct_desc(account); 341 new_string = unistr2_static(&delta->uni_acct_desc); 342 343 if (STRING_CHANGED) 344 pdb_set_acct_desc(account, new_string, PDB_CHANGED); 345 } 346 347 if (delta->hdr_workstations.buffer) { 348 old_string = pdb_get_workstations(account); 349 new_string = unistr2_static(&delta->uni_workstations); 350 351 if (STRING_CHANGED) 352 pdb_set_workstations(account, new_string, PDB_CHANGED); 353 } 354 355 if (delta->hdr_profile.buffer) { 356 old_string = pdb_get_profile_path(account); 357 new_string = unistr2_static(&delta->uni_profile); 358 359 if (STRING_CHANGED) 360 pdb_set_profile_path(account, new_string, PDB_CHANGED); 361 } 362 363 if (delta->hdr_parameters.buffer) { 364 DATA_BLOB mung; 365 char *newstr; 366 old_string = pdb_get_munged_dial(account); 367 mung.length = delta->hdr_parameters.uni_str_len; 368 mung.data = (uint8 *) delta->uni_parameters.buffer; 369 newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(mung); 370 371 if (STRING_CHANGED_NC(old_string, newstr)) 372 pdb_set_munged_dial(account, newstr, PDB_CHANGED); 373 SAFE_FREE(newstr); 374 } 375 376 /* User and group sid */ 377 if (pdb_get_user_rid(account) != delta->user_rid) 378 pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED); 379 if (pdb_get_group_rid(account) != delta->group_rid) 380 pdb_set_group_sid_from_rid(account, delta->group_rid, PDB_CHANGED); 381 382 /* Logon and password information */ 383 if (!nt_time_is_zero(&delta->logon_time)) { 384 unix_time = nt_time_to_unix(delta->logon_time); 385 stored_time = pdb_get_logon_time(account); 386 if (stored_time != unix_time) 387 pdb_set_logon_time(account, unix_time, PDB_CHANGED); 388 } 389 390 if (!nt_time_is_zero(&delta->logoff_time)) { 391 unix_time = nt_time_to_unix(delta->logoff_time); 392 stored_time = pdb_get_logoff_time(account); 393 if (stored_time != unix_time) 394 pdb_set_logoff_time(account, unix_time,PDB_CHANGED); 395 } 396 397 /* Logon Divs */ 398 if (pdb_get_logon_divs(account) != delta->logon_divs) 399 pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED); 400 401 /* Max Logon Hours */ 402 if (delta->unknown1 != pdb_get_unknown_6(account)) { 403 pdb_set_unknown_6(account, delta->unknown1, PDB_CHANGED); 404 } 405 406 /* Logon Hours Len */ 407 if (delta->buf_logon_hrs.buf_len != pdb_get_hours_len(account)) { 408 pdb_set_hours_len(account, delta->buf_logon_hrs.buf_len, PDB_CHANGED); 409 } 410 411 /* Logon Hours */ 412 if (delta->buf_logon_hrs.buffer) { 413 pstring oldstr, newstr; 414 pdb_sethexhours(oldstr, pdb_get_hours(account)); 415 pdb_sethexhours(newstr, delta->buf_logon_hrs.buffer); 416 if (!strequal(oldstr, newstr)) 417 pdb_set_hours(account, (const uint8 *)delta->buf_logon_hrs.buffer, PDB_CHANGED); 418 } 419 420 if (pdb_get_bad_password_count(account) != delta->bad_pwd_count) 421 pdb_set_bad_password_count(account, delta->bad_pwd_count, PDB_CHANGED); 422 423 if (pdb_get_logon_count(account) != delta->logon_count) 424 pdb_set_logon_count(account, delta->logon_count, PDB_CHANGED); 425 426 if (!nt_time_is_zero(&delta->pwd_last_set_time)) { 427 unix_time = nt_time_to_unix(delta->pwd_last_set_time); 428 stored_time = pdb_get_pass_last_set_time(account); 429 if (stored_time != unix_time) 430 pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED); 431 } else { 432 /* no last set time, make it now */ 433 pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED); 434 } 435 436#if 0 437/* No kickoff time in the delta? */ 438 if (!nt_time_is_zero(&delta->kickoff_time)) { 439 unix_time = nt_time_to_unix(&delta->kickoff_time); 440 stored_time = pdb_get_kickoff_time(account); 441 if (stored_time != unix_time) 442 pdb_set_kickoff_time(account, unix_time, PDB_CHANGED); 443 } 444#endif 445 446 /* Decode hashes from password hash 447 Note that win2000 may send us all zeros for the hashes if it doesn't 448 think this channel is secure enough - don't set the passwords at all 449 in that case 450 */ 451 if (memcmp(delta->pass.buf_lm_pwd, zero_buf, 16) != 0) { 452 sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0); 453 pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED); 454 } 455 456 if (memcmp(delta->pass.buf_nt_pwd, zero_buf, 16) != 0) { 457 sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0); 458 pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED); 459 } 460 461 /* TODO: account expiry time */ 462 463 pdb_set_acct_ctrl(account, delta->acb_info, PDB_CHANGED); 464 465 pdb_set_domain(account, lp_workgroup(), PDB_CHANGED); 466 467 return NT_STATUS_OK; 468} 469 470static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) 471{ 472 NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL; 473 fstring account; 474 pstring add_script; 475 struct samu *sam_account=NULL; 476 GROUP_MAP map; 477 struct group *grp; 478 DOM_SID user_sid; 479 DOM_SID group_sid; 480 struct passwd *passwd; 481 fstring sid_string; 482 483 fstrcpy(account, unistr2_static(&delta->uni_acct_name)); 484 d_printf("Creating account: %s\n", account); 485 486 if ( !(sam_account = samu_new( NULL )) ) { 487 return NT_STATUS_NO_MEMORY; 488 } 489 490 if (!(passwd = Get_Pwnam(account))) { 491 /* Create appropriate user */ 492 if (delta->acb_info & ACB_NORMAL) { 493 pstrcpy(add_script, lp_adduser_script()); 494 } else if ( (delta->acb_info & ACB_WSTRUST) || 495 (delta->acb_info & ACB_SVRTRUST) || 496 (delta->acb_info & ACB_DOMTRUST) ) { 497 pstrcpy(add_script, lp_addmachine_script()); 498 } else { 499 DEBUG(1, ("Unknown user type: %s\n", 500 pdb_encode_acct_ctrl(delta->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN))); 501 nt_ret = NT_STATUS_UNSUCCESSFUL; 502 goto done; 503 } 504 if (*add_script) { 505 int add_ret; 506 all_string_sub(add_script, "%u", account, 507 sizeof(account)); 508 add_ret = smbrun(add_script,NULL); 509 DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' " 510 "gave %d\n", add_script, add_ret)); 511 if (add_ret == 0) { 512 smb_nscd_flush_user_cache(); 513 } 514 } 515 516 /* try and find the possible unix account again */ 517 if ( !(passwd = Get_Pwnam(account)) ) { 518 d_fprintf(stderr, "Could not create posix account info for '%s'\n", account); 519 nt_ret = NT_STATUS_NO_SUCH_USER; 520 goto done; 521 } 522 } 523 524 sid_copy(&user_sid, get_global_sam_sid()); 525 sid_append_rid(&user_sid, delta->user_rid); 526 527 DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n", sid_to_string(sid_string, &user_sid), account)); 528 if (!pdb_getsampwsid(sam_account, &user_sid)) { 529 sam_account_from_delta(sam_account, delta); 530 DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n", 531 sid_to_string(sid_string, &user_sid), pdb_get_username(sam_account))); 532 if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) { 533 DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n", 534 account)); 535 return NT_STATUS_ACCESS_DENIED; 536 } 537 } else { 538 sam_account_from_delta(sam_account, delta); 539 DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n", 540 sid_to_string(sid_string, &user_sid), pdb_get_username(sam_account))); 541 if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account))) { 542 DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n", 543 account)); 544 TALLOC_FREE(sam_account); 545 return NT_STATUS_ACCESS_DENIED; 546 } 547 } 548 549 if (pdb_get_group_sid(sam_account) == NULL) { 550 return NT_STATUS_UNSUCCESSFUL; 551 } 552 553 group_sid = *pdb_get_group_sid(sam_account); 554 555 if (!pdb_getgrsid(&map, group_sid)) { 556 DEBUG(0, ("Primary group of %s has no mapping!\n", 557 pdb_get_username(sam_account))); 558 } else { 559 if (map.gid != passwd->pw_gid) { 560 if (!(grp = getgrgid(map.gid))) { 561 DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", 562 (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid))); 563 } else { 564 smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account)); 565 } 566 } 567 } 568 569 if ( !passwd ) { 570 DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", 571 pdb_get_username(sam_account))); 572 } 573 574 done: 575 TALLOC_FREE(sam_account); 576 return nt_ret; 577} 578 579static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) 580{ 581 fstring name; 582 fstring comment; 583 struct group *grp = NULL; 584 DOM_SID group_sid; 585 fstring sid_string; 586 GROUP_MAP map; 587 BOOL insert = True; 588 589 unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1); 590 unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1); 591 592 /* add the group to the mapping table */ 593 sid_copy(&group_sid, get_global_sam_sid()); 594 sid_append_rid(&group_sid, rid); 595 sid_to_string(sid_string, &group_sid); 596 597 if (pdb_getgrsid(&map, group_sid)) { 598 if ( map.gid != -1 ) 599 grp = getgrgid(map.gid); 600 insert = False; 601 } 602 603 if (grp == NULL) { 604 gid_t gid; 605 606 /* No group found from mapping, find it from its name. */ 607 if ((grp = getgrnam(name)) == NULL) { 608 609 /* No appropriate group found, create one */ 610 611 d_printf("Creating unix group: '%s'\n", name); 612 613 if (smb_create_group(name, &gid) != 0) 614 return NT_STATUS_ACCESS_DENIED; 615 616 if ((grp = getgrnam(name)) == NULL) 617 return NT_STATUS_ACCESS_DENIED; 618 } 619 } 620 621 map.gid = grp->gr_gid; 622 map.sid = group_sid; 623 map.sid_name_use = SID_NAME_DOM_GRP; 624 fstrcpy(map.nt_name, name); 625 if (delta->hdr_grp_desc.buffer) { 626 fstrcpy(map.comment, comment); 627 } else { 628 fstrcpy(map.comment, ""); 629 } 630 631 if (insert) 632 pdb_add_group_mapping_entry(&map); 633 else 634 pdb_update_group_mapping_entry(&map); 635 636 return NT_STATUS_OK; 637} 638 639static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) 640{ 641 int i; 642 TALLOC_CTX *t = NULL; 643 char **nt_members = NULL; 644 char **unix_members; 645 DOM_SID group_sid; 646 GROUP_MAP map; 647 struct group *grp; 648 649 if (delta->num_members == 0) { 650 return NT_STATUS_OK; 651 } 652 653 sid_copy(&group_sid, get_global_sam_sid()); 654 sid_append_rid(&group_sid, rid); 655 656 if (!get_domain_group_from_sid(group_sid, &map)) { 657 DEBUG(0, ("Could not find global group %d\n", rid)); 658 return NT_STATUS_NO_SUCH_GROUP; 659 } 660 661 if (!(grp = getgrgid(map.gid))) { 662 DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid)); 663 return NT_STATUS_NO_SUCH_GROUP; 664 } 665 666 d_printf("Group members of %s: ", grp->gr_name); 667 668 if (!(t = talloc_init("fetch_group_mem_info"))) { 669 DEBUG(0, ("could not talloc_init\n")); 670 return NT_STATUS_NO_MEMORY; 671 } 672 673 if (delta->num_members) { 674 if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, delta->num_members)) == NULL) { 675 DEBUG(0, ("talloc failed\n")); 676 talloc_free(t); 677 return NT_STATUS_NO_MEMORY; 678 } 679 } else { 680 nt_members = NULL; 681 } 682 683 for (i=0; i<delta->num_members; i++) { 684 struct samu *member = NULL; 685 DOM_SID member_sid; 686 687 if ( !(member = samu_new(t)) ) { 688 talloc_destroy(t); 689 return NT_STATUS_NO_MEMORY; 690 } 691 692 sid_copy(&member_sid, get_global_sam_sid()); 693 sid_append_rid(&member_sid, delta->rids[i]); 694 695 if (!pdb_getsampwsid(member, &member_sid)) { 696 DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n", 697 delta->rids[i], sid_string_static(&member_sid), grp->gr_name)); 698 TALLOC_FREE(member); 699 continue; 700 } 701 702 if (pdb_get_group_rid(member) == rid) { 703 d_printf("%s(primary),", pdb_get_username(member)); 704 TALLOC_FREE(member); 705 continue; 706 } 707 708 d_printf("%s,", pdb_get_username(member)); 709 nt_members[i] = talloc_strdup(t, pdb_get_username(member)); 710 TALLOC_FREE(member); 711 } 712 713 d_printf("\n"); 714 715 unix_members = grp->gr_mem; 716 717 while (*unix_members) { 718 BOOL is_nt_member = False; 719 for (i=0; i<delta->num_members; i++) { 720 if (nt_members[i] == NULL) { 721 /* This was a primary group */ 722 continue; 723 } 724 725 if (strcmp(*unix_members, nt_members[i]) == 0) { 726 is_nt_member = True; 727 break; 728 } 729 } 730 if (!is_nt_member) { 731 /* We look at a unix group member that is not 732 an nt group member. So, remove it. NT is 733 boss here. */ 734 smb_delete_user_group(grp->gr_name, *unix_members); 735 } 736 unix_members += 1; 737 } 738 739 for (i=0; i<delta->num_members; i++) { 740 BOOL is_unix_member = False; 741 742 if (nt_members[i] == NULL) { 743 /* This was the primary group */ 744 continue; 745 } 746 747 unix_members = grp->gr_mem; 748 749 while (*unix_members) { 750 if (strcmp(*unix_members, nt_members[i]) == 0) { 751 is_unix_member = True; 752 break; 753 } 754 unix_members += 1; 755 } 756 757 if (!is_unix_member) { 758 /* We look at a nt group member that is not a 759 unix group member currently. So, add the nt 760 group member. */ 761 smb_add_user_group(grp->gr_name, nt_members[i]); 762 } 763 } 764 765 talloc_destroy(t); 766 return NT_STATUS_OK; 767} 768 769static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, 770 DOM_SID dom_sid) 771{ 772 fstring name; 773 fstring comment; 774 struct group *grp = NULL; 775 DOM_SID alias_sid; 776 fstring sid_string; 777 GROUP_MAP map; 778 BOOL insert = True; 779 780 unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)-1); 781 unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)-1); 782 783 /* Find out whether the group is already mapped */ 784 sid_copy(&alias_sid, &dom_sid); 785 sid_append_rid(&alias_sid, rid); 786 sid_to_string(sid_string, &alias_sid); 787 788 if (pdb_getgrsid(&map, alias_sid)) { 789 grp = getgrgid(map.gid); 790 insert = False; 791 } 792 793 if (grp == NULL) { 794 gid_t gid; 795 796 /* No group found from mapping, find it from its name. */ 797 if ((grp = getgrnam(name)) == NULL) { 798 /* No appropriate group found, create one */ 799 d_printf("Creating unix group: '%s'\n", name); 800 if (smb_create_group(name, &gid) != 0) 801 return NT_STATUS_ACCESS_DENIED; 802 if ((grp = getgrgid(gid)) == NULL) 803 return NT_STATUS_ACCESS_DENIED; 804 } 805 } 806 807 map.gid = grp->gr_gid; 808 map.sid = alias_sid; 809 810 if (sid_equal(&dom_sid, &global_sid_Builtin)) 811 map.sid_name_use = SID_NAME_WKN_GRP; 812 else 813 map.sid_name_use = SID_NAME_ALIAS; 814 815 fstrcpy(map.nt_name, name); 816 fstrcpy(map.comment, comment); 817 818 if (insert) 819 pdb_add_group_mapping_entry(&map); 820 else 821 pdb_update_group_mapping_entry(&map); 822 823 return NT_STATUS_OK; 824} 825 826static NTSTATUS fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid) 827{ 828 return NT_STATUS_OK; 829} 830 831static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) 832{ 833 time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime; 834 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 835 pstring domname; 836 837 u_max_age = uint64s_nt_time_to_unix_abs(&delta->max_pwd_age); 838 u_min_age = uint64s_nt_time_to_unix_abs(&delta->min_pwd_age); 839 u_logout = uint64s_nt_time_to_unix_abs(&delta->force_logoff); 840 u_lockoutreset = uint64s_nt_time_to_unix_abs(&delta->account_lockout.reset_count); 841 u_lockouttime = uint64s_nt_time_to_unix_abs(&delta->account_lockout.lockout_duration); 842 843 unistr2_to_ascii(domname, &delta->uni_dom_name, sizeof(domname) - 1); 844 845 /* we don't handle BUILTIN account policies */ 846 if (!strequal(domname, get_global_sam_name())) { 847 printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname); 848 return NT_STATUS_OK; 849 } 850 851 852 if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, delta->pwd_history_len)) 853 return nt_status; 854 855 if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, delta->min_pwd_len)) 856 return nt_status; 857 858 if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age)) 859 return nt_status; 860 861 if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age)) 862 return nt_status; 863 864 if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout)) 865 return nt_status; 866 867 if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout)) 868 return nt_status; 869 870 if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60)) 871 return nt_status; 872 873 if (u_lockouttime != -1) 874 u_lockouttime /= 60; 875 876 if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime)) 877 return nt_status; 878 879 if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass)) 880 return nt_status; 881 882 return NT_STATUS_OK; 883} 884 885 886static void fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta, 887 DOM_SID dom_sid) 888{ 889 switch(hdr_delta->type) { 890 case SAM_DELTA_ACCOUNT_INFO: 891 fetch_account_info(hdr_delta->target_rid, 892 &delta->account_info); 893 break; 894 case SAM_DELTA_GROUP_INFO: 895 fetch_group_info(hdr_delta->target_rid, 896 &delta->group_info); 897 break; 898 case SAM_DELTA_GROUP_MEM: 899 fetch_group_mem_info(hdr_delta->target_rid, 900 &delta->grp_mem_info); 901 break; 902 case SAM_DELTA_ALIAS_INFO: 903 fetch_alias_info(hdr_delta->target_rid, 904 &delta->alias_info, dom_sid); 905 break; 906 case SAM_DELTA_ALIAS_MEM: 907 fetch_alias_mem(hdr_delta->target_rid, 908 &delta->als_mem_info, dom_sid); 909 break; 910 case SAM_DELTA_DOMAIN_INFO: 911 fetch_domain_info(hdr_delta->target_rid, 912 &delta->domain_info); 913 break; 914 /* The following types are recognised but not handled */ 915 case SAM_DELTA_RENAME_GROUP: 916 d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); 917 break; 918 case SAM_DELTA_RENAME_USER: 919 d_printf("SAM_DELTA_RENAME_USER not handled\n"); 920 break; 921 case SAM_DELTA_RENAME_ALIAS: 922 d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); 923 break; 924 case SAM_DELTA_POLICY_INFO: 925 d_printf("SAM_DELTA_POLICY_INFO not handled\n"); 926 break; 927 case SAM_DELTA_TRUST_DOMS: 928 d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); 929 break; 930 case SAM_DELTA_PRIVS_INFO: 931 d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); 932 break; 933 case SAM_DELTA_SECRET_INFO: 934 d_printf("SAM_DELTA_SECRET_INFO not handled\n"); 935 break; 936 case SAM_DELTA_DELETE_GROUP: 937 d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); 938 break; 939 case SAM_DELTA_DELETE_USER: 940 d_printf("SAM_DELTA_DELETE_USER not handled\n"); 941 break; 942 case SAM_DELTA_MODIFIED_COUNT: 943 d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); 944 break; 945 default: 946 d_printf("Unknown delta record type %d\n", hdr_delta->type); 947 break; 948 } 949} 950 951static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, DOM_SID dom_sid) 952{ 953 uint32 sync_context = 0; 954 NTSTATUS result; 955 int i; 956 TALLOC_CTX *mem_ctx; 957 SAM_DELTA_HDR *hdr_deltas; 958 SAM_DELTA_CTR *deltas; 959 uint32 num_deltas; 960 961 if (!(mem_ctx = talloc_init("fetch_database"))) 962 return NT_STATUS_NO_MEMORY; 963 964 switch( db_type ) { 965 case SAM_DATABASE_DOMAIN: 966 d_printf("Fetching DOMAIN database\n"); 967 break; 968 case SAM_DATABASE_BUILTIN: 969 d_printf("Fetching BUILTIN database\n"); 970 break; 971 case SAM_DATABASE_PRIVS: 972 d_printf("Fetching PRIVS databases\n"); 973 break; 974 default: 975 d_printf("Fetching unknown database type %u\n", db_type ); 976 break; 977 } 978 979 do { 980 result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, 981 db_type, sync_context, 982 &num_deltas, 983 &hdr_deltas, &deltas); 984 985 if (NT_STATUS_IS_OK(result) || 986 NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 987 for (i = 0; i < num_deltas; i++) { 988 fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); 989 } 990 } else 991 return result; 992 993 sync_context += 1; 994 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 995 996 talloc_destroy(mem_ctx); 997 998 return result; 999} 1000 1001static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char 1002 *builtin_sid, FILE *add_fd) 1003{ 1004 const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix; 1005 char *user_attr=NULL, *group_attr=NULL; 1006 char *suffix_attr; 1007 int len; 1008 1009 /* Get the suffix attribute */ 1010 suffix_attr = sstring_sub(suffix, '=', ','); 1011 if (suffix_attr == NULL) { 1012 len = strlen(suffix); 1013 suffix_attr = (char*)SMB_MALLOC(len+1); 1014 memcpy(suffix_attr, suffix, len); 1015 suffix_attr[len] = '\0'; 1016 } 1017 1018 /* Write the base */ 1019 fprintf(add_fd, "# %s\n", suffix); 1020 fprintf(add_fd, "dn: %s\n", suffix); 1021 fprintf(add_fd, "objectClass: dcObject\n"); 1022 fprintf(add_fd, "objectClass: organization\n"); 1023 fprintf(add_fd, "o: %s\n", suffix_attr); 1024 fprintf(add_fd, "dc: %s\n", suffix_attr); 1025 fprintf(add_fd, "\n"); 1026 fflush(add_fd); 1027 1028 user_suffix = lp_ldap_user_suffix(); 1029 if (user_suffix == NULL) { 1030 SAFE_FREE(suffix_attr); 1031 return NT_STATUS_NO_MEMORY; 1032 } 1033 /* If it exists and is distinct from other containers, 1034 Write the Users entity */ 1035 if (*user_suffix && strcmp(user_suffix, suffix)) { 1036 user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ','); 1037 fprintf(add_fd, "# %s\n", user_suffix); 1038 fprintf(add_fd, "dn: %s\n", user_suffix); 1039 fprintf(add_fd, "objectClass: organizationalUnit\n"); 1040 fprintf(add_fd, "ou: %s\n", user_attr); 1041 fprintf(add_fd, "\n"); 1042 fflush(add_fd); 1043 } 1044 1045 1046 group_suffix = lp_ldap_group_suffix(); 1047 if (group_suffix == NULL) { 1048 SAFE_FREE(suffix_attr); 1049 SAFE_FREE(user_attr); 1050 return NT_STATUS_NO_MEMORY; 1051 } 1052 /* If it exists and is distinct from other containers, 1053 Write the Groups entity */ 1054 if (*group_suffix && strcmp(group_suffix, suffix)) { 1055 group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); 1056 fprintf(add_fd, "# %s\n", group_suffix); 1057 fprintf(add_fd, "dn: %s\n", group_suffix); 1058 fprintf(add_fd, "objectClass: organizationalUnit\n"); 1059 fprintf(add_fd, "ou: %s\n", group_attr); 1060 fprintf(add_fd, "\n"); 1061 fflush(add_fd); 1062 } 1063 1064 /* If it exists and is distinct from other containers, 1065 Write the Computers entity */ 1066 machine_suffix = lp_ldap_machine_suffix(); 1067 if (machine_suffix == NULL) { 1068 SAFE_FREE(suffix_attr); 1069 SAFE_FREE(user_attr); 1070 SAFE_FREE(group_attr); 1071 return NT_STATUS_NO_MEMORY; 1072 } 1073 if (*machine_suffix && strcmp(machine_suffix, user_suffix) && 1074 strcmp(machine_suffix, suffix)) { 1075 char *machine_ou = NULL; 1076 fprintf(add_fd, "# %s\n", machine_suffix); 1077 fprintf(add_fd, "dn: %s\n", machine_suffix); 1078 fprintf(add_fd, "objectClass: organizationalUnit\n"); 1079 /* this isn't totally correct as it assumes that 1080 there _must_ be an ou. just fixing memleak now. jmcd */ 1081 machine_ou = sstring_sub(lp_ldap_machine_suffix(), '=', ','); 1082 fprintf(add_fd, "ou: %s\n", machine_ou); 1083 SAFE_FREE(machine_ou); 1084 fprintf(add_fd, "\n"); 1085 fflush(add_fd); 1086 } 1087 1088 /* If it exists and is distinct from other containers, 1089 Write the IdMap entity */ 1090 idmap_suffix = lp_ldap_idmap_suffix(); 1091 if (idmap_suffix == NULL) { 1092 SAFE_FREE(suffix_attr); 1093 SAFE_FREE(user_attr); 1094 SAFE_FREE(group_attr); 1095 return NT_STATUS_NO_MEMORY; 1096 } 1097 if (*idmap_suffix && 1098 strcmp(idmap_suffix, user_suffix) && 1099 strcmp(idmap_suffix, suffix)) { 1100 char *s; 1101 fprintf(add_fd, "# %s\n", idmap_suffix); 1102 fprintf(add_fd, "dn: %s\n", idmap_suffix); 1103 fprintf(add_fd, "ObjectClass: organizationalUnit\n"); 1104 s = sstring_sub(lp_ldap_idmap_suffix(), '=', ','); 1105 fprintf(add_fd, "ou: %s\n", s); 1106 SAFE_FREE(s); 1107 fprintf(add_fd, "\n"); 1108 fflush(add_fd); 1109 } 1110 1111 /* Write the domain entity */ 1112 fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix); 1113 fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(), 1114 suffix); 1115 fprintf(add_fd, "objectClass: sambaDomain\n"); 1116 fprintf(add_fd, "objectClass: sambaUnixIdPool\n"); 1117 fprintf(add_fd, "sambaDomainName: %s\n", lp_workgroup()); 1118 fprintf(add_fd, "sambaSID: %s\n", sid); 1119 fprintf(add_fd, "uidNumber: %d\n", ++ldif_uid); 1120 fprintf(add_fd, "gidNumber: %d\n", ++ldif_gid); 1121 fprintf(add_fd, "\n"); 1122 fflush(add_fd); 1123 1124 /* Write the Domain Admins entity */ 1125 fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr, 1126 suffix); 1127 fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr, 1128 suffix); 1129 fprintf(add_fd, "objectClass: posixGroup\n"); 1130 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1131 fprintf(add_fd, "cn: Domain Admins\n"); 1132 fprintf(add_fd, "memberUid: Administrator\n"); 1133 fprintf(add_fd, "description: Netbios Domain Administrators\n"); 1134 fprintf(add_fd, "gidNumber: 512\n"); 1135 fprintf(add_fd, "sambaSID: %s-512\n", sid); 1136 fprintf(add_fd, "sambaGroupType: 2\n"); 1137 fprintf(add_fd, "displayName: Domain Admins\n"); 1138 fprintf(add_fd, "\n"); 1139 fflush(add_fd); 1140 1141 /* Write the Domain Users entity */ 1142 fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr, 1143 suffix); 1144 fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr, 1145 suffix); 1146 fprintf(add_fd, "objectClass: posixGroup\n"); 1147 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1148 fprintf(add_fd, "cn: Domain Users\n"); 1149 fprintf(add_fd, "description: Netbios Domain Users\n"); 1150 fprintf(add_fd, "gidNumber: 513\n"); 1151 fprintf(add_fd, "sambaSID: %s-513\n", sid); 1152 fprintf(add_fd, "sambaGroupType: 2\n"); 1153 fprintf(add_fd, "displayName: Domain Users\n"); 1154 fprintf(add_fd, "\n"); 1155 fflush(add_fd); 1156 1157 /* Write the Domain Guests entity */ 1158 fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr, 1159 suffix); 1160 fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr, 1161 suffix); 1162 fprintf(add_fd, "objectClass: posixGroup\n"); 1163 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1164 fprintf(add_fd, "cn: Domain Guests\n"); 1165 fprintf(add_fd, "description: Netbios Domain Guests\n"); 1166 fprintf(add_fd, "gidNumber: 514\n"); 1167 fprintf(add_fd, "sambaSID: %s-514\n", sid); 1168 fprintf(add_fd, "sambaGroupType: 2\n"); 1169 fprintf(add_fd, "displayName: Domain Guests\n"); 1170 fprintf(add_fd, "\n"); 1171 fflush(add_fd); 1172 1173 /* Write the Domain Computers entity */ 1174 fprintf(add_fd, "# Domain Computers, %s, %s\n", group_attr, 1175 suffix); 1176 fprintf(add_fd, "dn: cn=Domain Computers,ou=%s,%s\n", 1177 group_attr, suffix); 1178 fprintf(add_fd, "objectClass: posixGroup\n"); 1179 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1180 fprintf(add_fd, "gidNumber: 515\n"); 1181 fprintf(add_fd, "cn: Domain Computers\n"); 1182 fprintf(add_fd, "description: Netbios Domain Computers accounts\n"); 1183 fprintf(add_fd, "sambaSID: %s-515\n", sid); 1184 fprintf(add_fd, "sambaGroupType: 2\n"); 1185 fprintf(add_fd, "displayName: Domain Computers\n"); 1186 fprintf(add_fd, "\n"); 1187 fflush(add_fd); 1188 1189 /* Write the Admininistrators Groups entity */ 1190 fprintf(add_fd, "# Administrators, %s, %s\n", group_attr, 1191 suffix); 1192 fprintf(add_fd, "dn: cn=Administrators,ou=%s,%s\n", group_attr, 1193 suffix); 1194 fprintf(add_fd, "objectClass: posixGroup\n"); 1195 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1196 fprintf(add_fd, "gidNumber: 544\n"); 1197 fprintf(add_fd, "cn: Administrators\n"); 1198 fprintf(add_fd, "description: Netbios Domain Members can fully administer the computer/sambaDomainName\n"); 1199 fprintf(add_fd, "sambaSID: %s-544\n", builtin_sid); 1200 fprintf(add_fd, "sambaGroupType: 5\n"); 1201 fprintf(add_fd, "displayName: Administrators\n"); 1202 fprintf(add_fd, "\n"); 1203 1204 /* Write the Print Operator entity */ 1205 fprintf(add_fd, "# Print Operators, %s, %s\n", group_attr, 1206 suffix); 1207 fprintf(add_fd, "dn: cn=Print Operators,ou=%s,%s\n", 1208 group_attr, suffix); 1209 fprintf(add_fd, "objectClass: posixGroup\n"); 1210 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1211 fprintf(add_fd, "gidNumber: 550\n"); 1212 fprintf(add_fd, "cn: Print Operators\n"); 1213 fprintf(add_fd, "description: Netbios Domain Print Operators\n"); 1214 fprintf(add_fd, "sambaSID: %s-550\n", builtin_sid); 1215 fprintf(add_fd, "sambaGroupType: 5\n"); 1216 fprintf(add_fd, "displayName: Print Operators\n"); 1217 fprintf(add_fd, "\n"); 1218 fflush(add_fd); 1219 1220 /* Write the Backup Operators entity */ 1221 fprintf(add_fd, "# Backup Operators, %s, %s\n", group_attr, 1222 suffix); 1223 fprintf(add_fd, "dn: cn=Backup Operators,ou=%s,%s\n", 1224 group_attr, suffix); 1225 fprintf(add_fd, "objectClass: posixGroup\n"); 1226 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1227 fprintf(add_fd, "gidNumber: 551\n"); 1228 fprintf(add_fd, "cn: Backup Operators\n"); 1229 fprintf(add_fd, "description: Netbios Domain Members can bypass file security to back up files\n"); 1230 fprintf(add_fd, "sambaSID: %s-551\n", builtin_sid); 1231 fprintf(add_fd, "sambaGroupType: 5\n"); 1232 fprintf(add_fd, "displayName: Backup Operators\n"); 1233 fprintf(add_fd, "\n"); 1234 fflush(add_fd); 1235 1236 /* Write the Replicators entity */ 1237 fprintf(add_fd, "# Replicators, %s, %s\n", group_attr, suffix); 1238 fprintf(add_fd, "dn: cn=Replicators,ou=%s,%s\n", group_attr, 1239 suffix); 1240 fprintf(add_fd, "objectClass: posixGroup\n"); 1241 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1242 fprintf(add_fd, "gidNumber: 552\n"); 1243 fprintf(add_fd, "cn: Replicators\n"); 1244 fprintf(add_fd, "description: Netbios Domain Supports file replication in a sambaDomainName\n"); 1245 fprintf(add_fd, "sambaSID: %s-552\n", builtin_sid); 1246 fprintf(add_fd, "sambaGroupType: 5\n"); 1247 fprintf(add_fd, "displayName: Replicators\n"); 1248 fprintf(add_fd, "\n"); 1249 fflush(add_fd); 1250 1251 /* Deallocate memory, and return */ 1252 SAFE_FREE(suffix_attr); 1253 SAFE_FREE(user_attr); 1254 SAFE_FREE(group_attr); 1255 return NT_STATUS_OK; 1256} 1257 1258static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, 1259 const char *suffix, const char *builtin_sid) 1260{ 1261 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); 1262 1263 /* Map the groups created by populate_ldap_for_ldif */ 1264 groupmap[0].rid = 512; 1265 groupmap[0].gidNumber = 512; 1266 pstr_sprintf(groupmap[0].sambaSID, "%s-512", sid); 1267 pstr_sprintf(groupmap[0].group_dn, "cn=Domain Admins,ou=%s,%s", 1268 group_attr, suffix); 1269 accountmap[0].rid = 512; 1270 pstr_sprintf(accountmap[0].cn, "%s", "Domain Admins"); 1271 1272 groupmap[1].rid = 513; 1273 groupmap[1].gidNumber = 513; 1274 pstr_sprintf(groupmap[1].sambaSID, "%s-513", sid); 1275 pstr_sprintf(groupmap[1].group_dn, "cn=Domain Users,ou=%s,%s", 1276 group_attr, suffix); 1277 accountmap[1].rid = 513; 1278 pstr_sprintf(accountmap[1].cn, "%s", "Domain Users"); 1279 1280 groupmap[2].rid = 514; 1281 groupmap[2].gidNumber = 514; 1282 pstr_sprintf(groupmap[2].sambaSID, "%s-514", sid); 1283 pstr_sprintf(groupmap[2].group_dn, "cn=Domain Guests,ou=%s,%s", 1284 group_attr, suffix); 1285 accountmap[2].rid = 514; 1286 pstr_sprintf(accountmap[2].cn, "%s", "Domain Guests"); 1287 1288 groupmap[3].rid = 515; 1289 groupmap[3].gidNumber = 515; 1290 pstr_sprintf(groupmap[3].sambaSID, "%s-515", sid); 1291 pstr_sprintf(groupmap[3].group_dn, "cn=Domain Computers,ou=%s,%s", 1292 group_attr, suffix); 1293 accountmap[3].rid = 515; 1294 pstr_sprintf(accountmap[3].cn, "%s", "Domain Computers"); 1295 1296 groupmap[4].rid = 544; 1297 groupmap[4].gidNumber = 544; 1298 pstr_sprintf(groupmap[4].sambaSID, "%s-544", builtin_sid); 1299 pstr_sprintf(groupmap[4].group_dn, "cn=Administrators,ou=%s,%s", 1300 group_attr, suffix); 1301 accountmap[4].rid = 515; 1302 pstr_sprintf(accountmap[4].cn, "%s", "Administrators"); 1303 1304 groupmap[5].rid = 550; 1305 groupmap[5].gidNumber = 550; 1306 pstr_sprintf(groupmap[5].sambaSID, "%s-550", builtin_sid); 1307 pstr_sprintf(groupmap[5].group_dn, "cn=Print Operators,ou=%s,%s", 1308 group_attr, suffix); 1309 accountmap[5].rid = 550; 1310 pstr_sprintf(accountmap[5].cn, "%s", "Print Operators"); 1311 1312 groupmap[6].rid = 551; 1313 groupmap[6].gidNumber = 551; 1314 pstr_sprintf(groupmap[6].sambaSID, "%s-551", builtin_sid); 1315 pstr_sprintf(groupmap[6].group_dn, "cn=Backup Operators,ou=%s,%s", 1316 group_attr, suffix); 1317 accountmap[6].rid = 551; 1318 pstr_sprintf(accountmap[6].cn, "%s", "Backup Operators"); 1319 1320 groupmap[7].rid = 552; 1321 groupmap[7].gidNumber = 552; 1322 pstr_sprintf(groupmap[7].sambaSID, "%s-552", builtin_sid); 1323 pstr_sprintf(groupmap[7].group_dn, "cn=Replicators,ou=%s,%s", 1324 group_attr, suffix); 1325 accountmap[7].rid = 551; 1326 pstr_sprintf(accountmap[7].cn, "%s", "Replicators"); 1327 SAFE_FREE(group_attr); 1328 return NT_STATUS_OK; 1329} 1330 1331/* 1332 * This is a crap routine, but I think it's the quickest way to solve the 1333 * UTF8->base64 problem. 1334 */ 1335 1336static int fprintf_attr(FILE *add_fd, const char *attr_name, 1337 const char *fmt, ...) 1338{ 1339 va_list ap; 1340 char *value, *p, *base64; 1341 DATA_BLOB base64_blob; 1342 BOOL do_base64 = False; 1343 int res; 1344 1345 va_start(ap, fmt); 1346 value = talloc_vasprintf(NULL, fmt, ap); 1347 va_end(ap); 1348 1349 SMB_ASSERT(value != NULL); 1350 1351 for (p=value; *p; p++) { 1352 if (*p & 0x80) { 1353 do_base64 = True; 1354 break; 1355 } 1356 } 1357 1358 if (!do_base64) { 1359 BOOL only_whitespace = True; 1360 for (p=value; *p; p++) { 1361 /* 1362 * I know that this not multibyte safe, but we break 1363 * on the first non-whitespace character anyway. 1364 */ 1365 if (!isspace(*p)) { 1366 only_whitespace = False; 1367 break; 1368 } 1369 } 1370 if (only_whitespace) { 1371 do_base64 = True; 1372 } 1373 } 1374 1375 if (!do_base64) { 1376 res = fprintf(add_fd, "%s: %s\n", attr_name, value); 1377 TALLOC_FREE(value); 1378 return res; 1379 } 1380 1381 base64_blob.data = (unsigned char *)value; 1382 base64_blob.length = strlen(value); 1383 1384 base64 = base64_encode_data_blob(base64_blob); 1385 SMB_ASSERT(base64 != NULL); 1386 1387 res = fprintf(add_fd, "%s:: %s\n", attr_name, base64); 1388 TALLOC_FREE(value); 1389 SAFE_FREE(base64); 1390 return res; 1391} 1392 1393static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, 1394 FILE *add_fd, fstring sid, char *suffix) 1395{ 1396 fstring groupname; 1397 uint32 grouptype = 0, g_rid = 0; 1398 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); 1399 1400 /* Get the group name */ 1401 unistr2_to_ascii(groupname, 1402 &(delta->group_info.uni_grp_name), 1403 sizeof(groupname)-1); 1404 1405 /* Set up the group type (always 2 for group info) */ 1406 grouptype = 2; 1407 1408 /* These groups are entered by populate_ldap_for_ldif */ 1409 if (strcmp(groupname, "Domain Admins") == 0 || 1410 strcmp(groupname, "Domain Users") == 0 || 1411 strcmp(groupname, "Domain Guests") == 0 || 1412 strcmp(groupname, "Domain Computers") == 0 || 1413 strcmp(groupname, "Administrators") == 0 || 1414 strcmp(groupname, "Print Operators") == 0 || 1415 strcmp(groupname, "Backup Operators") == 0 || 1416 strcmp(groupname, "Replicators") == 0) { 1417 SAFE_FREE(group_attr); 1418 return NT_STATUS_OK; 1419 } else { 1420 /* Increment the gid for the new group */ 1421 ldif_gid++; 1422 } 1423 1424 /* Map the group rid, gid, and dn */ 1425 g_rid = delta->group_info.gid.g_rid; 1426 groupmap->rid = g_rid; 1427 groupmap->gidNumber = ldif_gid; 1428 pstr_sprintf(groupmap->sambaSID, "%s-%d", sid, g_rid); 1429 pstr_sprintf(groupmap->group_dn, 1430 "cn=%s,ou=%s,%s", groupname, group_attr, suffix); 1431 1432 /* Write the data to the temporary add ldif file */ 1433 fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr, 1434 suffix); 1435 fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", groupname, group_attr, 1436 suffix); 1437 fprintf(add_fd, "objectClass: posixGroup\n"); 1438 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1439 fprintf_attr(add_fd, "cn", "%s", groupname); 1440 fprintf(add_fd, "gidNumber: %d\n", ldif_gid); 1441 fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID); 1442 fprintf(add_fd, "sambaGroupType: %d\n", grouptype); 1443 fprintf_attr(add_fd, "displayName", "%s", groupname); 1444 fprintf(add_fd, "\n"); 1445 fflush(add_fd); 1446 1447 SAFE_FREE(group_attr); 1448 /* Return */ 1449 return NT_STATUS_OK; 1450} 1451 1452static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, 1453 GROUPMAP *groupmap, 1454 ACCOUNTMAP *accountmap, 1455 FILE *add_fd, 1456 fstring sid, char *suffix, 1457 int alloced) 1458{ 1459 fstring username, logonscript, homedrive, homepath = "", homedir = ""; 1460 fstring hex_nt_passwd, hex_lm_passwd; 1461 fstring description, profilepath, fullname, sambaSID; 1462 uchar lm_passwd[16], nt_passwd[16]; 1463 char *flags, *user_rdn; 1464 const char *ou; 1465 const char* nopasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; 1466 static uchar zero_buf[16]; 1467 uint32 rid = 0, group_rid = 0, gidNumber = 0; 1468 time_t unix_time; 1469 int i; 1470 1471 /* Get the username */ 1472 unistr2_to_ascii(username, 1473 &(delta->account_info.uni_acct_name), 1474 sizeof(username)-1); 1475 1476 /* Get the rid */ 1477 rid = delta->account_info.user_rid; 1478 1479 /* Map the rid and username for group member info later */ 1480 accountmap->rid = rid; 1481 pstr_sprintf(accountmap->cn, "%s", username); 1482 1483 /* Get the home directory */ 1484 if (delta->account_info.acb_info & ACB_NORMAL) { 1485 unistr2_to_ascii(homedir, &(delta->account_info.uni_home_dir), 1486 sizeof(homedir)-1); 1487 if (!*homedir) { 1488 pstr_sprintf(homedir, "/home/%s", username); 1489 } else { 1490 pstr_sprintf(homedir, "/nobodyshomedir"); 1491 } 1492 ou = lp_ldap_user_suffix(); 1493 } else { 1494 ou = lp_ldap_machine_suffix(); 1495 pstr_sprintf(homedir, "/machinehomedir"); 1496 } 1497 1498 /* Get the logon script */ 1499 unistr2_to_ascii(logonscript, &(delta->account_info.uni_logon_script), 1500 sizeof(logonscript)-1); 1501 1502 /* Get the home drive */ 1503 unistr2_to_ascii(homedrive, &(delta->account_info.uni_dir_drive), 1504 sizeof(homedrive)-1); 1505 1506 /* Get the home path */ 1507 unistr2_to_ascii(homepath, &(delta->account_info.uni_home_dir), 1508 sizeof(homepath)-1); 1509 1510 /* Get the description */ 1511 unistr2_to_ascii(description, &(delta->account_info.uni_acct_desc), 1512 sizeof(description)-1); 1513 1514 /* Get the display name */ 1515 unistr2_to_ascii(fullname, &(delta->account_info.uni_full_name), 1516 sizeof(fullname)-1); 1517 1518 /* Get the profile path */ 1519 unistr2_to_ascii(profilepath, &(delta->account_info.uni_profile), 1520 sizeof(profilepath)-1); 1521 1522 /* Get lm and nt password data */ 1523 if (memcmp(delta->account_info.pass.buf_lm_pwd, zero_buf, 16) != 0) { 1524 sam_pwd_hash(delta->account_info.user_rid, 1525 delta->account_info.pass.buf_lm_pwd, 1526 lm_passwd, 0); 1527 pdb_sethexpwd(hex_lm_passwd, lm_passwd, 1528 delta->account_info.acb_info); 1529 } else { 1530 pdb_sethexpwd(hex_lm_passwd, NULL, 0); 1531 } 1532 if (memcmp(delta->account_info.pass.buf_nt_pwd, zero_buf, 16) != 0) { 1533 sam_pwd_hash(delta->account_info.user_rid, 1534 delta->account_info.pass.buf_nt_pwd, 1535 nt_passwd, 0); 1536 pdb_sethexpwd(hex_nt_passwd, nt_passwd, 1537 delta->account_info.acb_info); 1538 } else { 1539 pdb_sethexpwd(hex_nt_passwd, NULL, 0); 1540 } 1541 unix_time = nt_time_to_unix(delta->account_info.pwd_last_set_time); 1542 1543 /* Increment the uid for the new user */ 1544 ldif_uid++; 1545 1546 /* Set up group id and sambaSID for the user */ 1547 group_rid = delta->account_info.group_rid; 1548 for (i=0; i<alloced; i++) { 1549 if (groupmap[i].rid == group_rid) break; 1550 } 1551 if (i == alloced){ 1552 DEBUG(1, ("Could not find rid %d in groupmap array\n", 1553 group_rid)); 1554 return NT_STATUS_UNSUCCESSFUL; 1555 } 1556 gidNumber = groupmap[i].gidNumber; 1557 pstr_sprintf(sambaSID, groupmap[i].sambaSID); 1558 1559 /* Set up sambaAcctFlags */ 1560 flags = pdb_encode_acct_ctrl(delta->account_info.acb_info, 1561 NEW_PW_FORMAT_SPACE_PADDED_LEN); 1562 1563 /* Add the user to the temporary add ldif file */ 1564 /* this isn't quite right...we can't assume there's just OU=. jmcd */ 1565 user_rdn = sstring_sub(ou, '=', ','); 1566 fprintf(add_fd, "# %s, %s, %s\n", username, user_rdn, suffix); 1567 fprintf_attr(add_fd, "dn", "uid=%s,ou=%s,%s", username, user_rdn, 1568 suffix); 1569 SAFE_FREE(user_rdn); 1570 fprintf(add_fd, "ObjectClass: top\n"); 1571 fprintf(add_fd, "objectClass: inetOrgPerson\n"); 1572 fprintf(add_fd, "objectClass: posixAccount\n"); 1573 fprintf(add_fd, "objectClass: shadowAccount\n"); 1574 fprintf(add_fd, "objectClass: sambaSamAccount\n"); 1575 fprintf_attr(add_fd, "cn", "%s", username); 1576 fprintf_attr(add_fd, "sn", "%s", username); 1577 fprintf_attr(add_fd, "uid", "%s", username); 1578 fprintf(add_fd, "uidNumber: %d\n", ldif_uid); 1579 fprintf(add_fd, "gidNumber: %d\n", gidNumber); 1580 fprintf_attr(add_fd, "homeDirectory", "%s", homedir); 1581 if (*homepath) 1582 fprintf_attr(add_fd, "sambaHomePath", "%s", homepath); 1583 if (*homedrive) 1584 fprintf_attr(add_fd, "sambaHomeDrive", "%s", homedrive); 1585 if (*logonscript) 1586 fprintf_attr(add_fd, "sambaLogonScript", "%s", logonscript); 1587 fprintf(add_fd, "loginShell: %s\n", 1588 ((delta->account_info.acb_info & ACB_NORMAL) ? 1589 "/bin/bash" : "/bin/false")); 1590 fprintf(add_fd, "gecos: System User\n"); 1591 if (*description) 1592 fprintf_attr(add_fd, "description", "%s", description); 1593 fprintf(add_fd, "sambaSID: %s-%d\n", sid, rid); 1594 fprintf(add_fd, "sambaPrimaryGroupSID: %s\n", sambaSID); 1595 if(*fullname) 1596 fprintf_attr(add_fd, "displayName", "%s", fullname); 1597 if(*profilepath) 1598 fprintf_attr(add_fd, "sambaProfilePath", "%s", profilepath); 1599 if (strcmp(nopasswd, hex_lm_passwd) != 0) 1600 fprintf(add_fd, "sambaLMPassword: %s\n", hex_lm_passwd); 1601 if (strcmp(nopasswd, hex_nt_passwd) != 0) 1602 fprintf(add_fd, "sambaNTPassword: %s\n", hex_nt_passwd); 1603 fprintf(add_fd, "sambaPwdLastSet: %d\n", (int)unix_time); 1604 fprintf(add_fd, "sambaAcctFlags: %s\n", flags); 1605 fprintf(add_fd, "\n"); 1606 fflush(add_fd); 1607 1608 /* Return */ 1609 return NT_STATUS_OK; 1610} 1611 1612static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, 1613 GROUPMAP *groupmap, 1614 FILE *add_fd, fstring sid, 1615 char *suffix, 1616 unsigned db_type) 1617{ 1618 fstring aliasname, description; 1619 uint32 grouptype = 0, g_rid = 0; 1620 char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); 1621 1622 /* Get the alias name */ 1623 unistr2_to_ascii(aliasname, &(delta->alias_info.uni_als_name), 1624 sizeof(aliasname)-1); 1625 1626 /* Get the alias description */ 1627 unistr2_to_ascii(description, &(delta->alias_info.uni_als_desc), 1628 sizeof(description)-1); 1629 1630 /* Set up the group type */ 1631 switch (db_type) { 1632 case SAM_DATABASE_DOMAIN: 1633 grouptype = 4; 1634 break; 1635 case SAM_DATABASE_BUILTIN: 1636 grouptype = 5; 1637 break; 1638 default: 1639 grouptype = 4; 1640 break; 1641 } 1642 1643 /* 1644 These groups are entered by populate_ldap_for_ldif 1645 Note that populate creates a group called Relicators, 1646 but NT returns a group called Replicator 1647 */ 1648 if (strcmp(aliasname, "Domain Admins") == 0 || 1649 strcmp(aliasname, "Domain Users") == 0 || 1650 strcmp(aliasname, "Domain Guests") == 0 || 1651 strcmp(aliasname, "Domain Computers") == 0 || 1652 strcmp(aliasname, "Administrators") == 0 || 1653 strcmp(aliasname, "Print Operators") == 0 || 1654 strcmp(aliasname, "Backup Operators") == 0 || 1655 strcmp(aliasname, "Replicator") == 0) { 1656 SAFE_FREE(group_attr); 1657 return NT_STATUS_OK; 1658 } else { 1659 /* Increment the gid for the new group */ 1660 ldif_gid++; 1661 } 1662 1663 /* Map the group rid and gid */ 1664 g_rid = delta->group_info.gid.g_rid; 1665 groupmap->gidNumber = ldif_gid; 1666 pstr_sprintf(groupmap->sambaSID, "%s-%d", sid, g_rid); 1667 1668 /* Write the data to the temporary add ldif file */ 1669 fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr, 1670 suffix); 1671 fprintf_attr(add_fd, "dn", "cn=%s,ou=%s,%s", aliasname, group_attr, 1672 suffix); 1673 fprintf(add_fd, "objectClass: posixGroup\n"); 1674 fprintf(add_fd, "objectClass: sambaGroupMapping\n"); 1675 fprintf(add_fd, "cn: %s\n", aliasname); 1676 fprintf(add_fd, "gidNumber: %d\n", ldif_gid); 1677 fprintf(add_fd, "sambaSID: %s\n", groupmap->sambaSID); 1678 fprintf(add_fd, "sambaGroupType: %d\n", grouptype); 1679 fprintf_attr(add_fd, "displayName", "%s", aliasname); 1680 if (description[0]) 1681 fprintf_attr(add_fd, "description", "%s", description); 1682 fprintf(add_fd, "\n"); 1683 fflush(add_fd); 1684 1685 SAFE_FREE(group_attr); 1686 /* Return */ 1687 return NT_STATUS_OK; 1688} 1689 1690static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, 1691 SAM_DELTA_HDR *hdr_delta, 1692 GROUPMAP *groupmap, 1693 ACCOUNTMAP *accountmap, 1694 FILE *mod_fd, int alloced) 1695{ 1696 fstring group_dn; 1697 uint32 group_rid = 0, rid = 0; 1698 int i, j, k; 1699 1700 /* Get the dn for the group */ 1701 if (delta->grp_mem_info.num_members > 0) { 1702 group_rid = hdr_delta->target_rid; 1703 for (j=0; j<alloced; j++) { 1704 if (groupmap[j].rid == group_rid) break; 1705 } 1706 if (j == alloced){ 1707 DEBUG(1, ("Could not find rid %d in groupmap array\n", 1708 group_rid)); 1709 return NT_STATUS_UNSUCCESSFUL; 1710 } 1711 pstr_sprintf(group_dn, "%s", groupmap[j].group_dn); 1712 fprintf(mod_fd, "dn: %s\n", group_dn); 1713 1714 /* Get the cn for each member */ 1715 for (i=0; i<delta->grp_mem_info.num_members; i++) { 1716 rid = delta->grp_mem_info.rids[i]; 1717 for (k=0; k<alloced; k++) { 1718 if (accountmap[k].rid == rid) break; 1719 } 1720 if (k == alloced){ 1721 DEBUG(1, ("Could not find rid %d in " 1722 "accountmap array\n", rid)); 1723 return NT_STATUS_UNSUCCESSFUL; 1724 } 1725 fprintf(mod_fd, "memberUid: %s\n", accountmap[k].cn); 1726 } 1727 fprintf(mod_fd, "\n"); 1728 } 1729 fflush(mod_fd); 1730 1731 /* Return */ 1732 return NT_STATUS_OK; 1733} 1734 1735static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, 1736 uint32 db_type, 1737 DOM_SID dom_sid, 1738 const char *user_file) 1739{ 1740 char *suffix; 1741 const char *builtin_sid = "S-1-5-32"; 1742 char *add_name = NULL, *mod_name = NULL; 1743 const char *add_template = "/tmp/add.ldif.XXXXXX"; 1744 const char *mod_template = "/tmp/mod.ldif.XXXXXX"; 1745 fstring sid, domainname; 1746 uint32 sync_context = 0; 1747 NTSTATUS ret = NT_STATUS_OK, result; 1748 int k; 1749 TALLOC_CTX *mem_ctx; 1750 SAM_DELTA_HDR *hdr_deltas; 1751 SAM_DELTA_CTR *deltas; 1752 uint32 num_deltas; 1753 FILE *add_file = NULL, *mod_file = NULL, *ldif_file = NULL; 1754 int num_alloced = 0, g_index = 0, a_index = 0; 1755 1756 /* Set up array for mapping accounts to groups */ 1757 /* Array element is the group rid */ 1758 GROUPMAP *groupmap = NULL; 1759 1760 /* Set up array for mapping account rid's to cn's */ 1761 /* Array element is the account rid */ 1762 ACCOUNTMAP *accountmap = NULL; 1763 1764 if (!(mem_ctx = talloc_init("fetch_database"))) { 1765 return NT_STATUS_NO_MEMORY; 1766 } 1767 1768 /* Ensure we have an output file */ 1769 if (user_file) 1770 ldif_file = fopen(user_file, "a"); 1771 else 1772 ldif_file = stdout; 1773 1774 if (!ldif_file) { 1775 fprintf(stderr, "Could not open %s\n", user_file); 1776 DEBUG(1, ("Could not open %s\n", user_file)); 1777 ret = NT_STATUS_UNSUCCESSFUL; 1778 goto done; 1779 } 1780 1781 add_name = talloc_strdup(mem_ctx, add_template); 1782 mod_name = talloc_strdup(mem_ctx, mod_template); 1783 if (!add_name || !mod_name) { 1784 ret = NT_STATUS_NO_MEMORY; 1785 goto done; 1786 } 1787 1788 /* Open the add and mod ldif files */ 1789 if (!(add_file = fdopen(smb_mkstemp(add_name),"w"))) { 1790 DEBUG(1, ("Could not open %s\n", add_name)); 1791 ret = NT_STATUS_UNSUCCESSFUL; 1792 goto done; 1793 } 1794 if (!(mod_file = fdopen(smb_mkstemp(mod_name),"w"))) { 1795 DEBUG(1, ("Could not open %s\n", mod_name)); 1796 ret = NT_STATUS_UNSUCCESSFUL; 1797 goto done; 1798 } 1799 1800 /* Get the sid */ 1801 sid_to_string(sid, &dom_sid); 1802 1803 /* Get the ldap suffix */ 1804 suffix = lp_ldap_suffix(); 1805 if (suffix == NULL || strcmp(suffix, "") == 0) { 1806 DEBUG(0,("ldap suffix missing from smb.conf--exiting\n")); 1807 exit(1); 1808 } 1809 1810 /* Get other smb.conf data */ 1811 if (!(lp_workgroup()) || !*(lp_workgroup())) { 1812 DEBUG(0,("workgroup missing from smb.conf--exiting\n")); 1813 exit(1); 1814 } 1815 1816 /* Allocate initial memory for groupmap and accountmap arrays */ 1817 if (init_ldap == 1) { 1818 groupmap = SMB_MALLOC_ARRAY(GROUPMAP, 8); 1819 accountmap = SMB_MALLOC_ARRAY(ACCOUNTMAP, 8); 1820 if (groupmap == NULL || accountmap == NULL) { 1821 DEBUG(1,("GROUPMAP malloc failed\n")); 1822 ret = NT_STATUS_NO_MEMORY; 1823 goto done; 1824 } 1825 1826 /* Initialize the arrays */ 1827 memset(groupmap, 0, sizeof(GROUPMAP)*8); 1828 memset(accountmap, 0, sizeof(ACCOUNTMAP)*8); 1829 1830 /* Remember how many we malloced */ 1831 num_alloced = 8; 1832 1833 /* Initial database population */ 1834 populate_ldap_for_ldif(sid, suffix, builtin_sid, add_file); 1835 map_populate_groups(groupmap, accountmap, sid, suffix, 1836 builtin_sid); 1837 1838 /* Don't do this again */ 1839 init_ldap = 0; 1840 } 1841 1842 /* Announce what we are doing */ 1843 switch( db_type ) { 1844 case SAM_DATABASE_DOMAIN: 1845 d_fprintf(stderr, "Fetching DOMAIN database\n"); 1846 break; 1847 case SAM_DATABASE_BUILTIN: 1848 d_fprintf(stderr, "Fetching BUILTIN database\n"); 1849 break; 1850 case SAM_DATABASE_PRIVS: 1851 d_fprintf(stderr, "Fetching PRIVS databases\n"); 1852 break; 1853 default: 1854 d_fprintf(stderr, 1855 "Fetching unknown database type %u\n", 1856 db_type ); 1857 break; 1858 } 1859 1860 do { 1861 result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, 1862 db_type, sync_context, 1863 &num_deltas, &hdr_deltas, 1864 &deltas); 1865 if (!NT_STATUS_IS_OK(result) && 1866 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 1867 ret = NT_STATUS_OK; 1868 goto done; /* is this correct? jmcd */ 1869 } 1870 1871 /* Re-allocate memory for groupmap and accountmap arrays */ 1872 groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP, 1873 num_deltas+num_alloced); 1874 accountmap = SMB_REALLOC_ARRAY(accountmap, ACCOUNTMAP, 1875 num_deltas+num_alloced); 1876 if (groupmap == NULL || accountmap == NULL) { 1877 DEBUG(1,("GROUPMAP malloc failed\n")); 1878 ret = NT_STATUS_NO_MEMORY; 1879 goto done; 1880 } 1881 1882 /* Initialize the new records */ 1883 memset(&groupmap[num_alloced], 0, 1884 sizeof(GROUPMAP)*num_deltas); 1885 memset(&accountmap[num_alloced], 0, 1886 sizeof(ACCOUNTMAP)*num_deltas); 1887 1888 /* Remember how many we alloced this time */ 1889 num_alloced += num_deltas; 1890 1891 /* Loop through the deltas */ 1892 for (k=0; k<num_deltas; k++) { 1893 switch(hdr_deltas[k].type) { 1894 case SAM_DELTA_DOMAIN_INFO: 1895 /* Is this case needed? */ 1896 unistr2_to_ascii( 1897 domainname, 1898 &deltas[k].domain_info.uni_dom_name, 1899 sizeof(domainname)-1); 1900 break; 1901 1902 case SAM_DELTA_GROUP_INFO: 1903 fetch_group_info_to_ldif( 1904 &deltas[k], &groupmap[g_index], 1905 add_file, sid, suffix); 1906 g_index++; 1907 break; 1908 1909 case SAM_DELTA_ACCOUNT_INFO: 1910 fetch_account_info_to_ldif( 1911 &deltas[k], groupmap, 1912 &accountmap[a_index], add_file, 1913 sid, suffix, num_alloced); 1914 a_index++; 1915 break; 1916 1917 case SAM_DELTA_ALIAS_INFO: 1918 fetch_alias_info_to_ldif( 1919 &deltas[k], &groupmap[g_index], 1920 add_file, sid, suffix, db_type); 1921 g_index++; 1922 break; 1923 1924 case SAM_DELTA_GROUP_MEM: 1925 fetch_groupmem_info_to_ldif( 1926 &deltas[k], &hdr_deltas[k], 1927 groupmap, accountmap, 1928 mod_file, num_alloced); 1929 break; 1930 1931 case SAM_DELTA_ALIAS_MEM: 1932 break; 1933 case SAM_DELTA_POLICY_INFO: 1934 break; 1935 case SAM_DELTA_PRIVS_INFO: 1936 break; 1937 case SAM_DELTA_TRUST_DOMS: 1938 /* Implemented but broken */ 1939 break; 1940 case SAM_DELTA_SECRET_INFO: 1941 /* Implemented but broken */ 1942 break; 1943 case SAM_DELTA_RENAME_GROUP: 1944 /* Not yet implemented */ 1945 break; 1946 case SAM_DELTA_RENAME_USER: 1947 /* Not yet implemented */ 1948 break; 1949 case SAM_DELTA_RENAME_ALIAS: 1950 /* Not yet implemented */ 1951 break; 1952 case SAM_DELTA_DELETE_GROUP: 1953 /* Not yet implemented */ 1954 break; 1955 case SAM_DELTA_DELETE_USER: 1956 /* Not yet implemented */ 1957 break; 1958 case SAM_DELTA_MODIFIED_COUNT: 1959 break; 1960 default: 1961 break; 1962 } /* end of switch */ 1963 } /* end of for loop */ 1964 1965 /* Increment sync_context */ 1966 sync_context += 1; 1967 1968 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 1969 1970 /* Write ldif data to the user's file */ 1971 if (db_type == SAM_DATABASE_DOMAIN) { 1972 fprintf(ldif_file, 1973 "# SAM_DATABASE_DOMAIN: ADD ENTITIES\n"); 1974 fprintf(ldif_file, 1975 "# =================================\n\n"); 1976 fflush(ldif_file); 1977 } else if (db_type == SAM_DATABASE_BUILTIN) { 1978 fprintf(ldif_file, 1979 "# SAM_DATABASE_BUILTIN: ADD ENTITIES\n"); 1980 fprintf(ldif_file, 1981 "# ==================================\n\n"); 1982 fflush(ldif_file); 1983 } 1984 fseek(add_file, 0, SEEK_SET); 1985 transfer_file(fileno(add_file), fileno(ldif_file), (size_t) -1); 1986 1987 if (db_type == SAM_DATABASE_DOMAIN) { 1988 fprintf(ldif_file, 1989 "# SAM_DATABASE_DOMAIN: MODIFY ENTITIES\n"); 1990 fprintf(ldif_file, 1991 "# ====================================\n\n"); 1992 fflush(ldif_file); 1993 } else if (db_type == SAM_DATABASE_BUILTIN) { 1994 fprintf(ldif_file, 1995 "# SAM_DATABASE_BUILTIN: MODIFY ENTITIES\n"); 1996 fprintf(ldif_file, 1997 "# =====================================\n\n"); 1998 fflush(ldif_file); 1999 } 2000 fseek(mod_file, 0, SEEK_SET); 2001 transfer_file(fileno(mod_file), fileno(ldif_file), (size_t) -1); 2002 2003 2004 done: 2005 /* Close and delete the ldif files */ 2006 if (add_file) { 2007 fclose(add_file); 2008 } 2009 2010 if ((add_name != NULL) && 2011 strcmp(add_name, add_template) && (unlink(add_name))) { 2012 DEBUG(1,("unlink(%s) failed, error was (%s)\n", 2013 add_name, strerror(errno))); 2014 } 2015 2016 if (mod_file) { 2017 fclose(mod_file); 2018 } 2019 2020 if ((mod_name != NULL) && 2021 strcmp(mod_name, mod_template) && (unlink(mod_name))) { 2022 DEBUG(1,("unlink(%s) failed, error was (%s)\n", 2023 mod_name, strerror(errno))); 2024 } 2025 2026 if (ldif_file && (ldif_file != stdout)) { 2027 fclose(ldif_file); 2028 } 2029 2030 /* Deallocate memory for the mapping arrays */ 2031 SAFE_FREE(groupmap); 2032 SAFE_FREE(accountmap); 2033 2034 /* Return */ 2035 talloc_destroy(mem_ctx); 2036 return ret; 2037} 2038 2039/** 2040 * Basic usage function for 'net rpc vampire' 2041 * @param argc Standard main() style argc 2042 * @param argc Standard main() style argv. Initial components are already 2043 * stripped 2044 **/ 2045 2046int rpc_vampire_usage(int argc, const char **argv) 2047{ 2048 d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n" 2049 "\t to pull accounts from a remote PDC where we are a BDC\n" 2050 "\t\t no args puts accounts in local passdb from smb.conf\n" 2051 "\t\t ldif - put accounts in ldif format (file defaults to " 2052 "/tmp/tmp.ldif\n"); 2053 2054 net_common_flags_usage(argc, argv); 2055 return -1; 2056} 2057 2058 2059/* dump sam database via samsync rpc calls */ 2060NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, 2061 const char *domain_name, 2062 struct cli_state *cli, 2063 struct rpc_pipe_client *pipe_hnd, 2064 TALLOC_CTX *mem_ctx, 2065 int argc, 2066 const char **argv) 2067{ 2068 NTSTATUS result; 2069 fstring my_dom_sid_str; 2070 fstring rem_dom_sid_str; 2071 2072 if (!sid_equal(domain_sid, get_global_sam_sid())) { 2073 d_printf("Cannot import users from %s at this time, " 2074 "as the current domain:\n\t%s: %s\nconflicts " 2075 "with the remote domain\n\t%s: %s\n" 2076 "Perhaps you need to set: \n\n\tsecurity=user\n\t" 2077 "workgroup=%s\n\n in your smb.conf?\n", 2078 domain_name, 2079 get_global_sam_name(), 2080 sid_to_string(my_dom_sid_str, 2081 get_global_sam_sid()), 2082 domain_name, sid_to_string(rem_dom_sid_str, 2083 domain_sid), 2084 domain_name); 2085 return NT_STATUS_UNSUCCESSFUL; 2086 } 2087 2088 if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) { 2089 result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_DOMAIN, 2090 *domain_sid, argv[1]); 2091 } else { 2092 result = fetch_database(pipe_hnd, SAM_DATABASE_DOMAIN, 2093 *domain_sid); 2094 } 2095 2096 if (!NT_STATUS_IS_OK(result)) { 2097 d_fprintf(stderr, "Failed to fetch domain database: %s\n", 2098 nt_errstr(result)); 2099 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) 2100 d_fprintf(stderr, "Perhaps %s is a Windows 2000 " 2101 "native mode domain?\n", domain_name); 2102 goto fail; 2103 } 2104 2105 if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) { 2106 result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_BUILTIN, 2107 global_sid_Builtin, argv[1]); 2108 } else { 2109 result = fetch_database(pipe_hnd, SAM_DATABASE_BUILTIN, 2110 global_sid_Builtin); 2111 } 2112 2113 if (!NT_STATUS_IS_OK(result)) { 2114 d_fprintf(stderr, "Failed to fetch builtin database: %s\n", 2115 nt_errstr(result)); 2116 goto fail; 2117 } 2118 2119 /* Currently we crash on PRIVS somewhere in unmarshalling */ 2120 /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ 2121 2122 fail: 2123 return result; 2124} 2125