"Fossies" - the Fresh Open Source Software Archive

Member "sssd-2.2.3/src/providers/ad/ad_gpo_ndr.c" (30 Nov 2019, 18108 Bytes) of package /linux/misc/sssd-2.2.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ad_gpo_ndr.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.0.0_vs_2.1.0.

    1 /*
    2     SSSD
    3 
    4     ad_gpo_ndr.c
    5 
    6     Authors:
    7     Yassir Elley <yelley@redhat.com>
    8 
    9     Copyright (C) 2014 Red Hat
   10 
   11     This program is free software; you can redistribute it and/or modify
   12     it under the terms of the GNU General Public License as published by
   13     the Free Software Foundation; either version 3 of the License, or
   14     (at your option) any later version.
   15 
   16     This program is distributed in the hope that it will be useful,
   17     but WITHOUT ANY WARRANTY; without even the implied warranty of
   18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19     GNU General Public License for more details.
   20 
   21     You should have received a copy of the GNU General Public License
   22     along with this program.  If not, see <http://www.gnu.org/licenses/>.
   23 */
   24 
   25 /*
   26  * This file contains a copy of samba's ndr_pull_* functions needed
   27  * to parse a security_descriptor. We are copying them here so that we don't
   28  * have to link against libsamba-security, which is a private samba library
   29  * These functions are taken from:
   30  *  librpc/ndr/gen_ndr/ndr_security.c
   31  *  librpc/ndr/ndr_misc.c
   32  *  librpc/ndr/ndr_sec_helper.c
   33  */
   34 
   35 #include "util/util.h"
   36 #include <ndr.h>
   37 #include <gen_ndr/security.h>
   38 
   39 static enum ndr_err_code
   40 ndr_pull_GUID(struct ndr_pull *ndr,
   41               int ndr_flags,
   42               struct GUID *r)
   43 {
   44     uint32_t size_clock_seq_0 = 0;
   45     uint32_t size_node_0 = 0;
   46     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
   47     if (ndr_flags & NDR_SCALARS) {
   48         NDR_CHECK(ndr_pull_align(ndr, 4));
   49         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time_low));
   50         NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_mid));
   51         NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_hi_and_version));
   52         size_clock_seq_0 = 2;
   53         NDR_CHECK(ndr_pull_array_uint8(ndr,
   54                                        NDR_SCALARS,
   55                                        r->clock_seq,
   56                                        size_clock_seq_0));
   57         size_node_0 = 6;
   58         NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->node, size_node_0));
   59         NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
   60     }
   61     if (ndr_flags & NDR_BUFFERS) {
   62     }
   63     return NDR_ERR_SUCCESS;
   64 }
   65 
   66 static enum ndr_err_code
   67 ndr_pull_security_ace_flags(struct ndr_pull *ndr,
   68                             int ndr_flags,
   69                             uint8_t *r)
   70 {
   71     uint8_t v;
   72     NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &v));
   73     *r = v;
   74     return NDR_ERR_SUCCESS;
   75 }
   76 
   77 
   78 static enum ndr_err_code
   79 ndr_pull_security_ace_type(struct ndr_pull *ndr,
   80                            int ndr_flags,
   81                            enum security_ace_type *r)
   82 {
   83     uint8_t v;
   84     NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v));
   85     *r = v;
   86     return NDR_ERR_SUCCESS;
   87 }
   88 
   89 
   90 static enum ndr_err_code
   91 ndr_pull_security_ace_object_flags(struct ndr_pull *ndr,
   92                                    int ndr_flags,
   93                                    uint32_t *r)
   94 {
   95     uint32_t v;
   96     NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v));
   97     *r = v;
   98     return NDR_ERR_SUCCESS;
   99 }
  100 
  101 
  102 static enum ndr_err_code
  103 ndr_pull_security_ace_object_type(struct ndr_pull *ndr,
  104                                   int ndr_flags,
  105                                   union security_ace_object_type *r)
  106 {
  107     uint32_t level;
  108     level = ndr_pull_get_switch_value(ndr, r);
  109     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  110     if (ndr_flags & NDR_SCALARS) {
  111         NDR_CHECK(ndr_pull_union_align(ndr, 4));
  112         switch (level) {
  113         case SEC_ACE_OBJECT_TYPE_PRESENT: {
  114             NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->type));
  115             break; }
  116         default: {
  117             break; }
  118         }
  119     }
  120     if (ndr_flags & NDR_BUFFERS) {
  121         switch (level) {
  122         case SEC_ACE_OBJECT_TYPE_PRESENT:
  123             break;
  124         default:
  125             break;
  126         }
  127     }
  128     return NDR_ERR_SUCCESS;
  129 }
  130 
  131 
  132 static enum ndr_err_code
  133 ndr_pull_security_ace_object_inherited_type(struct ndr_pull *ndr,
  134                                             int ndr_flags,
  135                                             union security_ace_object_inherited_type *r)
  136 {
  137     uint32_t level;
  138     level = ndr_pull_get_switch_value(ndr, r);
  139     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  140     if (ndr_flags & NDR_SCALARS) {
  141         NDR_CHECK(ndr_pull_union_align(ndr, 4));
  142         switch (level) {
  143         case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: {
  144             NDR_CHECK(ndr_pull_GUID(ndr,
  145                                     NDR_SCALARS,
  146                                     &r->inherited_type));
  147             break; }
  148         default: {
  149             break; }
  150         }
  151     }
  152     if (ndr_flags & NDR_BUFFERS) {
  153         switch (level) {
  154         case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT:
  155             break;
  156         default:
  157             break;
  158         }
  159     }
  160     return NDR_ERR_SUCCESS;
  161 }
  162 
  163 static enum ndr_err_code
  164 ndr_pull_security_ace_object(struct ndr_pull *ndr,
  165                              int ndr_flags,
  166                              struct security_ace_object *r)
  167 {
  168     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  169     if (ndr_flags & NDR_SCALARS) {
  170         NDR_CHECK(ndr_pull_align(ndr, 4));
  171         NDR_CHECK(ndr_pull_security_ace_object_flags
  172                   (ndr, NDR_SCALARS, &r->flags));
  173         NDR_CHECK(ndr_pull_set_switch_value
  174                   (ndr, &r->type, r->flags & SEC_ACE_OBJECT_TYPE_PRESENT));
  175         NDR_CHECK(ndr_pull_security_ace_object_type
  176                   (ndr, NDR_SCALARS, &r->type));
  177         NDR_CHECK(ndr_pull_set_switch_value
  178                   (ndr,
  179                    &r->inherited_type,
  180                    r->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT));
  181         NDR_CHECK(ndr_pull_security_ace_object_inherited_type
  182                   (ndr, NDR_SCALARS, &r->inherited_type));
  183         NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
  184     }
  185     if (ndr_flags & NDR_BUFFERS) {
  186         NDR_CHECK(ndr_pull_security_ace_object_type
  187                   (ndr, NDR_BUFFERS, &r->type));
  188         NDR_CHECK(ndr_pull_security_ace_object_inherited_type
  189                   (ndr, NDR_BUFFERS, &r->inherited_type));
  190     }
  191     return NDR_ERR_SUCCESS;
  192 }
  193 
  194 
  195 static enum ndr_err_code
  196 ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr,
  197                                  int ndr_flags,
  198                                  union security_ace_object_ctr *r)
  199 {
  200     uint32_t level;
  201     level = ndr_pull_get_switch_value(ndr, r);
  202     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  203     if (ndr_flags & NDR_SCALARS) {
  204         NDR_CHECK(ndr_pull_union_align(ndr, 4));
  205         switch (level) {
  206         case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: {
  207             NDR_CHECK(ndr_pull_security_ace_object
  208                       (ndr, NDR_SCALARS, &r->object));
  209             break; }
  210         case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: {
  211             NDR_CHECK(ndr_pull_security_ace_object
  212                       (ndr, NDR_SCALARS, &r->object));
  213             break; }
  214         case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: {
  215             NDR_CHECK(ndr_pull_security_ace_object
  216                       (ndr, NDR_SCALARS, &r->object));
  217             break; }
  218         case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: {
  219             NDR_CHECK(ndr_pull_security_ace_object
  220                       (ndr, NDR_SCALARS, &r->object));
  221             break; }
  222         default: {
  223             break; }
  224         }
  225     }
  226     if (ndr_flags & NDR_BUFFERS) {
  227         switch (level) {
  228         case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
  229             NDR_CHECK(ndr_pull_security_ace_object
  230                       (ndr, NDR_BUFFERS, &r->object));
  231             break;
  232         case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
  233             NDR_CHECK(ndr_pull_security_ace_object
  234                       (ndr, NDR_BUFFERS, &r->object));
  235             break;
  236         case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
  237             NDR_CHECK(ndr_pull_security_ace_object
  238                       (ndr, NDR_BUFFERS, &r->object));
  239             break;
  240         case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
  241             NDR_CHECK(ndr_pull_security_ace_object
  242                       (ndr, NDR_BUFFERS, &r->object));
  243             break;
  244         default:
  245             break;
  246         }
  247     }
  248     return NDR_ERR_SUCCESS;
  249 }
  250 
  251 static enum ndr_err_code
  252 ndr_pull_dom_sid(struct ndr_pull *ndr,
  253                  int ndr_flags,
  254                  struct dom_sid *r)
  255 {
  256     uint32_t cntr_sub_auths_0;
  257     if (ndr_flags & NDR_SCALARS) {
  258         NDR_CHECK(ndr_pull_align(ndr, 4));
  259         NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num));
  260         NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths));
  261         if (r->num_auths < 0 || r->num_auths > N_ELEMENTS(r->sub_auths)) {
  262             return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
  263         }
  264         NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
  265         memset(&r->sub_auths, 0, sizeof(r->sub_auths));
  266         for (cntr_sub_auths_0 = 0;
  267              cntr_sub_auths_0 < r->num_auths;
  268              cntr_sub_auths_0++) {
  269             NDR_CHECK(ndr_pull_uint32
  270                       (ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0]));
  271         }
  272     }
  273     return NDR_ERR_SUCCESS;
  274 }
  275 
  276 static enum ndr_err_code
  277 ndr_pull_security_ace(struct ndr_pull *ndr,
  278                       int ndr_flags,
  279                       struct security_ace *r)
  280 {
  281     if (ndr_flags & NDR_SCALARS) {
  282         uint32_t start_ofs = ndr->offset;
  283         uint32_t size = 0;
  284         uint32_t pad = 0;
  285         NDR_CHECK(ndr_pull_align(ndr, 4));
  286         NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
  287         NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
  288         NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
  289         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
  290         NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
  291         NDR_CHECK(ndr_pull_security_ace_object_ctr
  292                   (ndr, NDR_SCALARS, &r->object));
  293         NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
  294         size = ndr->offset - start_ofs;
  295         if (r->size < size) {
  296             return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
  297                                   "ndr_pull_security_ace: r->size %u < size %u",
  298                                   (unsigned)r->size, size);
  299         }
  300         pad = r->size - size;
  301         NDR_PULL_NEED_BYTES(ndr, pad);
  302         ndr->offset += pad;
  303     }
  304     if (ndr_flags & NDR_BUFFERS) {
  305         NDR_CHECK(ndr_pull_security_ace_object_ctr
  306                   (ndr, NDR_BUFFERS, &r->object));
  307     }
  308     return NDR_ERR_SUCCESS;
  309 }
  310 
  311 static enum ndr_err_code
  312 ndr_pull_security_acl_revision(struct ndr_pull *ndr,
  313                                int ndr_flags,
  314                                enum security_acl_revision *r)
  315 {
  316     uint16_t v;
  317     NDR_CHECK(ndr_pull_enum_uint1632(ndr, ndr_flags, &v));
  318     *r = v;
  319     return NDR_ERR_SUCCESS;
  320 }
  321 
  322 
  323 static enum ndr_err_code
  324 ndr_pull_security_acl(struct ndr_pull *ndr,
  325                       int ndr_flags,
  326                       struct security_acl *r)
  327 {
  328     uint32_t size_aces_0 = 0;
  329     uint32_t cntr_aces_0;
  330     TALLOC_CTX *_mem_save_aces_0;
  331     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  332     if (ndr_flags & NDR_SCALARS) {
  333         NDR_CHECK(ndr_pull_align(ndr, 4));
  334         NDR_CHECK(ndr_pull_security_acl_revision
  335                   (ndr, NDR_SCALARS, &r->revision));
  336         NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
  337         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_aces));
  338         if (r->num_aces > 1000) {
  339             return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
  340         }
  341         size_aces_0 = r->num_aces;
  342         NDR_PULL_ALLOC_N(ndr, r->aces, size_aces_0);
  343         _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr);
  344         NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0);
  345         for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) {
  346             NDR_CHECK(ndr_pull_security_ace
  347                       (ndr, NDR_SCALARS, &r->aces[cntr_aces_0]));
  348         }
  349         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0);
  350         NDR_CHECK(ndr_pull_trailer_align(ndr, 4));
  351     }
  352     if (ndr_flags & NDR_BUFFERS) {
  353         size_aces_0 = r->num_aces;
  354         _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr);
  355         NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0);
  356         for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) {
  357             NDR_CHECK(ndr_pull_security_ace
  358                       (ndr, NDR_BUFFERS, &r->aces[cntr_aces_0]));
  359         }
  360         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0);
  361     }
  362     return NDR_ERR_SUCCESS;
  363 }
  364 
  365 
  366 static enum ndr_err_code
  367 ndr_pull_security_descriptor_revision(struct ndr_pull *ndr,
  368                                       int ndr_flags,
  369                                       enum security_descriptor_revision *r)
  370 {
  371     uint8_t v;
  372     NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v));
  373     *r = v;
  374     return NDR_ERR_SUCCESS;
  375 }
  376 
  377 
  378 
  379 static enum ndr_err_code
  380 ndr_pull_security_descriptor_type(struct ndr_pull *ndr,
  381                                   int ndr_flags,
  382                                   uint16_t *r)
  383 {
  384     uint16_t v;
  385     NDR_CHECK(ndr_pull_uint16(ndr, ndr_flags, &v));
  386     *r = v;
  387     return NDR_ERR_SUCCESS;
  388 }
  389 
  390 
  391 enum ndr_err_code
  392 ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr,
  393                                     int ndr_flags,
  394                                     struct security_descriptor *r)
  395 {
  396     uint32_t _ptr_owner_sid;
  397     TALLOC_CTX *_mem_save_owner_sid_0;
  398     uint32_t _ptr_group_sid;
  399     TALLOC_CTX *_mem_save_group_sid_0;
  400     uint32_t _ptr_sacl;
  401     TALLOC_CTX *_mem_save_sacl_0;
  402     uint32_t _ptr_dacl;
  403     TALLOC_CTX *_mem_save_dacl_0;
  404     uint32_t _flags_save_STRUCT = ndr->flags;
  405     uint32_t _relative_save_offset;
  406 
  407     ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
  408     NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
  409     if (ndr_flags & NDR_SCALARS) {
  410         NDR_CHECK(ndr_pull_align(ndr, 5));
  411         NDR_CHECK(ndr_pull_security_descriptor_revision(ndr,
  412                                                         NDR_SCALARS,
  413                                                         &r->revision));
  414         NDR_CHECK(ndr_pull_security_descriptor_type(ndr,
  415                                                     NDR_SCALARS,
  416                                                     &r->type));
  417         NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_owner_sid));
  418         if (_ptr_owner_sid) {
  419             NDR_PULL_ALLOC(ndr, r->owner_sid);
  420             NDR_CHECK(ndr_pull_relative_ptr1(ndr,
  421                                              r->owner_sid,
  422                                              _ptr_owner_sid));
  423         } else {
  424             r->owner_sid = NULL;
  425         }
  426         NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_sid));
  427         if (_ptr_group_sid) {
  428             NDR_PULL_ALLOC(ndr, r->group_sid);
  429             NDR_CHECK(ndr_pull_relative_ptr1(ndr,
  430                                              r->group_sid,
  431                                              _ptr_group_sid));
  432         } else {
  433             r->group_sid = NULL;
  434         }
  435         NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sacl));
  436         if (_ptr_sacl) {
  437             NDR_PULL_ALLOC(ndr, r->sacl);
  438             NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->sacl, _ptr_sacl));
  439         } else {
  440             r->sacl = NULL;
  441         }
  442         NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_dacl));
  443         if (_ptr_dacl) {
  444             NDR_PULL_ALLOC(ndr, r->dacl);
  445             NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->dacl, _ptr_dacl));
  446         } else {
  447             r->dacl = NULL;
  448         }
  449         NDR_CHECK(ndr_pull_trailer_align(ndr, 5));
  450     }
  451     if (ndr_flags & NDR_BUFFERS) {
  452         if (r->owner_sid) {
  453             _relative_save_offset = ndr->offset;
  454             NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->owner_sid));
  455             _mem_save_owner_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
  456             NDR_PULL_SET_MEM_CTX(ndr, r->owner_sid, 0);
  457             NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->owner_sid));
  458             NDR_PULL_SET_MEM_CTX(ndr, _mem_save_owner_sid_0, 0);
  459             if (ndr->offset > ndr->relative_highest_offset) {
  460                 ndr->relative_highest_offset = ndr->offset;
  461             }
  462             ndr->offset = _relative_save_offset;
  463         }
  464         if (r->group_sid) {
  465             _relative_save_offset = ndr->offset;
  466             NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->group_sid));
  467             _mem_save_group_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
  468             NDR_PULL_SET_MEM_CTX(ndr, r->group_sid, 0);
  469             NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->group_sid));
  470             NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_sid_0, 0);
  471             if (ndr->offset > ndr->relative_highest_offset) {
  472                 ndr->relative_highest_offset = ndr->offset;
  473             }
  474             ndr->offset = _relative_save_offset;
  475         }
  476         if (r->sacl) {
  477             _relative_save_offset = ndr->offset;
  478             NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->sacl));
  479             _mem_save_sacl_0 = NDR_PULL_GET_MEM_CTX(ndr);
  480             NDR_PULL_SET_MEM_CTX(ndr, r->sacl, 0);
  481             NDR_CHECK(ndr_pull_security_acl(ndr,
  482                                             NDR_SCALARS|NDR_BUFFERS,
  483                                             r->sacl));
  484             NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sacl_0, 0);
  485             if (ndr->offset > ndr->relative_highest_offset) {
  486                 ndr->relative_highest_offset = ndr->offset;
  487             }
  488             ndr->offset = _relative_save_offset;
  489         }
  490         if (r->dacl) {
  491             _relative_save_offset = ndr->offset;
  492             NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->dacl));
  493             _mem_save_dacl_0 = NDR_PULL_GET_MEM_CTX(ndr);
  494             NDR_PULL_SET_MEM_CTX(ndr, r->dacl, 0);
  495             NDR_CHECK(ndr_pull_security_acl(ndr,
  496                                             NDR_SCALARS|NDR_BUFFERS,
  497                                             r->dacl));
  498             NDR_PULL_SET_MEM_CTX(ndr, _mem_save_dacl_0, 0);
  499             if (ndr->offset > ndr->relative_highest_offset) {
  500                 ndr->relative_highest_offset = ndr->offset;
  501             }
  502             ndr->offset = _relative_save_offset;
  503         }
  504 
  505         ndr->flags = _flags_save_STRUCT;
  506     }
  507     return NDR_ERR_SUCCESS;
  508 }