예제 #1
0
DWORD
LWICheckSecurity(
    handle_t        hBindingHandle,
    ACCESS_MASK dwAccessMask
    )
{
    DWORD dwError = ERROR_SUCCESS;
    volatile unsigned32 rpcError;
    PACCESS_TOKEN        pUserToken = NULL;

    TRY
    {
        rpc_binding_inq_access_token_caller(
            hBindingHandle,
            &pUserToken,
            (unsigned32*)&rpcError);
    }
    CATCH_ALL
    ENDTRY;

    BAIL_ON_DCE_ERROR(dwError, rpcError);

    dwError = EVTCheckAllowed(
            pUserToken, 
            dwAccessMask);
    BAIL_ON_EVT_ERROR(dwError);

error:
    if (pUserToken)
    {
        RtlReleaseAccessToken(&pUserToken);
    }
    return dwError;
}
예제 #2
0
파일: common.c 프로젝트: borland667/pbis
static
NTSTATUS
LwIoFuseCreateAccessTokenForOther(
    PACCESS_TOKEN* ppOtherToken
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PACCESS_TOKEN pOtherToken = NULL;
    TOKEN_USER user = {{0}};
    TOKEN_OWNER owner = {0};
    TOKEN_GROUPS groups = {0};
    TOKEN_PRIVILEGES privileges = {0};
    TOKEN_PRIMARY_GROUP primaryGroup = {0};
    TOKEN_DEFAULT_DACL dacl = {0};

    status = RtlAllocateSidFromCString(
        &user.User.Sid,
        "S-1-1-0");
    BAIL_ON_NT_STATUS(status);
    
    status = RtlCreateAccessToken(
        &pOtherToken,
        &user,
        &groups,
	&privileges,
        &owner,
        &primaryGroup,
        &dacl,
        NULL);
    BAIL_ON_NT_STATUS(status);

    *ppOtherToken = pOtherToken;

cleanup:

    RTL_FREE(&user.User.Sid);

    return status;

error:

    *ppOtherToken = NULL;

    if (pOtherToken)
    {
        RtlReleaseAccessToken(&pOtherToken);
    }

    goto cleanup;
}
예제 #3
0
파일: common.c 프로젝트: borland667/pbis
static
NTSTATUS
LwIoFuseCreateAccessTokenForGroup(
    PSID pGroupSid,
    PACCESS_TOKEN* ppGroupToken
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PACCESS_TOKEN pGroupToken = NULL;
    TOKEN_USER user = {{0}};
    TOKEN_OWNER owner = {0};
    TOKEN_GROUPS groups = {0};
    TOKEN_PRIVILEGES privileges = {0};
    TOKEN_PRIMARY_GROUP primaryGroup = {0};
    TOKEN_DEFAULT_DACL dacl = {0};

    user.User.Sid = pGroupSid;
    
    status = RtlCreateAccessToken(
        &pGroupToken,
        &user,
        &groups,
	&privileges,
        &owner,
        &primaryGroup,
        &dacl,
        NULL);
    BAIL_ON_NT_STATUS(status);

    *ppGroupToken = pGroupToken;

cleanup:

    return status;

error:

    *ppGroupToken = NULL;

    if (pGroupToken)
    {
        RtlReleaseAccessToken(&pGroupToken);
    }

    goto cleanup;
}
예제 #4
0
void
LwmEvtSrvDestructSession(
    LWMsgSecurityToken* pToken,
    void* pSessionData
)
{
    PLWMSG_LW_EVENTLOG_CONNECTION pConn =
        (PLWMSG_LW_EVENTLOG_CONNECTION)pSessionData;

    if (pConn)
    {
        if (pConn->pUserToken)
        {
            RtlReleaseAccessToken(&pConn->pUserToken);
        }
        LW_SAFE_FREE_MEMORY(pConn);
    }
}
예제 #5
0
void
RegSrvCloseServer(
    HANDLE hServer
    )
{
    PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)hServer;

    if (pServerState->hEventLog != (HANDLE)NULL)
    {
       //RegSrvCloseEventLog(pServerState->hEventLog);
    }

    if (pServerState->pToken)
    {
        RtlReleaseAccessToken(&pServerState->pToken);
    }

    LwRtlMemoryFree(pServerState);
}
예제 #6
0
VOID
LsaSrvFreeAuthInfo(
    IN  PPOLICY_CONTEXT pPolCtx
    )
{
    if (pPolCtx == NULL) return;

    if (pPolCtx->pUserToken)
    {
        RtlReleaseAccessToken(&pPolCtx->pUserToken);
        pPolCtx->pUserToken = NULL;
    }

    if (pPolCtx->pSessionKey)
    {
        LW_SECURE_FREE_MEMORY(pPolCtx->pSessionKey, pPolCtx->dwSessionKeyLen);
        pPolCtx->pSessionKey     = NULL;
        pPolCtx->dwSessionKeyLen = 0;
    }
}
예제 #7
0
VOID
SamrSrvFreeAuthInfo(
    IN  PCONNECT_CONTEXT pConnCtx
    )
{
    if (pConnCtx == NULL) return;

    if (pConnCtx->pUserToken)
    {
        RtlReleaseAccessToken(&pConnCtx->pUserToken);
        pConnCtx->pUserToken = NULL;
    }

    if (pConnCtx->pSessionKey)
    {
        LW_SECURE_FREE_MEMORY(pConnCtx->pSessionKey, pConnCtx->dwSessionKeyLen);
        pConnCtx->pSessionKey     = NULL;
        pConnCtx->dwSessionKeyLen = 0;
    }
}
예제 #8
0
파일: ccb.c 프로젝트: bhanug/likewise-open
NTSTATUS
PvfsFreeCCB(
    PPVFS_CCB pCCB
    )
{
    LWIO_ASSERT(pCCB->RefCount == 0);

    if (pCCB->pScb)
    {
        PvfsRemoveCCBFromSCB(pCCB->pScb, pCCB);
        PvfsReleaseSCB(&pCCB->pScb);
    }

    if (pCCB->pDirContext)
    {
        PvfsFreeDirectoryContext(pCCB->pDirContext);
    }

    if (pCCB->pUserToken)
    {
        RtlReleaseAccessToken(&pCCB->pUserToken);
        pCCB->pUserToken = NULL;
    }

    PvfsListDestroy(&pCCB->pZctContextList);

    LwRtlWC16StringFree(&pCCB->pwszShareName);

    PVFS_FREE(&pCCB->LockTable.ExclusiveLocks.pLocks);
    PVFS_FREE(&pCCB->LockTable.SharedLocks.pLocks);

    pthread_mutex_destroy(&pCCB->ControlBlock);

    PVFS_FREE(&pCCB);

    InterlockedDecrement(&gPvfsDriverState.Counters.Ccb);

    return STATUS_SUCCESS;
}
예제 #9
0
DWORD
LsaSrvPrivsLookupPrivilegeValue(
    IN OPTIONAL HANDLE hServer,
    IN OPTIONAL PACCESS_TOKEN AccessToken,
    IN PCWSTR pwszPrivilegeName,
    OUT PLUID pPrivilegeValue
    )
{
    DWORD err = ERROR_SUCCESS;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PLSASRV_PRIVILEGE_GLOBALS pGlobals = &gLsaPrivilegeGlobals;
    PACCESS_TOKEN accessToken = AccessToken;
    BOOLEAN releaseAccessToken = FALSE;
    ACCESS_MASK accessRights = LSA_ACCESS_VIEW_POLICY_INFO;
    ACCESS_MASK grantedAccess = 0;
    GENERIC_MAPPING genericMapping = {0};
    PSTR pszPrivilegeName = NULL;
    PLSA_PRIVILEGE pPrivilegeEntry = NULL;

    if (!accessToken)
    {
        err = LsaSrvPrivsGetAccessTokenFromServerHandle(
                                hServer,
                                &accessToken);
        BAIL_ON_LSA_ERROR(err);

        releaseAccessToken = TRUE;
    }

    if (!RtlAccessCheck(pGlobals->pPrivilegesSecDesc,
                        accessToken,
                        accessRights,
                        0,
                        &genericMapping,
                        &grantedAccess,
                        &ntStatus))
    {
        BAIL_ON_NT_STATUS(ntStatus);
    }

    err = LwWc16sToMbs(pwszPrivilegeName,
                       &pszPrivilegeName);
    BAIL_ON_LSA_ERROR(err);

    err = LsaSrvGetPrivilegeEntryByName(
                       pszPrivilegeName,
                       &pPrivilegeEntry);
    BAIL_ON_LSA_ERROR(err);

    *pPrivilegeValue = pPrivilegeEntry->Luid;

error:
    if (err || ntStatus)
    {
        if (pPrivilegeValue)
        {
            pPrivilegeValue->HighPart = 0;
            pPrivilegeValue->LowPart = 0;
        }
    }

    LW_SAFE_FREE_MEMORY(pszPrivilegeName);

    if (releaseAccessToken)
    {
        RtlReleaseAccessToken(&accessToken);
    }

    if (err == ERROR_SUCCESS &&
        ntStatus != STATUS_SUCCESS)
    {
        err = LwNtStatusToWin32Error(ntStatus);
    }

    return err;
}
예제 #10
0
DWORD
LsaSrvPrivsLookupPrivilegeDescription(
    IN OPTIONAL HANDLE hServer,
    IN OPTIONAL PACCESS_TOKEN AccessToken,
    IN PCWSTR PrivilegeName,
    IN SHORT ClientLanguageId,
    IN SHORT ClientSystemLanguageId,
    OUT PWSTR *pPrivilegeDescription,
    OUT PUSHORT pLanguageId
    )
{
    DWORD err = ERROR_SUCCESS;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PLSASRV_PRIVILEGE_GLOBALS pGlobals = &gLsaPrivilegeGlobals;
    PACCESS_TOKEN accessToken = AccessToken;
    BOOLEAN releaseAccessToken = FALSE;
    ACCESS_MASK accessRights = LSA_ACCESS_VIEW_POLICY_INFO;
    ACCESS_MASK grantedAccess = 0;
    GENERIC_MAPPING genericMapping = {0};
    PSTR pszPrivilegeName = NULL;
    PLSA_PRIVILEGE pPrivilegeEntry = NULL;
    PWSTR privilegeDescription = NULL;
    USHORT descriptionLanguageId = 0;

    if (!accessToken)
    {
        err = LsaSrvPrivsGetAccessTokenFromServerHandle(
                                hServer,
                                &accessToken);
        BAIL_ON_LSA_ERROR(err);

        releaseAccessToken = TRUE;
    }

    if (!RtlAccessCheck(pGlobals->pPrivilegesSecDesc,
                        accessToken,
                        accessRights,
                        0,
                        &genericMapping,
                        &grantedAccess,
                        &ntStatus))
    {
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (ClientLanguageId || ClientSystemLanguageId)
    {
        //
        // Right now we don't support multilingual privilege descriptions
        // so just return 0x0409 (which means "en-US") whenever a caller
        // requests some particular language id
        //
        descriptionLanguageId = 0x0409;
    }

    err = LwWc16sToMbs(PrivilegeName,
                       &pszPrivilegeName);
    BAIL_ON_LSA_ERROR(err);

    err = LsaSrvGetPrivilegeEntryByName(
                       pszPrivilegeName,
                       &pPrivilegeEntry);
    BAIL_ON_LSA_ERROR(err);

    err = LwAllocateWc16String(
                       &privilegeDescription,
                       pPrivilegeEntry->pwszDescription);
    BAIL_ON_LSA_ERROR(err);

    *pPrivilegeDescription = privilegeDescription;
    *pLanguageId           = descriptionLanguageId;

error:
    if (err || ntStatus)
    {
        if (pPrivilegeDescription)
        {
            *pPrivilegeDescription = NULL;
        }

        if (pLanguageId)
        {
            *pLanguageId = 0;
        }
    }

    LW_SAFE_FREE_MEMORY(pszPrivilegeName);

    if (releaseAccessToken)
    {
        RtlReleaseAccessToken(&accessToken);
    }

    if (err == ERROR_SUCCESS &&
        ntStatus != STATUS_SUCCESS)
    {
        err = LwNtStatusToWin32Error(ntStatus);
    }

    return err;
}
예제 #11
0
파일: common.c 프로젝트: borland667/pbis
static
NTSTATUS
LwIoFuseTranslateAbsoluteSecurityDescriptor(
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecurityDescriptor,
    PSID pOwnerSid,
    PSID pGroupSid,
    struct stat* pStatbuf
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PACCESS_TOKEN pOwnerToken = NULL;
    PACCESS_TOKEN pGroupToken = NULL;
    PACCESS_TOKEN pOtherToken = NULL;
    PLW_MAP_SECURITY_CONTEXT pContext = NULL;
    ULONG ulUserId = 0;
    ULONG ulGroupId = 0;
    BOOLEAN bIsUser = TRUE;

    status = LwMapSecurityCreateContext(&pContext);
    BAIL_ON_NT_STATUS(status);

    status = LwMapSecurityGetIdFromSid(
        pContext,
        &bIsUser,
        &ulUserId,
        pOwnerSid);
    if (status != STATUS_SUCCESS || bIsUser != TRUE)
    {
        status = STATUS_SUCCESS;
        ulUserId = 0;
    }
    
    status = LwMapSecurityGetIdFromSid(
        pContext,
        &bIsUser,
        &ulGroupId,
        pGroupSid);
    if (status != STATUS_SUCCESS || bIsUser != FALSE)
    {
        status = STATUS_SUCCESS;
        ulGroupId = 0;
    }

    pStatbuf->st_uid = (uid_t) ulUserId;
    pStatbuf->st_gid = (gid_t) ulGroupId;
    
    /* Create access tokens for user/group/other */
    status = LwIoFuseCreateAccessTokenForOwner(
        pOwnerSid,
        &pOwnerToken);
    BAIL_ON_NT_STATUS(status);

    status = LwIoFuseCreateAccessTokenForGroup(
        pGroupSid,
        &pGroupToken);
    BAIL_ON_NT_STATUS(status);

    status = LwIoFuseCreateAccessTokenForOther(
        &pOtherToken);
    BAIL_ON_NT_STATUS(status);

    /* Generate unix permissions */
    status = LwIoFuseTranslateSecurityDescriptorPermissions(
        pSecurityDescriptor,
        pOwnerToken,
        pGroupToken,
        pOtherToken,
        pStatbuf);
    BAIL_ON_NT_STATUS(status);

error:
    
    if (pOwnerToken)
    {
        RtlReleaseAccessToken(&pOwnerToken);
    }

    if (pGroupToken)
    {
        RtlReleaseAccessToken(&pGroupToken);
    }

    if (pOtherToken)
    {
        RtlReleaseAccessToken(&pOtherToken);
    }

    return status;
}
예제 #12
0
파일: main.c 프로젝트: nks5295/lightwave
static
DWORD
test_access_token(
    PCSTR pszUpn)
{
    PTOKEN_USER              pUser  = NULL;
    PTOKEN_GROUPS            pGroups = NULL;
    PACCESS_TOKEN            pAccessToken = NULL;
    PSTR                     pszUserSid = NULL;
    PSTR                     pszGroupSid = NULL;
    PLW_MAP_SECURITY_CONTEXT pMapSecurityContext = NULL;
    DWORD                    ulBufLen = 0;
    DWORD                    dwError = 0;
    DWORD                    dwIndex = 0;

    dwError = LwMapSecurityCreateContext(&pMapSecurityContext);
    BAIL_ON_VMDIR_ERROR(dwError);

    printf("Creating access token for UPN: %s\n", pszUpn);

    dwError = LwMapSecurityCreateAccessTokenFromCStringUsername(
                  pMapSecurityContext,
                  &pAccessToken,
                  pszUpn);
    BAIL_ON_VMDIR_ERROR(dwError);

    // get user sid
    dwError = RtlQueryAccessTokenInformation(
                  pAccessToken,
                  TokenUser,
                  NULL,
                  0,
                  &ulBufLen);
    dwError = LwNtStatusToWin32Error(dwError);
    BAIL_ON_VMDIR_ERROR(dwError != ERROR_INSUFFICIENT_BUFFER);

    pUser = RtlMemoryAllocate(ulBufLen, TRUE);
    if (!pUser)
    {
        dwError = ERROR_NOT_ENOUGH_MEMORY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = RtlQueryAccessTokenInformation(
                  pAccessToken,
                  TokenUser,
                  pUser,
                  ulBufLen,
                  &ulBufLen);
    dwError = LwNtStatusToWin32Error(dwError);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = RtlAllocateCStringFromSid(
                  &pszUserSid,
                  pUser->User.Sid);
    BAIL_ON_VMDIR_ERROR(dwError);

    printf("User SID: %s\n", pszUserSid);

    dwError = RtlQueryAccessTokenInformation(
                  pAccessToken,
                  TokenGroups,
                  NULL,
                  0,
                  &ulBufLen);
    dwError = LwNtStatusToWin32Error(dwError);
    BAIL_ON_VMDIR_ERROR(dwError != ERROR_INSUFFICIENT_BUFFER);

    pGroups = RtlMemoryAllocate(ulBufLen, TRUE);
    if (!pGroups)
    {
        dwError = ERROR_NOT_ENOUGH_MEMORY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = RtlQueryAccessTokenInformation(
                  pAccessToken,
                  TokenGroups,
                  pGroups,
                  ulBufLen,
                  &ulBufLen);
    dwError = LwNtStatusToWin32Error(dwError);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwIndex = 0; dwIndex < pGroups->GroupCount; dwIndex++)
    {
        dwError = RtlAllocateCStringFromSid(
                      &pszGroupSid,
                      pGroups->Groups[dwIndex].Sid);
        BAIL_ON_VMDIR_ERROR(dwError);

        printf("Group SID: %s\n", pszGroupSid);
    }

cleanup:
    if (pMapSecurityContext)
    {
        LwMapSecurityFreeContext(&pMapSecurityContext);
    }
    if (pAccessToken)
    {
        RtlReleaseAccessToken(&pAccessToken);
    }
    if (pszUserSid)
    {
        RtlMemoryFree(pszUserSid);
    }
    if (pGroups)
    {
        RtlMemoryFree(pGroups);
    }
    if (pUser)
    {
        RtlMemoryFree(pUser);
    }

    return dwError;

error:
    goto cleanup;
}
예제 #13
0
NTSTATUS
RtlCreateAccessToken(
    OUT PACCESS_TOKEN* AccessToken,
    IN PTOKEN_USER User,
    IN PTOKEN_GROUPS Groups,
    IN PTOKEN_PRIVILEGES Privileges,
    IN PTOKEN_OWNER Owner,
    IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
    IN PTOKEN_DEFAULT_DACL DefaultDacl,
    IN OPTIONAL PTOKEN_UNIX Unix
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int unixError = 0;
    ULONG requiredSize = 0;
    PACCESS_TOKEN token = NULL;
    ULONG i = 0;
    ULONG size = 0;
    PVOID location = NULL;

    if (!User || !User->User.Sid ||
        !Groups ||
        !Owner ||
        !PrimaryGroup ||
        !DefaultDacl)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    if (!RtlValidSid(User->User.Sid) ||
        (Owner->Owner && !RtlValidSid(Owner->Owner)) ||
        (PrimaryGroup->PrimaryGroup && !RtlValidSid(PrimaryGroup->PrimaryGroup)))
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    // No user attributes currently exist.
    if (User->User.Attributes != 0)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    for (i = 0; i < Groups->GroupCount; i++)
    {
        // TODO-Perhaps validate Group attributes
        if (!Groups->Groups[i].Sid)
        {
            status = STATUS_INVALID_PARAMETER;
            GOTO_CLEANUP();
        }
        if (!RtlValidSid(Groups->Groups[i].Sid))
        {
            status = STATUS_INVALID_SID;
            GOTO_CLEANUP();
        }
    }

    if (DefaultDacl->DefaultDacl &&
        !RtlValidAcl(DefaultDacl->DefaultDacl, NULL))
    {
        status = STATUS_INVALID_ACL;
        GOTO_CLEANUP();
    }

    // Compute size required

    requiredSize = sizeof(*token);

    size = RtlLengthSid(User->User.Sid);
    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Owner->Owner)
    {
        size = RtlLengthSid(Owner->Owner);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        size = RtlLengthSid(PrimaryGroup->PrimaryGroup);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (DefaultDacl->DefaultDacl)
    {
        status = RtlSafeAddULONG(&requiredSize, requiredSize,
                                 DefaultDacl->DefaultDacl->AclSize);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size, sizeof(Groups->Groups[0]), Groups->GroupCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    for (i = 0; i < Groups->GroupCount; i++)
    {
        size = RtlLengthSid(Groups->Groups[i].Sid);

        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size,
                                  sizeof(Privileges->Privileges[0]),
                                  Privileges->PrivilegeCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RTL_ALLOCATE(&token, ACCESS_TOKEN, requiredSize);
    GOTO_CLEANUP_ON_STATUS(status);

    location = LW_PTR_ADD(token, sizeof(*token));

    // Initialize

    token->ReferenceCount = 1;
    token->Flags = 0;
    unixError = pthread_rwlock_init(&token->RwLock, NULL);
    if (unixError)
    {
        LW_RTL_LOG_ERROR("Failed to init rwlock in access token "
                         "(error = %d).", unixError);
        status = LwErrnoToNtStatus(unixError);
        GOTO_CLEANUP();
    }
    token->pRwLock = &token->RwLock;

    token->User.Attributes = User->User.Attributes;
    token->User.Sid = (PSID) location;
    location = RtlpAppendData(location,
                              User->User.Sid,
                              RtlLengthSid(User->User.Sid));

    token->GroupCount = Groups->GroupCount;
    token->Groups = (PSID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(location, sizeof(Groups->Groups[0]) * Groups->GroupCount);
    for (i = 0; i < Groups->GroupCount; i++)
    {
        token->Groups[i].Attributes = Groups->Groups[i].Attributes;
        token->Groups[i].Sid = (PSID) location;
        location = RtlpAppendData(location,
                                  Groups->Groups[i].Sid,
                                  RtlLengthSid(Groups->Groups[i].Sid));
    }

    token->PrivilegeCount = Privileges->PrivilegeCount;
    token->Privileges = (PLUID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(
                location,
                sizeof(Privileges->Privileges[0]) * Privileges->PrivilegeCount);
    memcpy(token->Privileges,
           Privileges->Privileges,
           sizeof(token->Privileges[0]) * token->PrivilegeCount);

    if (Owner->Owner)
    {
        token->Owner = (PSID) location;
        location = RtlpAppendData(location,
                                  Owner->Owner,
                                  RtlLengthSid(Owner->Owner));
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        token->PrimaryGroup = (PSID) location;
        location = RtlpAppendData(location,
                                  PrimaryGroup->PrimaryGroup,
                                  RtlLengthSid(PrimaryGroup->PrimaryGroup));
    }

    if (DefaultDacl->DefaultDacl)
    {
        token->DefaultDacl = (PACL) location;
        location = RtlpAppendData(location,
                                  DefaultDacl->DefaultDacl,
                                  DefaultDacl->DefaultDacl->AclSize);
    }

    if (Unix)
    {
        SetFlag(token->Flags, ACCESS_TOKEN_FLAG_UNIX_PRESENT);
        token->Uid = Unix->Uid;
        token->Gid = Unix->Gid;
        token->Umask = Unix->Umask;
    }

    if (location != LW_PTR_ADD(token, requiredSize))
    {
        status = STATUS_ASSERTION_FAILURE;
        GOTO_CLEANUP();
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RtlReleaseAccessToken(&token);
    }

    *AccessToken = token;

    return status;
}