LCOV - code coverage report
Current view: top level - libcli/security - secace.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 41 59 69.5 %
Date: 2024-06-13 04:01:37 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /* 
       2             :  *  Unix SMB/Netbios implementation.
       3             :  *  struct security_ace handling functions
       4             :  *  Copyright (C) Andrew Tridgell              1992-1998,
       5             :  *  Copyright (C) Jeremy R. Allison            1995-2003.
       6             :  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
       7             :  *  Copyright (C) Paul Ashton                  1997-1998.
       8             :  *  
       9             :  *  This program is free software; you can redistribute it and/or modify
      10             :  *  it under the terms of the GNU General Public License as published by
      11             :  *  the Free Software Foundation; either version 3 of the License, or
      12             :  *  (at your option) any later version.
      13             :  *  
      14             :  *  This program is distributed in the hope that it will be useful,
      15             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :  *  GNU General Public License for more details.
      18             :  *  
      19             :  *  You should have received a copy of the GNU General Public License
      20             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      21             :  */
      22             : 
      23             : #include "includes.h"
      24             : #include "librpc/gen_ndr/ndr_security.h"
      25             : #include "libcli/security/security.h"
      26             : #include "lib/util/tsort.h"
      27             : 
      28             : #define  SEC_ACE_HEADER_SIZE (2 * sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t))
      29             : 
      30             : /**
      31             :  * Check if ACE has OBJECT type.
      32             :  */
      33           4 : bool sec_ace_object(uint8_t type)
      34             : {
      35           4 :         if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
      36           4 :             type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
      37           4 :             type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
      38             :             type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
      39           0 :                 return true;
      40             :         }
      41           4 :         return false;
      42             : }
      43             : 
      44             : /**
      45             :  * copy a struct security_ace structure.
      46             :  */
      47           0 : void sec_ace_copy(struct security_ace *ace_dest, const struct security_ace *ace_src)
      48             : {
      49           0 :         ace_dest->type  = ace_src->type;
      50           0 :         ace_dest->flags = ace_src->flags;
      51           0 :         ace_dest->size  = ace_src->size;
      52           0 :         ace_dest->access_mask = ace_src->access_mask;
      53           0 :         ace_dest->object = ace_src->object;
      54           0 :         ace_dest->trustee = ace_src->trustee;
      55           0 : }
      56             : 
      57             : /*******************************************************************
      58             :  Sets up a struct security_ace structure.
      59             : ********************************************************************/
      60             : 
      61       70818 : void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum security_ace_type type,
      62             :                   uint32_t mask, uint8_t flag)
      63             : {
      64       70818 :         t->type = type;
      65       70818 :         t->flags = flag;
      66       70818 :         t->size = ndr_size_dom_sid(sid, 0) + 8;
      67       70818 :         t->access_mask = mask;
      68             : 
      69       70818 :         t->trustee = *sid;
      70       70818 : }
      71             : 
      72       41836 : int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2)
      73             : {
      74       41836 :         int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
      75       41836 :         int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
      76             : 
      77       41836 :         if (a1_inh == a2_inh)
      78       41836 :                 return 0;
      79             : 
      80           0 :         if (!a1_inh && a2_inh)
      81           0 :                 return -1;
      82           0 :         return 1;
      83             : }
      84             : 
      85             : /*******************************************************************
      86             :   Comparison function to apply the order explained below in a group.
      87             : *******************************************************************/
      88             : 
      89       46760 : int nt_ace_canon_comp( const struct security_ace *a1,  const struct security_ace *a2)
      90             : {
      91       46760 :         if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
      92           0 :                                 (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
      93           0 :                 return -1;
      94             : 
      95       46760 :         if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
      96           0 :                                 (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
      97           0 :                 return 1;
      98             : 
      99             :         /* Both access denied or access allowed. */
     100             : 
     101             :         /* 1. ACEs that apply to the object itself */
     102             : 
     103       81407 :         if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
     104       44325 :                         (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
     105        2063 :                 return -1;
     106       78868 :         else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
     107       43655 :                         (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
     108        1393 :                 return 1;
     109             : 
     110             :         /* 2. ACEs that apply to a subobject of the object, such as
     111             :          * a property set or property. */
     112             : 
     113       57273 :         if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
     114       17441 :                         !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
     115         578 :                 return -1;
     116       60846 :         else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
     117       22489 :                         !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
     118        5626 :                 return 1;
     119             : 
     120       37100 :         return 0;
     121             : }
     122             : 
     123             : /*******************************************************************
     124             :  Functions to convert a SEC_DESC ACE DACL list into canonical order.
     125             :  JRA.
     126             : 
     127             : --- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
     128             : 
     129             : The following describes the preferred order:
     130             : 
     131             :  To ensure that noninherited ACEs have precedence over inherited ACEs,
     132             :  place all noninherited ACEs in a group before any inherited ACEs.
     133             :  This ordering ensures, for example, that a noninherited access-denied ACE
     134             :  is enforced regardless of any inherited ACE that allows access.
     135             : 
     136             :  Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
     137             :         1. Access-denied ACEs that apply to the object itself
     138             :         2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
     139             :         3. Access-allowed ACEs that apply to the object itself
     140             :         4. Access-allowed ACEs that apply to a subobject of the object"
     141             : 
     142             : ********************************************************************/
     143             : 
     144        6192 : void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces)
     145             : {
     146             :         unsigned int i;
     147             : 
     148        6192 :         if (!srclist || num_aces == 0)
     149           0 :                 return;
     150             : 
     151             :         /* Sort so that non-inherited ACE's come first. */
     152        6192 :         TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp);
     153             : 
     154             :         /* Find the boundary between non-inherited ACEs. */
     155       36088 :         for (i = 0; i < num_aces; i++ ) {
     156       29896 :                 struct security_ace *curr_ace = &srclist[i];
     157             : 
     158       29896 :                 if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
     159           0 :                         break;
     160             :         }
     161             : 
     162             :         /* i now points at entry number of the first inherited ACE. */
     163             : 
     164             :         /* Sort the non-inherited ACEs. */
     165        6192 :         TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp);
     166             : 
     167             :         /* Now sort the inherited ACEs. */
     168        6192 :         TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp);
     169             : }
     170             : 
     171             : 

Generated by: LCOV version 1.13