Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/security/object_tree.c
Line
Count
Source
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
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
0
{
46
0
  struct object_tree *new_node;
47
48
0
  if (!guid || GUID_all_zero(guid)){
49
0
    return true;
50
0
  }
51
52
0
  if (!root) {
53
0
    root = talloc_zero(mem_ctx, struct object_tree);
54
0
    if (!root) {
55
0
      return false;
56
0
    }
57
0
    new_node = root;
58
0
  } else {
59
0
    int i;
60
61
0
    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
0
      }
68
0
    }
69
70
0
    root->children = talloc_realloc(mem_ctx, root->children,
71
0
            struct object_tree,
72
0
            root->num_of_children + 1);
73
0
    if (!root->children) {
74
0
      return false;
75
0
    }
76
0
    new_node = &root->children[root->num_of_children];
77
0
    root->num_of_children++;
78
0
  }
79
80
0
  new_node->children = NULL;
81
0
  new_node->guid = *guid;
82
0
  new_node->remaining_access = init_access;
83
0
  new_node->num_of_children = 0;
84
85
0
  *new_node_out = new_node;
86
0
  return true;
87
0
}
88
89
/* search by GUID */
90
struct object_tree *get_object_tree_by_GUID(struct object_tree *root,
91
               const struct GUID *guid)
92
0
{
93
0
  struct object_tree *result = NULL;
94
0
  int i;
95
96
0
  if (!root || GUID_equal(&root->guid, guid)) {
97
0
    result = root;
98
0
    return result;
99
0
  }
100
0
  for (i = 0; i < root->num_of_children; i++) {
101
0
    if ((result = get_object_tree_by_GUID(&root->children[i], guid)))
102
0
      break;
103
0
  }
104
0
  return result;
105
0
}
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
void object_tree_modify_access(struct object_tree *root,
120
             uint32_t access_mask)
121
0
{
122
0
  int i;
123
0
  root->remaining_access &= ~access_mask;
124
0
  for (i = 0; i < root->num_of_children; i++) {
125
0
    object_tree_modify_access(&root->children[i], access_mask);
126
0
  }
127
0
}