Changeset 134 for trunk/lib/smb_deps.c


Ignore:
Timestamp:
01/16/09 13:36:04 (15 years ago)
Author:
tim
Message:

rewrote winsec library, stripping out Samba dependencies

eliminated remaining Samba prs functions

added support for 'li' subkey list records

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/smb_deps.c

    r132 r134  
    142142
    143143/* End of stuff from lib/time.c */
    144 
    145 /* From parse_prs.c */
    146 
    147 /*******************************************************************
    148  Attempt, if needed, to grow a data buffer.
    149  Also depends on the data stream mode (io).
    150  ********************************************************************/
    151 bool prs_grow(prs_struct *ps, uint32 extra_space)
    152 {
    153   uint32 new_size;
    154   char *new_data;
    155  
    156   ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);
    157  
    158   if(ps->data_offset + extra_space <= ps->buffer_size)
    159     return true;
    160  
    161   /*
    162    * We cannot grow the buffer if we're not reading
    163    * into the prs_struct, or if we don't own the memory.
    164    */
    165  
    166   if(ps->io || !ps->is_dynamic)
    167     return false;
    168  
    169   /*
    170    * Decide how much extra space we really need.
    171    */
    172   extra_space -= (ps->buffer_size - ps->data_offset);
    173   if(ps->buffer_size == 0)
    174   {
    175     /*
    176      * Ensure we have at least a PDU's length, or extra_space,
    177      * whichever is greater.
    178      */ 
    179     new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
    180    
    181     if((new_data = zalloc(new_size)) == NULL)
    182       return false;
    183   }
    184   else
    185   {
    186     /*
    187      * If the current buffer size is bigger than the space needed, just
    188      * double it, else add extra_space.
    189      */
    190     new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);           
    191    
    192     if ((new_data = (char*)realloc(ps->data_p, new_size)) == NULL)
    193       return false;
    194    
    195     memset(&new_data[ps->buffer_size], '\0',
    196            (size_t)(new_size - ps->buffer_size));
    197   }
    198   ps->buffer_size = new_size;
    199   ps->data_p = new_data;
    200  
    201   return true;
    202 }
    203 
    204 
    205 /*******************************************************************
    206  Align a the data_len to a multiple of align bytes - filling with
    207  zeros.
    208  ********************************************************************/
    209 bool prs_align(prs_struct *ps)
    210 {
    211   uint32 mod = ps->data_offset & (ps->align-1);
    212  
    213   if (ps->align != 0 && mod != 0)
    214   {
    215     uint32 extra_space = (ps->align - mod);
    216     if(!prs_grow(ps, extra_space))
    217       return false;
    218     memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
    219     ps->data_offset += extra_space;
    220   }
    221  
    222   return true;
    223 }
    224 
    225 
    226 /**
    227  * Initialise an expandable parse structure.
    228  *
    229  * @param size Initial buffer size.  If >0, a new buffer will be
    230  * created with malloc().
    231  *
    232  * @return false if allocation fails, otherwise true.
    233  **/
    234 
    235 bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io)
    236 {
    237   if(ps == NULL)
    238     return false;
    239   memset(ps, 0, sizeof(prs_struct));
    240 
    241   ps->io = io;
    242   ps->bigendian_data = RPC_LITTLE_ENDIAN;
    243   ps->align = RPC_PARSE_ALIGN;
    244   ps->is_dynamic = false;
    245   ps->data_offset = 0;
    246   ps->buffer_size = 0;
    247   ps->data_p = NULL;
    248   ps->mem_ctx = ctx;
    249  
    250   if (size != 0)
    251   {
    252     ps->buffer_size = size;
    253     if((ps->data_p = (char *)zalloc((size_t)size)) == NULL)
    254       return false;
    255 
    256     ps->is_dynamic = true; /* We own this memory. */
    257   }
    258  
    259   return true;
    260 }
    261 
    262 
    263 char *prs_mem_get(prs_struct *ps, uint32 extra_size)
    264 {
    265   if(ps->io)
    266   {
    267     /*
    268      * If reading, ensure that we can read the requested size item.
    269      */
    270     if (ps->data_offset + extra_size > ps->buffer_size)
    271       return NULL;
    272   }
    273   else
    274   {
    275     /*
    276      * Writing - grow the buffer if needed.
    277      */
    278     if(!prs_grow(ps, extra_size))
    279       return NULL;
    280   }
    281 
    282   return &ps->data_p[ps->data_offset];
    283 }
    284 
    285 
    286 /*******************************************************************
    287  Stream a uint32.
    288  ********************************************************************/
    289 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)
    290 {
    291   char *q = prs_mem_get(ps, sizeof(uint32));
    292   if (q == NULL)
    293     return false;
    294  
    295   if (ps->io)
    296   {
    297     if (ps->bigendian_data)
    298       *data32 = RIVAL(q,0);
    299     else
    300       *data32 = IVAL(q,0);
    301   }
    302   else
    303   {
    304     if (ps->bigendian_data)
    305       RSIVAL(q,0,*data32);
    306     else
    307       SIVAL(q,0,*data32);
    308   }
    309   ps->data_offset += sizeof(uint32);
    310  
    311   return true;
    312 }
    313 
    314 
    315 /******************************************************************
    316  Stream an array of uint32s. Length is number of uint32s.
    317  ********************************************************************/
    318 bool prs_uint32s(const char *name, prs_struct *ps,
    319                  int depth, uint32 *data32s, int len)
    320 {
    321   int i;
    322   char *q = prs_mem_get(ps, len * sizeof(uint32));
    323   if (q == NULL)
    324     return false;
    325  
    326   if (ps->io)
    327   {
    328     if (ps->bigendian_data)
    329     {
    330       for (i = 0; i < len; i++)
    331         data32s[i] = RIVAL(q, 4*i);
    332     }
    333     else
    334     {
    335       for (i = 0; i < len; i++)
    336         data32s[i] = IVAL(q, 4*i);
    337     }
    338   }
    339   else
    340   {
    341     if (ps->bigendian_data)
    342     {
    343       for (i = 0; i < len; i++)
    344         RSIVAL(q, 4*i, data32s[i]);
    345     }
    346     else
    347     {
    348       for (i = 0; i < len; i++)
    349         SIVAL(q, 4*i, data32s[i]);
    350     }
    351   }
    352   ps->data_offset += (len * sizeof(uint32));
    353  
    354   return true;
    355 }
    356 
    357 
    358 /*******************************************************************
    359  Stream a uint16.
    360  ********************************************************************/
    361 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)
    362 {
    363   char *q = prs_mem_get(ps, sizeof(uint16));
    364   if (q == NULL)
    365     return false;
    366  
    367   if (ps->io)
    368   {
    369     if (ps->bigendian_data)
    370       *data16 = RSVAL(q,0);
    371     else
    372       *data16 = SVAL(q,0);
    373   }
    374   else
    375   {
    376     if (ps->bigendian_data)
    377       RSSVAL(q,0,*data16);
    378     else
    379       SSVAL(q,0,*data16);
    380   }
    381   ps->data_offset += sizeof(uint16);
    382  
    383   return true;
    384 }
    385 
    386 
    387 /*******************************************************************
    388  prs_uint16 wrapper. Call this and it sets up a pointer to where the
    389  uint16 should be stored, or gets the size if reading.
    390  ********************************************************************/
    391 bool prs_uint16_pre(const char *name, prs_struct *ps, int depth,
    392                     uint16 *data16, uint32 *offset)
    393 {
    394   *offset = ps->data_offset;
    395   if (ps->io)
    396   {
    397     /* reading. */
    398     return prs_uint16(name, ps, depth, data16);
    399   }
    400   else
    401   {
    402     char *q = prs_mem_get(ps, sizeof(uint16));
    403     if(q ==NULL)
    404       return false;
    405     ps->data_offset += sizeof(uint16);
    406   }
    407   return true;
    408 }
    409 
    410 
    411 /*******************************************************************
    412  prs_uint16 wrapper.  call this and it retrospectively stores the size.
    413  does nothing on reading, as that is already handled by ...._pre()
    414  ********************************************************************/
    415 bool prs_uint16_post(const char *name, prs_struct *ps, int depth,
    416                      uint16 *data16, uint32 ptr_uint16, uint32 start_offset)
    417 {
    418   if (!ps->io)
    419   {
    420     /*
    421      * Writing - temporarily move the offset pointer.
    422      */
    423     uint16 data_size = ps->data_offset - start_offset;
    424     uint32 old_offset = ps->data_offset;
    425    
    426     ps->data_offset = ptr_uint16;
    427     if(!prs_uint16(name, ps, depth, &data_size))
    428     {
    429       ps->data_offset = old_offset;
    430       return false;
    431     }
    432     ps->data_offset = old_offset;
    433   }
    434   else
    435     ps->data_offset = start_offset + (uint32)(*data16);
    436 
    437   return true;
    438 }
    439 
    440 
    441 /*******************************************************************
    442  Stream a uint8.
    443  ********************************************************************/
    444 bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
    445 {
    446   char *q = prs_mem_get(ps, 1);
    447   if (q == NULL)
    448     return false;
    449  
    450   if (ps->io)
    451     *data8 = CVAL(q,0);
    452   else
    453     SCVAL(q,0,*data8);
    454  
    455   ps->data_offset += 1;
    456  
    457   return true;
    458 }
    459 
    460 
    461 /******************************************************************
    462  Stream an array of uint8s. Length is number of uint8s.
    463  ********************************************************************/
    464 bool prs_uint8s(const char *name, prs_struct *ps, int depth,
    465                 uint8* data8s, int len)
    466 {
    467   int i;
    468   char *q = prs_mem_get(ps, len);
    469   if (q == NULL)
    470     return false;
    471  
    472   if (ps->io)
    473   {
    474     for (i = 0; i < len; i++)
    475       data8s[i] = CVAL(q,i);
    476   }
    477   else
    478   {
    479     for (i = 0; i < len; i++)
    480       SCVAL(q, i, data8s[i]);
    481   }
    482  
    483   ps->data_offset += len;
    484  
    485   return true;
    486 }
    487 
    488 
    489 /*******************************************************************
    490  Set the current offset (external interface).
    491  ********************************************************************/
    492 bool prs_set_offset(prs_struct *ps, uint32 offset)
    493 {
    494   if(offset <= ps->data_offset)
    495   {
    496     ps->data_offset = offset;
    497     return true;
    498   }
    499  
    500   if(!prs_grow(ps, offset - ps->data_offset))
    501     return false;
    502  
    503   ps->data_offset = offset;
    504   return true;
    505 }
    506 
    507 /* End of stuff from parse_prs.c */
    508 
    509 /* From rpc_parse/parse_misc.c */
    510 
    511 /*******************************************************************
    512  Reads or writes a struct uuid
    513 ********************************************************************/
    514 bool smb_io_uuid(const char *desc, struct uuid *uuid,
    515                  prs_struct *ps, int depth)
    516 {
    517   if (uuid == NULL)
    518     return false;
    519   depth++;
    520  
    521   if(!prs_uint32 ("data   ", ps, depth, &uuid->time_low))
    522     return false;
    523   if(!prs_uint16 ("data   ", ps, depth, &uuid->time_mid))
    524     return false;
    525   if(!prs_uint16 ("data   ", ps, depth, &uuid->time_hi_and_version))
    526     return false;
    527  
    528   if(!prs_uint8s ("data   ", ps, depth,
    529                   uuid->clock_seq, sizeof(uuid->clock_seq)))
    530     return false;
    531 
    532   if(!prs_uint8s ("data   ", ps, depth, uuid->node, sizeof(uuid->node)))
    533     return false;
    534  
    535   return true;
    536 }
    537 
    538 
    539 /*******************************************************************
    540  Reads or writes an NTTIME structure.
    541 ********************************************************************/
    542 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
    543 {
    544   if (nttime == NULL)
    545     return false;
    546   depth++;
    547 
    548   if(!prs_align(ps))
    549     return false;
    550        
    551   if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
    552     return false;
    553   if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
    554     return false;
    555 
    556   return true;
    557 }
Note: See TracChangeset for help on using the changeset viewer.