r10608: - fix hierachical memory handling in ndr_pull_nbt_name
authorStefan Metzmacher <metze@samba.org>
Thu, 29 Sep 2005 14:00:07 +0000 (14:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:39:12 +0000 (13:39 -0500)
- add wrepl_nbt_name scalar type and do the pull/push in the ndr layer
  instead of the caller
- give the flags and group_flag in the wrepl_name a meaning

metze
(This used to be commit b98efc2905e1147eb97111b46a877bdb9d8dd154)

source4/libcli/nbt/nbtname.c
source4/libcli/wrepl/winsrepl.c
source4/libcli/wrepl/winsrepl.h
source4/pidl/lib/Parse/Pidl/Typelist.pm
source4/torture/nbt/winsreplication.c

index ae6df8a18d30b0c5df4619264f5ff01fcb0016f5..86309b7f6bacbbcf7f77d4e23784d67e34a99c9b 100644 (file)
@@ -294,7 +294,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name
        scope = strchr(s, '.');
        if (scope) {
                *scope = 0;
-               r->scope = talloc_strdup(ndr, scope+1);
+               r->scope = talloc_strdup(ndr->current_mem_ctx, scope+1);
                NT_STATUS_HAVE_NO_MEMORY(r->scope);
        } else {
                r->scope = NULL;
@@ -312,7 +312,7 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name
        status = decompress_name(cname, &r->type);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       r->name = talloc_strdup(ndr, cname);
+       r->name = talloc_strdup(ndr->current_mem_ctx, cname);
        NT_STATUS_HAVE_NO_MEMORY(r->name);
 
        talloc_free(cname);
@@ -344,12 +344,7 @@ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt
        }
        
        status = ndr_push_nbt_string(ndr, ndr_flags, fullname);
-#if 0
-       /* this free conflicts with the use of pointers into strings
-          in the ndr_token_store() calls above. Metze, can you look
-          at this? */
-       talloc_free(fullname);
-#endif
+
        return status;
 }
 
@@ -476,3 +471,118 @@ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name)
        return ret;
 }
 
+/*
+  pull a nbt name, WINS Replication uses another on wire format for nbt name
+*/
+NTSTATUS ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r)
+{
+       uint8_t *namebuf;
+       uint32_t namebuf_len;
+
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
+       }
+
+       NDR_CHECK(ndr_pull_align(ndr, 4));
+       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len));
+       if (namebuf_len < 1 || namebuf_len > 255) {
+               return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range");
+       }
+       NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len);
+       NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
+
+       /* oh wow, what a nasty bug in windows ... */
+       if (namebuf[0] == 0x1b && namebuf_len >= 16) {
+               namebuf[0] = namebuf[15];
+               namebuf[15] = 0x1b;
+       }
+
+       if (namebuf_len < 17) {
+               r->type = 0x00;
+
+               r->name = talloc_strndup(ndr->current_mem_ctx, (char *)namebuf, namebuf_len);
+               if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
+
+               r->scope= NULL;
+
+               talloc_free(namebuf);
+               return NT_STATUS_OK;
+       }
+
+       r->type = namebuf[15];
+
+       namebuf[15] = '\0';
+       trim_string((char *)namebuf, NULL, " ");
+       r->name = talloc_strdup(ndr->current_mem_ctx, (char *)namebuf);
+       if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
+
+       if (namebuf_len > 18) {
+               r->scope = talloc_strndup(ndr->current_mem_ctx, (char *)(namebuf+17), namebuf_len-17);
+               if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
+       } else {
+               r->scope = NULL;
+       }
+
+       talloc_free(namebuf);
+       return NT_STATUS_OK;
+}
+
+/*
+  push a nbt name, WINS Replication uses another on wire format for nbt name
+*/
+NTSTATUS ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name r)
+{
+       uint8_t *namebuf;
+       uint32_t namebuf_len;
+       uint32_t name_len;
+       uint32_t scope_len = 0;
+
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
+       }
+
+       name_len = strlen(r.name);
+       if (name_len > 15) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       if (r.scope) {
+               scope_len = strlen(r.scope);
+       }
+       if (scope_len > 238) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s",
+                                            r.name, 'X',
+                                            (r.scope?r.scope:""));
+       if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory");
+
+       namebuf_len = strlen((char *)namebuf) + 1;
+
+       /*
+        * we need to set the type here, and use a place-holder in the talloc_asprintf()
+        * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results
+        */
+       namebuf[15] = r.type;
+
+       /* oh wow, what a nasty bug in windows ... */
+       if (r.type == 0x1b) {
+               namebuf[15] = namebuf[0];
+               namebuf[0] = 0x1b;
+       }
+
+       NDR_CHECK(ndr_push_align(ndr, 4));
+       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len));
+       NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
+
+       talloc_free(namebuf);
+       return NT_STATUS_OK;
+}
+
+void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name r)
+{
+       char *s = nbt_name_string(ndr, &r);
+       ndr_print_string(ndr, name, s);
+       talloc_free(s);
+}
index 069ee2940794bcbb7ebdc5a05af20762f8f0f6dc..feeea321b101817e0b8c6a02dd3d46478f2133e2 100644 (file)
@@ -671,40 +671,6 @@ struct wrepl_request *wrepl_pull_names_send(struct wrepl_socket *wrepl_socket,
        return req;     
 }
 
-
-/*
-  extract a nbt_name from a WINS name buffer
-*/
-static NTSTATUS wrepl_extract_name(struct nbt_name *name,
-                                  TALLOC_CTX *mem_ctx,
-                                  uint8_t *namebuf, uint32_t len)
-{
-       char *s;
-
-       /* oh wow, what a nasty bug in windows ... */
-       if (namebuf[0] == 0x1b && len >= 16) {
-               namebuf[0] = namebuf[15];
-               namebuf[15] = 0x1b;
-       }
-
-       if (len < 17) {
-               make_nbt_name_client(name, talloc_strndup(mem_ctx, (char *)namebuf, len));
-               return NT_STATUS_OK;
-       }
-
-       s = talloc_strndup(mem_ctx, (char *)namebuf, 15);
-       trim_string(s, NULL, " ");
-       name->name = s;
-       name->type = namebuf[15];
-       if (len > 18) {
-               name->scope = talloc_strndup(mem_ctx, (char *)(namebuf+17), len-17);
-       } else {
-               name->scope = NULL;
-       }
-
-       return NT_STATUS_OK;
-}
-
 /*
   fetch the names for a WINS partner - recv
 */
@@ -735,12 +701,15 @@ NTSTATUS wrepl_pull_names_recv(struct wrepl_request *req,
        for (i=0;i<io->out.num_names;i++) {
                struct wrepl_wins_name *wname = &packet->message.replication.info.reply.names[i];
                struct wrepl_name *name = &io->out.names[i];
-               status = wrepl_extract_name(&name->name, io->out.names, 
-                                           wname->name, wname->name_len);
-               if (!NT_STATUS_IS_OK(status)) goto failed;
 
-               name->flags     = wname->flags;
-               name->group_flag= wname->group_flag;
+               name->name      = wname->name;
+               talloc_steal(io->out.names, wname->name.name);
+               talloc_steal(io->out.names, wname->name.scope);
+               name->type      = WREPL_NAME_TYPE(wname->flags);
+               name->state     = WREPL_NAME_STATE(wname->flags);
+               name->node      = WREPL_NBT_NODE(wname->flags);
+               name->is_static = WREPL_NAME_IS_STATIC(wname->flags);
+               name->raw_flags = wname->flags;
                name->version_id= wname->id;
                name->owner     = talloc_strdup(io->out.names, io->in.partner.address);
                if (name->owner == NULL) goto nomem;
index 2253fe181ebef3b83de0f20d3071433615fe04e0..9b9362e4b33777e63653db4243fa8f955392bb2b 100644 (file)
@@ -104,6 +104,15 @@ struct wrepl_pull_table {
        } out;
 };
 
+#define WREPL_NAME_TYPE(flags) (flags & WREPL_FLAGS_RECORD_TYPE)
+#define WREPL_NAME_STATE(flags) ((flags & WREPL_FLAGS_RECORD_STATE)>>2)
+#define WREPL_NBT_NODE(flags) ((flags & WREPL_FLAGS_NODE_TYPE)<<8)
+#define WREPL_NAME_IS_STATIC(flags) ((flags & WREPL_FLAGS_IS_STATIC)?True:False)
+
+#define WREPL_NAME_FLAGS(type, state, node, is_static) \
+       (type | (state << 2) | (node>>8) | \
+        (is_static ? WREPL_FLAGS_IS_STATIC : 0))
+
 /*
   a full pull replication
 */
@@ -116,8 +125,11 @@ struct wrepl_pull_names {
                uint32_t num_names;
                struct wrepl_name {
                        struct nbt_name name;
-                       uint32_t flags;
-                       uint32_t group_flag;
+                       enum wrepl_name_type type;
+                       enum wrepl_name_state state;
+                       enum nbt_node_type node;
+                       BOOL is_static;
+                       uint32_t raw_flags;
                        uint64_t version_id;
                        const char *owner;
                        uint32_t num_addresses;
index 7dfbe761de105939a2ccef9543f2cdc213e744fd..d81fedf71e06bfb086e0ecc6810f9462966cb47c 100644 (file)
@@ -140,9 +140,9 @@ my $scalars = {
                                NDR_ALIGN       => 4
                        },
        "COMRESULT" => { 
-                               "C_TYPE"        => "COMRESULT",
-                               IS_REFERENCE => 0,
-                               NDR_ALIGN => 4
+                               C_TYPE          => "COMRESULT",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
                        },
 
        # special types
@@ -151,6 +151,11 @@ my $scalars = {
                                IS_REFERENCE    => 1,
                                NDR_ALIGN       => 4 #???
                        },
+       "wrepl_nbt_name"=> {
+                               C_TYPE          => "struct nbt_name",
+                               IS_REFERENCE    => 0,
+                               NDR_ALIGN       => 4
+                       },
        "ipv4address"   => {
                                C_TYPE          => "const char *",
                                IS_REFERENCE    => 1,
index cd60e12499b2571db12b2a266a6f4ed486d42ac2..d3ec5e84d67c0d49bca758d06c2c0a2ac7d72c81 100644 (file)
@@ -147,9 +147,10 @@ static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
        int i;
 
        printf("%s\n", nbt_name_string(mem_ctx, &name->name));
-       printf("\tFLAGS: 0x%08X G_FLAG: 0x%08X VERSION_ID: %llu\n",
-               name->flags, name->group_flag, name->version_id);
-       printf("\tOWNER: %-15s\n", name->owner);
+       printf("\tTYPE:%u STATE:%u NODE:0x%04X STATIC:%u VERSION_ID: %llu\n",
+               name->type, name->state, name->node, name->is_static, name->version_id);
+       printf("\tRAW_FLAGS:0x%08X OWNER: %-15s\n",
+               name->raw_flags, name->owner);
        for (i=0;i<name->num_addresses;i++) {
                printf("\tADDR: %-15s OWNER: %-15s\n", 
                        name->addresses[i].address, name->addresses[i].owner);