/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
*/
/*
* Copyright Likewise Software. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the license, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy
* of the GNU Lesser General Public License along with this program. If
* not, see .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
/*
* Copyright (C) Likewise Software. All rights reserved.
*
* Module Name:
*
* lwmapsecurity.c
*
* Abstract:
*
* Likewise Map Security - Access Token Create Information
*
* Authors: Danilo Almeida (dalmeida@likewise.com)
*/
#include
#include
#include
#include
#include
#include
#include "config.h"
#include
#include
#ifdef HAVE_DLFCN_H
#include
#endif
#define ENABLE_LOGGING 0
#if ENABLE_LOGGING
#include
#endif
#define SAFE_LOG_STRING(String) \
( (String) ? (String) : "" )
#if ENABLE_LOGGING
#define LOG_ERROR(Format, ...) \
fprintf(stderr, Format, ## __VA_ARGS__)
#else
#define LOG_ERROR(Format, ...)
#endif
#define ASSERT(Expression) \
do { \
if (!(Expression)) \
{ \
LOG_ERROR("ASSERTION FAILED: " # Expression); \
abort(); \
} \
} while (0)
#define LOCK_MUTEX(pMutex, bInLock) \
do { \
int _unixError = pthread_mutex_lock(pMutex); \
if (_unixError) \
{ \
LOG_ERROR("ABORTING: Failed to lock mutex (error = %d).", _unixError); \
abort(); \
} \
bInLock = TRUE; \
} while (0)
#define UNLOCK_MUTEX(pMutex, bInLock) \
do { \
if (bInLock) \
{ \
int _unixError = pthread_mutex_unlock(pMutex); \
if (_unixError) \
{ \
LOG_ERROR("ABORTING: Failed to unlock mutex (error = %d).", _unixError); \
abort(); \
} \
bInLock = FALSE; \
} \
} while (0)
#define LW_MAP_SECURITY_PLUGIN_PATH LIBDIR "/liblwmapsecurity_lsass" MOD_EXT
//
// Unmapped Unix User and Group SIDs
//
// S-1-22-1-UID for users
// S-1-22-2-GID for groups
//
#define SECURITY_UNMAPPED_UNIX_AUTHORITY { 0, 0, 0, 0, 0, 22 }
#define SECURITY_UNMAPPED_UNIX_UID_RID 1
#define SECURITY_UNMAPPED_UNIX_GID_RID 2
#define SECURITY_UNMAPPED_UNIX_RID_COUNT 2
#define SECURITY_UNMAPPED_UNIX_UID_PREFIX "S-1-22-1-"
#define SECURITY_UNMAPPED_UNIX_GID_PREFIX "S-1-22-2-"
//
// Structures
//
typedef struct _LW_MAP_SECURITY_CONTEXT {
PSTR LibraryPath;
PVOID LibraryHandle;
PLW_MAP_SECURITY_PLUGIN_CONTEXT PluginContext;
PLW_MAP_SECURITY_PLUGIN_INTERFACE PluginInterface;
} LW_MAP_SECURITY_CONTEXT;
typedef struct _LW_MAP_SECURITY_STATE {
pthread_mutex_t Mutex;
LONG InitCount;
LONG RefCount;
PLW_MAP_SECURITY_CONTEXT Context;
LWMSP_CREATE_CONTEXT_CALLBACK pCreateContextCallback;
} LW_MAP_SECURITY_STATE, *PLW_MAP_SECURITY_STATE;
//
// Global State
//
LW_MAP_SECURITY_STATE gLwMapSecurityState = {
.Mutex = PTHREAD_MUTEX_INITIALIZER,
.pCreateContextCallback = NULL
};
//
// Prototypes
//
static
NTSTATUS
LwMapSecurityCreateContextInternal(
OUT PLW_MAP_SECURITY_CONTEXT* Context,
IN LWMSP_CREATE_CONTEXT_CALLBACK pCreateContextCallback
);
static
VOID
LwMapSecurityFreeContextInternal(
IN OUT PLW_MAP_SECURITY_CONTEXT* Context
);
//
// Plugin Functions
//
NTSTATUS
LwMapSecurityInitializeSidFromUnmappedId(
IN ULONG SidSize,
OUT PSID Sid,
IN BOOLEAN IsUser,
IN ULONG Id
)
{
NTSTATUS status = STATUS_SUCCESS;
SID_IDENTIFIER_AUTHORITY identifierAuthority = { SECURITY_UNMAPPED_UNIX_AUTHORITY };
if (SidSize < RtlLengthRequiredSid(SECURITY_UNMAPPED_UNIX_RID_COUNT))
{
status = STATUS_BUFFER_TOO_SMALL;
GOTO_CLEANUP();
}
status = RtlInitializeSid(
Sid,
&identifierAuthority,
SECURITY_UNMAPPED_UNIX_RID_COUNT);
GOTO_CLEANUP_ON_STATUS(status);
if (IsUser)
{
Sid->SubAuthority[0] = SECURITY_UNMAPPED_UNIX_UID_RID;
}
else
{
Sid->SubAuthority[0] = SECURITY_UNMAPPED_UNIX_GID_RID;
}
Sid->SubAuthority[1] = Id;
cleanup:
return status;
}
//
// API Functions
//
NTSTATUS
LwMapSecurityInitialize(
VOID
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN bInLock = FALSE;
LOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
gLwMapSecurityState.InitCount++;
ASSERT(gLwMapSecurityState.InitCount >= 1);
if (!gLwMapSecurityState.Context)
{
// Ignore failure
status = LwMapSecurityCreateContextInternal(
&gLwMapSecurityState.Context,
gLwMapSecurityState.pCreateContextCallback);
status = STATUS_SUCCESS;
}
UNLOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
return status;
}
VOID
LwMapSecurityCleanup(
VOID
)
{
BOOLEAN bInLock = FALSE;
LOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
gLwMapSecurityState.InitCount--;
ASSERT(gLwMapSecurityState.InitCount >= 0);
if (0 == gLwMapSecurityState.InitCount)
{
if (0 == gLwMapSecurityState.RefCount)
{
LwMapSecurityFreeContextInternal(&gLwMapSecurityState.Context);
}
else
{
LOG_ERROR("lwmapsecurity refcount != 0 (%d) - probably resource leak",
gLwMapSecurityState.RefCount);
}
}
UNLOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
}
NTSTATUS
LwMapSecurityCreateContext(
OUT PLW_MAP_SECURITY_CONTEXT* Context
)
{
NTSTATUS status = STATUS_SUCCESS;
int EE = 0;
PLW_MAP_SECURITY_CONTEXT pContext = NULL;
BOOLEAN bInLock = FALSE;
LOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
if (!gLwMapSecurityState.Context)
{
status = LwMapSecurityCreateContextInternal(
&gLwMapSecurityState.Context,
gLwMapSecurityState.pCreateContextCallback);
GOTO_CLEANUP_ON_STATUS_EE(status, EE);
}
pContext = gLwMapSecurityState.Context;
gLwMapSecurityState.RefCount++;
ASSERT(gLwMapSecurityState.RefCount >= 1);
cleanup:
UNLOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
*Context = pContext;
return status;
}
VOID
LwMapSecurityFreeContext(
IN OUT PLW_MAP_SECURITY_CONTEXT* Context
)
{
PLW_MAP_SECURITY_CONTEXT context = *Context;
// We must be coming into this block with the MapSecurityState
// mutex locked
if (context)
{
if (context != gLwMapSecurityState.Context)
{
LwMapSecurityFreeContextInternal(&context);
goto cleanup;
}
// This is our global Context
gLwMapSecurityState.RefCount--;
if (gLwMapSecurityState.RefCount < 0)
{
// Logic error. Bail out. May leak memory.
goto cleanup;
}
if ((0 == gLwMapSecurityState.RefCount) &&
(0 == gLwMapSecurityState.InitCount))
{
LwMapSecurityFreeContextInternal(&gLwMapSecurityState.Context);
}
}
cleanup:
*Context = NULL;
return;
}
VOID
LwMapSecurityUseInternalPlugin(
IN LWMSP_CREATE_CONTEXT_CALLBACK pCreateContextCallback
)
{
BOOLEAN bInLock = FALSE;
LOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
gLwMapSecurityState.pCreateContextCallback = pCreateContextCallback;
UNLOCK_MUTEX(&gLwMapSecurityState.Mutex, bInLock);
}
static
NTSTATUS
LwMapSecurityCreateContextInternal(
OUT PLW_MAP_SECURITY_CONTEXT* Context,
IN LWMSP_CREATE_CONTEXT_CALLBACK pCallback
)
{
NTSTATUS status = 0;
int EE = 0;
PCSTR pszError = NULL;
PLW_MAP_SECURITY_CONTEXT pContext = NULL;
LWMSP_CREATE_CONTEXT_CALLBACK pCreateContextCallback = NULL;
status = RTL_ALLOCATE(&pContext, LW_MAP_SECURITY_CONTEXT, sizeof(*pContext));
GOTO_CLEANUP_ON_STATUS_EE(status, EE);
if (!pCallback)
{
status = RtlCStringDuplicate(&pContext->LibraryPath, LW_MAP_SECURITY_PLUGIN_PATH);
GOTO_CLEANUP_ON_STATUS_EE(status, EE);
dlerror();
pContext->LibraryHandle = dlopen(pContext->LibraryPath, RTLD_NOW | RTLD_GLOBAL);
if (!pContext->LibraryHandle)
{
#if ENABLE_LOGGING
int error = errno;
#endif
pszError = dlerror();
LOG_ERROR("Failed to load %s (%s (%d))", pContext->LibraryPath,
SAFE_LOG_STRING(pszError), error);
status = STATUS_UNSUCCESSFUL;
GOTO_CLEANUP_EE(EE);
}
dlerror();
pCreateContextCallback = (LWMSP_CREATE_CONTEXT_CALLBACK)
dlsym(pContext->LibraryHandle,
LWMSP_CREATE_CONTEXT_FUNCTION_NAME);
if (!pCreateContextCallback)
{
pszError = dlerror();
LOG_ERROR("Failed to load " LWMSP_CREATE_CONTEXT_FUNCTION_NAME
" function from %s (%s)",
pContext->LibraryPath, SAFE_LOG_STRING(pszError));
status = STATUS_UNSUCCESSFUL;
GOTO_CLEANUP_EE(EE);
}
}
else
{
pCreateContextCallback = pCallback;
if (!pCreateContextCallback)
{
LOG_ERROR("Couldn't find any context create callback function.");
status = STATUS_UNSUCCESSFUL;
GOTO_CLEANUP_EE(EE);
}
}
status = pCreateContextCallback(&pContext->PluginContext,
&pContext->PluginInterface);
GOTO_CLEANUP_ON_STATUS_EE(status, EE);
cleanup:
if (!NT_SUCCESS(status))
{
LwMapSecurityFreeContext(&pContext);
}
*Context = pContext;
return status;
}
static
VOID
LwMapSecurityFreeContextInternal(
IN OUT PLW_MAP_SECURITY_CONTEXT* Context
)
{
PLW_MAP_SECURITY_CONTEXT context = *Context;
if (context)
{
if (context->PluginContext)
{
context->PluginInterface->FreeContext(&context->PluginContext);
}
if (context->LibraryHandle)
{
int err = dlclose(context->LibraryHandle);
if (err)
{
LOG_ERROR("Failed to dlclose() %s", context->LibraryPath);
}
}
RtlCStringFree(&context->LibraryPath);
RtlMemoryFree(context);
*Context = NULL;
}
}
NTSTATUS
LwMapSecurityGetIdFromSid(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PBOOLEAN IsUser,
OUT PULONG Id,
IN PSID Sid
)
{
NTSTATUS status = STATUS_SUCCESS;
SID_IDENTIFIER_AUTHORITY unixIdAuthority = { SECURITY_UNMAPPED_UNIX_AUTHORITY };
SID_IDENTIFIER_AUTHORITY ntIdAuthority = { SECURITY_NT_AUTHORITY };
BOOLEAN isUser = FALSE;
ULONG id = 0;
if (RtlEqualMemory(&Sid->IdentifierAuthority,
&unixIdAuthority,
sizeof(unixIdAuthority)))
{
if (Sid->SubAuthorityCount != SECURITY_UNMAPPED_UNIX_RID_COUNT)
{
status = STATUS_INVALID_SID;
GOTO_CLEANUP();
}
switch (Sid->SubAuthority[0])
{
case SECURITY_UNMAPPED_UNIX_UID_RID:
isUser = TRUE;
id = Sid->SubAuthority[1];
break;
case SECURITY_UNMAPPED_UNIX_GID_RID:
isUser = FALSE;
id = Sid->SubAuthority[1];
break;
default:
status = STATUS_INVALID_SID;
GOTO_CLEANUP();
}
}
else if (Sid->SubAuthorityCount == 1 &&
Sid->SubAuthority[0] == SECURITY_LOCAL_SYSTEM_RID &&
RtlEqualMemory(&Sid->IdentifierAuthority,
&ntIdAuthority,
sizeof(ntIdAuthority)))
{
isUser = TRUE;
id = 0;
}
else
{
status = Context->PluginInterface->GetIdFromSid(
Context->PluginContext,
&isUser,
&id,
Sid);
GOTO_CLEANUP_ON_STATUS(status);
}
cleanup:
if (!NT_SUCCESS(status))
{
isUser = FALSE;
id = (ULONG) -1;
}
*IsUser = isUser;
*Id = id;
return status;
}
NTSTATUS
LwMapSecurityGetSidFromId(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PSID* Sid,
IN BOOLEAN IsUser,
IN ULONG Id
)
{
NTSTATUS status = STATUS_SUCCESS;
PSID sid = NULL;
if (0 == Id)
{
union {
SID Sid;
BYTE Buffer[SID_MAX_SIZE];
} sidBuffer;
ULONG ulSidSize = sizeof(sidBuffer);
if (IsUser)
{
status = RtlCreateWellKnownSid(WinLocalSystemSid,
NULL,
&sidBuffer.Sid,
&ulSidSize);
GOTO_CLEANUP_ON_STATUS(status);
}
else
{
status = LwMapSecurityInitializeSidFromUnmappedId(
sizeof(sidBuffer),
&sidBuffer.Sid ,
IsUser,
Id);
GOTO_CLEANUP_ON_STATUS(status);
}
status = Context->PluginInterface->DuplicateSid(
Context->PluginContext,
&sid,
&sidBuffer.Sid);
GOTO_CLEANUP_ON_STATUS(status);
}
else
{
status = Context->PluginInterface->GetSidFromId(
Context->PluginContext,
&sid,
IsUser,
Id);
GOTO_CLEANUP_ON_STATUS(status);
}
cleanup:
if (!NT_SUCCESS(status) && sid)
{
Context->PluginInterface->FreeSid(
Context->PluginContext,
&sid);
}
*Sid = sid;
return status;
}
VOID
LwMapSecurityFreeSid(
IN PLW_MAP_SECURITY_CONTEXT Context,
IN OUT PSID* Sid
)
{
if (*Sid)
{
Context->PluginInterface->FreeSid(
Context->PluginContext,
Sid);
}
}
static
VOID
LwMapSecurityFreeAccessTokenCreateInformation(
IN PLW_MAP_SECURITY_CONTEXT Context,
IN OUT PACCESS_TOKEN_CREATE_INFORMATION* CreateInformation
)
{
if (*CreateInformation)
{
Context->PluginInterface->FreeAccessTokenCreateInformation(
Context->PluginContext,
CreateInformation);
}
}
static
NTSTATUS
LwMapSecurityCreateExtendedGroups(
OUT PTOKEN_GROUPS* ExtendedTokenGroups,
IN PTOKEN_GROUPS OriginalTokenGroups,
IN ULONG SidCount,
IN PSID* Sids
)
{
NTSTATUS status = STATUS_SUCCESS;
PTOKEN_GROUPS tokenGroups = NULL;
ULONG groupCount = OriginalTokenGroups->GroupCount + SidCount;
ULONG size = 0;
ULONG i = 0;
status = RtlSafeMultiplyULONG(&size, groupCount, sizeof(tokenGroups->Groups[0]));
GOTO_CLEANUP_ON_STATUS(status);
status = RtlSafeAddULONG(&size, size, sizeof(*tokenGroups));
GOTO_CLEANUP_ON_STATUS(status);
status = RTL_ALLOCATE(&tokenGroups, TOKEN_GROUPS, size);
GOTO_CLEANUP_ON_STATUS(status);
for (i = 0; i < SidCount; i++)
{
tokenGroups->Groups[tokenGroups->GroupCount].Attributes = SE_GROUP_ENABLED;
tokenGroups->Groups[tokenGroups->GroupCount].Sid = Sids[i];
tokenGroups->GroupCount++;
}
for (i = 0; i < OriginalTokenGroups->GroupCount; i++)
{
tokenGroups->Groups[tokenGroups->GroupCount] = OriginalTokenGroups->Groups[i];
tokenGroups->GroupCount++;
}
cleanup:
if (!NT_SUCCESS(status))
{
RTL_FREE(&tokenGroups);
}
*ExtendedTokenGroups = tokenGroups;
return status;
}
static
NTSTATUS
LwMapSecurityCreateExtendedAccessToken(
OUT PACCESS_TOKEN* AccessToken,
IN PTOKEN_USER User,
IN PTOKEN_GROUPS Groups,
IN PTOKEN_OWNER Owner,
IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
IN PTOKEN_DEFAULT_DACL DefaultDacl,
IN OPTIONAL PTOKEN_UNIX Unix
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
ULONG sidBuffer1[SID_MAX_SIZE / sizeof(ULONG) + 1] = { 0 };
ULONG sidBuffer2[SID_MAX_SIZE / sizeof(ULONG) + 1] = { 0 };
PSID sids[2] = { (PSID) sidBuffer1, (PSID) sidBuffer2 };
ULONG sidCount = LW_ARRAY_SIZE(sids);
ULONG size = 0;
PTOKEN_GROUPS extendedGroups = NULL;
size = sizeof(sidBuffer1);
status = RtlCreateWellKnownSid(
WinWorldSid,
NULL,
(PSID) sidBuffer1,
&size);
GOTO_CLEANUP_ON_STATUS(status);
size = sizeof(sidBuffer2);
status = RtlCreateWellKnownSid(
WinAuthenticatedUserSid,
NULL,
(PSID) sidBuffer2,
&size);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateExtendedGroups(
&extendedGroups,
Groups,
sidCount,
sids);
GOTO_CLEANUP_ON_STATUS(status);
status = RtlCreateAccessToken(
&accessToken,
User,
extendedGroups,
Owner,
PrimaryGroup,
DefaultDacl,
Unix);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
RTL_FREE(&extendedGroups);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromUidGid(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN ULONG Uid,
IN ULONG Gid
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
PSID userSid = NULL;
PSID groupSid = NULL;
PACCESS_TOKEN_CREATE_INFORMATION createInformation = NULL;
if (0 == Uid)
{
TOKEN_USER tokenUser = { { 0 } };
union {
TOKEN_GROUPS tokenGroups;
struct {
ULONG GroupCount;
SID_AND_ATTRIBUTES Groups[1];
};
} tokenGroupsUnion = { .tokenGroups = { 0 } };
TOKEN_OWNER tokenOwner = { 0 };
TOKEN_PRIMARY_GROUP tokenPrimaryGroup = { 0 };
TOKEN_DEFAULT_DACL tokenDefaultDacl = { 0 };
TOKEN_UNIX tokenUnix = { 0 };
/* Force gid to be 0 to avoid deadlocking call back into
lsass when it runs with non-zero gid (Solaris, HP-UX) */
Gid = 0;
status = LwMapSecurityGetSidFromId(Context, &userSid, TRUE, Uid);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityGetSidFromId(Context, &groupSid, FALSE, Gid);
GOTO_CLEANUP_ON_STATUS(status);
tokenUser.User.Sid = userSid;
tokenGroupsUnion.tokenGroups.GroupCount = 1;
tokenGroupsUnion.tokenGroups.Groups[0].Sid = groupSid;
tokenOwner.Owner = userSid;
tokenPrimaryGroup.PrimaryGroup = groupSid;
tokenUnix.Uid = Uid;
tokenUnix.Gid = Gid;
tokenUnix.Umask = 0;
status = LwMapSecurityCreateExtendedAccessToken(
&accessToken,
&tokenUser,
&tokenGroupsUnion.tokenGroups,
&tokenOwner,
&tokenPrimaryGroup,
&tokenDefaultDacl,
&tokenUnix);
GOTO_CLEANUP_ON_STATUS(status);
}
else
{
status = Context->PluginInterface->GetAccessTokenCreateInformationFromUid(
Context->PluginContext,
&createInformation,
Uid,
&Gid);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateExtendedAccessToken(
&accessToken,
createInformation->User,
createInformation->Groups,
createInformation->Owner,
createInformation->PrimaryGroup,
createInformation->DefaultDacl,
createInformation->Unix);
GOTO_CLEANUP_ON_STATUS(status);
}
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwMapSecurityFreeSid(Context, &userSid);
LwMapSecurityFreeSid(Context, &groupSid);
LwMapSecurityFreeAccessTokenCreateInformation(Context, &createInformation);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromUnicodeStringUsername(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN PUNICODE_STRING Username
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
PACCESS_TOKEN_CREATE_INFORMATION createInformation = NULL;
status = Context->PluginInterface->GetAccessTokenCreateInformationFromUsername(
Context->PluginContext,
&createInformation,
Username);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateExtendedAccessToken(
&accessToken,
createInformation->User,
createInformation->Groups,
createInformation->Owner,
createInformation->PrimaryGroup,
createInformation->DefaultDacl,
createInformation->Unix);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwMapSecurityFreeAccessTokenCreateInformation(Context, &createInformation);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromGssContext(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN LW_MAP_SECURITY_GSS_CONTEXT GssContext
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
PACCESS_TOKEN_CREATE_INFORMATION createInformation = NULL;
status = Context->PluginInterface->GetAccessTokenCreateInformationFromGssContext(
Context->PluginContext,
&createInformation,
GssContext);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateExtendedAccessToken(
&accessToken,
createInformation->User,
createInformation->Groups,
createInformation->Owner,
createInformation->PrimaryGroup,
createInformation->DefaultDacl,
createInformation->Unix);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwMapSecurityFreeAccessTokenCreateInformation(Context, &createInformation);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromAnsiStringUsername(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN PANSI_STRING Username
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
UNICODE_STRING unicodeUsername = { 0 };
status = LwRtlUnicodeStringAllocateFromAnsiString(
&unicodeUsername,
Username);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateAccessTokenFromUnicodeStringUsername(
Context,
&accessToken,
&unicodeUsername);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwRtlUnicodeStringFree(&unicodeUsername);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromWC16StringUsername(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN PCWSTR Username
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
UNICODE_STRING unicodeUsername = { 0 };
status = LwRtlUnicodeStringAllocateFromWC16String(
&unicodeUsername,
Username);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateAccessTokenFromUnicodeStringUsername(
Context,
&accessToken,
&unicodeUsername);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwRtlUnicodeStringFree(&unicodeUsername);
*AccessToken = accessToken;
return status;
}
NTSTATUS
LwMapSecurityCreateAccessTokenFromCStringUsername(
IN PLW_MAP_SECURITY_CONTEXT Context,
OUT PACCESS_TOKEN* AccessToken,
IN PCSTR Username
)
{
NTSTATUS status = STATUS_SUCCESS;
PACCESS_TOKEN accessToken = NULL;
UNICODE_STRING unicodeUsername = { 0 };
status = LwRtlUnicodeStringAllocateFromCString(
&unicodeUsername,
Username);
GOTO_CLEANUP_ON_STATUS(status);
status = LwMapSecurityCreateAccessTokenFromUnicodeStringUsername(
Context,
&accessToken,
&unicodeUsername);
GOTO_CLEANUP_ON_STATUS(status);
cleanup:
if (!NT_SUCCESS(status))
{
if (accessToken)
{
RtlReleaseAccessToken(&accessToken);
}
}
LwRtlUnicodeStringFree(&unicodeUsername);
*AccessToken = accessToken;
return status;
}
/*
local variables:
mode: c
c-basic-offset: 4
indent-tabs-mode: nil
tab-width: 4
end:
*/