From c39d1b829b02d275ea1052afec58ab40f22267a3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 22 Sep 2008 17:50:43 -0700 Subject: Remove unused parameter from decode_pw_buffer and fail on invalid UTF-16 input The input checking is important, as otherwise we could set the wrong password. Andrew Bartlett --- source4/libcli/auth/smbencrypt.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 7de9627302..b50f003b91 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -497,10 +497,10 @@ bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag returned password including termination. ************************************************************/ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32_t *new_pw_len, - int string_flags) + int new_pwrd_size, int string_flags) { int byte_len=0; + ssize_t converted_pw_len; /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; @@ -526,13 +526,17 @@ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + converted_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); + if (converted_pw_len == -1) { + return false; + } + #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len); - DEBUG(100,("multibyte len:%d\n", *new_pw_len)); + dump_data(100, (const uint8_t *)new_pwrd, converted_pw_len); + DEBUG(100,("multibyte len:%d\n", converted_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif -- cgit From 9216153827f0000cc82cb51adcba722181c94999 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 22 Sep 2008 22:22:04 +0200 Subject: s4-nbt: remove unrequired include. Guenther --- source4/libcli/nbt/nbtname.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 97ae2e9d72..67bb4486e5 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -27,7 +27,6 @@ #include "librpc/gen_ndr/ndr_nbt.h" #include "librpc/gen_ndr/ndr_misc.h" #include "system/locale.h" -#include "param/param.h" /* don't allow an unlimited number of name components */ #define MAX_COMPONENTS 10 -- cgit From 13a3971438fb12d60aa0eaf88d22019a5e4f67cd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 09:02:16 +0200 Subject: s4-nbt: use private_data instead of private. Guenther --- source4/libcli/composite/composite.c | 2 +- source4/libcli/finddcs.c | 2 +- source4/libcli/nbt/libnbt.h | 8 ++++---- source4/libcli/nbt/namerefresh.c | 8 ++++---- source4/libcli/nbt/nameregister.c | 14 +++++++------- source4/libcli/nbt/nbtsocket.c | 2 +- source4/libcli/resolve/nbtlist.c | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 3e3f224f47..91a842706f 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -214,5 +214,5 @@ _PUBLIC_ void composite_continue_nbt(struct composite_context *ctx, { if (composite_nomem(new_req, ctx)) return; new_req->async.fn = continuation; - new_req->async.private = private_data; + new_req->async.private_data = private_data; } diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 56f931ce19..f12f1ac805 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -217,7 +217,7 @@ static void fallback_node_status(struct finddcs_state *state) static void fallback_node_status_replied(struct nbt_name_request *name_req) { int i; - struct finddcs_state *state = talloc_get_type(name_req->async.private, struct finddcs_state); + struct finddcs_state *state = talloc_get_type(name_req->async.private_data, struct finddcs_state); state->ctx->status = nbt_name_status_recv(name_req, state, &state->node_status); if (!composite_is_ok(state->ctx)) return; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 0b01365510..ff4fe65ac8 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -83,7 +83,7 @@ struct nbt_name_request { /* information on what to do on completion */ struct { void (*fn)(struct nbt_name_request *); - void *private; + void *private_data; } async; }; @@ -113,14 +113,14 @@ struct nbt_name_socket { struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, struct socket_address *); - void *private; + void *private_data; } incoming; /* what to do with unexpected replies */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, struct socket_address *); - void *private; + void *private_data; } unexpected; }; @@ -323,7 +323,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, struct socket_address *), - void *private); + void *private_data); NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, struct socket_address *dest, struct nbt_name_packet *request); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index b372e4a3f3..b939c97740 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -159,7 +159,7 @@ struct refresh_wins_state { */ static void name_refresh_wins_handler(struct nbt_name_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct refresh_wins_state *state = talloc_get_type(c->private_data, struct refresh_wins_state); @@ -184,7 +184,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; } } else if (!NT_STATUS_IS_OK(status)) { c->state = COMPOSITE_STATE_ERROR; @@ -200,7 +200,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req) c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; } } else { c->state = COMPOSITE_STATE_DONE; @@ -259,7 +259,7 @@ _PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_so if (state->req == NULL) goto failed; state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; c->private_data = state; c->state = COMPOSITE_STATE_IN_PROGRESS; diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 9c5ae43d40..c50f9b3b3a 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -161,7 +161,7 @@ struct register_bcast_state { */ static void name_register_bcast_handler(struct nbt_name_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state); NTSTATUS status; @@ -183,7 +183,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req) c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_bcast_handler; - state->req->async.private = c; + state->req->async.private_data = c; } } else if (!NT_STATUS_IS_OK(status)) { c->state = COMPOSITE_STATE_ERROR; @@ -241,7 +241,7 @@ _PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_ if (state->req == NULL) goto failed; state->req->async.fn = name_register_bcast_handler; - state->req->async.private = c; + state->req->async.private_data = c; c->private_data = state; c->state = COMPOSITE_STATE_IN_PROGRESS; @@ -297,7 +297,7 @@ struct register_wins_state { */ static void name_register_wins_handler(struct nbt_name_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct register_wins_state *state = talloc_get_type(c->private_data, struct register_wins_state); @@ -322,7 +322,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; } } else if (!NT_STATUS_IS_OK(status)) { c->state = COMPOSITE_STATE_ERROR; @@ -338,7 +338,7 @@ static void name_register_wins_handler(struct nbt_name_request *req) c->status = NT_STATUS_NO_MEMORY; } else { state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; } } else { c->state = COMPOSITE_STATE_DONE; @@ -399,7 +399,7 @@ _PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_s if (state->req == NULL) goto failed; state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; + state->req->async.private_data = c; c->private_data = state; c->state = COMPOSITE_STATE_IN_PROGRESS; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 5d4611e2d9..49f175b8a3 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -488,7 +488,7 @@ _PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void *private) { nbtsock->incoming.handler = handler; - nbtsock->incoming.private = private; + nbtsock->incoming.private_data = private; EVENT_FD_READABLE(nbtsock->fde); return NT_STATUS_OK; } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 8f085c5404..0cc2ee6726 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -46,7 +46,7 @@ struct nbtlist_state { */ static void nbtlist_handler(struct nbt_name_request *req) { - struct composite_context *c = talloc_get_type(req->async.private, + struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); struct nbt_name_query *q; @@ -169,7 +169,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->queries[i], c)) return c; state->queries[i]->async.fn = nbtlist_handler; - state->queries[i]->async.private = c; + state->queries[i]->async.private_data = c; } return c; -- cgit From be8b72dd5541182e24f522026bafbaef044a47e3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 09:34:03 +0200 Subject: s4-nbt: merge some fixes from samba3 nbt helper. Guenther --- source4/libcli/nbt/libnbt.h | 6 +++--- source4/libcli/nbt/nbtname.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index ff4fe65ac8..8529ec362b 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -329,9 +329,9 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request); -NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *) -NDR_SCALAR_PROTO(nbt_string, const char *) -NDR_BUFFER_PROTO(nbt_name, struct nbt_name) +NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *); +NDR_SCALAR_PROTO(nbt_string, const char *); +NDR_BUFFER_PROTO(nbt_name, struct nbt_name); NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); struct composite_context; diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 67bb4486e5..338cb21089 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. manipulate nbt name structures Copyright (C) Andrew Tridgell 2005 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -111,7 +111,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_fla /* break up name into a list of components */ for (num_components=0;num_componentsnbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { uint8_t b[2]; - + if (offset > 0x3FFF) { return ndr_push_error(ndr, NDR_ERR_STRING, "offset for nbt string label pointer %u[%08X] > 0x00003FFF", @@ -218,7 +218,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type) c2 < 'A' || c2 > 'P') { return false; } - name[i] = ((c1-'A')<<4) | (c2-'A'); + name[i] = ((c1-'A')<<4) | (c2-'A'); } name[i] = 0; if (i == 16) { @@ -233,7 +233,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type) for (;i>0 && name[i-1]==' ';i--) { name[i-1] = 0; } - + return true; } @@ -241,7 +241,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type) /* compress a name component */ -static uint8_t *compress_name(TALLOC_CTX *mem_ctx, +static uint8_t *compress_name(TALLOC_CTX *mem_ctx, const uint8_t *name, enum nbt_name_type type) { uint8_t *cname; @@ -355,7 +355,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags } else { fullname = cname; } - + ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); return ndr_err; @@ -421,7 +421,7 @@ _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, n->scope = NULL; n->type = type; - if (is_ipaddress(name) || name == NULL) { + if ((name == NULL) || is_ipaddress(name)) { n->name = "*SMBSERVER"; return; } @@ -433,11 +433,11 @@ _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, return; } s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); - n->name = strupper_talloc(mem_ctx, s); + n->name = talloc_strdup_upper(mem_ctx, s); return; } - n->name = strupper_talloc(mem_ctx, name); + n->name = talloc_strdup_upper(mem_ctx, name); } @@ -482,14 +482,14 @@ _PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) { TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); char *ret; - if (name->scope) { + if (name->scope) { ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", nbt_hex_encode(tmp_ctx, name->name), - name->type, + name->type, nbt_hex_encode(tmp_ctx, name->scope)); } else { - ret = talloc_asprintf(mem_ctx, "%s<%02x>", - nbt_hex_encode(tmp_ctx, name->name), + ret = talloc_asprintf(mem_ctx, "%s<%02x>", + nbt_hex_encode(tmp_ctx, name->name), name->type); } talloc_free(tmp_ctx); @@ -517,7 +517,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len); NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); - NDR_PULL_ALLOC(ndr, r); + NDR_PULL_ALLOC(ndr, r); /* oh wow, what a nasty bug in windows ... */ if (namebuf[0] == 0x1b && namebuf_len >= 16) { @@ -564,7 +564,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr { uint8_t *namebuf; uint32_t namebuf_len; - uint32_t name_len; + uint32_t _name_len; uint32_t scope_len = 0; if (r == NULL) { @@ -576,8 +576,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr return NDR_ERR_SUCCESS; } - name_len = strlen(r->name); - if (name_len > 15) { + _name_len = strlen(r->name); + if (_name_len > 15) { return ndr_push_error(ndr, NDR_ERR_STRING, "wrepl_nbt_name longer as 15 chars: %s", r->name); -- cgit From 6f33f3e4c26564602d5d13c7459938955b56a16e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 06:58:17 +0200 Subject: s4-nbt: move libcli/nbt up one level. Guenther --- source4/libcli/nbt/libnbt.h | 351 --------------------- source4/libcli/nbt/namequery.c | 235 -------------- source4/libcli/nbt/namerefresh.c | 302 ------------------ source4/libcli/nbt/nameregister.c | 442 -------------------------- source4/libcli/nbt/namerelease.c | 135 -------- source4/libcli/nbt/nbtname.c | 648 -------------------------------------- source4/libcli/nbt/nbtsocket.c | 521 ------------------------------ source4/libcli/nbt/pynbt.c | 408 ------------------------ 8 files changed, 3042 deletions(-) delete mode 100644 source4/libcli/nbt/libnbt.h delete mode 100644 source4/libcli/nbt/namequery.c delete mode 100644 source4/libcli/nbt/namerefresh.c delete mode 100644 source4/libcli/nbt/nameregister.c delete mode 100644 source4/libcli/nbt/namerelease.c delete mode 100644 source4/libcli/nbt/nbtname.c delete mode 100644 source4/libcli/nbt/nbtsocket.c delete mode 100644 source4/libcli/nbt/pynbt.c (limited to 'source4/libcli') diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h deleted file mode 100644 index 8529ec362b..0000000000 --- a/source4/libcli/nbt/libnbt.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a raw async NBT library - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __LIBNBT_H__ -#define __LIBNBT_H__ - -#include "librpc/gen_ndr/nbt.h" -#include "librpc/ndr/libndr.h" - -/* - possible states for pending requests -*/ -enum nbt_request_state {NBT_REQUEST_SEND, - NBT_REQUEST_WAIT, - NBT_REQUEST_DONE, - NBT_REQUEST_TIMEOUT, - NBT_REQUEST_ERROR}; - -/* - a nbt name request -*/ -struct nbt_name_request { - struct nbt_name_request *next, *prev; - - enum nbt_request_state state; - - NTSTATUS status; - - /* the socket this was on */ - struct nbt_name_socket *nbtsock; - - /* where to send the request */ - struct socket_address *dest; - - /* timeout between retries */ - int timeout; - - /* how many retries to send on timeout */ - int num_retries; - - /* whether we have received a WACK */ - bool received_wack; - - /* the timeout event */ - struct timed_event *te; - - /* the name transaction id */ - uint16_t name_trn_id; - - /* is it a reply? */ - bool is_reply; - - /* the encoded request */ - DATA_BLOB encoded; - - /* shall we allow multiple replies? */ - bool allow_multiple_replies; - - unsigned int num_replies; - struct nbt_name_reply { - struct nbt_name_packet *packet; - struct socket_address *dest; - } *replies; - - /* information on what to do on completion */ - struct { - void (*fn)(struct nbt_name_request *); - void *private_data; - } async; -}; - - - -/* - context structure for operations on name queries -*/ -struct nbt_name_socket { - struct socket_context *sock; - struct event_context *event_ctx; - struct smb_iconv_convenience *iconv_convenience; - - /* a queue of requests pending to be sent */ - struct nbt_name_request *send_queue; - - /* the fd event */ - struct fd_event *fde; - - /* mapping from name_trn_id to pending event */ - struct idr_context *idr; - - /* how many requests are waiting for a reply */ - uint16_t num_pending; - - /* what to do with incoming request packets */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *private_data; - } incoming; - - /* what to do with unexpected replies */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *private_data; - } unexpected; -}; - - -/* a simple name query */ -struct nbt_name_query { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - bool broadcast; - bool wins_lookup; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - int16_t num_addrs; - const char **reply_addrs; - } out; -}; - -/* a simple name status query */ -struct nbt_name_status { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - struct nbt_rdata_status status; - } out; -}; - -/* a name registration request */ -struct nbt_name_register { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool register_demand; - bool broadcast; - bool multi_homed; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* a send 3 times then demand name broadcast name registration */ -struct nbt_name_register_bcast { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - uint32_t ttl; - } in; -}; - - -/* wins name register with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_register_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - - -/* a name refresh request */ -struct nbt_name_refresh { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* wins name refresh with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_refresh_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - -/* a name release request */ -struct nbt_name_release { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct smb_iconv_convenience *iconv_convenience); -struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, - struct nbt_name_query *io); -NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, - struct nbt_name_status *io); -NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); -NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); - -NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname); -NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name); -NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name); -void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type); -char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name); -NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); -NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); -NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register *io); -NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); - -struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, - struct nbt_name_release *io); - -NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); - -NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *), - void *private_data); -NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request); - - -NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *); -NDR_SCALAR_PROTO(nbt_string, const char *); -NDR_BUFFER_PROTO(nbt_name, struct nbt_name); -NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); - -struct composite_context; -struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io); -NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c); -struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); - - -#endif /* __LIBNBT_H__ */ diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c deleted file mode 100644 index 2e1bcd818b..0000000000 --- a/source4/libcli/nbt/namequery.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - make nbt name query requests - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "libcli/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/** - send a nbt name query -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, - struct nbt_name_query *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->operation = NBT_OPCODE_QUERY; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - if (io->in.wins_lookup) { - packet->operation |= NBT_FLAG_RECURSION_DESIRED; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/** - wait for a name query reply -*/ -_PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - int i; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if ((packet->operation & NBT_RCODE) != 0) { - status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); - talloc_free(req); - return status; - } - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return status; - } - - io->out.name = packet->answers[0].name; - io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; - io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs+1); - if (io->out.reply_addrs == NULL) { - talloc_free(req); - return NT_STATUS_NO_MEMORY; - } - - for (i=0;iout.num_addrs;i++) { - io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs, - packet->answers[0].rdata.netbios.addresses[i].ipaddr); - } - io->out.reply_addrs[i] = NULL; - - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/** - wait for a name query reply -*/ -_PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - struct nbt_name_request *req = nbt_name_query_send(nbtsock, io); - return nbt_name_query_recv(req, mem_ctx, io); -} - - -/** - send a nbt name status -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, - struct nbt_name_status *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->operation = NBT_OPCODE_QUERY; - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_STATUS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/** - wait for a name status reply -*/ -_PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - int i; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if ((packet->operation & NBT_RCODE) != 0) { - status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); - talloc_free(req); - return status; - } - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_STATUS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.name = packet->answers[0].name; - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - io->out.status = packet->answers[0].rdata.status; - talloc_steal(mem_ctx, io->out.status.names); - for (i=0;iout.status.num_names;i++) { - talloc_steal(io->out.status.names, io->out.status.names[i].name); - } - - - talloc_free(req); - - return NT_STATUS_OK; -} - -/** - wait for a name status reply -*/ -_PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io) -{ - struct nbt_name_request *req = nbt_name_status_send(nbtsock, io); - return nbt_name_status_recv(req, mem_ctx, io); -} - - diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c deleted file mode 100644 index b939c97740..0000000000 --- a/source4/libcli/nbt/namerefresh.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name refresh request - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "libcli/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "libcli/composite/composite.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/* - send a nbt name refresh request -*/ -struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - packet->operation = NBT_OPCODE_REFRESH; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = io->in.ttl; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - - dest = socket_address_from_strings(nbtsock, - nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a refresh reply -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name refresh request -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) -{ - struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io); - return nbt_name_refresh_recv(req, mem_ctx, io); -} - - - -/** - a wins name refresh with multiple WINS servers and multiple - addresses to refresh. Try each WINS server in turn, until we get a - reply for each address -*/ -struct refresh_wins_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_refresh *io; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - int address_idx; - struct nbt_name_request *req; -}; - - -/** - state handler for WINS multi-homed multi-server name refresh -*/ -static void name_refresh_wins_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct refresh_wins_state *state = talloc_get_type(c->private_data, - struct refresh_wins_state); - NTSTATUS status; - - status = nbt_name_refresh_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - /* the refresh timed out - try the next WINS server */ - state->wins_servers++; - state->address_idx = 0; - if (state->wins_servers[0] == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - goto done; - } - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = state->addresses[0]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private_data = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - if (state->io->out.rcode == 0 && - state->addresses[state->address_idx+1] != NULL) { - /* refresh our next address */ - state->io->in.address = state->addresses[++(state->address_idx)]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private_data = c; - } - } else { - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - } - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/** - the async send call for a multi-server WINS refresh -*/ -_PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io) -{ - struct composite_context *c; - struct refresh_wins_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct refresh_wins_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_refresh); - if (state->io == NULL) goto failed; - - state->wins_port = io->in.wins_port; - state->wins_servers = str_list_copy(state, io->in.wins_servers); - if (state->wins_servers == NULL || - state->wins_servers[0] == NULL) goto failed; - - state->addresses = str_list_copy(state, io->in.addresses); - if (state->addresses == NULL || - state->addresses[0] == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = io->in.addresses[0]; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = false; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 2; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - state->address_idx = 0; - - state->req = nbt_name_refresh_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private_data = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - multi-homed WINS name refresh - recv side -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) -{ - NTSTATUS status; - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct refresh_wins_state *state = - talloc_get_type(c->private_data, struct refresh_wins_state); - io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); - io->out.rcode = state->io->out.rcode; - } - talloc_free(c); - return status; -} - -/* - multi-homed WINS refresh - sync interface -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) -{ - struct composite_context *c = nbt_name_refresh_wins_send(nbtsock, io); - return nbt_name_refresh_wins_recv(c, mem_ctx, io); -} diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c deleted file mode 100644 index c50f9b3b3a..0000000000 --- a/source4/libcli/nbt/nameregister.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name registration request - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "libcli/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "libcli/composite/composite.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -/* - send a nbt name registration request -*/ -struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - if (io->in.multi_homed) { - packet->operation = NBT_OPCODE_MULTI_HOME_REG; - } else { - packet->operation = NBT_OPCODE_REGISTER; - } - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - if (io->in.register_demand) { - packet->operation |= NBT_FLAG_RECURSION_DESIRED; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = io->in.ttl; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a registration reply -*/ -_PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name registration request -*/ -_PUBLIC_ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io) -{ - struct nbt_name_request *req = nbt_name_register_send(nbtsock, io); - return nbt_name_register_recv(req, mem_ctx, io); -} - - -/* - a 4 step broadcast registration. 3 lots of name registration requests, followed by - a name registration demand -*/ -struct register_bcast_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_register *io; - struct nbt_name_request *req; -}; - - -/* - state handler for 4 stage name registration -*/ -static void name_register_bcast_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context); - struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state); - NTSTATUS status; - - status = nbt_name_register_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - if (state->io->in.register_demand == true) { - /* all done */ - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - goto done; - } - - /* the registration timed out - good, send the demand */ - state->io->in.register_demand = true; - state->io->in.retries = 0; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_bcast_handler; - state->req->async.private_data = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_CONFLICTING_ADDRESSES; - DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n", - state->io->out.reply_from, - nbt_name_string(state, &state->io->out.name), - state->io->out.reply_addr, - state->io->out.rcode)); - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - the async send call for a 4 stage name registration -*/ -_PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io) -{ - struct composite_context *c; - struct register_bcast_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct register_bcast_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_register); - if (state->io == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = io->in.dest_addr; - state->io->in.dest_port = io->in.dest_port; - state->io->in.address = io->in.address; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.register_demand = false; - state->io->in.broadcast = true; - state->io->in.multi_homed = false; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 1; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - - state->req = nbt_name_register_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_register_bcast_handler; - state->req->async.private_data = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - broadcast 4 part name register - recv -*/ -_PUBLIC_ NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c) -{ - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; -} - -/* - broadcast 4 part name register - sync interface -*/ -NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io) -{ - struct composite_context *c = nbt_name_register_bcast_send(nbtsock, io); - return nbt_name_register_bcast_recv(c); -} - - -/* - a wins name register with multiple WINS servers and multiple - addresses to register. Try each WINS server in turn, until we get a - reply for each address -*/ -struct register_wins_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_register *io; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - int address_idx; - struct nbt_name_request *req; -}; - - -/* - state handler for WINS multi-homed multi-server name register -*/ -static void name_register_wins_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct register_wins_state *state = talloc_get_type(c->private_data, - struct register_wins_state); - NTSTATUS status; - - status = nbt_name_register_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - /* the register timed out - try the next WINS server */ - state->wins_servers++; - state->address_idx = 0; - if (state->wins_servers[0] == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - goto done; - } - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = state->addresses[0]; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_wins_handler; - state->req->async.private_data = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - if (state->io->out.rcode == 0 && - state->addresses[state->address_idx+1] != NULL) { - /* register our next address */ - state->io->in.address = state->addresses[++(state->address_idx)]; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_wins_handler; - state->req->async.private_data = c; - } - } else { - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - } - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - the async send call for a multi-server WINS register -*/ -_PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_wins *io) -{ - struct composite_context *c; - struct register_wins_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct register_wins_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_register); - if (state->io == NULL) goto failed; - - state->wins_port = io->in.wins_port; - state->wins_servers = str_list_copy(state, io->in.wins_servers); - if (state->wins_servers == NULL || - state->wins_servers[0] == NULL) goto failed; - - state->addresses = str_list_copy(state, io->in.addresses); - if (state->addresses == NULL || - state->addresses[0] == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = io->in.addresses[0]; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = false; - state->io->in.register_demand = false; - state->io->in.multi_homed = (io->in.nb_flags & NBT_NM_GROUP)?false:true; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 3; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - state->address_idx = 0; - - state->req = nbt_name_register_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_register_wins_handler; - state->req->async.private_data = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - multi-homed WINS name register - recv side -*/ -_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io) -{ - NTSTATUS status; - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct register_wins_state *state = - talloc_get_type(c->private_data, struct register_wins_state); - io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); - io->out.rcode = state->io->out.rcode; - } - talloc_free(c); - return status; -} - -/* - multi-homed WINS register - sync interface -*/ -_PUBLIC_ NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io) -{ - struct composite_context *c = nbt_name_register_wins_send(nbtsock, io); - return nbt_name_register_wins_recv(c, mem_ctx, io); -} diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c deleted file mode 100644 index ba3af41752..0000000000 --- a/source4/libcli/nbt/namerelease.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name release request - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "libcli/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/* - send a nbt name release request -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, - struct nbt_name_release *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - packet->operation = NBT_OPCODE_RELEASE; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = 0; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a release reply -*/ -_PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name release request -*/ -_PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io) -{ - struct nbt_name_request *req = nbt_name_release_send(nbtsock, io); - return nbt_name_release_recv(req, mem_ctx, io); -} diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c deleted file mode 100644 index 338cb21089..0000000000 --- a/source4/libcli/nbt/nbtname.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - manipulate nbt name structures - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - see rfc1002 for the detailed format of compressed names -*/ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "system/locale.h" - -/* don't allow an unlimited number of name components */ -#define MAX_COMPONENTS 10 - -/** - print a nbt string -*/ -_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) -{ - ndr_print_string(ndr, name, s); -} - -/* - pull one component of a nbt_string -*/ -static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr, - uint8_t **component, - uint32_t *offset, - uint32_t *max_offset) -{ - uint8_t len; - uint_t loops = 0; - while (loops < 5) { - if (*offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - len = ndr->data[*offset]; - if (len == 0) { - *offset += 1; - *max_offset = MAX(*max_offset, *offset); - *component = NULL; - return NDR_ERR_SUCCESS; - } - if ((len & 0xC0) == 0xC0) { - /* its a label pointer */ - if (1 + *offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *max_offset = MAX(*max_offset, *offset + 2); - *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; - *max_offset = MAX(*max_offset, *offset); - loops++; - continue; - } - if ((len & 0xC0) != 0) { - /* its a reserved length field */ - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - if (*offset + len + 2 > ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); - NDR_ERR_HAVE_NO_MEMORY(*component); - *offset += len + 1; - *max_offset = MAX(*max_offset, *offset); - return NDR_ERR_SUCCESS; - } - - /* too many pointers */ - return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component"); -} - -/** - pull a nbt_string from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) -{ - uint32_t offset = ndr->offset; - uint32_t max_offset = offset; - unsigned num_components; - char *name; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - name = NULL; - - /* break up name into a list of components */ - for (num_components=0;num_componentsoffset = max_offset; - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt string to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) -{ - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - while (s && *s) { - enum ndr_err_code ndr_err; - char *compname; - size_t complen; - uint32_t offset; - - /* see if we have pushed the remaing string allready, - * if so we use a label pointer to this string - */ - ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - uint8_t b[2]; - - if (offset > 0x3FFF) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "offset for nbt string label pointer %u[%08X] > 0x00003FFF", - offset, offset); - } - - b[0] = 0xC0 | (offset>>8); - b[1] = (offset & 0xFF); - - return ndr_push_bytes(ndr, b, 2); - } - - complen = strcspn(s, "."); - - /* we need to make sure the length fits into 6 bytes */ - if (complen >= 0x3F) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "component length %u[%08X] > 0x00003F", - (unsigned)complen, (unsigned)complen); - } - - compname = talloc_asprintf(ndr, "%c%*.*s", - (unsigned char)complen, - (unsigned char)complen, - (unsigned char)complen, s); - NDR_ERR_HAVE_NO_MEMORY(compname); - - /* remember the current componemt + the rest of the string - * so it can be reused later - */ - NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset)); - - /* push just this component into the blob */ - NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1)); - talloc_free(compname); - - s += complen; - if (*s == '.') s++; - } - - /* if we reach the end of the string and have pushed the last component - * without using a label pointer, we need to terminate the string - */ - return ndr_push_bytes(ndr, (const uint8_t *)"", 1); -} - - -/* - decompress a 'compressed' name component - */ -static bool decompress_name(char *name, enum nbt_name_type *type) -{ - int i; - for (i=0;name[2*i];i++) { - uint8_t c1 = name[2*i]; - uint8_t c2 = name[1+(2*i)]; - if (c1 < 'A' || c1 > 'P' || - c2 < 'A' || c2 > 'P') { - return false; - } - name[i] = ((c1-'A')<<4) | (c2-'A'); - } - name[i] = 0; - if (i == 16) { - *type = (enum nbt_name_type)(name[15]); - name[15] = 0; - i--; - } else { - *type = NBT_NAME_CLIENT; - } - - /* trim trailing spaces */ - for (;i>0 && name[i-1]==' ';i--) { - name[i-1] = 0; - } - - return true; -} - - -/* - compress a name component - */ -static uint8_t *compress_name(TALLOC_CTX *mem_ctx, - const uint8_t *name, enum nbt_name_type type) -{ - uint8_t *cname; - int i; - uint8_t pad_char; - - if (strlen((const char *)name) > 15) { - return NULL; - } - - cname = talloc_array(mem_ctx, uint8_t, 33); - if (cname == NULL) return NULL; - - for (i=0;name[i];i++) { - cname[2*i] = 'A' + (name[i]>>4); - cname[1+2*i] = 'A' + (name[i]&0xF); - } - if (strcmp((const char *)name, "*") == 0) { - pad_char = 0; - } else { - pad_char = ' '; - } - for (;i<15;i++) { - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - } - - pad_char = type; - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - - cname[32] = 0; - return cname; -} - - -/** - pull a nbt name from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) -{ - uint8_t *scope; - char *cname; - const char *s; - bool ok; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s)); - - scope = (uint8_t *)strchr(s, '.'); - if (scope) { - *scope = 0; - r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]); - NDR_ERR_HAVE_NO_MEMORY(r->scope); - } else { - r->scope = NULL; - } - - cname = discard_const_p(char, s); - - /* the first component is limited to 16 bytes in the DOS charset, - which is 32 in the 'compressed' form */ - if (strlen(cname) > 32) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME cname > 32"); - } - - /* decompress the first component */ - ok = decompress_name(cname, &r->type); - if (!ok) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME failed to decompress"); - } - - r->name = talloc_strdup(ndr->current_mem_ctx, cname); - NDR_ERR_HAVE_NO_MEMORY(r->name); - - talloc_free(cname); - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) -{ - uint8_t *cname, *fullname; - enum ndr_err_code ndr_err; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - if (strlen(r->name) > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "nbt_name longer as 15 chars: %s", - r->name); - } - - cname = compress_name(ndr, (const uint8_t *)r->name, r->type); - NDR_ERR_HAVE_NO_MEMORY(cname); - - if (r->scope) { - fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope); - NDR_ERR_HAVE_NO_MEMORY(fullname); - talloc_free(cname); - } else { - fullname = cname; - } - - ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); - - return ndr_err; -} - - -/** - copy a nbt name structure -*/ -_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname) -{ - *newname = *name; - newname->name = talloc_strdup(mem_ctx, newname->name); - NT_STATUS_HAVE_NO_MEMORY(newname->name); - newname->scope = talloc_strdup(mem_ctx, newname->scope); - if (name->scope) { - NT_STATUS_HAVE_NO_MEMORY(newname->scope); - } - return NT_STATUS_OK; -} - -/** - push a nbt name into a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_push_struct_blob(blob, mem_ctx, iconv_convenience, name, (ndr_push_flags_fn_t)ndr_push_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - -/** - pull a nbt name from a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, name, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - - -/** - choose a name to use when calling a server in a NBT session request. - we use heuristics to see if the name we have been given is a IP - address, or a too-long name. If it is then use *SMBSERVER, or a - truncated name -*/ -_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, - struct nbt_name *n, const char *name, int type) -{ - n->scope = NULL; - n->type = type; - - if ((name == NULL) || is_ipaddress(name)) { - n->name = "*SMBSERVER"; - return; - } - if (strlen(name) > 15) { - const char *p = strchr(name, '.'); - char *s; - if (p - name > 15) { - n->name = "*SMBSERVER"; - return; - } - s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); - n->name = talloc_strdup_upper(mem_ctx, s); - return; - } - - n->name = talloc_strdup_upper(mem_ctx, name); -} - - -/* - escape a string into a form containing only a small set of characters, - the rest is hex encoded. This is similar to URL encoding -*/ -static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) -{ - int i, len; - char *ret; - const char *valid_chars = "_-.$@ "; -#define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c)) - - for (len=i=0;s[i];i++,len++) { - if (!NBT_CHAR_ALLOW(s[i])) { - len += 2; - } - } - - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - for (len=i=0;s[i];i++) { - if (NBT_CHAR_ALLOW(s[i])) { - ret[len++] = s[i]; - } else { - snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]); - len += 3; - } - } - ret[len] = 0; - - return ret; -} - - -/** - form a string for a NBT name -*/ -_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) -{ - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - char *ret; - if (name->scope) { - ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", - nbt_hex_encode(tmp_ctx, name->name), - name->type, - nbt_hex_encode(tmp_ctx, name->scope)); - } else { - ret = talloc_asprintf(mem_ctx, "%s<%02x>", - nbt_hex_encode(tmp_ctx, name->name), - name->type); - } - talloc_free(tmp_ctx); - return ret; -} - -/** - pull a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) -{ - struct nbt_name *r; - uint8_t *namebuf; - uint32_t namebuf_len; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - 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)); - - NDR_PULL_ALLOC(ndr, r); - - /* 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(r, (char *)namebuf, namebuf_len); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - r->scope= NULL; - - talloc_free(namebuf); - *_r = r; - return NDR_ERR_SUCCESS; - } - - r->type = namebuf[15]; - - namebuf[15] = '\0'; - trim_string((char *)namebuf, NULL, " "); - r->name = talloc_strdup(r, (char *)namebuf); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - if (namebuf_len > 18) { - r->scope = talloc_strndup(r, (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); - *_r = r; - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code 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 (r == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, - "wrepl_nbt_name NULL pointer"); - } - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - _name_len = strlen(r->name); - if (_name_len > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name longer as 15 chars: %s", - r->name); - } - - if (r->scope) { - scope_len = strlen(r->scope); - } - if (scope_len > 238) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name scope longer as 238 chars: %s", - r->scope); - } - - 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 NDR_ERR_SUCCESS; -} - -_PUBLIC_ 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); -} - -_PUBLIC_ enum ndr_err_code ndr_push_nbt_res_rec(struct ndr_push *ndr, int ndr_flags, const struct nbt_res_rec *r) -{ - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_nbt_name(ndr, NDR_SCALARS, &r->name)); - NDR_CHECK(ndr_push_nbt_qtype(ndr, NDR_SCALARS, r->rr_type)); - NDR_CHECK(ndr_push_nbt_qclass(ndr, NDR_SCALARS, r->rr_class)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, ((((r->rr_type) == NBT_QTYPE_NETBIOS) && ((r->rdata).data.length == 2))?0:r->rr_type))); - NDR_CHECK(ndr_push_nbt_rdata(ndr, NDR_SCALARS, &r->rdata)); - } - if (ndr_flags & NDR_BUFFERS) { - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c deleted file mode 100644 index 49f175b8a3..0000000000 --- a/source4/libcli/nbt/nbtsocket.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - low level socket handling for nbt requests - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include "lib/util/dlinklist.h" -#include "libcli/nbt/libnbt.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -#define NBT_MAX_REPLIES 1000 - -/* - destroy a pending request -*/ -static int nbt_name_request_destructor(struct nbt_name_request *req) -{ - if (req->state == NBT_REQUEST_SEND) { - DLIST_REMOVE(req->nbtsock->send_queue, req); - } - if (req->state == NBT_REQUEST_WAIT) { - req->nbtsock->num_pending--; - } - if (req->name_trn_id != 0 && !req->is_reply) { - idr_remove(req->nbtsock->idr, req->name_trn_id); - req->name_trn_id = 0; - } - if (req->te) { - talloc_free(req->te); - req->te = NULL; - } - if (req->nbtsock->send_queue == NULL) { - EVENT_FD_NOT_WRITEABLE(req->nbtsock->fde); - } - if (req->nbtsock->num_pending == 0 && - req->nbtsock->incoming.handler == NULL) { - EVENT_FD_NOT_READABLE(req->nbtsock->fde); - } - return 0; -} - - -/* - handle send events on a nbt name socket -*/ -static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) -{ - struct nbt_name_request *req = nbtsock->send_queue; - TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); - NTSTATUS status; - - while ((req = nbtsock->send_queue)) { - size_t len; - - len = req->encoded.length; - status = socket_sendto(nbtsock->sock, &req->encoded, &len, - req->dest); - if (NT_STATUS_IS_ERR(status)) goto failed; - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - DLIST_REMOVE(nbtsock->send_queue, req); - req->state = NBT_REQUEST_WAIT; - if (req->is_reply) { - talloc_free(req); - } else { - EVENT_FD_READABLE(nbtsock->fde); - nbtsock->num_pending++; - } - } - - EVENT_FD_NOT_WRITEABLE(nbtsock->fde); - talloc_free(tmp_ctx); - return; - -failed: - DLIST_REMOVE(nbtsock->send_queue, req); - nbt_name_request_destructor(req); - req->status = status; - req->state = NBT_REQUEST_ERROR; - talloc_free(tmp_ctx); - if (req->async.fn) { - req->async.fn(req); - } else if (req->is_reply) { - talloc_free(req); - } - return; -} - - -/* - handle a request timeout -*/ -static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) -{ - struct nbt_name_request *req = talloc_get_type(private, - struct nbt_name_request); - - if (req->num_retries != 0) { - req->num_retries--; - req->te = event_add_timed(req->nbtsock->event_ctx, req, - timeval_add(&t, req->timeout, 0), - nbt_name_socket_timeout, req); - if (req->state != NBT_REQUEST_SEND) { - req->state = NBT_REQUEST_SEND; - DLIST_ADD_END(req->nbtsock->send_queue, req, - struct nbt_name_request *); - } - EVENT_FD_WRITEABLE(req->nbtsock->fde); - return; - } - - nbt_name_request_destructor(req); - if (req->num_replies == 0) { - req->state = NBT_REQUEST_TIMEOUT; - req->status = NT_STATUS_IO_TIMEOUT; - } else { - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - } - if (req->async.fn) { - req->async.fn(req); - } else if (req->is_reply) { - talloc_free(req); - } -} - - - -/** - handle recv events on a nbt name socket -*/ -static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) -{ - TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); - NTSTATUS status; - enum ndr_err_code ndr_err; - struct socket_address *src; - DATA_BLOB blob; - size_t nread, dsize; - struct nbt_name_packet *packet; - struct nbt_name_request *req; - - status = socket_pending(nbtsock->sock, &dsize); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - blob = data_blob_talloc(tmp_ctx, NULL, dsize); - if (blob.data == NULL) { - talloc_free(tmp_ctx); - return; - } - - status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, - tmp_ctx, &src); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - packet = talloc(tmp_ctx, struct nbt_name_packet); - if (packet == NULL) { - talloc_free(tmp_ctx); - return; - } - - /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, nbtsock->iconv_convenience, packet, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(2,("Failed to parse incoming NBT name packet - %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return; - } - - if (DEBUGLVL(10)) { - DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - (int)blob.length, src->addr, src->port)); - NDR_PRINT_DEBUG(nbt_name_packet, packet); - } - - /* if its not a reply then pass it off to the incoming request - handler, if any */ - if (!(packet->operation & NBT_FLAG_REPLY)) { - if (nbtsock->incoming.handler) { - nbtsock->incoming.handler(nbtsock, packet, src); - } - talloc_free(tmp_ctx); - return; - } - - /* find the matching request */ - req = (struct nbt_name_request *)idr_find(nbtsock->idr, - packet->name_trn_id); - if (req == NULL) { - if (nbtsock->unexpected.handler) { - nbtsock->unexpected.handler(nbtsock, packet, src); - } else { - DEBUG(10,("Failed to match request for incoming name packet id 0x%04x on %p\n", - packet->name_trn_id, nbtsock)); - } - talloc_free(tmp_ctx); - return; - } - - /* if this is a WACK response, this we need to go back to waiting, - but perhaps increase the timeout */ - if ((packet->operation & NBT_OPCODE) == NBT_OPCODE_WACK) { - if (req->received_wack || packet->ancount < 1) { - nbt_name_request_destructor(req); - req->status = NT_STATUS_INVALID_NETWORK_RESPONSE; - req->state = NBT_REQUEST_ERROR; - goto done; - } - talloc_free(req->te); - /* we know we won't need any more retries - the server - has received our request */ - req->num_retries = 0; - req->received_wack = true; - /* although there can be a timeout in the packet, w2k3 screws it up, - so better to set it ourselves */ - req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30); - req->te = event_add_timed(req->nbtsock->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - nbt_name_socket_timeout, req); - talloc_free(tmp_ctx); - return; - } - - - req->replies = talloc_realloc(req, req->replies, struct nbt_name_reply, req->num_replies+1); - if (req->replies == NULL) { - nbt_name_request_destructor(req); - req->state = NBT_REQUEST_ERROR; - req->status = NT_STATUS_NO_MEMORY; - goto done; - } - - talloc_steal(req, src); - req->replies[req->num_replies].dest = src; - talloc_steal(req, packet); - req->replies[req->num_replies].packet = packet; - req->num_replies++; - - /* if we don't want multiple replies then we are done */ - if (req->allow_multiple_replies && - req->num_replies < NBT_MAX_REPLIES) { - talloc_free(tmp_ctx); - return; - } - - nbt_name_request_destructor(req); - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - -done: - talloc_free(tmp_ctx); - if (req->async.fn) { - req->async.fn(req); - } -} - -/* - handle fd events on a nbt_name_socket -*/ -static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - struct nbt_name_socket *nbtsock = talloc_get_type(private, - struct nbt_name_socket); - if (flags & EVENT_FD_WRITE) { - nbt_name_socket_send(nbtsock); - } - if (flags & EVENT_FD_READ) { - nbt_name_socket_recv(nbtsock); - } -} - - -/* - initialise a nbt_name_socket. The event_ctx is optional, if provided - then operations will use that event context -*/ -_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct smb_iconv_convenience *iconv_convenience) -{ - struct nbt_name_socket *nbtsock; - NTSTATUS status; - - nbtsock = talloc(mem_ctx, struct nbt_name_socket); - if (nbtsock == NULL) goto failed; - - nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx); - if (nbtsock->event_ctx == NULL) goto failed; - - status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0); - if (!NT_STATUS_IS_OK(status)) goto failed; - - socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); - - talloc_steal(nbtsock, nbtsock->sock); - - nbtsock->idr = idr_init(nbtsock); - if (nbtsock->idr == NULL) goto failed; - - nbtsock->send_queue = NULL; - nbtsock->num_pending = 0; - nbtsock->incoming.handler = NULL; - nbtsock->unexpected.handler = NULL; - nbtsock->iconv_convenience = iconv_convenience; - - nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock, - socket_get_fd(nbtsock->sock), 0, - nbt_name_socket_handler, nbtsock); - - return nbtsock; - -failed: - talloc_free(nbtsock); - return NULL; -} - -/* - send off a nbt name request -*/ -struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request, - int timeout, int retries, - bool allow_multiple_replies) -{ - struct nbt_name_request *req; - int id; - enum ndr_err_code ndr_err; - - req = talloc_zero(nbtsock, struct nbt_name_request); - if (req == NULL) goto failed; - - req->nbtsock = nbtsock; - req->allow_multiple_replies = allow_multiple_replies; - req->state = NBT_REQUEST_SEND; - req->is_reply = false; - req->timeout = timeout; - req->num_retries = retries; - req->dest = dest; - if (talloc_reference(req, dest) == NULL) goto failed; - - /* we select a random transaction id unless the user supplied one */ - if (request->name_trn_id == 0) { - id = idr_get_new_random(req->nbtsock->idr, req, UINT16_MAX); - } else { - if (idr_find(req->nbtsock->idr, request->name_trn_id)) goto failed; - id = idr_get_new_above(req->nbtsock->idr, req, request->name_trn_id, - UINT16_MAX); - } - if (id == -1) goto failed; - - request->name_trn_id = id; - req->name_trn_id = id; - - req->te = event_add_timed(nbtsock->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - nbt_name_socket_timeout, req); - - talloc_set_destructor(req, nbt_name_request_destructor); - - ndr_err = ndr_push_struct_blob(&req->encoded, req, - req->nbtsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed; - - DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - - if (DEBUGLVL(10)) { - DEBUG(10,("Queueing nbt packet to %s:%d\n", - req->dest->addr, req->dest->port)); - NDR_PRINT_DEBUG(nbt_name_packet, request); - } - - EVENT_FD_WRITEABLE(nbtsock->fde); - - return req; - -failed: - talloc_free(req); - return NULL; -} - - -/* - send off a nbt name reply -*/ -_PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request) -{ - struct nbt_name_request *req; - enum ndr_err_code ndr_err; - - req = talloc_zero(nbtsock, struct nbt_name_request); - NT_STATUS_HAVE_NO_MEMORY(req); - - req->nbtsock = nbtsock; - req->dest = dest; - if (talloc_reference(req, dest) == NULL) goto failed; - req->state = NBT_REQUEST_SEND; - req->is_reply = true; - - talloc_set_destructor(req, nbt_name_request_destructor); - - if (DEBUGLVL(10)) { - NDR_PRINT_DEBUG(nbt_name_packet, request); - } - - ndr_err = ndr_push_struct_blob(&req->encoded, req, - req->nbtsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(req); - return ndr_map_error2ntstatus(ndr_err); - } - - DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - - EVENT_FD_WRITEABLE(nbtsock->fde); - - return NT_STATUS_OK; - -failed: - talloc_free(req); - return NT_STATUS_NO_MEMORY; -} - -/* - wait for a nbt request to complete -*/ -NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) -{ - if (!req) return NT_STATUS_NO_MEMORY; - - while (req->state < NBT_REQUEST_DONE) { - if (event_loop_once(req->nbtsock->event_ctx) != 0) { - req->state = NBT_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - break; - } - } - return req->status; -} - - -/* - setup a handler for incoming requests -*/ -_PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *), - void *private) -{ - nbtsock->incoming.handler = handler; - nbtsock->incoming.private_data = private; - EVENT_FD_READABLE(nbtsock->fde); - return NT_STATUS_OK; -} - - -/* - turn a NBT rcode into a NTSTATUS -*/ -_PUBLIC_ NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) -{ - int i; - struct { - enum nbt_rcode rcode; - NTSTATUS status; - } map[] = { - { NBT_RCODE_FMT, NT_STATUS_INVALID_PARAMETER }, - { NBT_RCODE_SVR, NT_STATUS_SERVER_DISABLED }, - { NBT_RCODE_NAM, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { NBT_RCODE_IMP, NT_STATUS_NOT_SUPPORTED }, - { NBT_RCODE_RFS, NT_STATUS_ACCESS_DENIED }, - { NBT_RCODE_ACT, NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { NBT_RCODE_CFT, NT_STATUS_CONFLICTING_ADDRESSES } - }; - for (i=0;i 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include -#include "libcli/util/pyerrors.h" -#include "libcli/nbt/libnbt.h" -#include "lib/events/events.h" -#include "param/param.h" - -PyAPI_DATA(PyTypeObject) nbt_node_Type; - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct nbt_name_socket *socket; -} nbt_node_Object; - -static void py_nbt_node_dealloc(PyObject *obj) -{ - talloc_free(((nbt_node_Object *)obj)->mem_ctx); - PyObject_Del(obj); -} - -static PyObject *py_nbt_node_init(PyTypeObject *self, PyObject *args, PyObject *kwargs) -{ - struct event_context *ev; - nbt_node_Object *ret = PyObject_New(nbt_node_Object, &nbt_node_Type); - - ret->mem_ctx = talloc_new(NULL); - if (ret->mem_ctx == NULL) - return NULL; - - ev = s4_event_context_init(ret->mem_ctx); - ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm)); - return (PyObject *)ret; -} - -static bool PyObject_AsDestinationTuple(PyObject *obj, const char **dest_addr, uint16_t *dest_port) -{ - if (PyString_Check(obj)) { - *dest_addr = PyString_AsString(obj); - *dest_port = NBT_NAME_SERVICE_PORT; - return true; - } - - if (PyTuple_Check(obj)) { - if (PyTuple_Size(obj) < 1) { - PyErr_SetString(PyExc_TypeError, "Destination tuple size invalid"); - return false; - } - - if (!PyString_Check(PyTuple_GetItem(obj, 0))) { - PyErr_SetString(PyExc_TypeError, "Destination tuple first element not string"); - return false; - } - - *dest_addr = PyString_AsString(obj); - - if (PyTuple_Size(obj) == 1) { - *dest_port = NBT_NAME_SERVICE_PORT; - return true; - } else if (PyInt_Check(PyTuple_GetItem(obj, 1))) { - *dest_port = PyInt_AsLong(PyTuple_GetItem(obj, 1)); - return true; - } else { - PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); - return false; - } - } - - PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); - return false; -} - -static bool PyObject_AsNBTName(PyObject *obj, struct nbt_name_socket *socket, struct nbt_name *name) -{ - if (PyTuple_Check(obj)) { - if (PyTuple_Size(obj) == 2) { - name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); - name->type = PyInt_AsLong(PyTuple_GetItem(obj, 1)); - name->scope = NULL; - return true; - } else if (PyTuple_Size(obj) == 3) { - name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); - name->scope = PyString_AsString(PyTuple_GetItem(obj, 1)); - name->type = PyInt_AsLong(PyTuple_GetItem(obj, 2)); - return true; - } else { - PyErr_SetString(PyExc_TypeError, "Invalid tuple size"); - return false; - } - } - - if (PyString_Check(obj)) { - /* FIXME: Parse string to be able to interpret things like RHONWYN<02> ? */ - name->name = PyString_AsString(obj); - name->scope = NULL; - name->type = 0; - return true; - } - - PyErr_SetString(PyExc_TypeError, "Invalid type for object"); - return false; -} - -static PyObject *PyObject_FromNBTName(struct nbt_name_socket *socket, struct smb_iconv_convenience *ic, - struct nbt_name *name) -{ - if (name->scope) { - return Py_BuildValue("(ssi)", name->name, name->scope, name->type); - } else { - return Py_BuildValue("(si)", name->name, name->type); - } -} - -static PyObject *py_nbt_name_query(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *reply_addrs, *py_dest, *py_name; - struct nbt_name_query io; - NTSTATUS status; - int i; - - const char *kwnames[] = { "name", "dest", "broadcast", "wins", "timeout", - "retries", NULL }; - io.in.broadcast = true; - io.in.wins_lookup = false; - io.in.timeout = 0; - io.in.retries = 3; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bbii:query_name", - discard_const_p(char *, kwnames), - &py_name, &py_dest, - &io.in.broadcast, &io.in.wins_lookup, - &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_query(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - reply_addrs = PyList_New(io.out.num_addrs); - if (reply_addrs == NULL) { - Py_DECREF(ret); - return NULL; - } - - for (i = 0; i < io.out.num_addrs; i++) { - PyList_SetItem(reply_addrs, i, PyString_FromString(io.out.reply_addrs[i])); - } - - PyTuple_SetItem(ret, 2, reply_addrs); - return ret; -} - -static PyObject *py_nbt_name_status(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name, *py_names; - struct nbt_name_status io; - int i; - NTSTATUS status; - - const char *kwnames[] = { "name", "dest", "timeout", "retries", NULL }; - - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii:name_status", - discard_const_p(char *, kwnames), - &py_name, &py_dest, - &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_status(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - py_names = PyList_New(io.out.status.num_names); - - for (i = 0; i < io.out.status.num_names; i++) { - PyList_SetItem(py_names, i, Py_BuildValue("(sii)", - io.out.status.names[i].name, - io.out.status.names[i].nb_flags, - io.out.status.names[i].type)); - } - - PyTuple_SetItem(ret, 2, py_names); - - return ret; -} - -static PyObject *py_nbt_name_register(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name; - struct nbt_name_register io; - NTSTATUS status; - - const char *kwnames[] = { "name", "address", "dest", "register_demand", "broadcast", - "multi_homed", "ttl", "timeout", "retries", NULL }; - - io.in.broadcast = true; - io.in.multi_homed = true; - io.in.register_demand = true; - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|bbbiii:query_name", - discard_const_p(char *, kwnames), - &py_name, &io.in.address, &py_dest, - &io.in.register_demand, - &io.in.broadcast, &io.in.multi_homed, - &io.in.ttl, &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_register(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); - - PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); - - return ret; -} - -static PyObject *py_nbt_name_refresh(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name; - struct nbt_name_refresh io; - NTSTATUS status; - - const char *kwnames[] = { "name", "address", "dest", "nb_flags", "broadcast", - "ttl", "timeout", "retries", NULL }; - - io.in.broadcast = true; - io.in.nb_flags = 0; - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|ibiii:query_name", - discard_const_p(char *, kwnames), - &py_name, &io.in.address, &py_dest, - &io.in.nb_flags, - &io.in.broadcast, - &io.in.ttl, &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_refresh(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); - - PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); - - return ret; -} - -static PyObject *py_nbt_name_release(PyObject *self, PyObject *args, PyObject *kwargs) -{ - return Py_None; /* FIXME */ -} - -static PyMethodDef py_nbt_methods[] = { - { "query_name", (PyCFunction)py_nbt_name_query, METH_VARARGS|METH_KEYWORDS, - "S.query_name(name, dest, broadcast=True, wins=False, timeout=0, retries=3) -> (reply_from, name, reply_addr)\n" - "Query for a NetBIOS name" }, - { "register_name", (PyCFunction)py_nbt_name_register, METH_VARARGS|METH_KEYWORDS, - "S.register_name(name, address, dest, register_demand=True, broadcast=True, multi_homed=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" - "Register a new name" }, - { "release_name", (PyCFunction)py_nbt_name_release, METH_VARARGS|METH_KEYWORDS, "S.release_name(name, address, dest, nb_flags=0, broadcast=true, timeout=0, retries=3) -> (reply_from, name, reply_addr, rcode)\n" - "release a previously registered name" }, - { "refresh_name", (PyCFunction)py_nbt_name_refresh, METH_VARARGS|METH_KEYWORDS, "S.refresh_name(name, address, dest, nb_flags=0, broadcast=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" - "release a previously registered name" }, - { "name_status", (PyCFunction)py_nbt_name_status, METH_VARARGS|METH_KEYWORDS, - "S.name_status(name, dest, timeout=0, retries=0) -> (reply_from, name, status)\n" - "Find the status of a name" }, - - { NULL } -}; - -PyTypeObject nbt_node_Type = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "netbios.Node", - .tp_basicsize = sizeof(nbt_node_Object), - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_new = py_nbt_node_init, - .tp_dealloc = py_nbt_node_dealloc, - .tp_methods = py_nbt_methods, - .tp_doc = "Node()\n" - "Create a new NetBIOS node\n" -}; - -void initnetbios(void) -{ - PyObject *mod; - if (PyType_Ready(&nbt_node_Type) < 0) - return; - - mod = Py_InitModule3("netbios", NULL, "NetBIOS over TCP/IP support"); - - Py_INCREF((PyObject *)&nbt_node_Type); - PyModule_AddObject(mod, "Node", (PyObject *)&nbt_node_Type); -} -- cgit From a1a92688ba0a811400b4d12920988c62fa0efdf4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:06:33 +0200 Subject: s4-nbt: use ../libcli/nbt Guenther --- source4/libcli/composite/composite.c | 2 +- source4/libcli/config.mk | 10 +++++----- source4/libcli/raw/clitransport.c | 2 +- source4/libcli/resolve/nbtlist.c | 2 +- source4/libcli/resolve/resolve.h | 2 +- source4/libcli/resolve/wins.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 91a842706f..104397fa48 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -28,7 +28,7 @@ #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" #include "librpc/rpc/dcerpc.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" /* create a new composite_context structure diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 262a2cfa22..cee51439ab 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -40,22 +40,22 @@ $(eval $(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBC [SUBSYSTEM::NDR_NBT_BUF] -NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o +NDR_NBT_BUF_OBJ_FILES = ../$(libclisrcdir)/nbt/nbtname.o -$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,../$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_NBT] PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL -LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ +LIBCLI_NBT_OBJ_FILES = $(addprefix ../$(libclisrcdir)/nbt/, \ nbtsocket.o \ namequery.o \ nameregister.o \ namerefresh.o \ namerelease.o) -$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,../$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_NDR_NETLOGON] PUBLIC_DEPENDENCIES = LIBNDR \ @@ -85,7 +85,7 @@ $(eval $(call proto_header_template,$(libclisrcdir)/drsblobs_proto.h,$(LIBCLI_DR LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG -python_netbios_OBJ_FILES = $(libclisrcdir)/nbt/pynbt.o +python_netbios_OBJ_FILES = ../$(libclisrcdir)/nbt/pynbt.o $(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index e95ae3271e..f8ef343e3a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -28,7 +28,7 @@ #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 0cc2ee6726..7dafd130f8 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -28,7 +28,7 @@ #include "system/network.h" #include "lib/socket/netif.h" #include "librpc/gen_ndr/ndr_nbt.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" #include "param/param.h" struct nbtlist_state { diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 79b91dc836..22de146c99 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -22,7 +22,7 @@ #ifndef __RESOLVE_H__ #define __RESOLVE_H__ -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *); typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); #include "libcli/resolve/proto.h" diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 3ec180f332..ebce9b98bd 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" #include "libcli/resolve/resolve.h" #include "param/param.h" #include "lib/socket/netif.h" -- cgit From 781d7c4c1cbd34413450f251d4078a9cb8055831 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Sep 2008 17:50:30 +0200 Subject: libcli/raw: give the caller the chance to prevent the talloc_free(req) in the _recv functions metze --- source4/libcli/raw/libcliraw.h | 3 +++ source4/libcli/raw/rawrequest.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index d55b4cc42c..c9cafedd4c 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -261,6 +261,9 @@ struct smbcli_request { counter by one */ uint_t sign_single_increment:1; + /* give the caller a chance to prevent the talloc_free() in the _recv() function */ + bool do_not_free; + /* the mid of this packet - used to match replies */ uint16_t mid; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a0e6452748..dd9b1f3e96 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -72,7 +72,11 @@ _PUBLIC_ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) } status = req->status; - talloc_free(req); + + if (!req->do_not_free) { + talloc_free(req); + } + return status; } -- cgit From e00ab641b4aeafa70d035c66baf31b965a7e5734 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Sep 2008 17:54:13 +0200 Subject: libcli/raw: give the caller the chance to do the signing checks on its own. metze --- source4/libcli/raw/libcliraw.h | 3 +++ source4/libcli/raw/smb_signing.c | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index c9cafedd4c..bd9bda0db1 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -261,6 +261,9 @@ struct smbcli_request { counter by one */ uint_t sign_single_increment:1; + /* the caller wants to do the signing check */ + bool sign_caller_checks; + /* give the caller a chance to prevent the talloc_free() in the _recv() function */ bool do_not_free; diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 1d03686d9a..ae17dadf33 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -298,6 +298,13 @@ bool smbcli_request_check_sign_mac(struct smbcli_request *req) { bool good; + if (!req->transport->negotiate.sign_info.doing_signing && + req->sign_caller_checks) { + return true; + } + + req->sign_caller_checks = false; + switch (req->transport->negotiate.sign_info.signing_state) { case SMB_SIGNING_ENGINE_OFF: -- cgit From 7deacc615e92221548fea940b0e90fe03a3ec098 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Sep 2008 17:56:11 +0200 Subject: libcli/raw: in SMB_SIGNING_ENGINE_BSRSPYL state it's ok to accept any signature Even if signing is mandatory. With NTLMSSP this happens for the session setup: request1 => BSRSPYL response1 => BSRSPYL request2 => BSRSPYL response2 => and with krb5: request1 => BSRSPYL response1 => metze --- source4/libcli/raw/smb_signing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index ae17dadf33..c23fb16128 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -310,6 +310,8 @@ bool smbcli_request_check_sign_mac(struct smbcli_request *req) case SMB_SIGNING_ENGINE_OFF: return true; case SMB_SIGNING_ENGINE_BSRSPYL: + return true; + case SMB_SIGNING_ENGINE_ON: { if (req->in.size < (HDR_SS_FIELD + 8)) { -- cgit From 8c3d96993421e8e6a9fc5d265e4caa71acbd80c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Sep 2008 02:29:20 +0200 Subject: libcli/raw: real signing starts at seqnumber 2 metze --- source4/libcli/raw/smb_signing.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index c23fb16128..826d7dd56b 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -359,6 +359,7 @@ bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length); sign_info->signing_state = SMB_SIGNING_ENGINE_ON; + sign_info->next_seq_num = 2; return true; } -- cgit From c01426ce731e2cf0b04ee3a0376e613f4970fb30 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Sep 2008 18:02:07 +0200 Subject: libcli/smb_composite: for spnego session setups check the smb signature manually We need to start signing when we got NT_STATUS_OK from the server and manually check the signature of the servers response. This is needed as the response might be signed with the krb5 acceptor subkey, which comes within the server response. With NTLMSSP this happens for the session setup: request1 => BSRSPYL seqnum: 0 response1 => BSRSPYL seqnum: 0 request2 => BSRSPYL seqnum: 0 response2 => seqnum: 1 and with krb5: request1 => BSRSPYL seqnum: 0 response1 => seqnum: 1 metze --- source4/libcli/smb_composite/sesssetup.c | 80 +++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 23 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 11ac37e257..92b49dc3d4 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -35,6 +35,7 @@ struct sesssetup_state { union smb_sesssetup setup; + NTSTATUS remote_status; NTSTATUS gensec_status; struct smb_composite_sesssetup *io; struct smbcli_request *req; @@ -85,8 +86,15 @@ static void request_handler(struct smbcli_request *req) DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); NTSTATUS session_key_err, nt_status; + struct smbcli_request *check_req = NULL; - c->status = smb_raw_sesssetup_recv(req, state, &state->setup); + if (req->sign_caller_checks) { + req->do_not_free = true; + check_req = req; + } + + state->remote_status = smb_raw_sesssetup_recv(req, state, &state->setup); + c->status = state->remote_status; state->req = NULL; switch (state->setup.old.level) { @@ -102,6 +110,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -120,6 +129,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -138,6 +148,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -169,12 +180,16 @@ static void request_handler(struct smbcli_request *req) state->setup.spnego.in.secblob = data_blob(NULL, 0); } - /* we need to do another round of session setup. We keep going until both sides - are happy */ - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - set_user_session_key(session, &session_key); - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + if (NT_STATUS_IS_OK(state->remote_status)) { + if (state->setup.spnego.in.secblob.length) { + c->status = NT_STATUS_INTERNAL_ERROR; + break; + } + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { + set_user_session_key(session, &session_key); + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } } if (state->setup.spnego.in.secblob.length) { @@ -186,6 +201,9 @@ static void request_handler(struct smbcli_request *req) session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); session->vuid = vuid; + if (state->req) { + state->req->sign_caller_checks = true; + } composite_continue_smb(c, state->req, request_handler, c); return; } @@ -196,6 +214,15 @@ static void request_handler(struct smbcli_request *req) break; } + if (check_req) { + check_req->sign_caller_checks = false; + if (!smbcli_request_check_sign_mac(check_req)) { + c->status = NT_STATUS_ACCESS_DENIED; + } + talloc_free(check_req); + check_req = NULL; + } + /* enforce the local signing required flag */ if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { if (!session->transport->negotiate.sign_info.doing_signing @@ -222,11 +249,14 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, struct smb_composite_sesssetup *io, struct smbcli_request **req) { - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm)); - DATA_BLOB session_key; + DATA_BLOB session_key = data_blob(NULL, 0); int flags = CLI_CRED_NTLM_AUTH; + + smbcli_temp_set_signing(session->transport); + if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } @@ -258,12 +288,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, &state->setup.nt1.in.password2, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); - - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - data_blob_free(&session_key); } else if (session->options.plaintext_auth) { const char *password = cli_credentials_get_password(io->in.credentials); state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password)); @@ -277,6 +301,15 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, if (!*req) { return NT_STATUS_NO_MEMORY; } + + if (NT_STATUS_IS_OK(nt_status)) { + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } + return (*req)->status; } @@ -350,9 +383,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, struct smbcli_request **req) { struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); - NTSTATUS status, session_key_err; - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB null_data_blob = data_blob(NULL, 0); + NTSTATUS status; const char *chosen_oid = NULL; state->setup.spnego.level = RAW_SESSSETUP_SPNEGO; @@ -440,15 +471,18 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, } state->gensec_status = status; - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); - } - *req = smb_raw_sesssetup_send(session, &state->setup); if (!*req) { return NT_STATUS_NO_MEMORY; } + + /* + * we need to check the signature ourself + * as the session key might be the acceptor subkey + * which comes within the response itself + */ + (*req)->sign_caller_checks = true; + return (*req)->status; } -- cgit