Example #1
0
static BOOL
OpenUserRegistryPathPerProcessId(DWORD ProcessId,
                                 PHKEY hResult,
                                 REGSAM samDesired)
{
    BOOL bRet = TRUE;
    HANDLE hProcessToken = NULL;
    HANDLE hProcess;
    BYTE Buffer[256];
    DWORD Length = 0;
    UNICODE_STRING SidName;
    PTOKEN_USER TokUser;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
    if (!hProcess)
    {
        DPRINT1("Error: OpenProcess failed(0x%x)\n", GetLastError());
        return FALSE;
    }

    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
    {
        DPRINT1("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
        CloseHandle(hProcess);
        return FALSE;
    }

    if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
    {
        DPRINT1("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
        CloseHandle(hProcessToken);
        CloseHandle(hProcess);
        return FALSE;
    }

    TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
    if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
    {
        DPRINT1("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
        CloseHandle(hProcessToken);
        CloseHandle(hProcess);
        return FALSE;
    }

    /*
     * Might fail for LiveCD... Why ? Because only HKU\.DEFAULT exists.
     */
    bRet = (RegOpenKeyExW(HKEY_USERS,
                          SidName.Buffer,
                          0,
                          samDesired,
                          hResult) == ERROR_SUCCESS);

    RtlFreeUnicodeString(&SidName);

    CloseHandle(hProcessToken);
    CloseHandle(hProcess);

    return bRet;
}
Example #2
0
File: util.c Project: Endt4sk/sebek
// Largely based off of undelete.c from sysinternals
BOOLEAN GetUserSIDFromProcess(EPROCESS *pProcess, UNICODE_STRING *pusSID)
{
	NTSTATUS status;
	ULONG RetLen;
	HANDLE hToken;
	PTOKEN_USER tokenInfoBuffer;
	PACCESS_TOKEN Token;

	Token = PsReferencePrimaryToken(pProcess);

	status = ObOpenObjectByPointer(Token, 0, NULL, TOKEN_QUERY, NULL, KernelMode, &hToken);
	ObDereferenceObject(Token);

	if(!NT_SUCCESS(status))
		return FALSE;

	// Get the size of the sid.
	status = ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &RetLen);
	if(status != STATUS_BUFFER_TOO_SMALL) {
    ZwClose(hToken);
    return FALSE;
  }

	tokenInfoBuffer = (PTOKEN_USER)ExAllocatePoolWithTag(NonPagedPool, RetLen, HELPER_POOL_TAG);
	if(tokenInfoBuffer)
      status = ZwQueryInformationToken(hToken, TokenUser, tokenInfoBuffer, RetLen, &RetLen);
 
  if(!NT_SUCCESS(status) || !tokenInfoBuffer ) {
    DBGOUT(("Error getting token information: %x\n", status));
    if(tokenInfoBuffer)
			ExFreePool(tokenInfoBuffer);
    ZwClose(hToken);
    return FALSE;
  }
  ZwClose(hToken);

  status = RtlConvertSidToUnicodeString(pusSID, tokenInfoBuffer->User.Sid, FALSE);
  ExFreePool(tokenInfoBuffer);

  if(!NT_SUCCESS(status)) {
    DBGOUT(("Unable to convert SID to UNICODE: %x\n", status ));
    return FALSE;
  }

	return TRUE;
}
Example #3
0
/******************************************************************************
 * ConvertSidToStringSidW [ADVAPI32.@]
 */
BOOL WINAPI ConvertSidToStringSidW(PSID sid, LPWSTR* stringSid)
{
    NTSTATUS ret;
    UNICODE_STRING str = { 0, 0, NULL };
    ret = RtlConvertSidToUnicodeString(&str, sid, TRUE);

    if (ret == STATUS_NO_MEMORY)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    /* FIXME: error codes for other ret values,
     * which don't exist in NTDLL yet */

    *stringSid = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, (str.Length+1)*sizeof(WCHAR));
    lstrcpynW(*stringSid, str.Buffer, str.Length + 1);
    RtlFreeUnicodeString(&str);

    return TRUE;
}
Example #4
0
FLT_POSTOP_CALLBACK_STATUS
claimsmanPostOperation(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
/*++

Routine Description:

This routine is the post-operation completion routine for this
miniFilter.

This is non-pageable because it may be called at DPC level.

Arguments:

Data - Pointer to the filter callbackData that is passed to us.

FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.

CompletionContext - The completion context set in the pre-operation routine.

Flags - Denotes whether the completion is successful or is being drained.

Return Value:

The return value is the status of the operation.

--*/
{
	UNREFERENCED_PARAMETER(Data);
	UNREFERENCED_PARAMETER(CompletionContext);
	UNREFERENCED_PARAMETER(Flags);
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
	PUNICODE_STRING fileName = NULL;
	PTOKEN_USER pTokenUser = NULL;
	UNICODE_STRING sidString;
	
	LARGE_INTEGER Timeout;
	Timeout.QuadPart = (LONGLONG)1 * 10 * 1000 * 1000;
	
	// If there is no client registered, bail out immediately!
	// If the event is from kernel, bail out immediately!
	// If the event check for existence of file, bail out immediately!
	if (
		(ClaimsmanData.ClientPort == NULL) || 
		(Data->RequestorMode == KernelMode) ||
		(Data->IoStatus.Information == FILE_DOES_NOT_EXIST) ||
		(Data->IoStatus.Information == FILE_EXISTS)
		) {
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//  We got a log record, if there is a file object, get its name.

	if (FltObjects->FileObject != NULL) {
		status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&nameInfo);
	}
	else {
		//  Can't get a name when there's no file object
		status = STATUS_UNSUCCESSFUL;
	}

	if (NT_SUCCESS(status)) {
		FltParseFileNameInformation(nameInfo);
		fileName = &nameInfo->Name;
		// Produces way too much logging
		//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
		//	("claimsman!claimsmanPostOperation: fileName=%wZ\n", fileName));
	}
	else
	{
		// No point continuing because we obviously did not get a filename anyways
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//The only IRP you can trust for user information is IRP_MJ_CREATE. Things 
	//like write can be in arbitrary thread context, and even if the call works
	//you can get the wrong SID.

	status = SeQueryInformationToken(SeQuerySubjectContextToken(&(Data->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext)), TokenUser, &pTokenUser);
	if (STATUS_SUCCESS == status && RtlValidSid(pTokenUser->User.Sid))
	{
		// Interesting extension?
		if (ClaimsmanCheckExtension(&nameInfo->Extension)) {
			CLAIMSMAN_MESSAGE msg;

			status = RtlConvertSidToUnicodeString(&sidString, pTokenUser->User.Sid, TRUE);

			if (NT_SUCCESS(status)) {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: SID=%wZ\n", &sidString));
			}
			else {
				// No point continuing because we obviously did not get a valid SID
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			if (ClaimsmanCheckUserIgnore(&sidString)) {
				// Ignored user! Bail out!
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				RtlFreeUnicodeString(&sidString);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			LONGLONG size;
			LONGLONG modified;
			getSizeModified(FltObjects->Instance, fileName, &size, &modified);

			InitializeMessage(&msg, &sidString, fileName, FltObjects->FileObject->ReadAccess, FltObjects->FileObject->WriteAccess, FltObjects->FileObject->DeleteAccess, size, modified, Data->IoStatus.Status);

			// Ready, send the message!
			// But only if there's a client connected
			if (ClaimsmanData.ClientPort != NULL) {

				FltSendMessage(ClaimsmanData.Filter,
					&ClaimsmanData.ClientPort,
					&msg,
					sizeof(msg),
					NULL,
					0,
					&Timeout
					);
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: sent message=%d\n", status));
			}
			else {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: no client connected!"));
			}
			RtlFreeUnicodeString(&sidString);
		}
	}

	FltReleaseFileNameInformation(nameInfo);
	if (pTokenUser != NULL) {
		ExFreePool(pTokenUser);
	}
	return FLT_POSTOP_FINISHED_PROCESSING;
}
Example #5
0
DWORD
WINAPI
PlayLogonSoundThread(
    IN LPVOID lpParameter)
{
    BYTE TokenUserBuffer[256];
    PTOKEN_USER pTokenUser = (TOKEN_USER*)TokenUserBuffer;
    ULONG Length;
    HKEY hKey;
    WCHAR wszBuffer[MAX_PATH] = {0};
    WCHAR wszDest[MAX_PATH];
    DWORD dwSize = sizeof(wszBuffer), dwType;
    SERVICE_STATUS_PROCESS Info;
    UNICODE_STRING SidString;
    NTSTATUS Status;
    ULONG Index = 0;
    SC_HANDLE hSCManager, hService;

    //
    // FIXME: Isn't it possible to *JUST* impersonate the current user
    // *AND* open its HKCU??
    //

    /* Get SID of current user */
    Status = NtQueryInformationToken((HANDLE)lpParameter,
                                     TokenUser,
                                     TokenUserBuffer,
                                     sizeof(TokenUserBuffer),
                                     &Length);
    if (!NT_SUCCESS(Status))
    {
        ERR("NtQueryInformationToken failed: %x!\n", Status);
        return 0;
    }

    /* Convert SID to string */
    RtlInitEmptyUnicodeString(&SidString, wszBuffer, sizeof(wszBuffer));
    Status = RtlConvertSidToUnicodeString(&SidString, pTokenUser->User.Sid, FALSE);
    if (!NT_SUCCESS(Status))
    {
        ERR("RtlConvertSidToUnicodeString failed: %x!\n", Status);
        return 0;
    }

    /* Build path to logon sound registry key.
       Note: We can't use HKCU here, because Winlogon is owned by SYSTEM user */
    if (FAILED(StringCbCopyW(wszBuffer + SidString.Length/sizeof(WCHAR),
                             sizeof(wszBuffer) - SidString.Length,
                             L"\\AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current")))
    {
        /* SID is too long. Should not happen. */
        ERR("StringCbCopyW failed!\n");
        return 0;
    }

    /* Open registry key and query sound path */
    if (RegOpenKeyExW(HKEY_USERS, wszBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    {
        ERR("RegOpenKeyExW(%ls) failed!\n", wszBuffer);
        return 0;
    }

    if (RegQueryValueExW(hKey, NULL, NULL, &dwType,
                      (LPBYTE)wszBuffer, &dwSize) != ERROR_SUCCESS ||
        (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
    {
        ERR("RegQueryValueExW failed!\n");
        RegCloseKey(hKey);
        return 0;
    }

    RegCloseKey(hKey);

    if (!wszBuffer[0])
    {
        /* No sound has been set */
        ERR("No sound has been set\n");
        return 0;
    }

    /* Expand environment variables */
    if (!ExpandEnvironmentStringsW(wszBuffer, wszDest, MAX_PATH))
    {
        ERR("ExpandEnvironmentStringsW failed!\n");
        return 0;
    }

    /* Open the service manager */
    hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (!hSCManager)
    {
        ERR("OpenSCManager failed (%x)\n", GetLastError());
        return 0;
    }

    /* Open the wdmaud service */
    hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
    if (!hService)
    {
        /* The service is not installed */
        TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
        CloseServiceHandle(hSCManager);
        return 0;
    }

    /* Wait for wdmaud to start */
    do
    {
        if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
        {
            TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError());
            break;
        }

        if (Info.dwCurrentState == SERVICE_RUNNING)
            break;

        Sleep(1000);

    } while (Index++ < 20);

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);

    /* If wdmaud is not running exit */
    if (Info.dwCurrentState != SERVICE_RUNNING)
    {
        WARN("wdmaud has not started!\n");
        return 0;
    }

    /* Sound subsystem is running. Play logon sound. */
    TRACE("Playing logon sound: %ls\n", wszDest);
    PlaySoundRoutine(wszDest, TRUE, SND_FILENAME);
    return 0;
}
Example #6
0
File: misc.c Project: GYGit/reactos
BOOL
GetUserSidStringFromToken(HANDLE hToken,
                          PUNICODE_STRING SidString)
{
    PTOKEN_USER UserBuffer, nsb;
    ULONG Length;
    NTSTATUS Status;

    Length = 256;
    UserBuffer = LocalAlloc(LPTR, Length);
    if (UserBuffer == NULL)
        return FALSE;

    Status = NtQueryInformationToken(hToken,
                                     TokenUser,
                                     (PVOID)UserBuffer,
                                     Length,
                                     &Length);
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        nsb = LocalReAlloc(UserBuffer,
                           Length,
                           LMEM_MOVEABLE);
        if (nsb == NULL)
        {
            LocalFree(UserBuffer);
            return FALSE;
        }

        UserBuffer = nsb;
        Status = NtQueryInformationToken(hToken,
                                         TokenUser,
                                         (PVOID)UserBuffer,
                                         Length,
                                         &Length);
    }

    if (!NT_SUCCESS (Status))
    {
        LocalFree(UserBuffer);
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    DPRINT("SidLength: %lu\n", RtlLengthSid (UserBuffer->User.Sid));

    Status = RtlConvertSidToUnicodeString(SidString,
                                          UserBuffer->User.Sid,
                                          TRUE);

    LocalFree(UserBuffer);

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    DPRINT("SidString.Length: %lu\n", SidString->Length);
    DPRINT("SidString.MaximumLength: %lu\n", SidString->MaximumLength);
    DPRINT("SidString: '%wZ'\n", SidString);

    return TRUE;
}
Example #7
0
/* Move a file handle to recycle bin
 * The pathname must be a valid NT file name generated using filename_to_nt_pathname()
 */
static NTSTATUS move_to_recycle_bin(HANDLE handle, WCHAR *pathname)
{
	IO_STATUS_BLOCK status_block;
	NTSTATUS status;

	/* TODO: Handle the case when recycle bin does not exist (according to cygwin) */
	/* TODO: Handle when the file is inside recycle bin */
	WCHAR recyclepath[512];
	UNICODE_STRING recycle;
	RtlInitEmptyUnicodeString(&recycle, recyclepath, sizeof(recyclepath));
	/* Root directory, should look like "\??\C:\", 7 characters */
	UNICODE_STRING root;
	RtlInitCountedUnicodeString(&root, pathname, sizeof(WCHAR) * 7);
	RtlAppendUnicodeStringToString(&recycle, &root);
	RtlAppendUnicodeToString(&recycle, L"$Recycle.Bin\\");

	WCHAR renamepath[512];
	UNICODE_STRING rename;
	RtlInitEmptyUnicodeString(&rename, renamepath, sizeof(renamepath));
	RtlAppendUnicodeStringToString(&rename, &recycle);
	/* Append user sid */
	{
		WCHAR buf[256];
		UNICODE_STRING sid;
		RtlInitEmptyUnicodeString(&sid, buf, sizeof(buf));
		RtlConvertSidToUnicodeString(&sid, get_user_sid(), FALSE);
		RtlAppendUnicodeStringToString(&rename, &sid);
		RtlAppendUnicodeToString(&rename, L"\\");
	}
	/* Generate an unique file name by append file id and a hash of the pathname,
	 * To allow unlinking multiple hard links of the same file
	 */
	RtlAppendUnicodeToString(&rename, L".flinux");
	/* Append file id */
	{
		FILE_INTERNAL_INFORMATION info;
		status = NtQueryInformationFile(handle, &status_block, &info, sizeof(info), FileInternalInformation);
		if (!NT_SUCCESS(status))
		{
			log_error("NtQueryInformationFile(FileInternalInformation) failed, status: %x", status);
			return status;
		}
		RtlAppendInt64ToString(info.IndexNumber.QuadPart, 16, &rename);
		RtlAppendUnicodeToString(&rename, L"_");
	}
	/* Append file path hash */
	{
		UNICODE_STRING path;
		RtlInitUnicodeString(&path, pathname);
		ULONG hash;
		RtlHashUnicodeString(&path, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &hash);
		RtlAppendIntegerToString(hash, 16, &rename);
	}
	/* Rename file */
	char buf[512];
	FILE_RENAME_INFORMATION *info = (FILE_RENAME_INFORMATION *)buf;
	info->ReplaceIfExists = FALSE;
	info->RootDirectory = NULL;
	info->FileNameLength = rename.Length;
	memcpy(info->FileName, rename.Buffer, rename.Length);
	status = NtSetInformationFile(handle, &status_block, info, sizeof(*info) + info->FileNameLength, FileRenameInformation);
	if (!NT_SUCCESS(status))
	{
		log_error("NtSetInformationFile(FileRenameInformation) failed, status: %x", status);
		return status;
	}
	return STATUS_SUCCESS;
}
Example #8
0
int
wmain(int argc, LPWSTR *argv)
{
  SetOemPrintFLineLength(GetStdHandle(STD_ERROR_HANDLE));

  DWORD (WINAPI *pConvertStringSidToSid)(LPCWSTR, PSID*) =
    (DWORD (WINAPI *)(LPCWSTR, PSID*))
    GetProcAddress(GetModuleHandleA("advapi32.dll"), "ConvertStringSidToSidW");

  if (argc < 2)
    {
      if (pConvertStringSidToSid != NULL)
	fputs("Utility to display basic account information about a user account given a user\r\n"
	      "name or SID.\r\n"
	      "\n"
	      "Syntax:\r\n"
	      "lookupacc [computer] S-n-n-n\r\n"
	      "lookupacc [computer] [domain\\]username\r\n"
	      "lookupacc [computer] username[@fqdn]\r\n", stderr);
      else
	fputs("Utility to display basic account information about a user account given a user\r\n"
	      "name.\r\n"
	      "\n"
	      "Syntax:\r\n"
	      "lookupacc [computer] [domain\\]username\r\n", stderr);
      return 1;
    }

  if (argc > 3)
    {
      fputs("Too many parameters.\r\n", stderr);
      return 1;
    }

  LPWSTR computername = NULL;
  if (argc > 2)
    {
      computername = argv[1];
      argc--;
      argv++;
    }

  SID_NAME_USE SIDnameuse;
  WCHAR userdomain[260] = L"";
  DWORD userdomainsiz = sizeof userdomain;
  WCHAR username[260] = L"";
  DWORD usernamesiz = sizeof username;
  BYTE userSID[260] = { 0 };
  DWORD userSIDsiz = sizeof userSID;
  LPWSTR wczUsername = L"(unknown)";
  PSID sidLookup = NULL;
  UNICODE_STRING StringSID = { 0 };
  BOOL bConversionResult = FALSE;

  if (pConvertStringSidToSid == NULL)
    bConversionResult = FALSE;
  else
    bConversionResult = pConvertStringSidToSid(argv[1], &sidLookup);

  if (bConversionResult)
    {
      if (!LookupAccountSid(computername, sidLookup, username, &usernamesiz,
			    userdomain, &userdomainsiz, &SIDnameuse))
	{
	  win_perror();
	  return 1;
	}

      RtlInitUnicodeString(&StringSID, argv[1]);
      wczUsername = username;
    }
  else
    {
      if (!LookupAccountName(computername, argv[1], &userSID, &userSIDsiz,
			     userdomain, &userdomainsiz, &SIDnameuse))
	{
	  win_perror();
	  return 1;
	}

      RtlConvertSidToUnicodeString(&StringSID, &userSID, TRUE);
      wczUsername = argv[1];
    }

  LPSTR czSIDnameuse;
  switch (SIDnameuse)
    {
    case SidTypeUser:
      czSIDnameuse = "User";
      break;
    case SidTypeGroup:
      czSIDnameuse = "Group";
      break;
    case SidTypeDomain:
      czSIDnameuse = "Domain";
      break;
    case SidTypeAlias:
      czSIDnameuse = "Alias";
      break;
    case SidTypeWellKnownGroup:
      czSIDnameuse = "Well known group";
      break;
    case SidTypeDeletedAccount:
      czSIDnameuse = "Deleted account";
      break;
    case SidTypeInvalid:
      czSIDnameuse = "Invalid";
      break;
    case SidTypeUnknown:
      czSIDnameuse = "Unknown";
      break;
    case SidTypeComputer:
      czSIDnameuse = "Computer";
      break;
    default:
      czSIDnameuse = "Not known";
      break;
    }

  oem_printf(stdout,
	     "Account type: %1%%n"
	     "User domain: %2!ws!%%n"
	     "User name: %3!ws!%%n"
	     "SID: %4!.*ws!%%n",
	     czSIDnameuse,
	     userdomain,
	     wczUsername,
	     StringSID.Length, StringSID.Buffer);

  return 0;
}