root/librpc/ndr/ndr_sec_helper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ndr_size_security_ace
  2. ndr_pull_security_ace
  3. ndr_size_security_acl
  4. ndr_size_security_descriptor
  5. ndr_size_dom_sid
  6. ndr_size_dom_sid28
  7. ndr_size_dom_sid0
  8. ndr_print_dom_sid
  9. ndr_print_dom_sid2
  10. ndr_print_dom_sid28
  11. ndr_print_dom_sid0
  12. ndr_pull_dom_sid2
  13. ndr_push_dom_sid2
  14. ndr_pull_dom_sid28
  15. ndr_push_dom_sid28
  16. ndr_pull_dom_sid0
  17. ndr_push_dom_sid0
  18. ndr_push_dom_sid
  19. ndr_pull_dom_sid

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

/* [<][>][^][v][top][bottom][index][help] */