rpc_parse/parse_sec.c

説明を見る。
00001 /* 
00002  *  Unix SMB/Netbios implementation.
00003  *  Version 1.9.
00004  *  RPC Pipe client / server routines
00005  *  Copyright (C) Andrew Tridgell              1992-1998,
00006  *  Copyright (C) Jeremy R. Allison            1995-2005.
00007  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
00008  *  Copyright (C) Paul Ashton                  1997-1998.
00009  *  
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *  
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *  
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023  */
00024 
00025 #include "includes.h"
00026 
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_RPC_PARSE
00029 
00030 /*******************************************************************
00031  Reads or writes a SEC_ACE structure.
00032 ********************************************************************/
00033 
00034 BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
00035 {
00036         uint32 old_offset;
00037         uint32 offset_ace_size;
00038 
00039         if (psa == NULL)
00040                 return False;
00041 
00042         prs_debug(ps, depth, desc, "sec_io_ace");
00043         depth++;
00044         
00045         old_offset = prs_offset(ps);
00046 
00047         if(!prs_uint8("type ", ps, depth, &psa->type))
00048                 return False;
00049 
00050         if(!prs_uint8("flags", ps, depth, &psa->flags))
00051                 return False;
00052 
00053         if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
00054                 return False;
00055 
00056         if (!prs_uint32("access_mask", ps, depth, &psa->access_mask))
00057                 return False;
00058 
00059         /* check whether object access is present */
00060         if (!sec_ace_object(psa->type)) {
00061                 if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
00062                         return False;
00063         } else {
00064                 if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
00065                         return False;
00066 
00067                 if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
00068                         if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
00069                                 return False;
00070 
00071                 if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
00072                         if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
00073                                 return False;
00074 
00075                 if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
00076                         return False;
00077         }
00078 
00079         /* Theorectically an ACE can have a size greater than the
00080            sum of its components. When marshalling, pad with extra null bytes up to the
00081            correct size. */
00082 
00083         if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
00084                 uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
00085                 uint32 i;
00086                 uint8 c = 0;
00087 
00088                 for (i = 0; i < extra_len; i++) {
00089                         if (!prs_uint8("ace extra space", ps, depth, &c))
00090                                 return False;
00091                 }
00092         }
00093 
00094         if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
00095                 return False;
00096 
00097         return True;
00098 }
00099 
00100 /*******************************************************************
00101  Reads or writes a SEC_ACL structure.  
00102 
00103  First of the xx_io_xx functions that allocates its data structures
00104  for you as it reads them.
00105 ********************************************************************/
00106 
00107 BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
00108 {
00109         unsigned int i;
00110         uint32 old_offset;
00111         uint32 offset_acl_size;
00112         SEC_ACL *psa;
00113 
00114         /*
00115          * Note that the size is always a multiple of 4 bytes due to the
00116          * nature of the data structure.  Therefore the prs_align() calls
00117          * have been removed as they through us off when doing two-layer
00118          * marshalling such as in the printing code (RPC_BUFFER).  --jerry
00119          */
00120 
00121         if (ppsa == NULL)
00122                 return False;
00123 
00124         psa = *ppsa;
00125 
00126         if(UNMARSHALLING(ps) && psa == NULL) {
00127                 /*
00128                  * This is a read and we must allocate the stuct to read into.
00129                  */
00130                 if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL)
00131                         return False;
00132                 *ppsa = psa;
00133         }
00134 
00135         prs_debug(ps, depth, desc, "sec_io_acl");
00136         depth++;
00137         
00138         old_offset = prs_offset(ps);
00139 
00140         if(!prs_uint16("revision", ps, depth, &psa->revision))
00141                 return False;
00142 
00143         if(!prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size))
00144                 return False;
00145 
00146         if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
00147                 return False;
00148 
00149         if (UNMARSHALLING(ps)) {
00150                 if (psa->num_aces) {
00151                         if((psa->aces = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces)) == NULL)
00152                                 return False;
00153                 } else {
00154                         psa->aces = NULL;
00155                 }
00156         }
00157 
00158         for (i = 0; i < psa->num_aces; i++) {
00159                 fstring tmp;
00160                 slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
00161                 if(!sec_io_ace(tmp, &psa->aces[i], ps, depth))
00162                         return False;
00163         }
00164 
00165         /* Theorectically an ACL can have a size greater than the
00166            sum of its components. When marshalling, pad with extra null bytes up to the
00167            correct size. */
00168 
00169         if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
00170                 uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
00171                 uint8 c = 0;
00172 
00173                 for (i = 0; i < extra_len; i++) {
00174                         if (!prs_uint8("acl extra space", ps, depth, &c))
00175                                 return False;
00176                 }
00177         }
00178 
00179         if(!prs_uint16_post("size     ", ps, depth, &psa->size, offset_acl_size, old_offset))
00180                 return False;
00181 
00182         return True;
00183 }
00184 
00185 /*******************************************************************
00186  Reads or writes a SEC_DESC structure.
00187  If reading and the *ppsd = NULL, allocates the structure.
00188 ********************************************************************/
00189 
00190 BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
00191 {
00192         uint32 old_offset;
00193         uint32 max_offset = 0; /* after we're done, move offset to end */
00194         uint32 tmp_offset = 0;
00195 
00196         SEC_DESC *psd;
00197 
00198         if (ppsd == NULL)
00199                 return False;
00200 
00201         psd = *ppsd;
00202 
00203         if (psd == NULL) {
00204                 if(UNMARSHALLING(ps)) {
00205                         if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL)
00206                                 return False;
00207                         *ppsd = psd;
00208                 } else {
00209                         /* Marshalling - just ignore. */
00210                         return True;
00211                 }
00212         }
00213 
00214         prs_debug(ps, depth, desc, "sec_io_desc");
00215         depth++;
00216 
00217         /* start of security descriptor stored for back-calc offset purposes */
00218         old_offset = prs_offset(ps);
00219 
00220         if(!prs_uint16("revision ", ps, depth, &psd->revision))
00221                 return False;
00222 
00223         if(!prs_uint16("type     ", ps, depth, &psd->type))
00224                 return False;
00225 
00226         if (MARSHALLING(ps)) {
00227                 uint32 offset = SEC_DESC_HEADER_SIZE;
00228 
00229                 /*
00230                  * Work out the offsets here, as we write it out.
00231                  */
00232 
00233                 if (psd->sacl != NULL) {
00234                         psd->off_sacl = offset;
00235                         offset += psd->sacl->size;
00236                 } else {
00237                         psd->off_sacl = 0;
00238                 }
00239 
00240                 if (psd->dacl != NULL) {
00241                         psd->off_dacl = offset;
00242                         offset += psd->dacl->size;
00243                 } else {
00244                         psd->off_dacl = 0;
00245                 }
00246 
00247                 if (psd->owner_sid != NULL) {
00248                         psd->off_owner_sid = offset;
00249                         offset += sid_size(psd->owner_sid);
00250                 } else {
00251                         psd->off_owner_sid = 0;
00252                 }
00253 
00254                 if (psd->group_sid != NULL) {
00255                         psd->off_grp_sid = offset;
00256                         offset += sid_size(psd->group_sid);
00257                 } else {
00258                         psd->off_grp_sid = 0;
00259                 }
00260         }
00261 
00262         if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
00263                 return False;
00264 
00265         if(!prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid))
00266                 return False;
00267 
00268         if(!prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl))
00269                 return False;
00270 
00271         if(!prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
00272                 return False;
00273 
00274         max_offset = MAX(max_offset, prs_offset(ps));
00275 
00276         if (psd->off_owner_sid != 0) {
00277 
00278                 tmp_offset = prs_offset(ps);
00279                 if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
00280                         return False;
00281 
00282                 if (UNMARSHALLING(ps)) {
00283                         /* reading */
00284                         if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
00285                                 return False;
00286                 }
00287 
00288                 if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
00289                         return False;
00290 
00291                 max_offset = MAX(max_offset, prs_offset(ps));
00292 
00293                 if (!prs_set_offset(ps,tmp_offset))
00294                         return False;
00295         }
00296 
00297         if (psd->off_grp_sid != 0) {
00298 
00299                 tmp_offset = prs_offset(ps);
00300                 if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
00301                         return False;
00302 
00303                 if (UNMARSHALLING(ps)) {
00304                         /* reading */
00305                         if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
00306                                 return False;
00307                 }
00308 
00309                 if(!smb_io_dom_sid("group_sid", psd->group_sid, ps, depth))
00310                         return False;
00311                         
00312                 max_offset = MAX(max_offset, prs_offset(ps));
00313 
00314                 if (!prs_set_offset(ps,tmp_offset))
00315                         return False;
00316         }
00317 
00318         if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
00319                 tmp_offset = prs_offset(ps);
00320                 if(!prs_set_offset(ps, old_offset + psd->off_sacl))
00321                         return False;
00322                 if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
00323                         return False;
00324                 max_offset = MAX(max_offset, prs_offset(ps));
00325                 if (!prs_set_offset(ps,tmp_offset))
00326                         return False;
00327         }
00328 
00329         if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
00330                 tmp_offset = prs_offset(ps);
00331                 if(!prs_set_offset(ps, old_offset + psd->off_dacl))
00332                         return False;
00333                 if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
00334                         return False;
00335                 max_offset = MAX(max_offset, prs_offset(ps));
00336                 if (!prs_set_offset(ps,tmp_offset))
00337                         return False;
00338         }
00339 
00340         if(!prs_set_offset(ps, max_offset))
00341                 return False;
00342 
00343         return True;
00344 }
00345 
00346 /*******************************************************************
00347  Reads or writes a SEC_DESC_BUF structure.
00348 ********************************************************************/
00349 
00350 BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
00351 {
00352         uint32 off_len;
00353         uint32 off_max_len;
00354         uint32 old_offset;
00355         uint32 size;
00356         SEC_DESC_BUF *psdb;
00357 
00358         if (ppsdb == NULL)
00359                 return False;
00360 
00361         psdb = *ppsdb;
00362 
00363         if (UNMARSHALLING(ps) && psdb == NULL) {
00364                 if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL)
00365                         return False;
00366                 *ppsdb = psdb;
00367         }
00368 
00369         prs_debug(ps, depth, desc, "sec_io_desc_buf");
00370         depth++;
00371 
00372         if(!prs_align(ps))
00373                 return False;
00374         
00375         if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
00376                 return False;
00377 
00378         if(!prs_uint32    ("ptr  ", ps, depth, &psdb->ptr))
00379                 return False;
00380 
00381         if(!prs_uint32_pre("len    ", ps, depth, &psdb->len, &off_len))
00382                 return False;
00383 
00384         old_offset = prs_offset(ps);
00385 
00386         /* reading, length is non-zero; writing, descriptor is non-NULL */
00387         if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) {
00388                 if(!sec_io_desc("sec   ", &psdb->sec, ps, depth))
00389                         return False;
00390         }
00391 
00392         if(!prs_align(ps))
00393                 return False;
00394         
00395         size = prs_offset(ps) - old_offset;
00396         if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
00397                 return False;
00398 
00399         if(!prs_uint32_post("len    ", ps, depth, &psdb->len, off_len, size))
00400                 return False;
00401 
00402         return True;
00403 }

Sambaに対してSat Aug 29 21:23:18 2009に生成されました。  doxygen 1.4.7