LCOV - code coverage report
Current view: top level - libcli/security - secace.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 61 70 87.1 %
Date: 2024-04-21 15:09:00 Functions: 8 8 100.0 %

          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 "replace.h"
      24             : #include "librpc/gen_ndr/ndr_security.h"
      25             : #include "libcli/security/security.h"
      26             : #include "lib/util/tsort.h"
      27             : 
      28             : /**
      29             :  * Check if ACE has OBJECT type.
      30             :  */
      31   523306795 : bool sec_ace_object(uint8_t type)
      32             : {
      33   523306795 :         if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
      34   204080076 :             type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
      35   198942044 :             type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
      36   198942044 :             type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT ||
      37   198942044 :             type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT ||
      38   179491882 :             type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT ||
      39             :             type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT) {
      40             :                 /*
      41             :                  * MS-DTYP has a reserved value for
      42             :                  * SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT, but we
      43             :                  * don't assume that it will be an object ACE just
      44             :                  * because it sounds like one.
      45             :                  */
      46   333466488 :                 return true;
      47             :         }
      48   179491882 :         return false;
      49             : }
      50             : 
      51             : /**
      52             :  * Check if ACE is a CALLBACK type, which means it will have a blob of data at
      53             :  * the end.
      54             :  */
      55   314611141 : bool sec_ace_callback(uint8_t type)
      56             : {
      57   314611141 :         if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK ||
      58   302328437 :             type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK ||
      59   302328437 :             type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT ||
      60   314605609 :             type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT ||
      61   314605609 :             type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK ||
      62    12277172 :             type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT) {
      63             :             /*
      64             :              * While SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK and
      65             :              * SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT sound like
      66             :              * callback types, they are reserved values in MS-DTYP,
      67             :              * and their eventual use is not defined.
      68             :              */
      69        9118 :                 return true;
      70             :         }
      71   302328437 :         return false;
      72             : }
      73             : 
      74             : /**
      75             :  * Check if an ACE type is resource attribute, which means it will
      76             :  * have a blob of data at the end defining an attribute on the object.
      77             :  * Resource attribute ACEs should only occur in SACLs.
      78             :  */
      79   232208910 : bool sec_ace_resource(uint8_t type)
      80             : {
      81   232208910 :         return type == SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE;
      82             : }
      83             : 
      84   219120487 : bool sec_ace_has_extra_blob(uint8_t type)
      85             : {
      86   219120487 :         return sec_ace_callback(type) || sec_ace_resource(type);
      87             : }
      88             : 
      89             : 
      90             : /*******************************************************************
      91             :  Sets up a struct security_ace structure.
      92             : ********************************************************************/
      93             : 
      94     2535331 : void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum security_ace_type type,
      95             :                   uint32_t mask, uint8_t flag)
      96             : {
      97     2535331 :         t->type = type;
      98     2535331 :         t->flags = flag;
      99     2535331 :         t->size = ndr_size_dom_sid(sid, 0) + 8;
     100     2535331 :         t->access_mask = mask;
     101             : 
     102     2535331 :         t->trustee = *sid;
     103     2535331 :         t->coda.ignored.data = NULL;
     104     2535331 :         t->coda.ignored.length = 0;
     105     2535331 : }
     106             : 
     107     1821715 : int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2)
     108             : {
     109     1821715 :         int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
     110     1821715 :         int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
     111             : 
     112     1821715 :         if (a1_inh == a2_inh)
     113     1813601 :                 return 0;
     114             : 
     115           0 :         if (!a1_inh && a2_inh)
     116           0 :                 return -1;
     117           0 :         return 1;
     118             : }
     119             : 
     120             : /*******************************************************************
     121             :   Comparison function to apply the order explained below in a group.
     122             : *******************************************************************/
     123             : 
     124     1842612 : int nt_ace_canon_comp( const struct security_ace *a1,  const struct security_ace *a2)
     125             : {
     126     1842612 :         if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
     127           0 :                                 (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
     128           0 :                 return -1;
     129             : 
     130     1842612 :         if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
     131           0 :                                 (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
     132           0 :                 return 1;
     133             : 
     134             :         /* Both access denied or access allowed. */
     135             : 
     136             :         /* 1. ACEs that apply to the object itself */
     137             : 
     138     1842612 :         if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
     139     1826214 :                         (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
     140       24757 :                 return -1;
     141     1817583 :         else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
     142     1796112 :                         (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
     143        2981 :                 return 1;
     144             : 
     145             :         /* 2. ACEs that apply to a subobject of the object, such as
     146             :          * a property set or property. */
     147             : 
     148     1814506 :         if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
     149       96723 :                         !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
     150       11993 :                 return -1;
     151     1802401 :         else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
     152      116380 :                         !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
     153       32206 :                 return 1;
     154             : 
     155     1762673 :         return 0;
     156             : }
     157             : 
     158             : /*******************************************************************
     159             :  Functions to convert a SEC_DESC ACE DACL list into canonical order.
     160             :  JRA.
     161             : 
     162             : --- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
     163             : 
     164             : The following describes the preferred order:
     165             : 
     166             :  To ensure that noninherited ACEs have precedence over inherited ACEs,
     167             :  place all noninherited ACEs in a group before any inherited ACEs.
     168             :  This ordering ensures, for example, that a noninherited access-denied ACE
     169             :  is enforced regardless of any inherited ACE that allows access.
     170             : 
     171             :  Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
     172             :         1. Access-denied ACEs that apply to the object itself
     173             :         2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
     174             :         3. Access-allowed ACEs that apply to the object itself
     175             :         4. Access-allowed ACEs that apply to a subobject of the object"
     176             : 
     177             : ********************************************************************/
     178             : 
     179      420648 : void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces)
     180             : {
     181        1655 :         unsigned int i;
     182             : 
     183      420648 :         if (!srclist || num_aces == 0)
     184           0 :                 return;
     185             : 
     186             :         /* Sort so that non-inherited ACE's come first. */
     187      420648 :         TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp);
     188             : 
     189             :         /* Find the boundary between non-inherited ACEs. */
     190     2038638 :         for (i = 0; i < num_aces; i++ ) {
     191     1617990 :                 struct security_ace *curr_ace = &srclist[i];
     192             : 
     193     1617990 :                 if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
     194           0 :                         break;
     195             :         }
     196             : 
     197             :         /* i now points at entry number of the first inherited ACE. */
     198             : 
     199             :         /* Sort the non-inherited ACEs. */
     200      420648 :         TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp);
     201             : 
     202             :         /* Now sort the inherited ACEs. */
     203      420648 :         TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp);
     204             : }

Generated by: LCOV version 1.14