291 lines
4.8 KiB
C
291 lines
4.8 KiB
C
|
/*++
|
||
|
|
||
|
Microsoft Confidential
|
||
|
Copyright (c) 1992-1997 Microsoft Corporation
|
||
|
All rights reserved
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
sid.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
SID management functions
|
||
|
|
||
|
Author:
|
||
|
|
||
|
(davidc) 26-Aug-1992
|
||
|
|
||
|
--*/
|
||
|
// NT base apis
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <ntdddisk.h>
|
||
|
|
||
|
#include "sysdm.h"
|
||
|
|
||
|
|
||
|
LPTSTR
|
||
|
GetSidString(
|
||
|
void
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Allocates and returns a string representing the sid of the current user
|
||
|
The returned pointer should be freed using DeleteSidString().
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Returns a pointer to the string or NULL on failure.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS NtStatus;
|
||
|
PSID UserSid;
|
||
|
UNICODE_STRING UnicodeString;
|
||
|
LPTSTR lpEnd;
|
||
|
#ifndef UNICODE
|
||
|
STRING String;
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Get the user sid
|
||
|
//
|
||
|
|
||
|
UserSid = GetUserSid();
|
||
|
if (UserSid == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert user SID to a string.
|
||
|
//
|
||
|
|
||
|
NtStatus = RtlConvertSidToUnicodeString(
|
||
|
&UnicodeString,
|
||
|
UserSid,
|
||
|
(BOOLEAN)TRUE // Allocate
|
||
|
);
|
||
|
//
|
||
|
// We're finished with the user sid
|
||
|
//
|
||
|
|
||
|
DeleteUserSid(UserSid);
|
||
|
|
||
|
//
|
||
|
// See if the conversion to a string worked
|
||
|
//
|
||
|
|
||
|
if (!NT_SUCCESS(NtStatus)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
|
||
|
|
||
|
return(UnicodeString.Buffer);
|
||
|
|
||
|
#else
|
||
|
|
||
|
//
|
||
|
// Convert the string to ansi
|
||
|
//
|
||
|
|
||
|
NtStatus = RtlUnicodeStringToAnsiString(&String, &UnicodeString, TRUE);
|
||
|
RtlFreeUnicodeString(&UnicodeString);
|
||
|
if (!NT_SUCCESS(NtStatus)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
return(String.Buffer);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
DeleteSidString(
|
||
|
IN LPTSTR SidString
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Frees up a sid string previously returned by GetSidString()
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SidString -
|
||
|
Supplies string to free
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
UNICODE_STRING String;
|
||
|
|
||
|
RtlInitUnicodeString(&String, SidString);
|
||
|
|
||
|
RtlFreeUnicodeString(&String);
|
||
|
#else
|
||
|
ANSI_STRING String;
|
||
|
|
||
|
RtlInitAnsiString(&String, SidString);
|
||
|
|
||
|
RtlFreeAnsiString(&String);
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
PSID
|
||
|
GetUserSid(
|
||
|
void
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Allocs space for the user sid, fills it in and returns a pointer. Caller
|
||
|
The sid should be freed by calling DeleteUserSid.
|
||
|
|
||
|
Note the sid returned is the user's real sid, not the per-logon sid.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Returns pointer to sid or NULL on failure.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PTOKEN_USER pUser, pTemp;
|
||
|
PSID pSid;
|
||
|
DWORD BytesRequired = 200;
|
||
|
NTSTATUS status;
|
||
|
HANDLE UserToken;
|
||
|
|
||
|
|
||
|
if (!OpenProcessToken (GetCurrentProcess(), TOKEN_READ, &UserToken)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate space for the user info
|
||
|
//
|
||
|
|
||
|
pUser = (PTOKEN_USER)LocalAlloc(LMEM_FIXED, BytesRequired);
|
||
|
|
||
|
|
||
|
if (pUser == NULL) {
|
||
|
CloseHandle (UserToken);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Read in the UserInfo
|
||
|
//
|
||
|
|
||
|
status = NtQueryInformationToken(
|
||
|
UserToken, // Handle
|
||
|
TokenUser, // TokenInformationClass
|
||
|
pUser, // TokenInformation
|
||
|
BytesRequired, // TokenInformationLength
|
||
|
&BytesRequired // ReturnLength
|
||
|
);
|
||
|
|
||
|
if (status == STATUS_BUFFER_TOO_SMALL) {
|
||
|
|
||
|
//
|
||
|
// Allocate a bigger buffer and try again.
|
||
|
//
|
||
|
|
||
|
pTemp = pUser;
|
||
|
pUser = (PTOKEN_USER)LocalReAlloc(pUser, BytesRequired, LMEM_MOVEABLE);
|
||
|
if (pUser == NULL) {
|
||
|
LocalFree((HLOCAL) pTemp);
|
||
|
CloseHandle (UserToken);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
status = NtQueryInformationToken(
|
||
|
UserToken, // Handle
|
||
|
TokenUser, // TokenInformationClass
|
||
|
pUser, // TokenInformation
|
||
|
BytesRequired, // TokenInformationLength
|
||
|
&BytesRequired // ReturnLength
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
LocalFree(pUser);
|
||
|
CloseHandle (UserToken);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
BytesRequired = RtlLengthSid(pUser->User.Sid);
|
||
|
pSid = LocalAlloc(LMEM_FIXED, BytesRequired);
|
||
|
if (pSid == NULL) {
|
||
|
LocalFree(pUser);
|
||
|
CloseHandle (UserToken);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid);
|
||
|
|
||
|
LocalFree(pUser);
|
||
|
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
LocalFree(pSid);
|
||
|
pSid = NULL;
|
||
|
}
|
||
|
|
||
|
CloseHandle (UserToken);
|
||
|
|
||
|
return pSid;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
DeleteUserSid(
|
||
|
IN PSID Sid
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Deletes a user sid previously returned by GetUserSid()
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Sid -
|
||
|
Supplies sid to delete
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
LocalFree(Sid);
|
||
|
}
|