Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

453 lines
12 KiB

/****************************************************************************
PROGRAM: TOKEN.C
PURPOSE: Contains routines that manipulate tokens
****************************************************************************/
#include "SECEDIT.h"
#include <sedapi.h>
BOOL
EditTokenDefaultAcl(
HWND Owner,
HANDLE Instance,
LPWSTR ObjectName,
HANDLE Token,
PSECURITY_DESCRIPTOR SecurityDescriptor,
DWORD *EditResult
);
/***************************************************************************\
* ApplySecurity
*
* Purpose : Called by ACL editor to set new default DACL on token
*
* Returns ERROR_SUCCESS or win error code.
*
* History:
* 09-17-92 Davidc Created.
\***************************************************************************/
DWORD
ApplySecurity(
HWND hwndParent,
HANDLE hInstance,
ULONG CallbackContext,
PSECURITY_DESCRIPTOR SecDesc,
PSECURITY_DESCRIPTOR SecDescNewObjects,
BOOLEAN ApplyToSubContainers,
BOOLEAN ApplyToSubObjects,
LPDWORD StatusReturn
)
{
HANDLE MyToken = (HANDLE)CallbackContext;
HANDLE Token = NULL;
PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
NTSTATUS Status;
BOOLEAN DaclPresent;
BOOLEAN DaclDefaulted;
*StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
//
// Get a handle to the token
//
Token = OpenToken(MyToken, TOKEN_ADJUST_DEFAULT);
if (Token == NULL) {
DbgPrint("SECEDIT : Failed to open the token for TOKEN_ADJUST_DEFAULT access\n");
goto CleanupAndExit;
}
DefaultDacl = Alloc(sizeof(TOKEN_DEFAULT_DACL));
if (DefaultDacl == NULL) {
goto CleanupAndExit;
}
Status = RtlGetDaclSecurityDescriptor (
SecDesc,
&DaclPresent,
&DefaultDacl->DefaultDacl,
&DaclDefaulted
);
ASSERT(NT_SUCCESS(Status));
ASSERT(DaclPresent);
if (SetTokenInfo(Token, TokenDefaultDacl, (PVOID)DefaultDacl)) {
*StatusReturn = SED_STATUS_MODIFIED;
}
CleanupAndExit:
if (Token != NULL) {
CloseToken(Token);
}
if (DefaultDacl != NULL) {
Free(DefaultDacl);
}
if (*StatusReturn != SED_STATUS_MODIFIED) {
MessageBox(hwndParent, "Failed to set default DACL", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
}
return(ERROR_SUCCESS);
}
/***************************************************************************\
* EditDefaultAcl
*
* Purpose : Displays and allows the user to edit the default Acl on the
* passed token.
*
* Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
*
* History:
* 09-17-92 Davidc Created.
\***************************************************************************/
BOOL
EditDefaultDacl(
HWND hwndOwner,
HANDLE Instance,
HANDLE MyToken
)
{
NTSTATUS Status;
BOOL Success = FALSE;
DWORD EditResult;
HANDLE Token = NULL;
PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
PTOKEN_OWNER Owner = NULL;
PTOKEN_PRIMARY_GROUP PrimaryGroup = NULL;
WCHAR string[MAX_STRING_LENGTH];
//
// Get the window text so we can use it as the token name
//
GetWindowTextW(((PMYTOKEN)MyToken)->hwnd, string, sizeof(string)/sizeof(*string));
//
// Get a handle to the token
//
Token = OpenToken(MyToken, TOKEN_QUERY);
if (Token == NULL) {
DbgPrint("SECEDIT : Failed to open the token with TOKEN_QUERY access\n");
goto CleanupAndExit;
}
//
// Read the default DACL from the token
//
if (!GetTokenInfo(Token, TokenDefaultDacl, (PPVOID)&DefaultDacl)) {
DbgPrint("SECEDIT : Failed to read default DACL from token\n");
goto CleanupAndExit;
}
//
// Get the owner and group of the token
//
if (!GetTokenInfo(Token, TokenOwner, (PPVOID)&Owner)) {
DbgPrint("SECEDIT : Failed to read owner from token\n");
goto CleanupAndExit;
}
if (!GetTokenInfo(Token, TokenPrimaryGroup, (PPVOID)&PrimaryGroup)) {
DbgPrint("SECEDIT : Failed to read primary group from token\n");
goto CleanupAndExit;
}
//
// Create a security descriptor
//
SecurityDescriptor = Alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
if (SecurityDescriptor == NULL) {
DbgPrint("SECEDIT : Failed to allocate security descriptor\n");
goto CleanupAndExit;
}
Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
ASSERT(NT_SUCCESS(Status));
//
// Set the DACL on the security descriptor
//
Status = RtlSetDaclSecurityDescriptor(
SecurityDescriptor,
TRUE, // DACL present
DefaultDacl->DefaultDacl,
FALSE // DACL defaulted
);
ASSERT(NT_SUCCESS(Status));
//
// Put the owner and group in the security descriptor to keep the
// ACL editor happy
//
Status = RtlSetOwnerSecurityDescriptor(
SecurityDescriptor,
Owner->Owner,
FALSE // Owner defaulted
);
ASSERT(NT_SUCCESS(Status));
Status = RtlSetGroupSecurityDescriptor(
SecurityDescriptor,
PrimaryGroup->PrimaryGroup,
FALSE // Owner defaulted
);
ASSERT(NT_SUCCESS(Status));
ASSERT(RtlValidSecurityDescriptor(SecurityDescriptor));
//
// Call the ACL editor, it will call our ApplySecurity function
// to store any ACL changes in the token.
//
Success = EditTokenDefaultAcl(
hwndOwner,
Instance,
string,
MyToken,
SecurityDescriptor,
&EditResult
);
if (!Success) {
DbgPrint("SECEDIT: Failed to edit token DACL\n");
}
CleanupAndExit:
if (DefaultDacl != NULL) {
FreeTokenInfo(DefaultDacl);
}
if (SecurityDescriptor != NULL) {
FreeTokenInfo(SecurityDescriptor);
}
if (PrimaryGroup != NULL) {
FreeTokenInfo(PrimaryGroup);
}
if (Owner != NULL) {
FreeTokenInfo(Owner);
}
if (Token != NULL) {
CloseToken(Token);
}
return(Success);
}
/***************************************************************************\
* EditTokenDefaultAcl
*
* Purpose : Displays and allows the user to edit the default Acl on the
* passed token.
*
* Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
*
* History:
* 09-17-92 Davidc Created.
\***************************************************************************/
BOOL
EditTokenDefaultAcl(
HWND Owner,
HANDLE Instance,
LPWSTR ObjectName,
HANDLE MyToken,
PSECURITY_DESCRIPTOR SecurityDescriptor,
DWORD *EditResult
)
{
DWORD Result;
SED_OBJECT_TYPE_DESCRIPTOR sedobjdesc;
GENERIC_MAPPING GenericMapping;
SED_HELP_INFO sedhelpinfo ;
SED_APPLICATION_ACCESSES SedAppAccesses ;
SED_APPLICATION_ACCESS SedAppAccess[20];
ULONG i;
//
// Initialize the application accesses
//
i=0;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_ASSIGN_PRIMARY;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Assign Primary";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_DUPLICATE;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Duplicate";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_IMPERSONATE;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Impersonate";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_QUERY;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Query";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_QUERY_SOURCE;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Query source";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_PRIVILEGES;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Adjust Privileges";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_GROUPS;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Adjust Groups";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_DEFAULT;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Adjust Default";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
SedAppAccess[i].AccessMask1 = GENERIC_ALL;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"All Access";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
SedAppAccess[i].AccessMask1 = TOKEN_READ;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Read";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
SedAppAccess[i].AccessMask1 = TOKEN_WRITE;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"Write";
i++;
SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
SedAppAccess[i].AccessMask1 = 0;
SedAppAccess[i].AccessMask2 = 0;
SedAppAccess[i].PermissionTitle = L"None";
i++;
ASSERT((sizeof(SedAppAccess)/sizeof(*SedAppAccess)) >= i);
SedAppAccesses.Count = i;
SedAppAccesses.AccessGroup = SedAppAccess;
SedAppAccesses.DefaultPermName = L"Read";
//
// Initialize generic mapping
//
GenericMapping.GenericRead = TOKEN_READ;
GenericMapping.GenericWrite = TOKEN_WRITE;
GenericMapping.GenericExecute = TOKEN_EXECUTE;
GenericMapping.GenericAll = TOKEN_ALL_ACCESS;
//
// Initialize help info
//
sedhelpinfo.pszHelpFileName = L"secedit.hlp";
sedhelpinfo.aulHelpContext[HC_MAIN_DLG] = 0 ;
sedhelpinfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0 ;
sedhelpinfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0 ;
sedhelpinfo.aulHelpContext[HC_ADD_USER_DLG] = 0 ;
//
// Initialize object description
//
sedobjdesc.Revision = SED_REVISION1;
sedobjdesc.IsContainer = FALSE;
sedobjdesc.AllowNewObjectPerms = FALSE;
sedobjdesc.MapSpecificPermsToGeneric = FALSE;
sedobjdesc.GenericMapping = &GenericMapping;
sedobjdesc.GenericMappingNewObjects = &GenericMapping;
sedobjdesc.HelpInfo = &sedhelpinfo;
sedobjdesc.ObjectTypeName = L"Token";
sedobjdesc.ApplyToSubContainerTitle = L"ApplyToSubContainerTitle";
sedobjdesc.ApplyToSubContainerHelpText = L"ApplyToSubContainerHelpText";
sedobjdesc.ApplyToSubContainerConfirmation = L"ApplyToSubContainerConfirmation";
sedobjdesc.SpecialObjectAccessTitle = L"Special...";
sedobjdesc.SpecialNewObjectAccessTitle = L"SpecialNewObjectAccessTitle";
//
// Call the ACL editor, it will call our ApplySecurity function
// to store any ACL changes in the token.
//
Result = SedDiscretionaryAclEditor(
Owner,
Instance,
NULL, // server
&sedobjdesc, // object type
&SedAppAccesses, // application accesses
ObjectName,
ApplySecurity, // Callback
(ULONG_PTR)MyToken, // Context
SecurityDescriptor,
FALSE, // Couldn't read DACL
EditResult
);
if (Result != ERROR_SUCCESS) {
DbgPrint("SECEDIT: Acleditor failed, error = %d\n", Result);
SetLastError(Result);
}
return (Result == ERROR_SUCCESS);
}