2007-08-14 18:47:08 +04:00
/*
2007-05-11 19:08:05 +04:00
* Unix SMB / CIFS implementation .
* Group Policy Object Support
* Copyright ( C ) Guenther Deschner 2007
2007-08-14 18:47:08 +04:00
*
2007-05-11 19:08:05 +04:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2007-05-11 19:08:05 +04:00
* ( at your option ) any later version .
2007-08-14 18:47:08 +04:00
*
2007-05-11 19:08:05 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2007-08-14 18:47:08 +04:00
*
2007-05-11 19:08:05 +04:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-05-11 19:08:05 +04:00
*/
# include "includes.h"
2009-03-01 20:44:58 +03:00
# include "libcli/security/dom_sid.h"
2010-05-10 02:07:10 +04:00
# include "../libgpo/gpo.h"
2009-03-01 20:44:58 +03:00
# if _SAMBA_BUILD_ == 4
# include "libgpo/ads_convenience.h"
2009-03-01 04:44:51 +03:00
# include "librpc/gen_ndr/security.h"
# include "librpc/gen_ndr/ndr_misc.h"
2009-03-15 06:40:12 +03:00
# include "../libcli/security/secace.h"
2009-03-01 20:44:58 +03:00
# endif
2007-05-11 19:08:05 +04:00
2007-07-11 13:39:08 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-11 19:28:07 +04:00
2007-10-19 04:40:25 +04:00
static bool gpo_sd_check_agp_object_guid ( const struct security_ace_object * object )
2007-07-11 13:39:08 +04:00
{
struct GUID ext_right_apg_guid ;
NTSTATUS status ;
if ( ! object ) {
2008-02-29 16:51:37 +03:00
return false ;
2007-07-11 13:39:08 +04:00
}
2007-05-11 19:28:07 +04:00
2007-07-11 13:39:08 +04:00
status = GUID_from_string ( ADS_EXTENDED_RIGHT_APPLY_GROUP_POLICY ,
& ext_right_apg_guid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-02-29 16:51:37 +03:00
return false ;
2007-07-11 13:39:08 +04:00
}
2007-05-11 19:28:07 +04:00
2007-07-11 13:39:08 +04:00
switch ( object - > flags ) {
2009-03-01 06:59:07 +03:00
case SEC_ACE_OBJECT_TYPE_PRESENT :
2007-07-11 13:39:08 +04:00
if ( GUID_equal ( & object - > type . type ,
& ext_right_apg_guid ) ) {
2009-03-01 04:44:51 +03:00
return true ;
2007-07-11 13:39:08 +04:00
}
2009-03-01 06:59:07 +03:00
case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT :
2007-07-11 13:39:08 +04:00
if ( GUID_equal ( & object - > inherited_type . inherited_type ,
& ext_right_apg_guid ) ) {
2009-03-01 04:44:51 +03:00
return true ;
2007-07-11 13:39:08 +04:00
}
default :
break ;
}
2007-05-11 19:28:07 +04:00
2008-02-29 16:51:37 +03:00
return false ;
2007-07-11 13:39:08 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 04:44:51 +03:00
static bool gpo_sd_check_agp_object ( const struct security_ace * ace )
2007-07-11 13:39:08 +04:00
{
2007-07-17 13:39:39 +04:00
if ( ! sec_ace_object ( ace - > type ) ) {
2008-02-29 16:51:37 +03:00
return false ;
2007-07-11 13:39:08 +04:00
}
2007-07-17 13:39:39 +04:00
return gpo_sd_check_agp_object_guid ( & ace - > object . object ) ;
2007-07-11 13:39:08 +04:00
}
2007-05-11 19:28:07 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool gpo_sd_check_agp_access_bits ( uint32_t access_mask )
2007-05-11 19:28:07 +04:00
{
2009-03-01 20:44:58 +03:00
return ( access_mask & SEC_ADS_CONTROL_ACCESS ) ;
2007-05-11 19:28:07 +04:00
}
2007-06-05 14:23:56 +04:00
#if 0
2007-05-11 19:28:07 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool gpo_sd_check_read_access_bits ( uint32_t access_mask )
2007-05-11 19:28:07 +04:00
{
2007-08-14 18:47:08 +04:00
uint32_t read_bits = SEC_RIGHTS_LIST_CONTENTS |
2007-05-11 19:28:07 +04:00
SEC_RIGHTS_READ_ALL_PROP |
SEC_RIGHTS_READ_PERMS ;
return ( read_bits = = ( access_mask & read_bits ) ) ;
}
2007-06-05 14:23:56 +04:00
# endif
2007-05-11 19:28:07 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 04:44:51 +03:00
static NTSTATUS gpo_sd_check_ace_denied_object ( const struct security_ace * ace ,
2010-08-26 16:08:22 +04:00
const struct security_token * token )
2007-05-11 19:28:07 +04:00
{
2009-03-01 20:44:58 +03:00
char * sid_str ;
2007-07-11 13:39:08 +04:00
if ( gpo_sd_check_agp_object ( ace ) & &
gpo_sd_check_agp_access_bits ( ace - > access_mask ) & &
2007-07-17 15:52:23 +04:00
nt_token_check_sid ( & ace - > trustee , token ) ) {
2009-03-01 20:44:58 +03:00
sid_str = dom_sid_string ( NULL , & ace - > trustee ) ;
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " gpo_sd_check_ace_denied_object: "
" Access denied as of ace for %s \n " ,
2009-03-01 20:44:58 +03:00
sid_str ) ) ;
talloc_free ( sid_str ) ;
2007-05-11 19:28:07 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
return STATUS_MORE_ENTRIES ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 04:44:51 +03:00
static NTSTATUS gpo_sd_check_ace_allowed_object ( const struct security_ace * ace ,
2010-08-26 16:08:22 +04:00
const struct security_token * token )
2007-05-11 19:28:07 +04:00
{
2009-03-01 20:44:58 +03:00
char * sid_str ;
2007-07-11 13:39:08 +04:00
if ( gpo_sd_check_agp_object ( ace ) & &
2007-08-14 18:47:08 +04:00
gpo_sd_check_agp_access_bits ( ace - > access_mask ) & &
2007-07-17 15:52:23 +04:00
nt_token_check_sid ( & ace - > trustee , token ) ) {
2009-03-01 20:44:58 +03:00
sid_str = dom_sid_string ( NULL , & ace - > trustee ) ;
2007-08-14 18:47:08 +04:00
DEBUG ( 10 , ( " gpo_sd_check_ace_allowed_object: "
" Access granted as of ace for %s \n " ,
2009-03-01 20:44:58 +03:00
sid_str ) ) ;
talloc_free ( sid_str ) ;
2007-05-11 19:28:07 +04:00
return NT_STATUS_OK ;
}
return STATUS_MORE_ENTRIES ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-01 04:44:51 +03:00
static NTSTATUS gpo_sd_check_ace ( const struct security_ace * ace ,
2010-08-26 16:08:22 +04:00
const struct security_token * token )
2007-05-11 19:28:07 +04:00
{
switch ( ace - > type ) {
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
return gpo_sd_check_ace_denied_object ( ace , token ) ;
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
return gpo_sd_check_ace_allowed_object ( ace , token ) ;
default :
return STATUS_MORE_ENTRIES ;
}
}
2007-05-11 19:08:05 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 18:47:08 +04:00
NTSTATUS gpo_apply_security_filtering ( const struct GROUP_POLICY_OBJECT * gpo ,
2010-08-26 16:08:22 +04:00
const struct security_token * token )
2007-05-11 19:08:05 +04:00
{
2009-03-01 04:44:51 +03:00
struct security_descriptor * sd = gpo - > security_descriptor ;
struct security_acl * dacl = NULL ;
2007-05-11 19:28:07 +04:00
NTSTATUS status = NT_STATUS_ACCESS_DENIED ;
int i ;
if ( ! token ) {
return NT_STATUS_INVALID_USER_BUFFER ;
}
if ( ! sd ) {
return NT_STATUS_INVALID_SECURITY_DESCR ;
}
dacl = sd - > dacl ;
if ( ! dacl ) {
return NT_STATUS_INVALID_SECURITY_DESCR ;
}
/* check all aces and only return NT_STATUS_OK (== Access granted) or
* NT_STATUS_ACCESS_DENIED ( = = Access denied ) - the default is to
* deny access */
for ( i = 0 ; i < dacl - > num_aces ; i + + ) {
status = gpo_sd_check_ace ( & dacl - > aces [ i ] , token ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_ACCESS_DENIED ) ) {
return status ;
} else if ( NT_STATUS_IS_OK ( status ) ) {
return status ;
}
continue ;
}
return NT_STATUS_ACCESS_DENIED ;
2007-05-11 19:08:05 +04:00
}