LCOV - code coverage report
Current view: top level - librpc/ndr - ndr_sec_helper.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 135 151 89.4 %
Date: 2024-02-14 10:14:15 Functions: 18 19 94.7 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    fast routines for getting the wire size of security objects
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Stefan Metzmacher 2006-2008
       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             : 
      24             : #include "includes.h"
      25             : #include "librpc/gen_ndr/ndr_security.h"
      26             : #include "../libcli/security/security.h"
      27             : 
      28             : /*
      29             :   return the wire size of a security_ace
      30             : */
      31    42805098 : size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
      32             : {
      33             :         size_t ret;
      34             : 
      35    42805098 :         if (!ace) return 0;
      36             : 
      37    42805098 :         ret = 8 + ndr_size_dom_sid(&ace->trustee, flags);
      38             : 
      39    42805098 :         switch (ace->type) {
      40    23554887 :         case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
      41             :         case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
      42             :         case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
      43             :         case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
      44    23554887 :                 ret += 4; /* uint32 bitmap ace->object.object.flags */
      45    23554887 :                 if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
      46    20926027 :                         ret += 16; /* GUID ace->object.object.type.type */
      47             :                 }
      48    23554887 :                 if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
      49    16083434 :                         ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */
      50             :                 }
      51    23554887 :                 break;
      52    19250211 :         default:
      53    19250211 :                 break;
      54             :         }
      55             : 
      56    42805098 :         return ret;
      57             : }
      58             : 
      59   229430694 : enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r)
      60             : {
      61   229430694 :         if (ndr_flags & NDR_SCALARS) {
      62   114715347 :                 uint32_t start_ofs = ndr->offset;
      63   114715347 :                 uint32_t size = 0;
      64   114715347 :                 uint32_t pad = 0;
      65   114715347 :                 NDR_CHECK(ndr_pull_align(ndr, 4));
      66   114715347 :                 NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
      67   114715347 :                 NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
      68   114715347 :                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
      69   114715347 :                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
      70   114715347 :                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
      71   114715347 :                 NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
      72   114715347 :                 NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
      73   114715347 :                 size = ndr->offset - start_ofs;
      74   114715347 :                 if (r->size < size) {
      75           0 :                         return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
      76             :                                               "ndr_pull_security_ace: r->size %u < size %u",
      77             :                                               (unsigned)r->size, size);
      78             :                 }
      79   114715347 :                 pad = r->size - size;
      80   114715347 :                 NDR_PULL_NEED_BYTES(ndr, pad);
      81   114715347 :                 ndr->offset += pad;
      82             :         }
      83   229430694 :         if (ndr_flags & NDR_BUFFERS) {
      84   114715347 :                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
      85   114715347 :                 NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
      86             :         }
      87   229430694 :         return NDR_ERR_SUCCESS;
      88             : }
      89             : 
      90             : /*
      91             :   return the wire size of a security_acl
      92             : */
      93     2978523 : size_t ndr_size_security_acl(const struct security_acl *theacl, int flags)
      94             : {
      95             :         size_t ret;
      96             :         int i;
      97     2978523 :         if (!theacl) return 0;
      98     2950498 :         ret = 8;
      99    24398715 :         for (i=0;i<theacl->num_aces;i++) {
     100    21448217 :                 ret += ndr_size_security_ace(&theacl->aces[i], flags);
     101             :         }
     102     2950498 :         return ret;
     103             : }
     104             : 
     105             : /*
     106             :   return the wire size of a security descriptor
     107             : */
     108       27914 : size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
     109             : {
     110             :         size_t ret;
     111       27914 :         if (!sd) return 0;
     112             :         
     113       27718 :         ret = 20;
     114       27718 :         ret += ndr_size_dom_sid(sd->owner_sid, flags);
     115       27718 :         ret += ndr_size_dom_sid(sd->group_sid, flags);
     116       27718 :         ret += ndr_size_security_acl(sd->dacl, flags);
     117       27718 :         ret += ndr_size_security_acl(sd->sacl, flags);
     118       27718 :         return ret;
     119             : }
     120             : 
     121             : /*
     122             :   return the wire size of a dom_sid
     123             : */
     124    52772776 : size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
     125             : {
     126    52772776 :         if (!sid) return 0;
     127    52743337 :         return 8 + 4*sid->num_auths;
     128             : }
     129             : 
     130     2643419 : size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
     131             : {
     132     2643419 :         if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) {
     133     2355798 :                 return 0;
     134             :         }
     135      287621 :         return ndr_size_dom_sid(sid, flags);
     136             : }
     137             : 
     138         498 : size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
     139             : {
     140         498 :         return ndr_size_dom_sid28(sid, flags);
     141             : }
     142             : 
     143             : /*
     144             :   print a dom_sid
     145             : */
     146       26761 : void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     147             : {
     148             :         struct dom_sid_buf buf;
     149       26761 :         ndr->print(ndr, "%-25s: %s", name, dom_sid_str_buf(sid, &buf));
     150       26761 : }
     151             : 
     152       11323 : void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     153             : {
     154       11323 :         ndr_print_dom_sid(ndr, name, sid);
     155       11323 : }
     156             : 
     157       14756 : void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     158             : {
     159       14756 :         ndr_print_dom_sid(ndr, name, sid);
     160       14756 : }
     161             : 
     162           0 : void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     163             : {
     164           0 :         ndr_print_dom_sid(ndr, name, sid);
     165           0 : }
     166             : 
     167             : 
     168             : /*
     169             :   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
     170             : */
     171      200298 : enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     172             : {
     173             :         uint32_t num_auths;
     174      200298 :         if (!(ndr_flags & NDR_SCALARS)) {
     175           0 :                 return NDR_ERR_SUCCESS;
     176             :         }
     177      200298 :         NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &num_auths));
     178      200298 :         NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
     179      200298 :         if (sid->num_auths != num_auths) {
     180           0 :                 return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
     181             :                                       "Bad num_auths %u; should equal %u",
     182             :                                       num_auths, sid->num_auths);
     183             :         }
     184      200298 :         return NDR_ERR_SUCCESS;
     185             : }
     186             : 
     187             : /*
     188             :   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
     189             : */
     190      176018 : enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     191             : {
     192      176018 :         if (!(ndr_flags & NDR_SCALARS)) {
     193           0 :                 return NDR_ERR_SUCCESS;
     194             :         }
     195      176018 :         NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, sid->num_auths));
     196      176018 :         return ndr_push_dom_sid(ndr, ndr_flags, sid);
     197             : }
     198             : 
     199             : /*
     200             :   parse a dom_sid28 - this is a dom_sid in a fixed 28 byte buffer, so we need to ensure there are only up to 5 sub_auth
     201             : */
     202     2338342 : enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     203             : {
     204             :         enum ndr_err_code status;
     205             :         struct ndr_pull *subndr;
     206             : 
     207     2338342 :         if (!(ndr_flags & NDR_SCALARS)) {
     208     1169171 :                 return NDR_ERR_SUCCESS;
     209             :         }
     210             : 
     211     1169171 :         subndr = talloc_zero(ndr, struct ndr_pull);
     212     1169171 :         NDR_ERR_HAVE_NO_MEMORY(subndr);
     213     1169171 :         subndr->flags                = ndr->flags;
     214     1169171 :         subndr->current_mem_ctx      = ndr->current_mem_ctx;
     215             : 
     216     1169171 :         subndr->data         = ndr->data + ndr->offset;
     217     1169171 :         subndr->data_size    = 28;
     218     1169171 :         subndr->offset               = 0;
     219             : 
     220     1169171 :         NDR_CHECK(ndr_pull_advance(ndr, 28));
     221             : 
     222     1169171 :         status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
     223     1169171 :         if (!NDR_ERR_CODE_IS_SUCCESS(status)) {
     224             :                 /* handle a w2k bug which send random data in the buffer */
     225           0 :                 ZERO_STRUCTP(sid);
     226     1169171 :         } else if (sid->num_auths == 0) {
     227     1052785 :                 ZERO_STRUCT(sid->sub_auths);
     228             :         }
     229             : 
     230     1169171 :         return NDR_ERR_SUCCESS;
     231             : }
     232             : 
     233             : /*
     234             :   push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
     235             : */
     236     5286022 : enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     237             : {
     238             :         uint32_t old_offset;
     239             :         uint32_t padding;
     240             : 
     241     5286022 :         if (!(ndr_flags & NDR_SCALARS)) {
     242     2643011 :                 return NDR_ERR_SUCCESS;
     243             :         }
     244             : 
     245     2643011 :         if (sid->num_auths > 5) {
     246           0 :                 return ndr_push_error(ndr, NDR_ERR_RANGE, 
     247             :                                       "dom_sid28 allows only up to 5 sub auth [%u]", 
     248             :                                       sid->num_auths);
     249             :         }
     250             : 
     251     2643011 :         old_offset = ndr->offset;
     252     2643011 :         NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
     253             : 
     254     2643011 :         padding = 28 - (ndr->offset - old_offset);
     255             : 
     256     2643011 :         if (padding > 0) {
     257     2417079 :                 NDR_CHECK(ndr_push_zero(ndr, padding));
     258             :         }
     259             : 
     260     2643011 :         return NDR_ERR_SUCCESS;
     261             : }
     262             : 
     263             : /*
     264             :   parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
     265             : */
     266           5 : enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     267             : {
     268           5 :         if (!(ndr_flags & NDR_SCALARS)) {
     269           0 :                 return NDR_ERR_SUCCESS;
     270             :         }
     271             : 
     272           5 :         if (ndr->data_size == ndr->offset) {
     273           0 :                 ZERO_STRUCTP(sid);
     274           0 :                 return NDR_ERR_SUCCESS;
     275             :         }
     276             : 
     277           5 :         return ndr_pull_dom_sid(ndr, ndr_flags, sid);
     278             : }
     279             : 
     280             : /*
     281             :   push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
     282             : */
     283           4 : enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     284             : {
     285           4 :         if (!(ndr_flags & NDR_SCALARS)) {
     286           0 :                 return NDR_ERR_SUCCESS;
     287             :         }
     288             : 
     289           4 :         if (!sid) {
     290           0 :                 return NDR_ERR_SUCCESS;
     291             :         }
     292             : 
     293           4 :         if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) {
     294           0 :                 return NDR_ERR_SUCCESS;
     295             :         }
     296             : 
     297           4 :         return ndr_push_dom_sid(ndr, ndr_flags, sid);
     298             : }
     299             : 
     300    34078378 : _PUBLIC_ enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
     301             : {
     302             :         uint32_t cntr_sub_auths_0;
     303    34078378 :         if (ndr_flags & NDR_SCALARS) {
     304    34078378 :                 NDR_CHECK(ndr_push_align(ndr, 4));
     305    34078378 :                 NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
     306    34078378 :                 NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
     307    34078378 :                 NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
     308    34078378 :                 if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) {
     309           0 :                         return ndr_push_error(ndr, NDR_ERR_RANGE, "value out of range");
     310             :                 }
     311   124916884 :                 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
     312    90838506 :                         NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
     313             :                 }
     314             :         }
     315    34078378 :         return NDR_ERR_SUCCESS;
     316             : }
     317             : 
     318   137571045 : _PUBLIC_ enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r)
     319             : {
     320             :         uint32_t cntr_sub_auths_0;
     321   137571045 :         if (ndr_flags & NDR_SCALARS) {
     322   137571045 :                 NDR_CHECK(ndr_pull_align(ndr, 4));
     323   137571045 :                 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
     324   137571045 :                 NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths));
     325   137571045 :                 if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) {
     326           4 :                         return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
     327             :                 }
     328   137571041 :                 NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
     329   137571041 :                 ZERO_STRUCT(r->sub_auths);
     330   482504563 :                 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
     331   344933522 :                         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
     332             :                 }
     333             :         }
     334   137571041 :         return NDR_ERR_SUCCESS;
     335             : }

Generated by: LCOV version 1.14