Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : 4 : security access checking routines 5 : 6 : Copyright (C) Nadezhda Ivanova 2009 7 : 8 : This program is free software; you can redistribute it and/or modify 9 : it under the terms of the GNU General Public License as published by 10 : the Free Software Foundation; either version 3 of the License, or 11 : (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program. If not, see <http://www.gnu.org/licenses/>. 20 : */ 21 : 22 : /* 23 : * Description: Contains data handler functions for 24 : * the object tree that must be constructed to perform access checks. 25 : * The object tree is an unbalanced tree of depth 3, indexed by 26 : * object type guid. Perhaps a different data structure 27 : * should be considered later to improve performance 28 : * 29 : * Author: Nadezhda Ivanova 30 : */ 31 : #include "replace.h" 32 : #include "libcli/security/security.h" 33 : #include "librpc/ndr/libndr.h" 34 : 35 : /* Adds a new node to the object tree. If attributeSecurityGUID is not zero and 36 : * has already been added to the tree, the new node is added as a child of that node 37 : * In all other cases as a child of the root 38 : */ 39 : 40 20371723 : bool insert_in_object_tree(TALLOC_CTX *mem_ctx, 41 : const struct GUID *guid, 42 : uint32_t init_access, 43 : struct object_tree *root, 44 : struct object_tree **new_node_out) 45 : { 46 95154 : struct object_tree *new_node; 47 : 48 20371723 : if (!guid || GUID_all_zero(guid)){ 49 0 : return true; 50 : } 51 : 52 20371723 : if (!root) { 53 7861649 : root = talloc_zero(mem_ctx, struct object_tree); 54 7861649 : if (!root) { 55 0 : return false; 56 : } 57 7772783 : new_node = root; 58 : } else { 59 : int i; 60 : 61 12510074 : for (i = 0; i < root->num_of_children; i++) { 62 0 : if (GUID_equal(&root->children[i].guid, guid)) { 63 0 : new_node = &root->children[i]; 64 0 : new_node->remaining_access |= init_access; 65 0 : *new_node_out = new_node; 66 0 : return true; 67 : } 68 : } 69 : 70 12510074 : root->children = talloc_realloc(mem_ctx, root->children, 71 : struct object_tree, 72 : root->num_of_children + 1); 73 12510074 : if (!root->children) { 74 0 : return false; 75 : } 76 12510074 : new_node = &root->children[root->num_of_children]; 77 12510074 : root->num_of_children++; 78 : } 79 : 80 20371723 : new_node->children = NULL; 81 20371723 : new_node->guid = *guid; 82 20371723 : new_node->remaining_access = init_access; 83 20371723 : new_node->num_of_children = 0; 84 : 85 20371723 : *new_node_out = new_node; 86 20371723 : return true; 87 : } 88 : 89 : /* search by GUID */ 90 10366663 : struct object_tree *get_object_tree_by_GUID(struct object_tree *root, 91 : const struct GUID *guid) 92 : { 93 10366663 : struct object_tree *result = NULL; 94 188208 : int i; 95 : 96 10366663 : if (!root || GUID_equal(&root->guid, guid)) { 97 675793 : result = root; 98 675793 : return result; 99 : } 100 14000276 : for (i = 0; i < root->num_of_children; i++) { 101 4964585 : if ((result = get_object_tree_by_GUID(&root->children[i], guid))) 102 655047 : break; 103 : } 104 9502910 : return result; 105 : } 106 : 107 : /** 108 : * @brief Modify the tree to mark specified access rights as granted 109 : * 110 : * This function will modify the root and the child of the tree pointed by 111 : * root, so that for each tree element the bits set in access_mask are 112 : * marked as granted. 113 : * 114 : * @param[in] root An object_tree structure that we want to modify 115 : * 116 : * @param[in] access_mask A bitfield of access right that we want to mark as 117 : * granted in the whole tree. 118 : */ 119 22377333 : void object_tree_modify_access(struct object_tree *root, 120 : uint32_t access_mask) 121 : { 122 139203 : int i; 123 22377333 : root->remaining_access &= ~access_mask; 124 35761212 : for (i = 0; i < root->num_of_children; i++) { 125 13383879 : object_tree_modify_access(&root->children[i], access_mask); 126 : } 127 22377333 : }