|
|
/****************************************************************************
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);
}
|