2009-09-22 04:27:50 +04:00
/*
Unix SMB / CIFS implementation .
security access checking routines
Copyright ( C ) Nadezhda Ivanova 2009
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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
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 .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/*
* Description : Contains data handler functions for
* the object tree that must be constructed to perform access checks .
* The object tree is an unbalanced tree of depth 3 , indexed by
* object type guid . Perhaps a different data structure
2023-04-27 16:56:42 +03:00
* should be considered later to improve performance
2009-09-22 04:27:50 +04:00
*
* Author : Nadezhda Ivanova
*/
2023-03-03 20:41:33 +03:00
# include "replace.h"
2009-09-22 04:27:50 +04:00
# include "libcli/security/security.h"
# include "librpc/ndr/libndr.h"
/* Adds a new node to the object tree. If attributeSecurityGUID is not zero and
* has already been added to the tree , the new node is added as a child of that node
* In all other cases as a child of the root
*/
2009-11-05 18:34:12 +03:00
bool insert_in_object_tree ( TALLOC_CTX * mem_ctx ,
2013-01-03 13:40:32 +04:00
const struct GUID * guid ,
uint32_t init_access ,
struct object_tree * root ,
struct object_tree * * new_node_out )
2009-09-22 04:27:50 +04:00
{
2013-01-03 13:40:32 +04:00
struct object_tree * new_node ;
2009-11-05 18:34:12 +03:00
if ( ! guid | | GUID_all_zero ( guid ) ) {
return true ;
2009-09-22 04:27:50 +04:00
}
2013-01-03 13:40:32 +04:00
if ( ! root ) {
root = talloc_zero ( mem_ctx , struct object_tree ) ;
if ( ! root ) {
2009-11-05 18:34:12 +03:00
return false ;
}
2013-01-03 13:40:32 +04:00
new_node = root ;
} else {
2009-11-05 18:34:12 +03:00
int i ;
2013-01-03 13:40:32 +04:00
for ( i = 0 ; i < root - > num_of_children ; i + + ) {
if ( GUID_equal ( & root - > children [ i ] . guid , guid ) ) {
new_node = & root - > children [ i ] ;
2013-01-15 22:03:00 +04:00
new_node - > remaining_access | = init_access ;
2013-01-03 13:40:32 +04:00
* new_node_out = new_node ;
2009-11-05 18:34:12 +03:00
return true ;
}
}
2013-01-03 13:40:32 +04:00
root - > children = talloc_realloc ( mem_ctx , root - > children ,
struct object_tree ,
root - > num_of_children + 1 ) ;
if ( ! root - > children ) {
return false ;
}
new_node = & root - > children [ root - > num_of_children ] ;
root - > num_of_children + + ;
2009-11-05 18:34:12 +03:00
}
2013-01-03 13:40:32 +04:00
new_node - > children = NULL ;
new_node - > guid = * guid ;
new_node - > remaining_access = init_access ;
new_node - > num_of_children = 0 ;
* new_node_out = new_node ;
return true ;
2009-09-22 04:27:50 +04:00
}
/* search by GUID */
2009-11-05 18:34:12 +03:00
struct object_tree * get_object_tree_by_GUID ( struct object_tree * root ,
2009-09-22 04:27:50 +04:00
const struct GUID * guid )
{
struct object_tree * result = NULL ;
2009-11-05 18:34:12 +03:00
int i ;
2009-09-22 04:27:50 +04:00
2009-11-05 18:34:12 +03:00
if ( ! root | | GUID_equal ( & root - > guid , guid ) ) {
2009-09-22 04:27:50 +04:00
result = root ;
2009-11-05 18:34:12 +03:00
return result ;
}
2013-01-03 14:30:12 +04:00
for ( i = 0 ; i < root - > num_of_children ; i + + ) {
2009-11-05 18:34:12 +03:00
if ( ( result = get_object_tree_by_GUID ( & root - > children [ i ] , guid ) ) )
2009-09-22 04:27:50 +04:00
break ;
}
return result ;
}
2012-10-14 02:28:08 +04:00
/**
* @ brief Modify the tree to mark specified access rights as granted
*
* This function will modify the root and the child of the tree pointed by
* root , so that for each tree element the bits set in access_mask are
* marked as granted .
*
* @ param [ in ] root An object_tree structure that we want to modify
*
* @ param [ in ] access_mask A bitfield of access right that we want to mark as
* granted in the whole tree .
*/
2009-09-22 04:27:50 +04:00
void object_tree_modify_access ( struct object_tree * root ,
2010-10-20 00:32:53 +04:00
uint32_t access_mask )
2009-09-22 04:27:50 +04:00
{
2013-01-03 14:30:12 +04:00
int i ;
2010-10-20 00:32:53 +04:00
root - > remaining_access & = ~ access_mask ;
2013-01-03 14:30:12 +04:00
for ( i = 0 ; i < root - > num_of_children ; i + + ) {
object_tree_modify_access ( & root - > children [ i ] , access_mask ) ;
2009-09-22 04:27:50 +04:00
}
}