1611 lines
47 KiB
C++
1611 lines
47 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 - 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dsacls.c
|
|
|
|
Abstract:
|
|
|
|
This Module implements the delegation tool, which allows for the management
|
|
of access to DS objects
|
|
|
|
Author:
|
|
|
|
Mac McLain (MacM) 10-15-96
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
Revision History:
|
|
|
|
Hitesh Raigandhi (hiteshr 6-29-98)
|
|
1: Changed the code to Old NTMART API's
|
|
2: Redesigned the structure
|
|
|
|
|
|
--*/
|
|
#include "stdafx.h"
|
|
#include "utils.h"
|
|
#include "dsace.h"
|
|
#include "dsacls.h"
|
|
|
|
#define DSACL_DBG 1
|
|
|
|
|
|
//
|
|
// Local helper macros
|
|
//
|
|
#define FLAG_ON(flag,bits) ((flag) & (bits))
|
|
#define IS_CMD_FLAG( string ) (*(string) == L'-' || *(string) == L'/' )
|
|
|
|
|
|
DSACLS_ARG DsAclsArgs[] = {
|
|
{ MSG_TAG_CI, NULL, 0, 0, MSG_TAG_CI, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED },
|
|
{ MSG_TAG_CN, NULL, 0, 0, MSG_TAG_CN, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CP, NULL, 0, 0, MSG_TAG_CP, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED },
|
|
{ MSG_TAG_CG, NULL, 0, 0, MSG_TAG_CG, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CD, NULL, 0, 0, MSG_TAG_CD, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CR, NULL, 0, 0, MSG_TAG_CR, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CS, NULL, 0, 0, MSG_TAG_CS, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CT, NULL, 0, 0, MSG_TAG_CT, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_CA, NULL, 0, 0, MSG_TAG_CA, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
|
|
{ MSG_TAG_GETSDDL,NULL, 0, 0, MSG_TAG_GETSDDL, 0, FALSE, DSACLS_EXTRA_INFO_OPTIONAL },
|
|
{ MSG_TAG_SETSDDL,NULL, 0, 0, MSG_TAG_SETSDDL, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED }
|
|
};
|
|
|
|
|
|
DSACLS_INHERIT DsAclsInherit[] = {
|
|
{ MSG_TAG_IS, NULL, 0, TRUE, CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE},
|
|
{ MSG_TAG_IT, NULL, 0, TRUE, CONTAINER_INHERIT_ACE },
|
|
{ MSG_TAG_IP, NULL, 0, TRUE, INHERIT_NO_PROPAGATE },
|
|
{ MSG_TAG_ID, NULL, 0, FALSE, INHERITED_ACCESS_ENTRY }
|
|
};
|
|
|
|
DSACLS_RIGHTS DsAclsRights[] = {
|
|
{ MSG_TAG_GR, NULL,MSG_TAG_GR_EX,NULL, 0, GENERIC_READ },
|
|
{ MSG_TAG_GE, NULL,MSG_TAG_GE_EX,NULL, 0, GENERIC_EXECUTE },
|
|
{ MSG_TAG_GW, NULL,MSG_TAG_GW_EX,NULL, 0, GENERIC_WRITE },
|
|
{ MSG_TAG_GA, NULL,MSG_TAG_GA_EX,NULL, 0, GENERIC_ALL },
|
|
{ MSG_TAG_SD, NULL,MSG_TAG_SD_EX,NULL, 0, DELETE },
|
|
{ MSG_TAG_RC, NULL,MSG_TAG_RC_EX,NULL, 0, READ_CONTROL },
|
|
{ MSG_TAG_WD, NULL,MSG_TAG_WD_EX,NULL, 0, WRITE_DAC },
|
|
{ MSG_TAG_WO, NULL,MSG_TAG_WO_EX,NULL, 0, WRITE_OWNER },
|
|
{ MSG_TAG_CC, NULL,MSG_TAG_CC_EX,NULL, 0, ACTRL_DS_CREATE_CHILD },
|
|
{ MSG_TAG_DC, NULL,MSG_TAG_DC_EX,NULL, 0, ACTRL_DS_DELETE_CHILD },
|
|
{ MSG_TAG_LC, NULL,MSG_TAG_LC_EX,NULL, 0, ACTRL_DS_LIST },
|
|
{ MSG_TAG_WS, NULL,MSG_TAG_WS_EX,NULL, 0, ACTRL_DS_SELF },
|
|
{ MSG_TAG_WP, NULL,MSG_TAG_WP_EX,NULL, 0, ACTRL_DS_WRITE_PROP },
|
|
{ MSG_TAG_RP, NULL,MSG_TAG_RP_EX,NULL, 0, ACTRL_DS_READ_PROP },
|
|
{ MSG_TAG_DT, NULL,MSG_TAG_DT_EX,NULL, 0, ACTRL_DS_DELETE_TREE },
|
|
{ MSG_TAG_LO, NULL,MSG_TAG_LO_EX,NULL, 0, ACTRL_DS_LIST_OBJECT },
|
|
{ MSG_TAG_AC, NULL,MSG_TAG_AC_EX,NULL, 0, ACTRL_DS_CONTROL_ACCESS } //This is only for input
|
|
};
|
|
|
|
DSACLS_PROTECT DsAclsProtect[] = {
|
|
{ MSG_TAG_PY, NULL, 0, PROTECTED_DACL_SECURITY_INFORMATION },
|
|
{ MSG_TAG_PN, NULL, 0, UNPROTECTED_DACL_SECURITY_INFORMATION }
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
Displays The security Descriptor
|
|
*/
|
|
DWORD
|
|
DumpAccess (
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN BOOL bDisplayAuditAndOwner
|
|
)
|
|
{
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
|
|
DWORD dwRevision;
|
|
PSID psidOwner = NULL;
|
|
PSID psidGroup = NULL;
|
|
PACL pDacl = NULL;
|
|
PACL pSacl = NULL;
|
|
BOOL bDefaulted;
|
|
BOOL bPresent;
|
|
LPWSTR pOwnerName = NULL;
|
|
LPWSTR pGroupName = NULL;
|
|
CAcl * pCSacl = NULL;
|
|
CAcl * pCDacl = NULL;
|
|
UINT nLen1 = 0;
|
|
UINT nLen2 = 0;
|
|
UINT nAllowDeny = 0;
|
|
UINT nAudit = 0;
|
|
WCHAR szLoadBuffer[1024];
|
|
|
|
if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
|
|
{
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
if( !GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted) )
|
|
{
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
if( !GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted) )
|
|
{
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
if( !GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted) )
|
|
{
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
if( !GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted) )
|
|
{
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
//Find out the Max len out of ( ALLOW, DENY ) and ( FAILURE, SUCCESS, BOTH)
|
|
nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_ALLOW, szLoadBuffer, 1023 );
|
|
nLen2 = LoadStringW( g_hInstance, MSG_DSACLS_DENY, szLoadBuffer, 1023 );
|
|
nAllowDeny = ( nLen1 > nLen2 ) ? nLen1 : nLen2;
|
|
nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_SUCCESS, szLoadBuffer, 1023 );
|
|
nLen2 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_FAILURE, szLoadBuffer, 1023 );
|
|
nAudit = ( nLen1 > nLen2 ) ? nLen1 : nLen2;
|
|
nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_ALL, szLoadBuffer, 1023 );
|
|
nAudit = ( nLen1 > nAudit ) ? nLen1 : nAudit;
|
|
|
|
|
|
if( bDisplayAuditAndOwner )
|
|
{
|
|
pCSacl = new CAcl();
|
|
CHECK_NULL( pCSacl, CLEAN_RETURN );
|
|
dwErr = pCSacl->Initialize(wSDControl & SE_SACL_PROTECTED,
|
|
pSacl,
|
|
nAllowDeny,
|
|
nAudit );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
return dwErr;
|
|
}
|
|
pCDacl = new CAcl();
|
|
CHECK_NULL( pCDacl,CLEAN_RETURN );
|
|
dwErr = pCDacl->Initialize(wSDControl & SE_DACL_PROTECTED,
|
|
pDacl,
|
|
nAllowDeny,
|
|
nAudit);
|
|
|
|
if( dwErr != ERROR_SUCCESS )
|
|
return dwErr;
|
|
|
|
if( ( dwErr = g_Cache->BuildCache() ) != ERROR_SUCCESS )
|
|
return dwErr;
|
|
|
|
pCDacl->GetInfoFromCache();
|
|
if( bDisplayAuditAndOwner )
|
|
{
|
|
if( ( dwErr = GetAccountNameFromSid( g_szServerName, psidOwner, &pOwnerName ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
DisplayMessageEx( 0, MSG_DSACLS_OWNER, pOwnerName );
|
|
if( ( dwErr = GetAccountNameFromSid( g_szServerName, psidGroup, &pGroupName ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
DisplayMessageEx( 0, MSG_DSACLS_GROUP, pGroupName );
|
|
DisplayNewLine();
|
|
DisplayMessageEx( 0, MSG_DSACLS_AUDIT );
|
|
pCSacl->Display();
|
|
DisplayNewLine();
|
|
}
|
|
|
|
|
|
DisplayMessageEx( 0, MSG_DSACLS_ACCESS );
|
|
pCDacl->Display();
|
|
|
|
CLEAN_RETURN:
|
|
if( pOwnerName )
|
|
LocalFree( pOwnerName );
|
|
if( pGroupName )
|
|
LocalFree( pGroupName );
|
|
if( pCSacl )
|
|
delete pCSacl;
|
|
if( pCDacl )
|
|
delete pCDacl;
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
This Function process the command line argument for /D /R /G
|
|
options and add the corresponding aces to pAcl.
|
|
*/
|
|
DWORD
|
|
ProcessCmdlineUsers ( IN WCHAR *argv[],
|
|
IN PDSACLS_ARG AclsArg,
|
|
IN DSACLS_OP Op,
|
|
IN ULONG Inheritance,
|
|
IN ULONG RightsListCount,
|
|
IN PDSACLS_RIGHTS RightsList,
|
|
OUT CAcl *pAcl )
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
ULONG i, j;
|
|
ULONG AccIndex, Access;
|
|
PEXPLICIT_ACCESS pListOfExplicitEntries = NULL;
|
|
PWSTR pObjectId = NULL;
|
|
PWSTR pTrustee = NULL;
|
|
PWSTR pInheritId = NULL;
|
|
ACCESS_MODE AccessMode;
|
|
CAce * pAce = NULL;
|
|
switch ( Op ) {
|
|
case REVOKE:
|
|
AccessMode = REVOKE_ACCESS;
|
|
break;
|
|
|
|
case GRANT:
|
|
AccessMode = GRANT_ACCESS;
|
|
break;
|
|
|
|
case DENY:
|
|
AccessMode = DENY_ACCESS;
|
|
break;
|
|
|
|
default:
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
goto FAILURE_RETURN;
|
|
|
|
for ( i = 0; i < AclsArg->SkipCount && dwErr == ERROR_SUCCESS; i++ )
|
|
{
|
|
dwErr = ParseUserAndPermissons( argv[AclsArg->StartIndex + 1 + i],
|
|
Op,
|
|
RightsListCount,
|
|
RightsList,
|
|
&pTrustee,
|
|
&Access,
|
|
&pObjectId,
|
|
&pInheritId );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto FAILURE_RETURN;
|
|
|
|
pAce = new CAce();
|
|
CHECK_NULL( pAce , FAILURE_RETURN);
|
|
dwErr= pAce->Initialize( pTrustee,
|
|
pObjectId,
|
|
pInheritId,
|
|
AccessMode,
|
|
Access,
|
|
Inheritance );
|
|
|
|
if( dwErr != ERROR_SUCCESS )
|
|
return dwErr;
|
|
|
|
pAcl->AddAce( pAce );
|
|
|
|
if( pObjectId )
|
|
{
|
|
LocalFree( pObjectId );
|
|
pObjectId = NULL;
|
|
}
|
|
|
|
if( pInheritId )
|
|
{
|
|
LocalFree( pInheritId );
|
|
pInheritId = NULL;
|
|
}
|
|
if( pTrustee )
|
|
{
|
|
LocalFree( pTrustee );
|
|
pTrustee = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
FAILURE_RETURN:
|
|
if( pObjectId )
|
|
{
|
|
LocalFree( pObjectId );
|
|
pObjectId = NULL;
|
|
}
|
|
|
|
if( pInheritId )
|
|
{
|
|
LocalFree( pInheritId );
|
|
pInheritId = NULL;
|
|
}
|
|
if( pTrustee )
|
|
{
|
|
LocalFree( pTrustee );
|
|
pTrustee = NULL;
|
|
}
|
|
|
|
return( dwErr );
|
|
}
|
|
|
|
//These five are global variables used by the dsacls
|
|
LPWSTR g_szSchemaNamingContext;
|
|
LPWSTR g_szConfigurationNamingContext;
|
|
HMODULE g_hInstance;
|
|
LPWSTR g_szServerName;
|
|
CCache *g_Cache;
|
|
|
|
__cdecl
|
|
main (
|
|
IN INT argc,
|
|
IN CHAR *argv[]
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
ULONG Length, Options = 0;
|
|
PWSTR pszObjectPath = NULL;
|
|
PWSTR pszLDAPObjectPath = NULL;
|
|
PSTR SddlString = NULL, TempString;
|
|
LPWSTR FileName = NULL;
|
|
CHAR ReadString[ 512 ];
|
|
BOOLEAN Mapped;
|
|
LPWSTR CurrentInherit = NULL;
|
|
LPWSTR CurrentProtect = NULL;
|
|
ULONG Inheritance = 0;
|
|
SECURITY_INFORMATION Protection = 0;
|
|
ULONG SddlStringLength = 0;
|
|
WCHAR ** wargv = NULL;
|
|
ULONG i = 0;
|
|
ULONG j = 0;
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
PACL pDacl = NULL;
|
|
SECURITY_INFORMATION SecurityInformation = DACL_SECURITY_INFORMATION;
|
|
PSECURITY_DESCRIPTOR pTempSD = NULL;
|
|
PACL pNewDacl = NULL;
|
|
CAcl * pCAclOld = NULL;
|
|
CAcl *pCAclNew = NULL;
|
|
BOOL bErrorShown = FALSE;
|
|
|
|
//Initialize Com Library
|
|
HRESULT hr = CoInitialize(NULL);
|
|
CHECK_HR(hr, CLEAN_RETURN);
|
|
//Get Instance Handle
|
|
g_hInstance = GetModuleHandle(NULL);
|
|
//Create global instance of Cache
|
|
g_Cache = new CCache();
|
|
CHECK_NULL(g_Cache,CLEAN_RETURN);
|
|
|
|
setlocale( LC_CTYPE, "" );
|
|
|
|
//Initialize Global Arrays
|
|
if( ( dwErr = InitializeGlobalArrays() ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
|
|
if ( argc == 1 )
|
|
{
|
|
DisplayMessage( 0, MSG_DSACLS_USAGE );
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
//Convert argv to Unicode
|
|
wargv = (LPWSTR*)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, argc * sizeof(LPWSTR) );
|
|
CHECK_NULL(wargv, CLEAN_RETURN );
|
|
|
|
if( ( dwErr = ConvertArgvToUnicode( wargv, argv, argc ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
//First Argument is Object Path or /?
|
|
if( IS_CMD_FLAG( wargv[ 1 ] ) )
|
|
{
|
|
if ( _wcsicmp( wargv[ 1 ] + 1, L"?" ) != 0 )
|
|
DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[1] );
|
|
|
|
DisplayMessage(0,MSG_DSACLS_USAGE);
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
Length = wcslen( wargv[1] );
|
|
pszObjectPath = (LPWSTR)LocalAlloc( LMEM_FIXED,
|
|
( Length + 1 ) * sizeof( WCHAR ) );
|
|
if ( !pszObjectPath )
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto CLEAN_RETURN;
|
|
} else
|
|
{
|
|
wcscpy( pszObjectPath,
|
|
wargv[ 1 ] );
|
|
}
|
|
//Get the name of server
|
|
dwErr = GetServerName( pszObjectPath, &g_szServerName );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
if( ( dwErr = BuildLdapPath( &pszLDAPObjectPath,
|
|
g_szServerName,
|
|
pszObjectPath ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
//Get Schema and Configuration naming context
|
|
dwErr = GetGlobalNamingContexts( g_szServerName,
|
|
&g_szSchemaNamingContext,
|
|
&g_szConfigurationNamingContext );
|
|
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
|
|
//
|
|
// Parse the command line
|
|
//
|
|
i = 2;
|
|
while ( i < ( ULONG )argc && dwErr == ERROR_SUCCESS )
|
|
{
|
|
if ( IS_CMD_FLAG( wargv[ i ] ) )
|
|
{
|
|
if ( !_wcsicmp( wargv[ i ] + 1, L"?" ) ) {
|
|
DisplayMessage( 0, MSG_DSACLS_USAGE );
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
Mapped = FALSE;
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
|
|
{
|
|
if ( !wcsncmp( wargv[ i ] + 1, DsAclsArgs[ j ].String,DsAclsArgs[ j ].Length ) )
|
|
{
|
|
if( DsAclsArgs[ j ].ExtraInfo )
|
|
{
|
|
if( ( DsAclsArgs[ j ].ExtraInfo == DSACLS_EXTRA_INFO_REQUIRED &&
|
|
wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == ':' &&
|
|
wargv[ i ][ DsAclsArgs[ j ].Length + 2 ] != '\0' ) ||
|
|
(DsAclsArgs[ j ].ExtraInfo == DSACLS_EXTRA_INFO_OPTIONAL &&
|
|
( ( wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == ':' &&
|
|
wargv[ i ][ DsAclsArgs[ j ].Length + 2 ] != '\0' ) ||
|
|
wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == '\0' ) ) )
|
|
{
|
|
Mapped = TRUE;
|
|
}
|
|
|
|
} else
|
|
{
|
|
Mapped = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}//For
|
|
|
|
|
|
if ( Mapped )
|
|
{
|
|
DsAclsArgs[ j ].StartIndex = i;
|
|
Options |= DsAclsArgs[ j ].Flag;
|
|
if ( DsAclsArgs[ j ].SkipNonFlag )
|
|
{
|
|
while ( i + 1 < ( ULONG )argc && !IS_CMD_FLAG( wargv[ i + 1 ] ) )
|
|
{
|
|
i++;
|
|
DsAclsArgs[ j ].SkipCount++;
|
|
}
|
|
|
|
if ( DsAclsArgs[ j ].SkipCount == 0 )
|
|
{
|
|
DisplayMessageEx( 0, MSG_DSACLS_NO_UA,
|
|
wargv[i] );
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[i] );
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
} else
|
|
{
|
|
DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[i] );
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
i++;
|
|
}//While
|
|
|
|
//Validate the command line argument
|
|
|
|
/*
|
|
if ( !FLAG_ON( Options, MSG_TAG_CR | MSG_TAG_CD | MSG_TAG_CG | MSG_TAG_CT | MSG_TAG_CS ) )
|
|
{
|
|
if ( FLAG_ON( Options, MSG_TAG_GETSDDL ) )
|
|
{
|
|
|
|
if ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
|
|
if ( !ConvertSecurityDescriptorToStringSecurityDescriptorA( pSD,
|
|
SDDL_REVISION,
|
|
SecurityInformation,
|
|
&SddlString,
|
|
NULL ) )
|
|
{
|
|
dwErr = GetLastError();
|
|
} else
|
|
{
|
|
//
|
|
// Get the file name to write it to if necessary
|
|
//
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
|
|
{
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_GETSDDL )
|
|
{
|
|
FileName = wcschr( wargv[ DsAclsArgs[ j ].StartIndex ] , L':' );
|
|
if ( FileName )
|
|
{
|
|
FileName++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( FileName )
|
|
{
|
|
HANDLE FileHandle = CreateFile( FileName,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL );
|
|
|
|
if ( FileHandle == INVALID_HANDLE_VALUE )
|
|
{
|
|
|
|
dwErr = GetLastError();
|
|
|
|
} else
|
|
{
|
|
|
|
ULONG BytesWritten;
|
|
|
|
if ( WriteFile( FileHandle,
|
|
( PVOID )SddlString,
|
|
strlen( SddlString ),
|
|
&BytesWritten,
|
|
NULL ) == FALSE )
|
|
{
|
|
dwErr = GetLastError();
|
|
} else
|
|
{
|
|
ASSERT( strlen( SddlString ) == BytesWritten );
|
|
}
|
|
CloseHandle( FileHandle );
|
|
}
|
|
} else
|
|
{
|
|
|
|
printf( "%s\n", SddlString );
|
|
}
|
|
LocalFree( SddlString );
|
|
}
|
|
|
|
//LocalFree( SD );
|
|
}
|
|
|
|
} else {
|
|
|
|
DumpAccess( pSD,
|
|
FLAG_ON( Options, MSG_TAG_CA ),
|
|
sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ),
|
|
DsAclsInherit,
|
|
sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
|
|
DsAclsRights );
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
//
|
|
// If we are parsing an SDDL file, go ahead and do that now...
|
|
//
|
|
if ( FLAG_ON( Options, MSG_TAG_SETSDDL ) )
|
|
{
|
|
|
|
//
|
|
// First, open the file
|
|
//
|
|
HANDLE FileHandle = INVALID_HANDLE_VALUE;
|
|
|
|
//
|
|
// Get the file name to write it to if necessary
|
|
//
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
|
|
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_SETSDDL ) {
|
|
|
|
FileName = wcschr( wargv[ DsAclsArgs[ j ].StartIndex ] , L':' );
|
|
if ( FileName ) {
|
|
|
|
FileName++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !FileName ) {
|
|
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
FileHandle = CreateFile( FileName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL );
|
|
|
|
if ( FileHandle == INVALID_HANDLE_VALUE ) {
|
|
|
|
dwErr = GetLastError();
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
//
|
|
// Now, parse it...
|
|
//
|
|
SddlStringLength = 0;
|
|
SddlString = NULL;
|
|
while ( TRUE ) {
|
|
|
|
ULONG Read = 0, Len = 0;
|
|
PSTR ReadPtr, TempPtr;
|
|
|
|
if ( ReadFile( FileHandle,
|
|
ReadString,
|
|
sizeof( ReadString ) / sizeof( CHAR ),
|
|
&Read,
|
|
NULL ) == FALSE ) {
|
|
|
|
dwErr = GetLastError();
|
|
break;
|
|
}
|
|
|
|
if ( Read == 0 ) {
|
|
|
|
break;
|
|
}
|
|
|
|
if ( *ReadString == ';' ) {
|
|
|
|
continue;
|
|
}
|
|
|
|
Len = SddlStringLength + ( Read / sizeof( CHAR ) );
|
|
|
|
TempString = (LPSTR)LocalAlloc( LMEM_FIXED,
|
|
Len + sizeof( CHAR ) );
|
|
|
|
if ( TempString ) {
|
|
|
|
if ( SddlString ) {
|
|
|
|
strcpy( TempString, SddlString );
|
|
|
|
} else {
|
|
|
|
*TempString = '\0';
|
|
}
|
|
|
|
TempPtr = TempString + SddlStringLength;
|
|
ReadPtr = ReadString;
|
|
|
|
while( Read-- > 0 ) {
|
|
|
|
if ( !isspace( *ReadPtr ) ) {
|
|
|
|
*TempPtr++ = *ReadPtr;
|
|
SddlStringLength++;
|
|
}
|
|
|
|
ReadPtr++;
|
|
}
|
|
|
|
*TempPtr = '\0';
|
|
|
|
LocalFree( SddlString );
|
|
SddlString = TempString;
|
|
|
|
} else {
|
|
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if ( dwErr == ERROR_SUCCESS ) {
|
|
|
|
//
|
|
// Convert it to a security descriptor, then to an access list, then set it.
|
|
//
|
|
if ( ConvertStringSecurityDescriptorToSecurityDescriptorA( SddlString,
|
|
SDDL_REVISION,
|
|
&pTempSD,
|
|
NULL ) == FALSE ) {
|
|
|
|
dwErr = GetLastError();
|
|
|
|
} else {
|
|
|
|
dwErr = WriteObjectSecurity( pszObjectPath,
|
|
DACL_SECURITY_INFORMATION,
|
|
pTempSD );
|
|
|
|
LocalFree( pTempSD );
|
|
}
|
|
}
|
|
|
|
LocalFree( SddlString );
|
|
|
|
if ( FileHandle != INVALID_HANDLE_VALUE ) {
|
|
|
|
CloseHandle( FileHandle );
|
|
}
|
|
|
|
goto CLEAN_RETURN;
|
|
}
|
|
*/
|
|
|
|
//
|
|
// Get the inheritance flags set
|
|
//
|
|
if ( FLAG_ON( Options, MSG_TAG_CI ) )
|
|
{
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
|
|
{
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_CI )
|
|
{
|
|
CurrentInherit = wargv[ DsAclsArgs[ j ].StartIndex ] + 3;
|
|
while ( CurrentInherit && *CurrentInherit && dwErr == ERROR_SUCCESS )
|
|
{
|
|
for ( i = 0; i < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); i++ )
|
|
{
|
|
if ( !_wcsnicmp( CurrentInherit,
|
|
DsAclsInherit[ i ].String,
|
|
DsAclsInherit[ i ].Length ) )
|
|
{
|
|
|
|
if ( !DsAclsInherit[ i ].ValidForInput )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
Inheritance |= DsAclsInherit[ i ].InheritFlag;
|
|
CurrentInherit += DsAclsInherit[ i ].Length;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( i == ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ) )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Get the protection flag
|
|
if ( FLAG_ON( Options, MSG_TAG_CP ) )
|
|
{
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
|
|
{
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_CP )
|
|
{
|
|
CurrentProtect = wargv[ DsAclsArgs[ j ].StartIndex ] + DsAclsArgs[ j ].Length + 2;
|
|
while ( CurrentProtect && *CurrentProtect )
|
|
{
|
|
for ( i = 0; i < ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ); i++ )
|
|
{
|
|
if ( !_wcsnicmp( CurrentProtect,
|
|
DsAclsProtect[ i ].String,
|
|
DsAclsProtect[ i ].Length ) )
|
|
{
|
|
|
|
Protection |= DsAclsProtect[ i ].Right;
|
|
CurrentProtect += DsAclsProtect[ i ].Length;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( i == ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ) )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Start processing them in order
|
|
//
|
|
if ( FLAG_ON( Options, MSG_TAG_CR | MSG_TAG_CD | MSG_TAG_CG | MSG_TAG_CP ) )
|
|
{
|
|
//
|
|
// Get the current information, if required
|
|
//
|
|
if( !FLAG_ON( Options, MSG_TAG_CN ) )
|
|
{
|
|
SecurityInformation = DACL_SECURITY_INFORMATION;
|
|
|
|
dwErr = GetNamedSecurityInfo( pszLDAPObjectPath,
|
|
SE_DS_OBJECT_ALL,
|
|
SecurityInformation,
|
|
NULL,
|
|
NULL,
|
|
&pDacl,
|
|
NULL,
|
|
&pSD );
|
|
|
|
if ( dwErr != ERROR_SUCCESS ) {
|
|
goto CLEAN_RETURN;
|
|
}
|
|
//pCAclOld represents existing ACL
|
|
pCAclOld = new CAcl();
|
|
CHECK_NULL( pCAclOld, CLEAN_RETURN );
|
|
dwErr = pCAclOld->Initialize( FALSE, pDacl,0 ,0 );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
if( !FLAG_ON( Options, MSG_TAG_CP ) )
|
|
{
|
|
dwErr = GetProtection( pSD, &Protection );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
}
|
|
}
|
|
|
|
pCAclNew = new CAcl();
|
|
CHECK_NULL( pCAclNew, CLEAN_RETURN );
|
|
|
|
//
|
|
// Grant
|
|
//
|
|
if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CG ) ) {
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
|
|
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_CG ) {
|
|
|
|
dwErr = ProcessCmdlineUsers( wargv,
|
|
&DsAclsArgs[ j ],
|
|
GRANT,
|
|
Inheritance,
|
|
sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
|
|
DsAclsRights,
|
|
pCAclNew );
|
|
|
|
if ( dwErr != ERROR_SUCCESS ) {
|
|
goto CLEAN_RETURN;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CD ) ) {
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
|
|
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_CD ) {
|
|
|
|
dwErr = ProcessCmdlineUsers( wargv,
|
|
&DsAclsArgs[ j ],
|
|
DENY,
|
|
Inheritance,
|
|
sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
|
|
DsAclsRights,
|
|
pCAclNew );
|
|
|
|
if ( dwErr != ERROR_SUCCESS ) {
|
|
goto CLEAN_RETURN;
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CR ) ) {
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
|
|
|
|
if ( DsAclsArgs[ j ].Flag == MSG_TAG_CR ) {
|
|
|
|
dwErr = ProcessCmdlineUsers( wargv,
|
|
&DsAclsArgs[ j ],
|
|
REVOKE,
|
|
Inheritance,
|
|
sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
|
|
DsAclsRights,
|
|
pCAclNew );
|
|
|
|
if ( dwErr != ERROR_SUCCESS ) {
|
|
goto CLEAN_RETURN;
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//Build Cache
|
|
g_Cache->BuildCache();
|
|
//Verify that we have been able to convert all ObjectType and InheritedObjectType
|
|
// names to GUIDs
|
|
pCAclNew->GetInfoFromCache();
|
|
if( !pCAclNew->VerifyAllNames() )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto CLEAN_RETURN;
|
|
}
|
|
if( pCAclOld )
|
|
pCAclOld->GetInfoFromCache();
|
|
|
|
if( pCAclOld )
|
|
{
|
|
pCAclOld->MergeAcl( pCAclNew );
|
|
if(( dwErr = pCAclOld->BuildAcl( &pNewDacl ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
}
|
|
else
|
|
{
|
|
if( ( dwErr = pCAclNew->BuildAcl( &pNewDacl ) ) != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
}
|
|
SecurityInformation = DACL_SECURITY_INFORMATION | Protection;
|
|
dwErr = SetNamedSecurityInfo ( pszLDAPObjectPath,
|
|
SE_DS_OBJECT_ALL,
|
|
SecurityInformation,
|
|
NULL,
|
|
NULL,
|
|
pNewDacl,
|
|
NULL );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
}
|
|
|
|
//
|
|
// Now, see if we have to restore any security to the defaults
|
|
//
|
|
if ( FLAG_ON( Options, MSG_TAG_CS ) ) {
|
|
|
|
dwErr = SetDefaultSecurityOnObjectTree( pszObjectPath,
|
|
( BOOLEAN )( FLAG_ON( Options, MSG_TAG_CT ) ?
|
|
TRUE : FALSE ),Protection );
|
|
if( dwErr != ERROR_SUCCESS )
|
|
goto CLEAN_RETURN;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//Display the security
|
|
if( pSD )
|
|
{
|
|
LocalFree( pSD );
|
|
pSD = NULL;
|
|
}
|
|
|
|
SecurityInformation = DACL_SECURITY_INFORMATION;
|
|
if ( FLAG_ON( Options, MSG_TAG_CA ) )
|
|
{
|
|
SecurityInformation |= SACL_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
OWNER_SECURITY_INFORMATION;
|
|
}
|
|
dwErr = GetNamedSecurityInfo( pszLDAPObjectPath,
|
|
SE_DS_OBJECT_ALL,
|
|
SecurityInformation,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&pSD );
|
|
|
|
if( dwErr != ERROR_SUCCESS )
|
|
{
|
|
if( dwErr == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
DisplayMessageEx( 0, MSG_INVALID_OBJECT_PATH );
|
|
bErrorShown = TRUE;
|
|
}
|
|
goto CLEAN_RETURN;
|
|
}
|
|
|
|
dwErr = DumpAccess( pSD,
|
|
FLAG_ON( Options, MSG_TAG_CA )
|
|
);
|
|
|
|
CLEAN_RETURN:
|
|
|
|
if ( dwErr == ERROR_SUCCESS )
|
|
{
|
|
DisplayMessageEx( 0, MSG_DSACLS_SUCCESS );
|
|
} else {
|
|
if(!bErrorShown)
|
|
DisplayErrorMessage( dwErr );
|
|
DisplayMessageEx( 0, MSG_DSACLS_FAILURE );
|
|
}
|
|
|
|
//Free Unicode Command Line Arguments
|
|
if( wargv )
|
|
{
|
|
//delete wargv and stuff
|
|
for( j = 0; j < argc; ++ j )
|
|
{
|
|
if( wargv[j] )
|
|
LocalFree(wargv[j] );
|
|
}
|
|
LocalFree( wargv );
|
|
}
|
|
|
|
|
|
if( pszObjectPath )
|
|
LocalFree( pszObjectPath );
|
|
|
|
if( pSD )
|
|
LocalFree( pSD );
|
|
|
|
if( pNewDacl )
|
|
LocalFree( pNewDacl );
|
|
|
|
//Free the Global Stuff
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
|
|
if( DsAclsArgs[ j ].String )
|
|
LocalFree( DsAclsArgs[ j ].String );
|
|
}
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); j++ ) {
|
|
if( DsAclsInherit[ j ].String )
|
|
LocalFree( DsAclsInherit[ j ].String );
|
|
}
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ ) {
|
|
if( DsAclsRights[ j ].String )
|
|
LocalFree( DsAclsRights[ j ].String );
|
|
|
|
if( DsAclsRights[ j ].StringEx )
|
|
LocalFree( DsAclsRights[ j ].StringEx );
|
|
|
|
}
|
|
|
|
if( pCAclOld )
|
|
delete pCAclOld ;
|
|
if( pCAclNew )
|
|
delete pCAclNew;
|
|
|
|
if( g_szSchemaNamingContext )
|
|
LocalFree( g_szSchemaNamingContext );
|
|
if( g_szConfigurationNamingContext )
|
|
LocalFree( g_szConfigurationNamingContext );
|
|
if( g_szServerName )
|
|
LocalFree( g_szServerName );
|
|
if( g_Cache )
|
|
delete g_Cache;
|
|
|
|
|
|
return( dwErr );
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
InitializeGlobalArrays()
|
|
{
|
|
|
|
HMODULE hCurrentModule;
|
|
WCHAR LoadBuffer[ 1024 ];
|
|
int j = 0;
|
|
|
|
hCurrentModule = GetModuleHandle( NULL );
|
|
|
|
for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG )); j++ )
|
|
{
|
|
long Length = LoadString( hCurrentModule,
|
|
DsAclsArgs[ j ].ResourceId,
|
|
LoadBuffer,
|
|
sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
|
|
|
|
if ( Length == 0 )
|
|
{
|
|
return GetLastError();
|
|
} else {
|
|
|
|
DsAclsArgs[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
|
|
( Length + 1 )*sizeof(WCHAR) );
|
|
if ( !DsAclsArgs[ j ].String )
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DsAclsArgs[ j ].Length = Length;
|
|
wcsncpy( DsAclsArgs[ j ].String, LoadBuffer, Length + 1 );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Load the inherit strings
|
|
//
|
|
for ( j = 0; j < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); j++ )
|
|
{
|
|
long Length = LoadString( hCurrentModule,
|
|
DsAclsInherit[ j ].ResourceId,
|
|
LoadBuffer,
|
|
sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
|
|
|
|
if ( Length == 0 ) {
|
|
return GetLastError();
|
|
} else
|
|
{
|
|
DsAclsInherit[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
|
|
( Length + 1 ) * sizeof( WCHAR ) );
|
|
if ( !DsAclsInherit[ j ].String )
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
wcsncpy( DsAclsInherit[ j ].String, LoadBuffer, Length + 1 );
|
|
DsAclsInherit[ j ].Length = Length;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
//Load The protect flags
|
|
//
|
|
|
|
for( j = 0; j < ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ); j++ )
|
|
{
|
|
long Length = LoadString( hCurrentModule,
|
|
DsAclsProtect[ j ].ResourceId,
|
|
LoadBuffer,
|
|
sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
|
|
|
|
if ( Length == 0 ) {
|
|
return GetLastError();
|
|
} else
|
|
{
|
|
DsAclsProtect[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
|
|
( Length + 1 ) * sizeof( WCHAR ) );
|
|
if ( !DsAclsProtect[ j ].String )
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
wcsncpy( DsAclsProtect[ j ].String, LoadBuffer, Length + 1 );
|
|
DsAclsProtect[ j ].Length = Length;
|
|
}
|
|
}
|
|
//
|
|
// Load the access rights
|
|
//
|
|
for ( j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ )
|
|
{
|
|
long Length = LoadString( hCurrentModule,
|
|
DsAclsRights[ j ].ResourceId,
|
|
LoadBuffer,
|
|
sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
|
|
if ( Length == 0 ) {
|
|
return GetLastError();
|
|
} else
|
|
{
|
|
DsAclsRights[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
|
|
( Length + 1 ) * sizeof( WCHAR ) );
|
|
if ( !DsAclsRights[ j ].String ) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
wcsncpy( DsAclsRights[ j ].String, LoadBuffer, Length + 1 );
|
|
DsAclsRights[ j ].Length = Length;
|
|
|
|
}
|
|
|
|
//Load Ex . Ex String are used for displaying the access rights
|
|
if( DsAclsRights[ j ].ResourceIdEx != -1 )
|
|
{
|
|
Length = LoadString( hCurrentModule,
|
|
DsAclsRights[ j ].ResourceIdEx,
|
|
LoadBuffer,
|
|
sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
|
|
|
|
if ( Length == 0 ) {
|
|
return GetLastError();
|
|
} else
|
|
{
|
|
DsAclsRights[ j ].StringEx = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
|
|
( Length + 1 ) * sizeof( WCHAR ) );
|
|
if ( !DsAclsRights[ j ].StringEx ) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
wcsncpy( DsAclsRights[ j ].StringEx, LoadBuffer, Length + 1 );
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ConvertArgvToUnicode
|
|
|
|
SYNOPSIS: Converts Command Line Arguments to UNICODE
|
|
RETURNS: ERROR_SUCCESS if success
|
|
ERROR_NOT_ENOUGH_MEMORY
|
|
|
|
********************************************************************/
|
|
DWORD
|
|
ConvertArgvToUnicode( LPWSTR * wargv, char ** argv, int argc )
|
|
{
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < argc ; ++i )
|
|
if( ( dwErr = ConvertStringAToStringW( argv[i], wargv + i ) ) != ERROR_SUCCESS )
|
|
return dwErr;
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
Sets Security Descriptor for pszObject
|
|
*/
|
|
DWORD
|
|
WriteObjectSecurity( IN LPWSTR pszObject,
|
|
IN SECURITY_INFORMATION si,
|
|
IN PSECURITY_DESCRIPTOR pSD )
|
|
{
|
|
DWORD dwErr;
|
|
SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
|
|
DWORD dwRevision;
|
|
PSID psidOwner = NULL;
|
|
PSID psidGroup = NULL;
|
|
PACL pDacl = NULL;
|
|
PACL pSacl = NULL;
|
|
BOOL bDefaulted;
|
|
BOOL bPresent;
|
|
LPWSTR pszLDAPObjectPath = NULL;
|
|
|
|
if( ( dwErr = BuildLdapPath( &pszLDAPObjectPath,
|
|
g_szServerName,
|
|
pszObject ) ) != ERROR_SUCCESS )
|
|
return dwErr;
|
|
//
|
|
// Get pointers to various security descriptor parts for
|
|
// calling SetNamedSecurityInfo
|
|
//
|
|
;
|
|
if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if( !GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if( !GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if( !GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if( !GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if ((si & DACL_SECURITY_INFORMATION) && (wSDControl & SE_DACL_PROTECTED))
|
|
si |= PROTECTED_DACL_SECURITY_INFORMATION;
|
|
if ((si & SACL_SECURITY_INFORMATION) && (wSDControl & SE_SACL_PROTECTED))
|
|
si |= PROTECTED_SACL_SECURITY_INFORMATION;
|
|
|
|
return SetNamedSecurityInfo( (LPWSTR)pszLDAPObjectPath,
|
|
SE_DS_OBJECT_ALL,
|
|
si,
|
|
psidOwner,
|
|
psidGroup,
|
|
pDacl,
|
|
pSacl);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: DisplayAccessRights
|
|
|
|
SYNOPSIS: Displays Access Rights in Acess Mask
|
|
RETURNS: NONE
|
|
|
|
********************************************************************/
|
|
void DisplayAccessRights( UINT nSpace, ACCESS_MASK m_Mask )
|
|
{
|
|
for ( int j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ )
|
|
{
|
|
if( FlagOn( m_Mask,DsAclsRights[j].Right ) )
|
|
{
|
|
DisplayStringWithNewLine( nSpace,DsAclsRights[j].StringEx );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ConvertAccessMaskToGenericString
|
|
|
|
SYNOPSIS: Map access mask to FULL CONTROL or SPECIAL
|
|
RETURNS: NONE
|
|
|
|
********************************************************************/
|
|
|
|
void ConvertAccessMaskToGenericString( ACCESS_MASK m_Mask, LPWSTR szLoadBuffer, UINT nBuffer )
|
|
{
|
|
szLoadBuffer[0] = 0;
|
|
WCHAR szTemp[1024];
|
|
if( GENERIC_ALL_MAPPING == ( m_Mask & GENERIC_ALL_MAPPING ) )
|
|
{
|
|
LoadString( g_hInstance, MSG_TAG_GA_EX, szLoadBuffer, nBuffer );
|
|
}
|
|
else
|
|
{
|
|
LoadString( g_hInstance, MSG_DSACLS_SPECIAL, szLoadBuffer, nBuffer );
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
NAME: MapGeneric
|
|
********************************************************************/
|
|
void MapGeneric( ACCESS_MASK * pMask )
|
|
{
|
|
GENERIC_MAPPING m = DS_GENERIC_MAPPING;
|
|
MapGenericMask( pMask, &m );
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: BuildExplicitAccess
|
|
|
|
SYNOPSIS: Builds Explicit Access
|
|
RETURNS: ERROR_SUCCESS if success
|
|
ERROR_NOT_ENOUGH_MEMORY
|
|
|
|
********************************************************************/
|
|
|
|
DWORD BuildExplicitAccess( IN PSID pSid,
|
|
IN GUID* pGuidObject,
|
|
IN GUID* pGuidInherit,
|
|
IN ACCESS_MODE AccessMode,
|
|
IN ULONG Access,
|
|
IN ULONG Inheritance,
|
|
OUT PEXPLICIT_ACCESS pExplicitAccess )
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
PSID pSidLocal = NULL;
|
|
DWORD cbSid = 0;
|
|
POBJECTS_AND_SID pOAS = NULL;
|
|
|
|
|
|
cbSid = GetLengthSid( pSid );
|
|
pSidLocal = (PSID) LocalAlloc( LMEM_FIXED, cbSid );
|
|
CHECK_NULL( pSidLocal,FAILURE_RETURN );
|
|
CopySid( cbSid,pSidLocal, pSid );
|
|
if( pGuidObject || pGuidInherit )
|
|
{
|
|
pOAS = (POBJECTS_AND_SID)LocalAlloc( LMEM_FIXED, sizeof( OBJECTS_AND_SID ) );
|
|
CHECK_NULL( pOAS, FAILURE_RETURN );
|
|
BuildTrusteeWithObjectsAndSid( &pExplicitAccess->Trustee,
|
|
pOAS,
|
|
pGuidObject,
|
|
pGuidInherit,
|
|
pSidLocal );
|
|
}
|
|
else
|
|
BuildTrusteeWithSid( &pExplicitAccess->Trustee,
|
|
pSidLocal );
|
|
MapGeneric( &Access );
|
|
pExplicitAccess->grfAccessMode = AccessMode;
|
|
pExplicitAccess->grfAccessPermissions =Access;
|
|
pExplicitAccess->grfInheritance = Inheritance;
|
|
|
|
goto SUCCESS_RETURN;
|
|
|
|
FAILURE_RETURN:
|
|
if(pSidLocal)
|
|
LocalFree(pSidLocal);
|
|
|
|
if( pOAS )
|
|
LocalFree( pOAS );
|
|
|
|
SUCCESS_RETURN:
|
|
return dwErr;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ParseUserAndPermissons
|
|
|
|
SYNOPSIS: Parses <GROUP\USER>:Access;[object\property];[inheritid]
|
|
********************************************************************/
|
|
DWORD ParseUserAndPermissons( IN LPWSTR pszArgument,
|
|
IN DSACLS_OP Op,
|
|
IN ULONG RightsListCount,
|
|
IN PDSACLS_RIGHTS RightsList,
|
|
OUT LPWSTR * ppszTrusteeName,
|
|
OUT PULONG pAccess,
|
|
OUT LPWSTR * ppszObjectId,
|
|
OUT LPWSTR * ppszInheritId )
|
|
{
|
|
|
|
LPWSTR pszTempString = NULL;
|
|
LPWSTR pszTempString2 = NULL;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
ULONG j = 0;
|
|
|
|
*ppszTrusteeName = NULL;
|
|
*pAccess = 0;
|
|
*ppszObjectId = NULL;
|
|
*ppszInheritId = NULL;
|
|
|
|
if ( Op != REVOKE )
|
|
{
|
|
pszTempString = wcschr( pszArgument, L':' );
|
|
if ( !pszTempString )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto FAILURE_RETURN;
|
|
}
|
|
*pszTempString = L'\0';
|
|
}
|
|
|
|
dwErr = CopyUnicodeString( ppszTrusteeName, pszArgument );
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
goto FAILURE_RETURN;
|
|
}
|
|
|
|
if ( Op != REVOKE )
|
|
{
|
|
*pszTempString = L':';
|
|
pszTempString++;
|
|
|
|
// Now, process all of the user rights
|
|
*pAccess = 0;
|
|
while ( pszTempString && !( *pszTempString == L';' || *pszTempString == L'\0' ) )
|
|
{
|
|
for ( j = 0; j < RightsListCount; j++ )
|
|
{
|
|
if ( !_wcsnicmp( pszTempString,
|
|
RightsList[ j ].String,
|
|
RightsList[ j ].Length ) )
|
|
{
|
|
*pAccess |= RightsList[ j ].Right;
|
|
pszTempString += RightsList[ j ].Length;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( j == RightsListCount )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto FAILURE_RETURN;
|
|
}
|
|
}
|
|
|
|
if ( *pAccess == 0 )
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto FAILURE_RETURN;
|
|
}
|
|
|
|
//
|
|
// Object id
|
|
//
|
|
if ( pszTempString && *pszTempString != L'\0' )
|
|
{
|
|
pszTempString++;
|
|
if ( pszTempString && *pszTempString != L';' && *pszTempString != L'\0' )
|
|
{
|
|
pszTempString2 = wcschr( pszTempString, L';' );
|
|
if ( pszTempString2 )
|
|
{
|
|
*pszTempString2 = L'\0';
|
|
}
|
|
dwErr = CopyUnicodeString( ppszObjectId,pszTempString );
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
goto FAILURE_RETURN;
|
|
}
|
|
|
|
if ( pszTempString2 )
|
|
{
|
|
*pszTempString2 = L';';
|
|
}
|
|
pszTempString = pszTempString2;
|
|
}
|
|
}
|
|
else
|
|
*ppszObjectId = NULL;
|
|
|
|
//
|
|
// Inherit id
|
|
//
|
|
if ( pszTempString && *pszTempString != L'\0' )
|
|
{
|
|
pszTempString++;
|
|
if ( pszTempString && *pszTempString != L'\0' )
|
|
{
|
|
dwErr = CopyUnicodeString( ppszInheritId,
|
|
pszTempString );
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
goto FAILURE_RETURN;
|
|
}
|
|
}
|
|
|
|
} else
|
|
*ppszInheritId = NULL;
|
|
|
|
}
|
|
|
|
|
|
FAILURE_RETURN:
|
|
if( dwErr != ERROR_SUCCESS )
|
|
{
|
|
if( *ppszTrusteeName )
|
|
{
|
|
LocalFree( *ppszTrusteeName );
|
|
*ppszTrusteeName = NULL;
|
|
}
|
|
if( *ppszObjectId )
|
|
{
|
|
LocalFree( *ppszObjectId );
|
|
*ppszObjectId = NULL;
|
|
}
|
|
if( *ppszInheritId )
|
|
{
|
|
LocalFree( *ppszInheritId );
|
|
*ppszInheritId = NULL;
|
|
}
|
|
*pAccess = 0;
|
|
}
|
|
|
|
return dwErr;
|
|
|
|
}
|
|
|