Listing 1: SetRegDacl.cpp /* SetRegDacl.cpp Application to set an user-supplied registry key to Administrators:F David LeBlanc 8/10/2000 */ #define UNICODE #include #include #include bool LookupAdminSid( PSID pSid, DWORD SidSize ) { DWORD* pRid; SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; // check arguments if( pSid == NULL ) { // we do the right thing in either debug or release assert( false ); return false; } // check to make sure we have enough room if( GetSidLengthRequired( 2 ) != SidSize ) { printf( "SID buffer size incorrect\n" ); assert( false ); return false; } // we want a well-known SID // these have 2 RIDs // since this is a well-known SID, we can build it by hand if( !InitializeSid( pSid, // pointer to SID &sia, // well-known SIA 2 )) // number of RIDs { // this should never fail - but if does, we trap it assert( false ); printf( "Cannot initialize SID - err = %d\n", GetLastError( ) ); return false; } // this won't fail unless we didn't allocate enough room for the SID // error return isn't defined pRid = GetSidSubAuthority( pSid, 0 ); *pRid = SECURITY_BUILTIN_DOMAIN_RID; pRid = GetSidSubAuthority( pSid, 1 ); *pRid = DOMAIN_ALIAS_RID_ADMINS; // we now have valid SID for administrators // note - this is language-independent return true; } int wmain( int argc, WCHAR* argv[] ) { HKEY key; DWORD ret; DWORD retval; // we have to check these at exit points for proper cleanup PACL pAcl = NULL; ACCESS_ALLOWED_ACE* pAce = NULL; if( argc != 2 ) { printf( "Usage is %s [registry path]\n", argv[0] ); return -1; } // first open the key ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // root key argv[1], // child key - must exist 0, // options - reserved KEY_ALL_ACCESS, // permissions requested &key ); // child key if( ret != ERROR_SUCCESS ) { wprintf( L"Cannot open %s - err = %d\n", argv[1], ret ); return -1; } // we now have the access we need, build a security descriptor // first allocate the ACE - // calculate how much memory to allocate // formula for the size of a SID is // size = sizeof( SID ) + ( number RIDS - 1 ) * sizeof( DWORD ) // // an ACE allows only sizeof( DWORD ) to put the SID // this SID is a well-known SID with 2 RIDs /* to spell it out - AceSize = sizeof( ACCESS_ALLOWED_ACE ) - sizeof( DWORD ) + sizeof( SID ) + ( 2 - 1 ) * sizeof( DWORD ); // but short version is: */ pAce = ( ACCESS_ALLOWED_ACE* ) GlobalAlloc( GPTR, sizeof( ACCESS_ALLOWED_ACE ) + sizeof( SID )); if( pAce == NULL ) { assert( false ); printf( "Cannot allocate memory!\n" ); retval = -1; goto cleanup; } //now start assigning values to the members pAce->Header.AceSize = sizeof( ACCESS_ALLOWED_ACE ) + sizeof( SID ); pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pAce->Header.AceFlags = OBJECT_INHERIT_ACE | OBJECT_INHERIT_ACE; pAce->Mask = KEY_ALL_ACCESS; if( !LookupAdminSid( (PSID )&pAce->SidStart, sizeof( SID ) + sizeof( DWORD )) ) { printf( "Cannot lookup admins SID\n" ); retval = -1; goto cleanup; } // now apply that ACE to a DACL // create the ACL pAcl = ( PACL )GlobalAlloc( GPTR, sizeof( ACL ) + pAce->Header.AceSize ); if( pAcl == NULL ) { assert( false ); printf( "Cannot allocate memory!\n" ); retval = -1; goto cleanup; } if( !InitializeAcl( pAcl, sizeof( ACL ) + pAce->Header.AceSize, ACL_REVISION )) { printf( "Cannot initialize ACL\n" ); retval = -1; goto cleanup; } //now add the ACE to the DACL if( !AddAce( pAcl, ACL_REVISION, 0, // first ace pAce, pAce->Header.AceSize )) { printf( "Cannot add ACE to DACL\n" ); retval = -1; goto cleanup; } SECURITY_DESCRIPTOR sd; if( !InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION )) { printf( "Cannot initialize security descriptor\n" ); retval = -1; goto cleanup; } if( !SetSecurityDescriptorDacl( &sd, TRUE, pAcl, FALSE )) { printf( "Cannot set security descriptor DACL\n" ); retval = -1; goto cleanup; } ret = RegSetKeySecurity( key, DACL_SECURITY_INFORMATION, &sd ); if( ret == ERROR_SUCCESS ) { wprintf( L"Permissions set on %s\n", argv[1] ); retval = 0; } else { wprintf( L"Cannot set permissions on %s - err = %d\n", argv[1], ret ); retval = -1; } cleanup: if( pAce != NULL ) GlobalFree( pAce ); if( pAcl != NULL ) GlobalFree( pAcl ); return retval; }