652 lines
19 KiB
C++
652 lines
19 KiB
C++
|
|
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1991 - 1995.
|
|
|
|
// File: acl.cxx
|
|
|
|
// Contents: Implementation for the Shares Acl Editor in the "Sharing"
|
|
// property page. It is just a front end for the Generic
|
|
// ACL Editor that is specific to Shares.
|
|
|
|
// History: 5-Apr-95 BruceFo Stole from net\ui\shellui\share\shareacl.cxx
|
|
|
|
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include <lmerr.h>
|
|
|
|
extern "C"
|
|
{
|
|
#include <sedapi.h>
|
|
}
|
|
|
|
#include "resource.h"
|
|
#include "helpids.h"
|
|
#include "acl.hxx"
|
|
#include "util.hxx"
|
|
|
|
|
|
|
|
|
|
typedef
|
|
DWORD
|
|
(*SedDiscretionaryAclEditorType)(
|
|
HWND Owner,
|
|
HANDLE Instance,
|
|
LPWSTR Server,
|
|
PSED_OBJECT_TYPE_DESCRIPTOR ObjectType,
|
|
PSED_APPLICATION_ACCESSES ApplicationAccesses,
|
|
LPWSTR ObjectName,
|
|
PSED_FUNC_APPLY_SEC_CALLBACK ApplySecurityCallbackRoutine,
|
|
ULONG CallbackContext,
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
BOOLEAN CouldntReadDacl,
|
|
BOOLEAN CantWriteDacl,
|
|
LPDWORD SEDStatusReturn,
|
|
DWORD Flags
|
|
);
|
|
|
|
// NOTE: the SedDiscretionaryAclEditor string is used in GetProcAddress to
|
|
// get the correct entrypoint. Since GetProcAddress is not UNICODE, this string
|
|
// must be ANSI.
|
|
#define ACLEDIT_DLL_STRING TEXT("acledit.dll")
|
|
#define SEDDISCRETIONARYACLEDITOR_STRING ("SedDiscretionaryAclEditor")
|
|
|
|
|
|
// Declare the callback routine based on typedef in sedapi.h.
|
|
|
|
|
|
DWORD
|
|
SedCallback(
|
|
HWND hwndParent,
|
|
HANDLE hInstance,
|
|
ULONG ulCallbackContext,
|
|
PSECURITY_DESCRIPTOR pSecDesc,
|
|
PSECURITY_DESCRIPTOR pSecDescNewObjects,
|
|
BOOLEAN fApplyToSubContainers,
|
|
BOOLEAN fApplyToSubObjects,
|
|
LPDWORD StatusReturn
|
|
);
|
|
|
|
|
|
// Structure for callback function's usage. A pointer to this is passed as
|
|
// ulCallbackContext. The callback functions sets bSecDescModified to TRUE
|
|
// and makes a copy of the security descriptor. The caller of EditShareAcl
|
|
// is responsible for deleting the memory in pSecDesc if bSecDescModified is
|
|
// TRUE. This flag will be FALSE if the user hit CANCEL in the ACL editor.
|
|
|
|
struct SHARE_CALLBACK_INFO
|
|
{
|
|
BOOL bSecDescModified;
|
|
PSECURITY_DESCRIPTOR pSecDesc;
|
|
};
|
|
|
|
|
|
|
|
// Local function prototypes
|
|
|
|
|
|
VOID
|
|
InitializeShareGenericMapping(
|
|
IN OUT PGENERIC_MAPPING pSHAREGenericMapping
|
|
);
|
|
|
|
LONG
|
|
CreateDefaultSecDesc(
|
|
OUT PSECURITY_DESCRIPTOR* ppSecDesc
|
|
);
|
|
|
|
VOID
|
|
DeleteDefaultSecDesc(
|
|
IN PSECURITY_DESCRIPTOR pSecDesc
|
|
);
|
|
|
|
|
|
// The following two arrays define the permission names for NT Files. Note
|
|
// that each index in one array corresponds to the index in the other array.
|
|
// The second array will be modifed to contain a string pointer pointing to
|
|
// a loaded string corresponding to the IDS_* in the first array.
|
|
|
|
DWORD g_dwSharePermNames[] =
|
|
{
|
|
IDS_ACLEDIT_PERM_GEN_NO_ACCESS,
|
|
IDS_ACLEDIT_PERM_GEN_READ,
|
|
IDS_ACLEDIT_PERM_GEN_MODIFY,
|
|
IDS_ACLEDIT_PERM_GEN_ALL
|
|
};
|
|
|
|
SED_APPLICATION_ACCESS g_SedAppAccessSharePerms[] =
|
|
{
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_NO_ACCESS, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_READ, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_MODIFY, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_ALL, 0, NULL }
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Function: EditShareAcl
|
|
|
|
// Synopsis: Invokes the generic ACL editor, specifically for NT shares
|
|
|
|
// Arguments: [hwndParent] - Parent window handle
|
|
// [pszShareName] - Fully qualified name of resource we will
|
|
// edit, basically a share name.
|
|
// [pSecDesc] - The initial security descriptor. If NULL, we will
|
|
// create a default that is "World all" access.
|
|
// [pbSecDescModified] - Set to TRUE if the security descriptor
|
|
// was modified (i.e., the user hit "OK"), or FALSE if not
|
|
// (i.e., the user hit "Cancel")
|
|
// [ppSecDesc] - *ppSecDesc points to a new security descriptor
|
|
// if *pbSecDescModified is TRUE. This memory must be freed
|
|
// by the caller.
|
|
|
|
// History:
|
|
// ChuckC 10-Aug-1992 Created. Culled from NTFS ACL code.
|
|
// Yi-HsinS 09-Oct-1992 Added ulHelpContextBase
|
|
// BruceFo 4-Apr-95 Stole and used in ntshrui.dll
|
|
|
|
|
|
|
|
LONG
|
|
EditShareAcl(
|
|
IN HWND hwndParent,
|
|
IN LPWSTR pszServerName,
|
|
IN TCHAR * pszShareName,
|
|
IN PSECURITY_DESCRIPTOR pSecDesc,
|
|
OUT BOOL* pbSecDescModified,
|
|
OUT PSECURITY_DESCRIPTOR* ppSecDesc
|
|
)
|
|
{
|
|
appAssert(NULL != pszShareName);
|
|
appDebugOut((DEB_TRACE, "EditShareAcl, share %ws\n", pszShareName));
|
|
|
|
appAssert(NULL == pSecDesc || IsValidSecurityDescriptor(pSecDesc));
|
|
appAssert(pbSecDescModified);
|
|
appAssert(ppSecDesc);
|
|
|
|
*pbSecDescModified = FALSE;
|
|
|
|
LONG err ;
|
|
PWSTR pszPermName;
|
|
BOOL bCreatedDefaultSecDesc = FALSE;
|
|
|
|
do // error breakout
|
|
{
|
|
/*
|
|
* if pSecDesc is NULL, this is new share or a share with no
|
|
* security descriptor.
|
|
* we go and create a new (default) security descriptor.
|
|
*/
|
|
if (NULL == pSecDesc)
|
|
{
|
|
LONG err = CreateDefaultSecDesc(&pSecDesc);
|
|
if (err != NERR_Success)
|
|
{
|
|
appDebugOut((DEB_ERROR, "CreateDefaultSecDesc failed, 0x%08lx\n", err));
|
|
break ;
|
|
}
|
|
|
|
appDebugOut((DEB_TRACE, "CreateDefaultSecDesc descriptor = 0x%08lx\n", pSecDesc));
|
|
bCreatedDefaultSecDesc = TRUE;
|
|
}
|
|
|
|
appAssert(IsValidSecurityDescriptor(pSecDesc));
|
|
|
|
/* Retrieve the resource strings appropriate for the type of object we
|
|
* are looking at
|
|
*/
|
|
|
|
WCHAR szTypeName[50];
|
|
LoadString(g_hInstance, IDS_ACLEDIT_TITLE, szTypeName, ARRAYLEN(szTypeName));
|
|
|
|
WCHAR szDefaultPermName[50];
|
|
LoadString(g_hInstance, IDS_ACLEDIT_PERM_GEN_READ, szDefaultPermName, ARRAYLEN(szDefaultPermName));
|
|
|
|
/*
|
|
* other misc stuff we need pass to security editor
|
|
*/
|
|
SED_OBJECT_TYPE_DESCRIPTOR sedObjDesc ;
|
|
SED_HELP_INFO sedHelpInfo ;
|
|
GENERIC_MAPPING SHAREGenericMapping ;
|
|
|
|
// setup mappings
|
|
InitializeShareGenericMapping( &SHAREGenericMapping ) ;
|
|
|
|
WCHAR szHelpFile[50];
|
|
LoadString(g_hInstance, IDS_HELPFILENAME, szHelpFile, ARRAYLEN(szHelpFile));
|
|
|
|
sedHelpInfo.pszHelpFileName = szHelpFile;
|
|
|
|
sedHelpInfo.aulHelpContext[HC_MAIN_DLG] = HC_UI_SHELL_BASE + HC_NTSHAREPERMS ;
|
|
sedHelpInfo.aulHelpContext[HC_ADD_USER_DLG] = HC_UI_SHELL_BASE + HC_SHAREADDUSER ;
|
|
sedHelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_LG_DLG] = HC_UI_SHELL_BASE + HC_SHAREADDUSER_LOCALGROUP ;
|
|
sedHelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_GG_DLG] = HC_UI_SHELL_BASE + HC_SHAREADDUSER_GLOBALGROUP ;
|
|
sedHelpInfo.aulHelpContext[HC_ADD_USER_SEARCH_DLG] = HC_UI_SHELL_BASE + HC_SHAREADDUSER_FINDUSER ;
|
|
|
|
// These are not used, set to zero
|
|
sedHelpInfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0 ;
|
|
sedHelpInfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0 ;
|
|
|
|
// setup the object description
|
|
sedObjDesc.Revision = SED_REVISION1 ;
|
|
sedObjDesc.IsContainer = FALSE ;
|
|
sedObjDesc.AllowNewObjectPerms = FALSE ;
|
|
sedObjDesc.MapSpecificPermsToGeneric = TRUE ;
|
|
sedObjDesc.GenericMapping = &SHAREGenericMapping ;
|
|
sedObjDesc.GenericMappingNewObjects = &SHAREGenericMapping ;
|
|
sedObjDesc.HelpInfo = &sedHelpInfo ;
|
|
sedObjDesc.ObjectTypeName = szTypeName ;
|
|
sedObjDesc.SpecialObjectAccessTitle = NULL ;
|
|
|
|
/* Now we need to load the global arrays with the permission names
|
|
* from the resource file.
|
|
*/
|
|
UINT cArrayItems = ARRAYLEN(g_SedAppAccessSharePerms);
|
|
PSED_APPLICATION_ACCESS aSedAppAccess = g_SedAppAccessSharePerms ;
|
|
|
|
/* Loop through each permission title retrieving the text from the
|
|
* resource file and setting the pointer in the array.
|
|
*/
|
|
|
|
for ( UINT i = 0 ; i < cArrayItems ; i++ )
|
|
{
|
|
pszPermName = GetResourceString(g_dwSharePermNames[i]) ;
|
|
if (NULL == pszPermName)
|
|
{
|
|
appDebugOut((DEB_ERROR, "GetResourceString failed\n"));
|
|
break ;
|
|
}
|
|
aSedAppAccess[i].PermissionTitle = pszPermName;
|
|
}
|
|
if (i < cArrayItems)
|
|
{
|
|
appDebugOut((DEB_ERROR, "failed to get all share permission names\n"));
|
|
break ;
|
|
}
|
|
|
|
SED_APPLICATION_ACCESSES sedAppAccesses ;
|
|
sedAppAccesses.Count = cArrayItems ;
|
|
sedAppAccesses.AccessGroup = aSedAppAccess ;
|
|
sedAppAccesses.DefaultPermName = szDefaultPermName;
|
|
|
|
/*
|
|
* pass this along so when the call back function is called,
|
|
* we can set it.
|
|
*/
|
|
SHARE_CALLBACK_INFO callbackinfo ;
|
|
callbackinfo.pSecDesc = NULL;
|
|
callbackinfo.bSecDescModified = FALSE;
|
|
|
|
|
|
// Now, load up the ACL editor and invoke it. We don't keep it around
|
|
// because our DLL is loaded whenever the system is, so we don't want
|
|
// the netui*.dll's hanging around as well...
|
|
|
|
|
|
HINSTANCE hInstanceAclEditor = NULL;
|
|
SedDiscretionaryAclEditorType pSedDiscretionaryAclEditor = NULL;
|
|
|
|
hInstanceAclEditor = LoadLibrary(ACLEDIT_DLL_STRING);
|
|
if (NULL == hInstanceAclEditor)
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "LoadLibrary of acledit.dll failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
pSedDiscretionaryAclEditor = (SedDiscretionaryAclEditorType)
|
|
GetProcAddress(hInstanceAclEditor,SEDDISCRETIONARYACLEDITOR_STRING);
|
|
if ( pSedDiscretionaryAclEditor == NULL )
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "GetProcAddress of SedDiscretionaryAclEditor failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
DWORD dwSedReturnStatus ;
|
|
|
|
appAssert(pSedDiscretionaryAclEditor != NULL);
|
|
err = (*pSedDiscretionaryAclEditor)(
|
|
hwndParent,
|
|
g_hInstance,
|
|
pszServerName,
|
|
&sedObjDesc,
|
|
&sedAppAccesses,
|
|
pszShareName,
|
|
SedCallback,
|
|
(ULONG) &callbackinfo,
|
|
pSecDesc,
|
|
FALSE, // always can read
|
|
FALSE, // If we can read, we can write
|
|
&dwSedReturnStatus,
|
|
0 ) ;
|
|
|
|
if (!FreeLibrary(hInstanceAclEditor))
|
|
{
|
|
LONG err2 = GetLastError();
|
|
appDebugOut((DEB_ERROR, "FreeLibrary of acledit.dll failed, 0x%08lx\n", err2));
|
|
// not fatal: continue...
|
|
}
|
|
|
|
if (0 != err)
|
|
{
|
|
appDebugOut((DEB_ERROR, "SedDiscretionaryAclEditor failed, 0x%08lx\n", err));
|
|
break ;
|
|
}
|
|
|
|
*pbSecDescModified = callbackinfo.bSecDescModified ;
|
|
|
|
if (*pbSecDescModified)
|
|
{
|
|
*ppSecDesc = callbackinfo.pSecDesc;
|
|
|
|
appDebugOut((DEB_TRACE, "After calling acl editor, *ppSecDesc = 0x%08lx\n", *ppSecDesc));
|
|
appAssert(IsValidSecurityDescriptor(*ppSecDesc));
|
|
}
|
|
|
|
} while (FALSE) ;
|
|
|
|
|
|
// Free memory...
|
|
|
|
|
|
UINT cArrayItems = ARRAYLEN(g_SedAppAccessSharePerms);
|
|
PSED_APPLICATION_ACCESS aSedAppAccess = g_SedAppAccessSharePerms ;
|
|
for ( UINT i = 0 ; i < cArrayItems ; i++ )
|
|
{
|
|
pszPermName = aSedAppAccess[i].PermissionTitle;
|
|
if (NULL == pszPermName)
|
|
{
|
|
// if we hit a NULL, that's it!
|
|
break ;
|
|
}
|
|
|
|
delete[] pszPermName;
|
|
}
|
|
|
|
if (bCreatedDefaultSecDesc)
|
|
{
|
|
DeleteDefaultSecDesc(pSecDesc);
|
|
}
|
|
|
|
appAssert(!*pbSecDescModified || IsValidSecurityDescriptor(*ppSecDesc));
|
|
|
|
if (0 != err)
|
|
{
|
|
MyErrorDialog(hwndParent, IERR_NOACLEDITOR);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function: SedCallback
|
|
|
|
// Synopsis: Security Editor callback for the SHARE ACL Editor
|
|
|
|
// Arguments: See sedapi.h
|
|
|
|
// History:
|
|
// ChuckC 10-Aug-1992 Created
|
|
// BruceFo 4-Apr-95 Stole and used in ntshrui.dll
|
|
|
|
|
|
|
|
DWORD
|
|
SedCallback(
|
|
HWND hwndParent,
|
|
HANDLE hInstance,
|
|
ULONG ulCallbackContext,
|
|
PSECURITY_DESCRIPTOR pSecDesc,
|
|
PSECURITY_DESCRIPTOR pSecDescNewObjects,
|
|
BOOLEAN fApplyToSubContainers,
|
|
BOOLEAN fApplyToSubObjects,
|
|
LPDWORD StatusReturn
|
|
)
|
|
{
|
|
appDebugOut((DEB_TRACE, "SedCallback, got pSecDesc = 0x%08lx\n", pSecDesc));
|
|
appAssert(IsValidSecurityDescriptor(pSecDesc));
|
|
|
|
SHARE_CALLBACK_INFO* pCallbackInfo = (SHARE_CALLBACK_INFO *)ulCallbackContext;
|
|
appAssert(NULL != pCallbackInfo);
|
|
|
|
delete[] (BYTE*)pCallbackInfo->pSecDesc;
|
|
pCallbackInfo->pSecDesc = CopySecurityDescriptor(pSecDesc);
|
|
pCallbackInfo->bSecDescModified = TRUE;
|
|
|
|
appAssert(IsValidSecurityDescriptor(pCallbackInfo->pSecDesc));
|
|
appDebugOut((DEB_TRACE, "SedCallback, return pSecDesc = 0x%08lx\n", pCallbackInfo->pSecDesc));
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function: InitializeShareGenericMapping
|
|
|
|
// Synopsis: Initializes the passed generic mapping structure for shares.
|
|
|
|
// Arguments: [pSHAREGenericMapping] - Pointer to GENERIC_MAPPING to be init.
|
|
|
|
// History:
|
|
// ChuckC 10-Aug-1992 Created. Culled from NTFS ACL code.
|
|
// BruceFo 4-Apr-95 Stole and used in ntshrui.dll
|
|
|
|
|
|
|
|
VOID
|
|
InitializeShareGenericMapping(
|
|
IN OUT PGENERIC_MAPPING pSHAREGenericMapping
|
|
)
|
|
{
|
|
appDebugOut((DEB_ITRACE, "InitializeShareGenericMapping\n"));
|
|
|
|
pSHAREGenericMapping->GenericRead = FILE_GENERIC_READ ;
|
|
pSHAREGenericMapping->GenericWrite = FILE_GENERIC_WRITE ;
|
|
pSHAREGenericMapping->GenericExecute = FILE_GENERIC_EXECUTE ;
|
|
pSHAREGenericMapping->GenericAll = FILE_ALL_ACCESS ;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function: CreateDefaultSecDesc
|
|
|
|
// Synopsis: Create a default ACL for either a new share or for
|
|
// a share that dont exist.
|
|
|
|
// Arguments: [ppSecDesc] - *ppSecDesc points to a "world all" access
|
|
// security descriptor on exit. Caller is responsible for
|
|
// freeing it.
|
|
|
|
// Returns: NERR_Success if OK, api error otherwise.
|
|
|
|
// History:
|
|
// ChuckC 10-Aug-1992 Created. Culled from NTFS ACL code.
|
|
// BruceFo 4-Apr-95 Stole and used in ntshrui.dll
|
|
|
|
|
|
|
|
LONG
|
|
CreateDefaultSecDesc(
|
|
OUT PSECURITY_DESCRIPTOR* ppSecDesc
|
|
)
|
|
{
|
|
appDebugOut((DEB_ITRACE, "CreateDefaultSecDesc\n"));
|
|
|
|
appAssert(NULL != ppSecDesc) ;
|
|
appAssert(NULL == *ppSecDesc) ;
|
|
|
|
LONG err = NERR_Success;
|
|
PSECURITY_DESCRIPTOR pSecDesc = NULL;
|
|
PACL pAcl = NULL;
|
|
DWORD cbAcl;
|
|
PSID pSid = NULL;
|
|
|
|
*ppSecDesc = NULL;
|
|
|
|
do // error breakout
|
|
{
|
|
// First, create a world SID. Next, create an access allowed
|
|
// ACE with "Generic All" access with the world SID. Put the ACE in
|
|
// the ACL and the ACL in the security descriptor.
|
|
|
|
SID_IDENTIFIER_AUTHORITY IDAuthorityWorld = SECURITY_WORLD_SID_AUTHORITY;
|
|
|
|
if (!AllocateAndInitializeSid(
|
|
&IDAuthorityWorld,
|
|
1,
|
|
SECURITY_WORLD_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pSid))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "AllocateAndInitializeSid failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
appAssert(IsValidSid(pSid));
|
|
|
|
cbAcl = sizeof(ACL)
|
|
+ (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
|
|
+ GetLengthSid(pSid)
|
|
;
|
|
|
|
pAcl = (PACL) new BYTE[cbAcl];
|
|
if (NULL == pAcl)
|
|
{
|
|
err = ERROR_OUTOFMEMORY;
|
|
appDebugOut((DEB_ERROR, "new ACL failed\n"));
|
|
break;
|
|
}
|
|
|
|
if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION2))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "InitializeAcl failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
if (!AddAccessAllowedAce(
|
|
pAcl,
|
|
ACL_REVISION2,
|
|
GENERIC_ALL,
|
|
pSid))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "AddAccessAllowedAce failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
appAssert(IsValidAcl(pAcl));
|
|
|
|
pSecDesc = (PSECURITY_DESCRIPTOR) new BYTE[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
|
if (NULL == pSecDesc)
|
|
{
|
|
err = ERROR_OUTOFMEMORY;
|
|
appDebugOut((DEB_ERROR, "new SECURITY_DESCRIPTOR failed\n"));
|
|
break;
|
|
}
|
|
|
|
if (!InitializeSecurityDescriptor(
|
|
pSecDesc,
|
|
SECURITY_DESCRIPTOR_REVISION1))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "InitializeSecurityDescriptor failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
if (!SetSecurityDescriptorDacl(
|
|
pSecDesc,
|
|
TRUE,
|
|
pAcl,
|
|
FALSE))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "SetSecurityDescriptorDacl failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
appAssert(IsValidSecurityDescriptor(pSecDesc));
|
|
|
|
// Make the security descriptor self-relative
|
|
|
|
DWORD dwLen = GetSecurityDescriptorLength(pSecDesc);
|
|
appDebugOut((DEB_ITRACE, "SECURITY_DESCRIPTOR length = %d\n", dwLen));
|
|
|
|
PSECURITY_DESCRIPTOR pSelfSecDesc = (PSECURITY_DESCRIPTOR) new BYTE[dwLen];
|
|
if (NULL == pSelfSecDesc)
|
|
{
|
|
err = ERROR_OUTOFMEMORY;
|
|
appDebugOut((DEB_ERROR, "new SECURITY_DESCRIPTOR (2) failed\n"));
|
|
break;
|
|
}
|
|
|
|
DWORD cbSelfSecDesc = dwLen;
|
|
if (!MakeSelfRelativeSD(pSecDesc, pSelfSecDesc, &cbSelfSecDesc))
|
|
{
|
|
err = GetLastError();
|
|
appDebugOut((DEB_ERROR, "MakeSelfRelativeSD failed, 0x%08lx\n", err));
|
|
break;
|
|
}
|
|
|
|
appAssert(IsValidSecurityDescriptor(pSelfSecDesc));
|
|
|
|
|
|
// all done: set the security descriptor
|
|
|
|
|
|
*ppSecDesc = pSelfSecDesc;
|
|
|
|
} while (FALSE) ;
|
|
|
|
if (NULL != pSid)
|
|
{
|
|
FreeSid(pSid);
|
|
}
|
|
delete[] (BYTE*)pAcl;
|
|
delete[] (BYTE*)pSecDesc;
|
|
|
|
appAssert(IsValidSecurityDescriptor(*ppSecDesc));
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function: DeleteDefaultSecDesc
|
|
|
|
// Synopsis: Delete a security descriptor that was created by
|
|
// CreateDefaultSecDesc
|
|
|
|
// Arguments: [pSecDesc] - security descriptor to delete
|
|
|
|
// Returns: nothing
|
|
|
|
// History:
|
|
// BruceFo 4-Apr-95 Created
|
|
|
|
|
|
|
|
VOID
|
|
DeleteDefaultSecDesc(
|
|
IN PSECURITY_DESCRIPTOR pSecDesc
|
|
)
|
|
{
|
|
appDebugOut((DEB_ITRACE, "DeleteDefaultSecDesc\n"));
|
|
|
|
delete[] (BYTE*)pSecDesc;
|
|
}
|