s3:registry/regfio read SD from the correct location
[sfrench/samba-autobuild/.git] / source3 / registry / regfio.c
index 38411d8556b5e27a8d192a4f33875ab6a7138ca5..b32bf0314df089201bd5e72a44b1358516e6125a 100644 (file)
  */
 
 #include "includes.h"
+#include "system/filesys.h"
 #include "regfio.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "../libcli/security/security_descriptor.h"
+#include "../libcli/security/secdesc.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_REGISTRY
  *
  ******************************************************************/
 
+#if defined(PARANOID_MALLOC_CHECKER)
+#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem_((ps),sizeof(type),(count))
+#else
+#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem((ps),sizeof(type),(count))
+#endif
+
+/*******************************************************************
+ Reads or writes an NTTIME structure.
+********************************************************************/
+
+static bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
+{
+       uint32 low, high;
+       if (nttime == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "smb_io_time");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if (MARSHALLING(ps)) {
+               low = *nttime & 0xFFFFFFFF;
+               high = *nttime >> 32;
+       }
+
+       if(!prs_uint32("low ", ps, depth, &low)) /* low part */
+               return False;
+       if(!prs_uint32("high", ps, depth, &high)) /* high part */
+               return False;
+
+       if (UNMARSHALLING(ps)) {
+               *nttime = (((uint64_t)high << 32) + low);
+       }
+
+       return True;
+}
 
 /*******************************************************************
 *******************************************************************/
@@ -45,7 +87,7 @@ static int write_block( REGF_FILE *file, prs_struct *ps, uint32 offset )
 
        /* check for end of file */
 
-       if ( sys_fstat( file->fd, &sbuf ) ) {
+       if (sys_fstat(file->fd, &sbuf, false)) {
                DEBUG(0,("write_block: stat() failed! (%s)\n", strerror(errno)));
                return -1;
        }
@@ -79,7 +121,7 @@ static int read_block( REGF_FILE *file, prs_struct *ps, uint32 file_offset, uint
 
        /* check for end of file */
 
-       if ( sys_fstat( file->fd, &sbuf ) ) {
+       if (sys_fstat(file->fd, &sbuf, false)) {
                DEBUG(0,("read_block: stat() failed! (%s)\n", strerror(errno)));
                return -1;
        }
@@ -456,7 +498,7 @@ static REGF_HBIN* read_hbin_block( REGF_FILE *file, off_t offset )
        REGF_HBIN *hbin;
        uint32 record_size, curr_off, block_size, header;
        
-       if ( !(hbin = TALLOC_ZERO_P(file->mem_ctx, REGF_HBIN)) ) 
+       if ( !(hbin = talloc_zero(file->mem_ctx, REGF_HBIN)) ) 
                return NULL;
        hbin->file_off = offset;
        hbin->free_off = -1;
@@ -480,7 +522,7 @@ static REGF_HBIN* read_hbin_block( REGF_FILE *file, off_t offset )
        /* remember that the record_size is in the 4 bytes preceeding the record itself */
 
        if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE-sizeof(uint32) ) )
-               return False;
+               return NULL;
 
        record_size = 0;
        header = 0;
@@ -503,12 +545,12 @@ static REGF_HBIN* read_hbin_block( REGF_FILE *file, off_t offset )
                }
 
                if ( !prs_set_offset( &hbin->ps, curr_off) )
-                       return False;
+                       return NULL;
 
                if ( !prs_uint32( "rec_size", &hbin->ps, 0, &record_size ) )
-                       return False;
+                       return NULL;
                if ( !prs_uint32( "header", &hbin->ps, 0, &header ) )
-                       return False;
+                       return NULL;
                
                SMB_ASSERT( record_size != 0 );
 
@@ -532,7 +574,7 @@ static REGF_HBIN* read_hbin_block( REGF_FILE *file, off_t offset )
        DEBUG(10,("read_hbin_block: free space offset == 0x%x\n", hbin->free_off));
 
        if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE )  )
-               return False;
+               return NULL;
        
        return hbin;
 }
@@ -726,8 +768,10 @@ static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_
                        if (!prs_copy_data_in(&hbin->ps, (const char *)blob.data, blob.length))
                                return False;
                } else {
-                       blob = data_blob_const(prs_data_p(&hbin->ps),
-                                              prs_data_size(&hbin->ps));
+                       blob = data_blob_const(
+                               prs_data_p(&hbin->ps) + prs_offset(&hbin->ps),
+                               prs_data_size(&hbin->ps) - prs_offset(&hbin->ps)
+                              );
                        status = unmarshall_sec_desc(mem_ctx,
                                                     blob.data, blob.length,
                                                     &sk->sec_desc);
@@ -953,7 +997,7 @@ static REGF_SK_REC* find_sk_record_by_offset( REGF_FILE *file, uint32 offset )
 /*******************************************************************
 *******************************************************************/
 
-static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, SEC_DESC *sd )
+static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, struct security_descriptor *sd )
 {
        REGF_SK_REC *p;
 
@@ -1025,13 +1069,13 @@ static bool hbin_prs_key( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk )
                if ( !hbin_contains_offset( hbin, nk->sk_off ) ) {
                        sub_hbin = lookup_hbin_block( file, nk->sk_off );
                        if ( !sub_hbin ) {
-                               DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_offset [0x%x]\n", 
-                                       nk->subkeys_off));
+                               DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_off [0x%x]\n",
+                                       nk->sk_off));
                                return False;
                        }
                }
                
-               if ( !(nk->sec_desc = TALLOC_ZERO_P( file->mem_ctx, REGF_SK_REC )) )
+               if ( !(nk->sec_desc = talloc_zero( file->mem_ctx, REGF_SK_REC )) )
                        return False;
                nk->sec_desc->sk_off = nk->sk_off;
                if ( !hbin_prs_sk_rec( "sk_rec", sub_hbin, depth, nk->sec_desc ))
@@ -1337,7 +1381,7 @@ REGF_NK_REC* regfio_rootkey( REGF_FILE *file )
        if ( !file )
                return NULL;
                
-       if ( !(nk = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) ) {
+       if ( !(nk = talloc_zero( file->mem_ctx, REGF_NK_REC )) ) {
                DEBUG(0,("regfio_rootkey: talloc() failed!\n"));
                return NULL;
        }
@@ -1405,7 +1449,7 @@ REGF_NK_REC* regfio_rootkey( REGF_FILE *file )
                return NULL;
                
        nk->subkey_index++;
-       if ( !(subkey = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) )
+       if ( !(subkey = talloc_zero( file->mem_ctx, REGF_NK_REC )) )
                return NULL;
                
        if ( !hbin_prs_key( file, hbin, subkey ) )
@@ -1423,13 +1467,13 @@ static REGF_HBIN* regf_hbin_allocate( REGF_FILE *file, uint32 block_size )
        REGF_HBIN *hbin;
        SMB_STRUCT_STAT sbuf;
 
-       if ( !(hbin = TALLOC_ZERO_P( file->mem_ctx, REGF_HBIN )) )
+       if ( !(hbin = talloc_zero( file->mem_ctx, REGF_HBIN )) )
                return NULL;
 
-       memcpy( hbin->header, "hbin", sizeof(HBIN_HDR_SIZE) );
+       memcpy( hbin->header, "hbin", HBIN_HDR_SIZE);
 
 
-       if ( sys_fstat( file->fd, &sbuf ) ) {
+       if (sys_fstat(file->fd, &sbuf, false)) {
                DEBUG(0,("regf_hbin_allocate: stat() failed! (%s)\n", strerror(errno)));
                return NULL;
        }
@@ -1437,7 +1481,7 @@ static REGF_HBIN* regf_hbin_allocate( REGF_FILE *file, uint32 block_size )
        hbin->file_off       = sbuf.st_ex_size;
 
        hbin->free_off       = HBIN_HEADER_REC_SIZE;
-       hbin->free_size      = block_size - hbin->free_off + sizeof(uint32);;
+       hbin->free_size      = block_size - hbin->free_off + sizeof(uint32);
 
        hbin->block_size     = block_size;
        hbin->first_hbin_off = hbin->file_off - REGF_BLOCKSIZE;
@@ -1557,7 +1601,7 @@ done:
           for the record */
 
        if ( !prs_uint32("allocated_size", &hbin->ps, 0, &size) )
-               return False;
+               return NULL;
 
        update_free_space( hbin, size );
        
@@ -1567,7 +1611,7 @@ done:
 /*******************************************************************
 *******************************************************************/
 
-static uint32 sk_record_data_size( SEC_DESC * sd )
+static uint32 sk_record_data_size( struct security_descriptor * sd )
 {
        uint32 size, size_mod8;
 
@@ -1575,7 +1619,7 @@ static uint32 sk_record_data_size( SEC_DESC * sd )
 
        /* the record size is sizeof(hdr) + name + static members + data_size_field */
 
-       size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, NULL, 0) + sizeof(uint32);
+       size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, 0) + sizeof(uint32);
 
        /* multiple of 8 */
        size_mod8 = size & 0xfffffff8;
@@ -1678,7 +1722,7 @@ static bool create_vk_record(REGF_FILE *file, REGF_VK_REC *vk,
        if ( vk->data_size > sizeof(uint32) ) {
                uint32 data_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8;
 
-               vk->data = (uint8 *)TALLOC_MEMDUP( file->mem_ctx,
+               vk->data = (uint8 *)talloc_memdup( file->mem_ctx,
                                                   regval_data_p(value),
                                                   vk->data_size );
                if (vk->data == NULL) {
@@ -1709,7 +1753,7 @@ static bool create_vk_record(REGF_FILE *file, REGF_VK_REC *vk,
 
 static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
 {
-       return StrCaseCmp( h1->fullname, h2->fullname );
+       return strcasecmp_m( h1->fullname, h2->fullname );
 }
 
 /*******************************************************************
@@ -1717,13 +1761,13 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
 
  REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name,
                                struct regval_ctr *values, struct regsubkey_ctr *subkeys,
-                               SEC_DESC *sec_desc, REGF_NK_REC *parent )
+                               struct security_descriptor *sec_desc, REGF_NK_REC *parent )
 {
        REGF_NK_REC *nk;
        REGF_HBIN *vlist_hbin = NULL;
        uint32 size;
 
-       if ( !(nk = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) )
+       if ( !(nk = talloc_zero( file->mem_ctx, REGF_NK_REC )) )
                return NULL;
 
        memcpy( nk->header, "nk", REC_HDR_SIZE );
@@ -1767,11 +1811,10 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                parent->subkey_index++;
 
                /* sort the list by keyname */
-
-               qsort( parent->subkeys.hashes, parent->subkey_index, sizeof(REGF_HASH_REC), QSORT_CAST hashrec_cmp );
+               TYPESAFE_QSORT(parent->subkeys.hashes, parent->subkey_index, hashrec_cmp);
 
                if ( !hbin_prs_lf_records( "lf_rec", parent->subkeys.hbin, 0, parent ) )
-                       return False;
+                       return NULL;
        }
 
        /* write the security descriptor */
@@ -1790,7 +1833,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                                return NULL;
                        }
 
-                       if ( !(nk->sec_desc = TALLOC_ZERO_P( file->mem_ctx, REGF_SK_REC )) )
+                       if ( !(nk->sec_desc = talloc_zero( file->mem_ctx, REGF_SK_REC )) )
                                return NULL;
        
                        /* now we have to store the security descriptor in the list and 
@@ -1806,7 +1849,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                        nk->sec_desc->ref_count = 0;
                        
                        /* size value must be self-inclusive */
-                       nk->sec_desc->size      = ndr_size_security_descriptor(sec_desc, NULL, 0)
+                       nk->sec_desc->size      = ndr_size_security_descriptor(sec_desc, 0)
                                + sizeof(uint32);
 
                        DLIST_ADD_END( file->sec_desc_list, nk->sec_desc, REGF_SK_REC *);
@@ -1815,8 +1858,8 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                           if this is the first record, then just set the next and prev
                           offsets to ourself. */
 
-                       if ( nk->sec_desc->prev ) {
-                               REGF_SK_REC *prev = nk->sec_desc->prev;
+                       if ( DLIST_PREV(nk->sec_desc) ) {
+                               REGF_SK_REC *prev = DLIST_PREV(nk->sec_desc);
 
                                nk->sec_desc->prev_sk_off = prev->hbin_off + prev->hbin->first_hbin_off - HBIN_HDR_SIZE;
                                prev->next_sk_off = nk->sec_desc->sk_off;
@@ -1857,7 +1900,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                
                nk->subkeys.num_keys = nk->num_subkeys;
                if (nk->subkeys.num_keys) {
-                       if ( !(nk->subkeys.hashes = TALLOC_ZERO_ARRAY( file->mem_ctx, REGF_HASH_REC, nk->subkeys.num_keys )) )
+                       if ( !(nk->subkeys.hashes = talloc_zero_array( file->mem_ctx, REGF_HASH_REC, nk->subkeys.num_keys )) )
                                return NULL;
                } else {
                        nk->subkeys.hashes = NULL;
@@ -1885,7 +1928,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
                nk->values_off = prs_offset( &vlist_hbin->ps ) + vlist_hbin->first_hbin_off - HBIN_HDR_SIZE;
        
                if (nk->num_values) {
-                       if ( !(nk->values = TALLOC_ARRAY( file->mem_ctx, REGF_VK_REC, nk->num_values )) )
+                       if ( !(nk->values = talloc_array( file->mem_ctx, REGF_VK_REC, nk->num_values )) )
                                return NULL;
                } else {
                        nk->values = NULL;
@@ -1923,11 +1966,11 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
        
        prs_set_offset( &nk->hbin->ps, nk->hbin_off );
        if ( !prs_nk_rec( "nk_rec", &nk->hbin->ps, 0, nk ) )
-               return False;
+               return NULL;
 
        if ( nk->num_values ) {
                if ( !hbin_prs_vk_records( "vk_records", vlist_hbin, 0, nk, file ) )
-                       return False;
+                       return NULL;
        }