s3-perfcount: fix incorrect array length calculations
[ddiss/samba.git] / source3 / registry / reg_perfcount.c
index 1991af10ca52e8fae6d1f0109d60b3bd0b0a6a38..3203e092e36726ee3efbe7a09a44245b8ea5cd49 100644 (file)
  */
 
 #include "includes.h"
+#include "system/filesys.h"
+#include "../librpc/gen_ndr/perfcount.h"
+#include "registry.h"
+#include "reg_perfcount.h"
+#include "../libcli/registry/util_reg.h"
+#include "util_tdb.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_REGISTRY
@@ -41,6 +47,11 @@ static char *counters_directory(const char *dbname)
        char *ret = NULL;
        TALLOC_CTX *ctx = talloc_tos();
 
+       path = state_path(PERFCOUNTDIR);
+       if (!directory_exist(path)) {
+               mkdir(path, 0755);
+       }
+
        path = talloc_asprintf(ctx, "%s/%s", PERFCOUNTDIR, dbname);
        if (!path) {
                return NULL;
@@ -54,21 +65,6 @@ static char *counters_directory(const char *dbname)
 /*********************************************************************
 *********************************************************************/
 
-void perfcount_init_keys( void )
-{
-       char *p = state_path(PERFCOUNTDIR);
-
-       /* no registry keys; just create the perfmon directory */
-
-       if ( !directory_exist( p ) )
-               mkdir( p, 0755 );
-
-       return;
-}
-
-/*********************************************************************
-*********************************************************************/
-
 uint32 reg_perfcount_get_base_index(void)
 {
        const char *fname = counters_directory( NAMES_DB );
@@ -99,7 +95,7 @@ uint32 reg_perfcount_get_base_index(void)
           and so on.
           So last_counter becomes num_counters*2, and last_help will be last_counter+1 */
        kbuf = string_tdb_data(key);
-       dbuf = tdb_fetch(names, kbuf);
+       dbuf = tdb_fetch_compat(names, kbuf);
        if(dbuf.dptr == NULL)
        {
                DEBUG(1, ("reg_perfcount_get_base_index: failed to find key \'1\' in [%s].\n", fname));
@@ -166,7 +162,7 @@ static uint32 _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
        memset(temp, 0, sizeof(temp));
        snprintf(temp, sizeof(temp), "%d", keyval);
        kbuf = string_tdb_data(temp);
-       dbuf = tdb_fetch(tdb, kbuf);
+       dbuf = tdb_fetch_compat(tdb, kbuf);
        if(dbuf.dptr == NULL)
        {
                /* If a key isn't there, just bypass it -- this really shouldn't 
@@ -351,7 +347,7 @@ static uint32 _reg_perfcount_get_numinst(int objInd, TDB_CONTEXT *names)
        char buf[PERFCOUNT_MAX_LEN];
 
        _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, objInd, "inst");
-       data = tdb_fetch(names, key);
+       data = tdb_fetch_compat(names, key);
 
        if(data.dptr == NULL)
                return (uint32)PERF_NO_INSTANCES;
@@ -380,7 +376,7 @@ static bool _reg_perfcount_add_object(struct PERF_DATA_BLOCK *block,
        bool success = True;
        struct PERF_OBJECT_TYPE *obj;
 
-       block->objects = (struct PERF_OBJECT_TYPE *)TALLOC_REALLOC_ARRAY(mem_ctx,
+       block->objects = (struct PERF_OBJECT_TYPE *)talloc_realloc(mem_ctx,
                                                                  block->objects,
                                                                  struct PERF_OBJECT_TYPE,
                                                                  block->NumObjectTypes+1);
@@ -425,7 +421,7 @@ static bool _reg_perfcount_get_counter_data(TDB_DATA key, TDB_DATA *data)
                return False;
        }    
 
-       *data = tdb_fetch(counters, key);
+       *data = tdb_fetch_compat(counters, key);
 
        tdb_close(counters);
 
@@ -492,7 +488,7 @@ static bool _reg_perfcount_get_counter_info(struct PERF_DATA_BLOCK *block,
        padding = 0;
 
        _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "type");
-       data = tdb_fetch(names, key);
+       data = tdb_fetch_compat(names, key);
        if(data.dptr == NULL)
        {
                DEBUG(3, ("_reg_perfcount_get_counter_info: No type data for counter [%d].\n", CounterIndex));
@@ -551,7 +547,7 @@ static bool _reg_perfcount_get_counter_info(struct PERF_DATA_BLOCK *block,
        SAFE_FREE(data.dptr);
 
        obj->counter_data.ByteLength += dsize + padding;
-       obj->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
+       obj->counter_data.data = talloc_realloc(mem_ctx,
                                                      obj->counter_data.data,
                                                      uint8,
                                                      obj->counter_data.ByteLength - sizeof(uint32));
@@ -618,14 +614,14 @@ static bool _reg_perfcount_add_counter(struct PERF_DATA_BLOCK *block,
        obj = NULL;
        memset(buf, 0, PERFCOUNT_MAX_LEN);
        memcpy(buf, data.dptr, data.dsize);
-       begin = index(buf, '[');
-       end = index(buf, ']');
+       begin = strchr(buf, '[');
+       end = strchr(buf, ']');
        if(begin == NULL || end == NULL)
                return False;
        start = begin+1;
 
        while(start < end) {
-               stop = index(start, ',');
+               stop = strchr(start, ',');
                if(stop == NULL)
                        stop = end;
                *stop = '\0';
@@ -639,7 +635,7 @@ static bool _reg_perfcount_add_counter(struct PERF_DATA_BLOCK *block,
                                  parent, num));
                        return False;
                }
-               obj->counters = (struct PERF_COUNTER_DEFINITION *)TALLOC_REALLOC_ARRAY(mem_ctx,
+               obj->counters = (struct PERF_COUNTER_DEFINITION *)talloc_realloc(mem_ctx,
                                                                                obj->counters,
                                                                                struct PERF_COUNTER_DEFINITION,
                                                                                obj->NumCounters+1);
@@ -691,7 +687,7 @@ static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *in
                return False;
        }
        inst->counter_data.ByteLength = data.dsize + sizeof(inst->counter_data.ByteLength);
-       inst->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
+       inst->counter_data.data = talloc_realloc(mem_ctx,
                                                       inst->counter_data.data,
                                                       uint8,
                                                       data.dsize);
@@ -705,7 +701,7 @@ static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *in
        memset(temp, 0, PERFCOUNT_MAX_LEN);
        snprintf(temp, PERFCOUNT_MAX_LEN, "i%dname", instId);
        _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
-       data = tdb_fetch(names, key);
+       data = tdb_fetch_compat(names, key);
        if(data.dptr == NULL)
        {
                /* Not actually an error, but possibly unintended? -- just logging FYI */
@@ -723,7 +719,7 @@ static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *in
                        SAFE_FREE(data.dptr);
                        return False;
                }
-               inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
+               inst->data = talloc_realloc(mem_ctx,
                                                  inst->data,
                                                  uint8,
                                                  inst->NameLength);
@@ -745,7 +741,7 @@ static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *in
        if((pad = (inst->ByteLength % 8)))
        {
                pad = 8 - pad;
-               inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
+               inst->data = talloc_realloc(mem_ctx,
                                                  inst->data,
                                                  uint8,
                                                  inst->NameLength + pad);
@@ -767,7 +763,7 @@ static bool _reg_perfcount_add_instance(struct PERF_OBJECT_TYPE *obj,
        struct PERF_INSTANCE_DEFINITION *inst;
 
        if(obj->instances == NULL) {
-               obj->instances = TALLOC_REALLOC_ARRAY(mem_ctx,
+               obj->instances = talloc_realloc(mem_ctx,
                                                      obj->instances,
                                                      struct PERF_INSTANCE_DEFINITION,
                                                      obj->NumInstances);
@@ -797,7 +793,7 @@ static int _reg_perfcount_assemble_global(struct PERF_DATA_BLOCK *block,
        {
                j = i*2;
                _reg_perfcount_make_key(&key, keybuf, PERFCOUNT_MAX_LEN, j, "rel");
-               data = tdb_fetch(names, key);
+               data = tdb_fetch_compat(names, key);
                if(data.dptr != NULL)
                {
                        if(_reg_perfcount_isparent(data))
@@ -835,7 +831,7 @@ static bool _reg_perfcount_get_64(uint64_t *retval,
 
        _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, key_part1, key_part2);
 
-       data = tdb_fetch(tdb, key);
+       data = tdb_fetch_compat(tdb, key);
        if(data.dptr == NULL)
        {
                DEBUG(3,("_reg_perfcount_get_64: No data found for key [%s].\n", key.dptr));
@@ -923,13 +919,13 @@ static bool _reg_perfcount_init_data_block(struct PERF_DATA_BLOCK *block,
                                           bool bigendian_data)
 {
        smb_ucs2_t *temp = NULL;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        time_t tm;
+       size_t sz;
 
-       if (rpcstr_push_talloc(mem_ctx, &temp, "PERF")==(size_t)-1) {
-               return false;
-       }
-       if (!temp) {
-               return false;
+       sz = rpcstr_push_talloc(tmp_ctx, &temp, "PERF");
+       if ((sz == -1) || (temp == NULL)) {
+               goto err_out;
        }
        memcpy(block->Signature, temp, strlen_w(temp) *2);
 
@@ -946,12 +942,15 @@ static bool _reg_perfcount_init_data_block(struct PERF_DATA_BLOCK *block,
        tm = time(NULL);
        make_systemtime(&(block->SystemTime), gmtime(&tm));
        _reg_perfcount_init_data_block_perf(block, names);
-       memset(temp, 0, sizeof(temp));
-       rpcstr_push((void *)temp, global_myname(), sizeof(temp), STR_TERMINATE);
+
+       sz = rpcstr_push_talloc(tmp_ctx, &temp, lp_netbios_name());
+       if ((sz == -1) || (temp == NULL)) {
+               goto err_out;
+       }
        block->SystemNameLength = (strlen_w(temp) * 2) + 2;
-       block->data = TALLOC_ZERO_ARRAY(mem_ctx, uint8, block->SystemNameLength + (8 - (block->SystemNameLength % 8)));
+       block->data = talloc_zero_array(mem_ctx, uint8, block->SystemNameLength + (8 - (block->SystemNameLength % 8)));
        if (block->data == NULL) {
-               return False;
+               goto err_out;
        }
        memcpy(block->data, temp, block->SystemNameLength);
        block->SystemNameOffset = sizeof(struct PERF_DATA_BLOCK) - sizeof(block->objects) - sizeof(block->data);
@@ -959,8 +958,13 @@ static bool _reg_perfcount_init_data_block(struct PERF_DATA_BLOCK *block,
        /* Make sure to adjust for 64-bit alignment for when we finish writing the system name,
           so that the PERF_OBJECT_TYPE struct comes out 64-bit aligned */
        block->HeaderLength += 8 - (block->HeaderLength % 8);
+       talloc_free(tmp_ctx);
 
-       return True;
+       return true;
+
+err_out:
+       talloc_free(tmp_ctx);
+       return false;
 }
 
 /*********************************************************************
@@ -997,7 +1001,7 @@ static uint32 _reg_perfcount_perf_data_block_fixup(struct PERF_DATA_BLOCK *block
                                counter_data = &(instance->counter_data);
                                counter = &(object[obj].counters[object[obj].NumCounters - 1]);
                                counter_data->ByteLength = counter->CounterOffset + counter->CounterSize + sizeof(counter_data->ByteLength);
-                               temp = TALLOC_REALLOC_ARRAY(mem_ctx,
+                               temp = talloc_realloc(mem_ctx,
                                                            temp, 
                                                            char, 
                                                            counter_data->ByteLength- sizeof(counter_data->ByteLength));
@@ -1018,7 +1022,7 @@ static uint32 _reg_perfcount_perf_data_block_fixup(struct PERF_DATA_BLOCK *block
                                {
                                        pad = 8 - pad;
                                }
-                               counter_data->data = TALLOC_REALLOC_ARRAY(mem_ctx,
+                               counter_data->data = talloc_realloc(mem_ctx,
                                                                         counter_data->data,
                                                                         uint8,
                                                                         counter_data->ByteLength - sizeof(counter_data->ByteLength) + pad);
@@ -1038,7 +1042,7 @@ static uint32 _reg_perfcount_perf_data_block_fixup(struct PERF_DATA_BLOCK *block
                        if((pad = (object[obj].counter_data.ByteLength % 8)))
                        {
                                pad = 8 - pad;
-                               object[obj].counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
+                               object[obj].counter_data.data = talloc_realloc(mem_ctx,
                                                                                     object[obj].counter_data.data,
                                                                                     uint8, 
                                                                                     object[obj].counter_data.ByteLength + pad);