Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

552 lines
15 KiB

/**********************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1990, 1991 **/
/**********************************************************************/
// Dacl.hxx will not define SIDS that are defined below
#define USEPRIVATESIDS
#include "pch.hxx"
#pragma hdrstop
#define SAF_SVCCTRL_USER_START (SERVICE_QUERY_CONFIG | \
SERVICE_QUERY_STATUS | \
SERVICE_ENUMERATE_DEPENDENTS | \
SERVICE_START | \
SERVICE_INTERROGATE)
#define SAF_SVCCTRL_USER_START_STOP (SAF_SVCCTRL_USER_START | \
SERVICE_STOP)
// The tables for all necessary static ACLs
static SID_AND_FLAG safWinNt [] =
{
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_PowerUsers, SAF_RIGHTS_WRITE, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safLanmanNt [] =
{
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_SystemOperators, SAF_RIGHTS_WRITE, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safProcessAces [] =
{
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safReplicator [] =
{
{ UI_SID_System, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_Replicator, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safWinNtSvcUserStart [] =
{
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_System, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_PowerUsers, SAF_RIGHTS_WRITE, SAF_INHERIT_STANDARD },
{ UI_SID_Interactive, SAF_SVCCTRL_USER_START, SAF_INHERIT_STANDARD },
{ UI_SID_Users, SAF_SVCCTRL_USER_START, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safLanmanNtSvcUserStart [] =
{
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_System, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_SystemOperators, SAF_RIGHTS_WRITE, SAF_INHERIT_STANDARD },
{ UI_SID_Interactive, SAF_SVCCTRL_USER_START, SAF_INHERIT_STANDARD },
{ UI_SID_Users, SAF_SVCCTRL_USER_START, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safSvcUserStartStop [] =
{
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_PowerUsers, SAF_RIGHTS_WRITE, SAF_INHERIT_STANDARD },
{ UI_SID_Interactive, SAF_SVCCTRL_USER_START_STOP, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG safLanmanNtReplicator [] =
{
{ UI_SID_System, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_World, SAF_RIGHTS_READ, SAF_INHERIT_STANDARD },
{ UI_SID_Admins, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_SystemOperators, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_Replicator, SAF_RIGHTS_ALL, SAF_INHERIT_STANDARD },
{ UI_SID_Invalid, 0, 0 }
};
static SID_AND_FLAG * psafEntries [NCSA_MAX] =
{
safWinNt,
safLanmanNt,
safReplicator,
safWinNtSvcUserStart,
safLanmanNtSvcUserStart,
safSvcUserStartStop,
safLanmanNtReplicator
};
APIERR NcpaCreateKeyAcl ( OS_ACL ** ppAclOut, INT nAcl )
{
APIERR err = 0 ;
OS_ACL * pAcl = new OS_ACL ;
OS_ACE osAce ;
OS_SID osSid ;
if ( nAcl >= NCSA_MAX )
{
return ERROR_INVALID_PARAMETER ;
}
SID_AND_FLAG * psaf = psafEntries[ nAcl ] ;
do // Pseudo loop for error break-out
{
if ( err = osAce.QueryError() )
break ;
if ( err = osSid.QueryError() )
break ;
if ( pAcl == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
if ( err = pAcl->QueryError() )
break ;
osAce.SetType( ACCESS_ALLOWED_ACE_TYPE ) ;
for ( INT i = 0;
err == 0 && psaf->euisid != UI_SID_Invalid ;
psaf++ )
{
osAce.SetAccessMask( psaf->dwRights );
osAce.SetInheritFlags( psaf->ucInherit ) ;
err = NT_ACCOUNTS_UTILITY::QuerySystemSid( psaf->euisid, & osSid ) ;
if ( err )
break ;
err = osAce.SetSID( osSid ) ;
if ( err )
break ;
err = pAcl->AddACE( MAXULONG, osAce ) ;
}
if ( err )
break ;
}
while ( FALSE ) ;
if ( err )
{
delete pAcl ;
*ppAclOut = NULL ;
}
else
{
*ppAclOut = pAcl ;
}
return err ;
}
APIERR NcpaCreateSecurityDescriptor ( OS_SECURITY_DESCRIPTOR ** pposecdesc, INT nAcl )
{
OS_ACL * posacl = NULL ;
OS_SECURITY_DESCRIPTOR * possd = NULL ;
OS_SID osSid ;
APIERR err ;
do // Pseudo-loop for break-out
{
if ( err = osSid.QueryError() )
break ;
if ( err = NcpaCreateKeyAcl( & posacl, nAcl ) )
break ;
possd = new OS_SECURITY_DESCRIPTOR ;
if ( possd == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
if ( err = possd->QueryError() )
break ;
// Set the owner as "current process owner"
err = NT_ACCOUNTS_UTILITY::QuerySystemSid(
UI_SID_CurrentProcessOwner,
& osSid ) ;
if ( err )
break ;
if ( err = possd->SetOwner( osSid ) )
break ;
// Set the group as "current owner's primary group"
err = NT_ACCOUNTS_UTILITY::QuerySystemSid(
UI_SID_CurrentProcessPrimaryGroup,
& osSid ) ;
if ( err )
break ;
if ( err = possd->SetGroup( osSid ) )
break ;
err = possd->SetDACL( TRUE, posacl ) ;
}
while ( FALSE ) ;
delete posacl ;
if ( err == 0 )
{
*pposecdesc = possd ;
}
else
{
delete possd ;
}
return err ;
}
APIERR NcpaCreateSecurityAttributes ( PSECURITY_ATTRIBUTES * ppsecattr, INT nAcl )
{
INT i = 0;
WRAP_SEC_ATTR * psecattr;
APIERR err;
OS_SECURITY_DESCRIPTOR * posecdesc;
psecattr = new WRAP_SEC_ATTR ;
err = 0 ;
posecdesc = NULL ;
do
{
if ( psecattr == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
if ( err = NcpaCreateSecurityDescriptor( & posecdesc, nAcl ) )
break ;
psecattr->sattr.nLength = sizeof *psecattr ;
psecattr->sattr.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) *posecdesc ;
psecattr->sattr.bInheritHandle = FALSE ;
psecattr->posdesc = posecdesc ;
}
while ( FALSE );
if ( err == 0 )
{
*ppsecattr = & psecattr->sattr ;
}
return err ;
}
VOID NcpaDestroySecurityAttributes ( PSECURITY_ATTRIBUTES psecattr )
{
WRAP_SEC_ATTR * pwsecattr ;
pwsecattr = (WRAP_SEC_ATTR *) psecattr ;
delete pwsecattr->posdesc ;
delete pwsecattr ;
}
/*******************************************************************
NAME: NcpaDupProcessDacl
SYNOPSIS: Create a duplicate of this process's DACL. Return
it in a newly allocated TOKEN_DEFAULT_DACL structure.
ENTRY:
EXIT: TOKEN_DEFAULT_DACL * * location to store
pointer to TOKEN_DEFAULT_DACL
RETURNS: APIERR if failure
NOTES:
HISTORY:
********************************************************************/
APIERR NcpaDupProcessDacl ( TOKEN_DEFAULT_DACL * * ppTokenDefaultDacl )
{
ULONG cbDaclLength, cbDaclLengthNew ;
HANDLE hToken = NULL ;
NTSTATUS ntStatus ;
APIERR err = 0 ;
do
{
*ppTokenDefaultDacl = NULL ;
// Open our process token
ntStatus = ::NtOpenProcessToken( NtCurrentProcess(),
TOKEN_QUERY,
& hToken );
if ( ! NT_SUCCESS( ntStatus ) )
break ;
// Get the length of the process DACL
ntStatus = ::NtQueryInformationToken( hToken,
TokenDefaultDacl,
NULL,
0,
& cbDaclLength );
if ( (! NT_SUCCESS( ntStatus )) && ntStatus != STATUS_BUFFER_TOO_SMALL )
break ;
// Zero length; return NULL as successful result.
if ( cbDaclLength == 0 )
break ;
// Allocate the DACL buffer
*ppTokenDefaultDacl = (TOKEN_DEFAULT_DACL *) new CHAR [cbDaclLength] ;
if ( *ppTokenDefaultDacl == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
// Query the DACL data into the new buffer
ntStatus =:: NtQueryInformationToken( hToken,
TokenDefaultDacl,
*ppTokenDefaultDacl,
cbDaclLength,
& cbDaclLengthNew ) ;
}
while ( FALSE ) ;
if ( err == 0 && ! NT_SUCCESS( ntStatus ) )
{
err = ERRMAP::MapNTStatus( ntStatus ) ;
}
if ( err )
{
NcpaDelProcessDacl( *ppTokenDefaultDacl ) ;
*ppTokenDefaultDacl = NULL ;
}
if ( hToken )
{
::NtClose( hToken ) ;
}
return err ;
}
/*******************************************************************
NAME: NcpaResetProcessDacl
SYNOPSIS: Set the current process's DACL to the DACL referenced by
TOKEN_DEFAULT_DACL.
ENTRY: TOKEN_DEFAULT_DACL * DACL to use
EXIT: nothing
RETURNS: APIERR if failure
NOTES:
HISTORY:
********************************************************************/
APIERR NcpaResetProcessDacl ( TOKEN_DEFAULT_DACL * pTokenDefaultDacl )
{
HANDLE hToken = NULL ;
NTSTATUS ntStatus ;
APIERR err = 0 ;
do
{
// Open our process token
ntStatus = ::NtOpenProcessToken( NtCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_DEFAULT,
& hToken );
if ( ! NT_SUCCESS( ntStatus ) )
break ;
ntStatus = ::NtSetInformationToken( hToken,
TokenDefaultDacl,
pTokenDefaultDacl,
sizeof( TOKEN_DEFAULT_DACL ) ) ;
}
while ( FALSE ) ;
if ( err == 0 && ! NT_SUCCESS( ntStatus ) )
{
err = ERRMAP::MapNTStatus( ntStatus ) ;
}
if ( hToken )
{
::NtClose( hToken ) ;
}
return err ;
}
/*******************************************************************
NAME: NcpaAlterProcessDacl
SYNOPSIS: Alter this process's DACL, adding ACEs for "world read"
and "admin all".
The current process DACL information is saved into
the pointer "ppTokenDefaultDacl".
ENTRY: TOKEN_DEFAULT_DACL * * location to store pointer
to generated
structure containing
original process DACL.
EXIT:
RETURNS:
NOTES:
HISTORY:
********************************************************************/
APIERR NcpaAlterProcessDacl ( TOKEN_DEFAULT_DACL * * ppTokenDefaultDacl )
{
APIERR err = 0 ;
NTSTATUS ntStatus = 0 ;
// Create a duplicate of this process's default DACL
*ppTokenDefaultDacl = NULL ;
if ( err = NcpaDupProcessDacl( ppTokenDefaultDacl ) )
return err ;
OS_ACL osaclDefault( (*ppTokenDefaultDacl)->DefaultDacl ) ;
OS_ACL osaclNew ;
OS_SID ossid ;
OS_ACE osace ;
SID_AND_FLAG * pSafNext = safProcessAces ;
TOKEN_DEFAULT_DACL daclNew ;
do // Pseudo-loop for error break-out
{
if ( err = osaclDefault.QueryError() )
break ;
if ( err = osaclNew.QueryError() )
break ;
if ( err = ossid.QueryError() )
break ;
if ( err = osace.QueryError() )
break ;
// Copy all the current ACEs to the new DACL
if ( err = osaclNew.Copy( osaclDefault ) )
break;
// Add our new ACEs
for ( INT i = 0 ;
err == 0 && pSafNext->euisid != UI_SID_Invalid ;
pSafNext++ )
{
osace.SetType( ACCESS_ALLOWED_ACE_TYPE ) ;
osace.SetAccessMask( pSafNext->dwRights ) ;
osace.SetInheritFlags( pSafNext->ucInherit ) ;
err = NT_ACCOUNTS_UTILITY::QuerySystemSid( pSafNext->euisid, & ossid ) ;
if ( err )
break ;
if ( err = osace.SetSID( ossid ) )
break ;
err = osaclNew.AddACE( MAXULONG, osace ) ;
}
if ( err )
break ;
daclNew.DefaultDacl = osaclNew.QueryAcl() ;
err = NcpaResetProcessDacl( & daclNew ) ;
}
while ( FALSE ) ;
if ( err == 0 && ! NT_SUCCESS( ntStatus ) )
{
err = ERRMAP::MapNTStatus( ntStatus ) ;
}
if ( err && *ppTokenDefaultDacl )
{
NcpaDelProcessDacl( *ppTokenDefaultDacl ) ;
*ppTokenDefaultDacl = NULL ;
}
return err ;
}
VOID NcpaDelProcessDacl ( TOKEN_DEFAULT_DACL * pTokenDefaultDacl )
{
delete (CHAR *) pTokenDefaultDacl ;
}
// End of NCPAACL.CXX