#91543 - 2003-02-19 03:31 PM
Re: Migrating Local User Profiles
|
Howard Bullock
KiX Supporter
   
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Below is some of the newer Perl code that has been included in the current approach of migrating profiles and security. I do not have time to write it in KiXtart so I will provide the Perl source to those of you that might want to understand the process. You may be able to translate it to KiXtart. I will try to answer any questions.
Here is how I modify the registry to preserve the profile. I load ALL the profiles that are listed in my migration scope as defined by my SID map of old SID to new SID.
code:
sub LoadProfileHives { # Open HKEY_USERS key my $HKEY_Users = $Registry->Open("Users/"); my @oldOpts= $HKEY_Users->SetOptions( AllowLoad=>1 );
# Open ProfileList key my $ProfileList = $Registry->Open("LMachine/Software/Microsoft/Windows NT/CurrentVersion/ProfileList/"); my @ProfileKeys = $ProfileList->SubKeyNames;
my %LoadedKey; foreach my $Pkey (@ProfileKeys) { #&LogText($LogFile, "Reg: $Pkey"); if (exists $SidMap{$Pkey}) { &LogText($LogFile, "Profile Match: $Pkey"); # Load user registry hives into HKEY_USERS if they are not currently loaded. if (! exists $HKEY_Users->{$Pkey . "/"}) { my $file = $ProfileList->{"$Pkey//ProfileImagePath"} . "\\NTUSER.DAT";
# Correct path for both NT and W2K $file =~s/\%(SystemRoot|SystemDrive)\%/$ENV{$1}/i;
$LoadedKey{$Pkey} = $HKEY_Users->Load($file, $Pkey); if (exists $LoadedKey{$Pkey}) { &LogText($LogFile, "Loaded: $file, $Pkey"); } else { &LogText($LogFile, "Failed to load: $file, $Pkey"); } } else { &LogText($LogFile, "Reg: $Pkey already loaded in HKEY_USERS"); } # Copy old OldSid key to NewSid key @oldOpts= $ProfileList->SetOptions( ArrayValues=>1 ); $ProfileList->{"$SidMap{$Pkey}/"} = $ProfileList->{"$Pkey/"}; &LogText($LogFile, "Copy $Pkey key to $SidMap{$Pkey} key"); # Set NewBinarySid to Sid value in new key $ProfileList->{"$SidMap{$Pkey}//Sid"} = [Win32::Lanman::StringToSid($SidMap{$Pkey}), "REG_BINARY" ]; @oldOpts= $ProfileList->SetOptions( ArrayValues=>0 ); } } # Call SubInACL &CallSubInACL;
The current version of SubInACL is a must. The resource kit does not contain the current version.
Subinacl command line: code:
sub CallSubInACL { my $cmdline = "$PerlServer\\subinacl\\subinacl.exe " . "/offlinesam=$ENV{'TEMP'}\\OfflineSAM.txt " . "/errorlog=$ENV{'TEMP'}\\subinaclerror.log " . "/playfile $ENV{'TEMP'}\\playfile.txt"; &LogText($LogFile,"EXEC: $cmdline"); system $cmdline; }
The playfile is a list of commands that subinacl will execute.
code:
sub BuildSubinaclPlayfile { unless (open(PLAYFILE, ">$ENV{'TEMP'}\\playfile.txt" )) { &LogText($LogFile, "Error opening $ENV{'TEMP'}\\playfile.txt"); exit 1; }
my $options = "\n/noverbose\n"; my $migratelines; my @ObjArray = ( "+subkeyreg HKEY_USERS\*", "+share *", "+printer *" );
my @drives = Win32API::File::getLogicalDrives(); my %Types = ( 0 => 'DRIVE_UNKNOWN', 1 => 'DRIVE_NO_ROOT_DIR', 2 => 'DRIVE_REMOVABLE', 3 => 'DRIVE_FIXED', 4 => 'DRIVE_REMOTE', 5 => 'DRIVE_CDROM', 6 => 'DRIVE_RAMDISK', ); foreach my $drive ( @drives ) { my $DriveType = Win32API::File::GetDriveType($drive); next if($Types{$DriveType} ne 'DRIVE_FIXED'); push(@ObjArray, "+subdirectories $drive\*\.\*"); push(@ObjArray, "+onlyfile $drive"); }
# Build array of lines for /migratetodomain option. # Copy Mapping file to %temp% so that subinacl can access it locally. if (-e "$DataPath\\$MapCFG") { unless (open(MAPCFG, "<$DataPath\\$MapCFG")) { &LogText($LogFile, "Fatal Error: Failed to open $DataPath\\$MapCFG: " . $^E); exit 1; } while (<MAPCFG>) { chomp; my ($MapFile, $OldDomain, $NewDomain) = split /\t/; if (Win32API::File::CopyFile("$DataPath\\$MapFile", "$ENV{'TEMP'}\\$MapFile", 0)) { &LogText($LogFile, "$DataPath\\$MapFile copied to $ENV{'TEMP'}"); } else { &LogText($LogFile, "Error copying $DataPath\\$MapFile " . $^E); } $migratelines .= "/migratetodomain=$OldDomain=$NewDomain=$ENV{'TEMP'}\\$MapFile\n"; } } else { &LogText($LogFile, "Fatal Error: Require file ( $DataPath\\$MapCFG ) could not be found."); exit 1; }
foreach my $obj (@ObjArray) { print PLAYFILE $obj . $options . $migratelines . "\n"; } close PLAYFILE; }
This code replaces the use of DumpACL and directly manipulate the local group memberships. code:
sub ProcessLocalGroups { #--------------------------------------------------------------------------------------------------------- # Perform security migration on local groups utilizing the SidMap hash. # Enumerate local groups. # Get members of each group. # Check to see if the Sid for the member is in the SidMap hash. # If it is, add the NewSid as a member to the group. #--------------------------------------------------------------------------------------------------------- my @Groups; my $Error; if (!Win32::Lanman::NetLocalGroupEnum("", \@Groups)) { $^E = $Error = Win32::Lanman::GetLastError(); &LogText($LogFile, "Error (Lanman::NetLocalGroupEnum(\"\"): $Error :" . $^E); &LogText($LogFile, "Exiting program: ABEND."); exit 1; } foreach my $Group (@Groups) { &LogText($LogFile, "Processing localgroup: ${$Group}{'name'}"); my @members; if(!Win32::Lanman::NetLocalGroupGetMembers("", ${$Group}{'name'}, \@members)) { $^E = $Error = Win32::Lanman::GetLastError(); &LogText($LogFile, "Error (Lanman::NetLocalGroupGetMembers(\"\", ${$Group}{'name'}): $Error :" . $^E ); &LogText($LogFile, "Exiting program: ABEND."); exit 1; } foreach my $member (@members) { my $OldTextSid = Win32::Lanman::SidToString(${$member}{'sid'}); if (exists $SidMap{$OldTextSid}) { my $NewBinarySid = Win32::Lanman::StringToSid($SidMap{$OldTextSid}); if(!Win32::Lanman::NetLocalGroupAddMember("", ${$Group}{'name'}, $NewBinarySid)) { $^E = $Error = Win32::Lanman::GetLastError(); &LogText($LogFile, "Error adding:\t$SidMap{$OldTextSid}\tOldMember: ${$member}{'domainandname'} $Error :" . $^E ); } else { &LogText($LogFile, "Added:\t$SidMap{$OldTextSid}\tOldMember: ${$member}{'domainandname'}"); } } else { #&LogText($LogFile, "Not in SidMap:\t${$Group}{'name'} Member: ${$member}{'domainandname'}\t$OldTextSid"); } } } undef @Groups; }
|
|
Top
|
|
|
|
Moderator: Shawn, ShaneEP, Ruud van Velsen, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Mart
|
0 registered
and 693 anonymous users online.
|
|
|