mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r10608: - fix hierachical memory handling in ndr_pull_nbt_name
- 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 commit is contained in:
parent
441419a08f
commit
b98efc2905
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user