LCOV - code coverage report
Current view: top level - librpc/ndr - ndr_sec_helper.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 136 152 89.5 %
Date: 2024-06-13 04:01:37 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    44573165 : size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
      32             : {
      33             :         size_t ret;
      34             : 
      35    44573165 :         if (!ace) return 0;
      36             : 
      37    44573165 :         ret = 8 + ndr_size_dom_sid(&ace->trustee, flags);
      38             : 
      39    44573165 :         switch (ace->type) {
      40    21908473 :         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    21908473 :                 ret += 4; /* uint32 bitmap ace->object.object.flags */
      45    21908473 :                 if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
      46    19464693 :                         ret += 16; /* GUID ace->object.object.type.type */
      47             :                 }
      48    21908473 :                 if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
      49    14958821 :                         ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */
      50             :                 }
      51    21908473 :                 break;
      52    22664692 :         default:
      53    22664692 :                 break;
      54             :         }
      55             : 
      56    44573165 :         return ret;
      57             : }
      58             : 
      59   228797452 : enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r)
      60             : {
      61   228797452 :         if (ndr_flags & NDR_SCALARS) {
      62   114398726 :                 uint32_t start_ofs = ndr->offset;
      63   114398726 :                 uint32_t size = 0;
      64   114398726 :                 uint32_t pad = 0;
      65   114398726 :                 NDR_CHECK(ndr_pull_align(ndr, 4));
      66   114398726 :                 NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
      67   114398726 :                 NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
      68   114398726 :                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
      69   114398726 :                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
      70   114398726 :                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
      71   114398726 :                 NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
      72   114398726 :                 NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
      73   114398726 :                 size = ndr->offset - start_ofs;
      74   114398726 :                 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   114398726 :                 pad = r->size - size;
      80   114398726 :                 NDR_PULL_NEED_BYTES(ndr, pad);
      81   114398726 :                 ndr->offset += pad;
      82             :         }
      83   228797452 :         if (ndr_flags & NDR_BUFFERS) {
      84   114398726 :                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
      85   114398726 :                 NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
      86             :         }
      87   228797452 :         return NDR_ERR_SUCCESS;
      88             : }
      89             : 
      90             : /*
      91             :   return the wire size of a security_acl
      92             : */
      93     3269458 : size_t ndr_size_security_acl(const struct security_acl *theacl, int flags)
      94             : {
      95             :         size_t ret;
      96             :         int i;
      97     3269458 :         if (!theacl) return 0;
      98     3241634 :         ret = 8;
      99    25573343 :         for (i=0;i<theacl->num_aces;i++) {
     100    22331709 :                 ret += ndr_size_security_ace(&theacl->aces[i], flags);
     101             :         }
     102     3241634 :         return ret;
     103             : }
     104             : 
     105             : /*
     106             :   return the wire size of a security descriptor
     107             : */
     108       27714 : size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
     109             : {
     110             :         size_t ret;
     111       27714 :         if (!sd) return 0;
     112             :         
     113       27518 :         ret = 20;
     114       27518 :         ret += ndr_size_dom_sid(sd->owner_sid, flags);
     115       27518 :         ret += ndr_size_dom_sid(sd->group_sid, flags);
     116       27518 :         ret += ndr_size_security_acl(sd->dacl, flags);
     117       27518 :         ret += ndr_size_security_acl(sd->sacl, flags);
     118       27518 :         return ret;
     119             : }
     120             : 
     121             : /*
     122             :   return the wire size of a dom_sid
     123             : */
     124    54071127 : size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
     125             : {
     126    54071127 :         if (!sid) return 0;
     127    54041643 :         return 8 + 4*sid->num_auths;
     128             : }
     129             : 
     130     2574287 : size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
     131             : {
     132     2574287 :         if (!sid) return 0;
     133             : 
     134     2574287 :         if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) {
     135     2298136 :                 return 0;
     136             :         }
     137             : 
     138      276151 :         return 8 + 4*sid->num_auths;
     139             : }
     140             : 
     141         498 : size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
     142             : {
     143         498 :         return ndr_size_dom_sid28(sid, flags);
     144             : }
     145             : 
     146             : /*
     147             :   print a dom_sid
     148             : */
     149       26756 : void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     150             : {
     151             :         struct dom_sid_buf buf;
     152       26756 :         ndr->print(ndr, "%-25s: %s", name, dom_sid_str_buf(sid, &buf));
     153       26756 : }
     154             : 
     155       11319 : void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     156             : {
     157       11319 :         ndr_print_dom_sid(ndr, name, sid);
     158       11319 : }
     159             : 
     160       14756 : void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     161             : {
     162       14756 :         ndr_print_dom_sid(ndr, name, sid);
     163       14756 : }
     164             : 
     165           0 : void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
     166             : {
     167           0 :         ndr_print_dom_sid(ndr, name, sid);
     168           0 : }
     169             : 
     170             : 
     171             : /*
     172             :   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
     173             : */
     174      199960 : enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     175             : {
     176             :         uint32_t num_auths;
     177      199960 :         if (!(ndr_flags & NDR_SCALARS)) {
     178           0 :                 return NDR_ERR_SUCCESS;
     179             :         }
     180      199960 :         NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &num_auths));
     181      199960 :         NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
     182      199960 :         if (sid->num_auths != num_auths) {
     183           0 :                 return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
     184             :                                       "Bad array size %u should exceed %u", 
     185             :                                       num_auths, sid->num_auths);
     186             :         }
     187      199960 :         return NDR_ERR_SUCCESS;
     188             : }
     189             : 
     190             : /*
     191             :   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
     192             : */
     193      176536 : enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     194             : {
     195      176536 :         if (!(ndr_flags & NDR_SCALARS)) {
     196           0 :                 return NDR_ERR_SUCCESS;
     197             :         }
     198      176536 :         NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, sid->num_auths));
     199      176536 :         return ndr_push_dom_sid(ndr, ndr_flags, sid);
     200             : }
     201             : 
     202             : /*
     203             :   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
     204             : */
     205     2272814 : enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     206             : {
     207             :         enum ndr_err_code status;
     208             :         struct ndr_pull *subndr;
     209             : 
     210     2272814 :         if (!(ndr_flags & NDR_SCALARS)) {
     211     1136407 :                 return NDR_ERR_SUCCESS;
     212             :         }
     213             : 
     214     1136407 :         subndr = talloc_zero(ndr, struct ndr_pull);
     215     1136407 :         NDR_ERR_HAVE_NO_MEMORY(subndr);
     216     1136407 :         subndr->flags                = ndr->flags;
     217     1136407 :         subndr->current_mem_ctx      = ndr->current_mem_ctx;
     218             : 
     219     1136407 :         subndr->data         = ndr->data + ndr->offset;
     220     1136407 :         subndr->data_size    = 28;
     221     1136407 :         subndr->offset               = 0;
     222             : 
     223     1136407 :         NDR_CHECK(ndr_pull_advance(ndr, 28));
     224             : 
     225     1136407 :         status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
     226     1136407 :         if (!NDR_ERR_CODE_IS_SUCCESS(status)) {
     227             :                 /* handle a w2k bug which send random data in the buffer */
     228           0 :                 ZERO_STRUCTP(sid);
     229     1136407 :         } else if (sid->num_auths == 0) {
     230     1025130 :                 ZERO_STRUCT(sid->sub_auths);
     231             :         }
     232             : 
     233     1136407 :         return NDR_ERR_SUCCESS;
     234             : }
     235             : 
     236             : /*
     237             :   push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
     238             : */
     239     5147754 : enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     240             : {
     241             :         uint32_t old_offset;
     242             :         uint32_t padding;
     243             : 
     244     5147754 :         if (!(ndr_flags & NDR_SCALARS)) {
     245     2573877 :                 return NDR_ERR_SUCCESS;
     246             :         }
     247             : 
     248     2573877 :         if (sid->num_auths > 5) {
     249           0 :                 return ndr_push_error(ndr, NDR_ERR_RANGE, 
     250             :                                       "dom_sid28 allows only up to 5 sub auth [%u]", 
     251             :                                       sid->num_auths);
     252             :         }
     253             : 
     254     2573877 :         old_offset = ndr->offset;
     255     2573877 :         NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
     256             : 
     257     2573877 :         padding = 28 - (ndr->offset - old_offset);
     258             : 
     259     2573877 :         if (padding > 0) {
     260     2358508 :                 NDR_CHECK(ndr_push_zero(ndr, padding));
     261             :         }
     262             : 
     263     2573877 :         return NDR_ERR_SUCCESS;
     264             : }
     265             : 
     266             : /*
     267             :   parse a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
     268             : */
     269           5 : enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
     270             : {
     271           5 :         if (!(ndr_flags & NDR_SCALARS)) {
     272           0 :                 return NDR_ERR_SUCCESS;
     273             :         }
     274             : 
     275           5 :         if (ndr->data_size == ndr->offset) {
     276           0 :                 ZERO_STRUCTP(sid);
     277           0 :                 return NDR_ERR_SUCCESS;
     278             :         }
     279             : 
     280           5 :         return ndr_pull_dom_sid(ndr, ndr_flags, sid);
     281             : }
     282             : 
     283             : /*
     284             :   push a dom_sid0 - this is a dom_sid in a variable byte buffer, which is maybe empty
     285             : */
     286           4 : enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
     287             : {
     288           4 :         if (!(ndr_flags & NDR_SCALARS)) {
     289           0 :                 return NDR_ERR_SUCCESS;
     290             :         }
     291             : 
     292           4 :         if (!sid) {
     293           0 :                 return NDR_ERR_SUCCESS;
     294             :         }
     295             : 
     296           4 :         if (all_zero((const uint8_t *)sid, sizeof(struct dom_sid))) {
     297           0 :                 return NDR_ERR_SUCCESS;
     298             :         }
     299             : 
     300           4 :         return ndr_push_dom_sid(ndr, ndr_flags, sid);
     301             : }
     302             : 
     303    35042884 : _PUBLIC_ enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
     304             : {
     305             :         uint32_t cntr_sub_auths_0;
     306    35042884 :         if (ndr_flags & NDR_SCALARS) {
     307    35042884 :                 NDR_CHECK(ndr_push_align(ndr, 4));
     308    35042884 :                 NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
     309    35042884 :                 NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
     310    35042884 :                 NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
     311    35042884 :                 if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) {
     312           0 :                         return ndr_push_error(ndr, NDR_ERR_RANGE, "value out of range");
     313             :                 }
     314   127259820 :                 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
     315    92216936 :                         NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
     316             :                 }
     317             :         }
     318    35042884 :         return NDR_ERR_SUCCESS;
     319             : }
     320             : 
     321   137075257 : _PUBLIC_ enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r)
     322             : {
     323             :         uint32_t cntr_sub_auths_0;
     324   137075257 :         if (ndr_flags & NDR_SCALARS) {
     325   137075257 :                 NDR_CHECK(ndr_pull_align(ndr, 4));
     326   137075257 :                 NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
     327   137075257 :                 NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths));
     328   137075257 :                 if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) {
     329           4 :                         return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
     330             :                 }
     331   137075253 :                 NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
     332   137075253 :                 ZERO_STRUCT(r->sub_auths);
     333   476055805 :                 for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
     334   338980552 :                         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
     335             :                 }
     336             :         }
     337   137075253 :         return NDR_ERR_SUCCESS;
     338             : }

Generated by: LCOV version 1.13