Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

367 lines
8.3 KiB

#include "pch.h"
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
VOID
pFixSomeSidReferences (
PSID ExistingSid,
PSID NewSid
);
VOID
PrintMessage (
IN UINT MsgId,
IN PCTSTR *ArgArray
)
{
DWORD rc;
PTSTR MsgBuf;
rc = FormatMessageW (
FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_ARGUMENT_ARRAY|
FORMAT_MESSAGE_FROM_HMODULE,
(LPVOID) GetModuleHandle(NULL),
(DWORD) MsgId,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPVOID) &MsgBuf,
0,
(va_list *) ArgArray
);
if (rc) {
_tprintf (TEXT("%s"), MsgBuf);
LocalFree (MsgBuf);
}
}
PTSTR
GetErrorText (
IN UINT Error
)
{
DWORD rc;
PTSTR MsgBuf;
if (Error == ERROR_NONE_MAPPED) {
Error = ERROR_NO_SUCH_USER;
} else if (Error & 0xF0000000) {
Error = RtlNtStatusToDosError (Error);
}
rc = FormatMessageW (
FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_ARGUMENT_ARRAY|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
(DWORD) Error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPVOID) &MsgBuf,
0,
NULL
);
if (!rc) {
MsgBuf = NULL;
}
return MsgBuf;
}
VOID
HelpAndExit (
VOID
)
{
//
// This routine is called whenever command line args are wrong
//
PrintMessage (MSG_HELP, NULL);
exit (1);
}
PSID
GetSidFromName (
IN PCTSTR RemoteTo,
IN PCTSTR Name
)
{
DWORD cbSid = 0;
PSID pSid = NULL;
DWORD cchDomain = 0;
PWSTR szDomain;
SID_NAME_USE SidUse;
BOOL bRet = FALSE;
bRet = LookupAccountName( RemoteTo,
Name,
NULL,
&cbSid,
NULL,
&cchDomain,
&SidUse );
if (!bRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
pSid = (PSID) LocalAlloc(LPTR, cbSid);
if (!pSid) {
return NULL;
}
szDomain = (PWSTR) LocalAlloc(LPTR, cchDomain * sizeof(WCHAR));
if (!szDomain) {
LocalFree(pSid);
return NULL;
}
bRet = LookupAccountName( RemoteTo,
Name,
pSid,
&cbSid,
szDomain,
&cchDomain,
&SidUse );
LocalFree(szDomain);
if (!bRet) {
LocalFree(pSid);
pSid = NULL;
}
}
return pSid;
}
PCTSTR
pSkipUnc (
PCTSTR Path
)
{
if (Path[0] == TEXT('\\') && Path[1] == TEXT('\\')) {
return Path + 2;
}
return Path;
}
INT
__cdecl
_tmain (
INT argc,
PCTSTR argv[]
)
{
INT i;
DWORD Size;
PCTSTR User1 = NULL;
PCTSTR User2 = NULL;
TCHAR FixedUser1[MAX_PATH];
TCHAR FixedUser2[MAX_PATH];
TCHAR Computer[MAX_COMPUTERNAME_LENGTH + 1];
BOOL Overwrite = FALSE;
INT c;
BOOL b;
PCTSTR RemoteTo = NULL;
NTSTATUS Status;
BYTE WasEnabled;
DWORD Error = ERROR_SUCCESS;
PCTSTR ArgArray[3];
PTSTR pErrText;
TCHAR RemoteToBuf[MAX_PATH];
BOOL NoDecoration = FALSE;
BOOL ReAdjust = FALSE;
BOOL KeepLocalUser = FALSE;
DWORD Flags;
HRESULT hr;
for (i = 1 ; i < argc ; i++) {
if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
c = _tcsnextc (argv[i] + 1);
switch (_totlower ((wint_t) c)) {
case TEXT('y'):
if (Overwrite) {
HelpAndExit();
}
Overwrite = TRUE;
break;
case TEXT('d'):
if (NoDecoration) {
HelpAndExit();
}
NoDecoration = TRUE;
break;
case TEXT('k'):
if (KeepLocalUser) {
HelpAndExit();
}
KeepLocalUser = TRUE;
break;
case TEXT('c'):
if (RemoteTo) {
HelpAndExit();
}
if (argv[i][2] == TEXT(':')) {
RemoteTo = &argv[i][3];
} else {
HelpAndExit();
}
if (pSkipUnc (RemoteTo) == RemoteTo) {
RemoteToBuf[0] = TEXT('\\');
RemoteToBuf[1] = TEXT('\\');
hr = StringCchCopy(RemoteToBuf + 2, ARRAYSIZE(RemoteToBuf) - 2, RemoteTo);
if (FAILED(hr)) {
HelpAndExit();
}
RemoteTo = RemoteToBuf;
}
if (!(*RemoteTo)) {
HelpAndExit();
}
break;
default:
HelpAndExit();
}
} else {
if (!User1) {
User1 = argv[i];
if (!(*User1)) {
HelpAndExit();
}
} else if (!User2) {
User2 = argv[i];
if (!(*User2)) {
HelpAndExit();
}
} else {
HelpAndExit();
}
}
}
if (!User2) {
HelpAndExit();
}
Size = ARRAYSIZE(Computer);
if (!GetComputerName (Computer, &Size)) {
Error = GetLastError();
goto Exit;
}
if (NoDecoration || _tcschr (User1, TEXT('\\'))) {
hr = StringCchCopy(FixedUser1, ARRAYSIZE(FixedUser1), User1);
if (FAILED(hr)) {
Error = HRESULT_CODE(hr);
goto Exit;
}
} else {
hr = StringCchPrintf(FixedUser1, ARRAYSIZE(FixedUser1), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User1);
if (FAILED(hr)) {
Error = HRESULT_CODE(hr);
goto Exit;
}
}
if (NoDecoration || _tcschr (User2, TEXT('\\'))) {
hr = StringCchCopy(FixedUser2, ARRAYSIZE(FixedUser2), User2);
if (FAILED(hr)) {
Error = HRESULT_CODE(hr);
goto Exit;
}
} else {
hr = StringCchPrintf(FixedUser2, ARRAYSIZE(FixedUser2), TEXT("%s\\%s"), RemoteTo ? pSkipUnc(RemoteTo) : Computer, User2);
if (FAILED(hr)) {
Error = HRESULT_CODE(hr);
goto Exit;
}
}
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasEnabled);
if (Status == STATUS_SUCCESS) {
ReAdjust = TRUE;
}
ArgArray[0] = FixedUser1;
ArgArray[1] = FixedUser2;
ArgArray[2] = RemoteTo;
if (!RemoteTo) {
PrintMessage (MSG_MOVING_PROFILE_LOCAL, ArgArray);
} else {
PrintMessage (MSG_MOVING_PROFILE_REMOTE, ArgArray);
}
Flags = 0;
if (KeepLocalUser) {
Flags |= REMAP_PROFILE_KEEPLOCALACCOUNT;
}
if (!Overwrite) {
Flags |= REMAP_PROFILE_NOOVERWRITE;
}
b = RemapAndMoveUser (
RemoteTo,
Flags,
FixedUser1,
FixedUser2
);
if (b) {
PrintMessage (MSG_SUCCESS, NULL);
} else {
Error = GetLastError();
}
if (ReAdjust) {
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
}
Exit:
if (Error != ERROR_SUCCESS) {
ArgArray[0] = (PTSTR) IntToPtr (Error);
ArgArray[1] = pErrText = GetErrorText (Error);
if (Error < 10000) {
PrintMessage (MSG_DECIMAL_ERROR, ArgArray);
} else {
PrintMessage (MSG_HEXADECIMAL_ERROR, ArgArray);
}
if (pErrText) {
LocalFree(pErrText);
}
}
return 0;
}