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 19413578 : 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 95132 : struct object_tree *new_node; 47 : 48 19413578 : if (!guid || GUID_all_zero(guid)){ 49 0 : return true; 50 : } 51 : 52 19413578 : if (!root) { 53 7509816 : root = talloc_zero(mem_ctx, struct object_tree); 54 7509816 : if (!root) { 55 0 : return false; 56 : } 57 7420972 : new_node = root; 58 : } else { 59 : int i; 60 : 61 11903762 : 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 11903762 : root->children = talloc_realloc(mem_ctx, root->children, 71 : struct object_tree, 72 : root->num_of_children + 1); 73 11903762 : if (!root->children) { 74 0 : return false; 75 : } 76 11903762 : new_node = &root->children[root->num_of_children]; 77 11903762 : root->num_of_children++; 78 : } 79 : 80 19413578 : new_node->children = NULL; 81 19413578 : new_node->guid = *guid; 82 19413578 : new_node->remaining_access = init_access; 83 19413578 : new_node->num_of_children = 0; 84 : 85 19413578 : *new_node_out = new_node; 86 19413578 : return true; 87 : } 88 : 89 : /* search by GUID */ 90 10348043 : struct object_tree *get_object_tree_by_GUID(struct object_tree *root, 91 : const struct GUID *guid) 92 : { 93 10348043 : struct object_tree *result = NULL; 94 188208 : int i; 95 : 96 10348043 : if (!root || GUID_equal(&root->guid, guid)) { 97 675759 : result = root; 98 675759 : return result; 99 : } 100 13970174 : for (i = 0; i < root->num_of_children; i++) { 101 4952932 : if ((result = get_object_tree_by_GUID(&root->children[i], guid))) 102 654910 : break; 103 : } 104 9484324 : 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 21419174 : void object_tree_modify_access(struct object_tree *root, 120 : uint32_t access_mask) 121 : { 122 139159 : int i; 123 21419174 : root->remaining_access &= ~access_mask; 124 34196867 : for (i = 0; i < root->num_of_children; i++) { 125 12777693 : object_tree_modify_access(&root->children[i], access_mask); 126 : } 127 21419174 : }