bool saf_join_store( const char *domain, const char *servername );
bool saf_delete( const char *domain );
char *saf_fetch( const char *domain );
-struct node_status *node_status_query(int fd,
- struct nmb_name *name,
- const struct sockaddr_storage *to_ss,
- int *num_names,
- struct node_status_extra *extra);
+NTSTATUS node_status_query(int fd,
+ struct nmb_name *name,
+ const struct sockaddr_storage *to_ss,
+ TALLOC_CTX *mem_ctx,
+ struct node_status **names,
+ int *num_names,
+ struct node_status_extra *extra);
bool name_status_find(const char *q_name,
int q_type,
int type,
Parse a node status response into an array of structures.
****************************************************************************/
-static struct node_status *parse_node_status(char *p,
+static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
int *num_names,
struct node_status_extra *extra)
{
if (*num_names == 0)
return NULL;
- ret = SMB_MALLOC_ARRAY(struct node_status,*num_names);
+ ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names);
if (!ret)
return NULL;
structures holding the returned names or NULL if the query failed.
**************************************************************************/
-struct node_status *node_status_query(int fd,
- struct nmb_name *name,
- const struct sockaddr_storage *to_ss,
- int *num_names,
- struct node_status_extra *extra)
+NTSTATUS node_status_query(int fd,
+ struct nmb_name *name,
+ const struct sockaddr_storage *to_ss,
+ TALLOC_CTX *mem_ctx,
+ struct node_status **names,
+ int *num_names,
+ struct node_status_extra *extra)
{
bool found=False;
int retries = 2;
if (to_ss->ss_family != AF_INET) {
/* Can't do node status to IPv6 */
- return NULL;
+ return NT_STATUS_INVALID_ADDRESS;
}
nmb->header.name_trn_id = generate_trn_id();
nmb->header.opcode = 0;
clock_gettime_mono(&tp);
if (!send_packet_request(&p))
- return NULL;
+ return NT_STATUS_NOT_FOUND;
retries--;
if (!retries)
break;
if (!found && !send_packet_request(&p))
- return NULL;
+ return NT_STATUS_NOT_FOUND;
clock_gettime_mono(&tp);
retries--;
}
continue;
}
- ret = parse_node_status(&nmb2->answers->rdata[0],
- num_names, extra);
+ ret = parse_node_status(
+ mem_ctx, &nmb2->answers->rdata[0], num_names,
+ extra);
free_packet(p2);
- return ret;
+
+ if (ret == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ *names = ret;
+ return NT_STATUS_OK;
}
}
- return NULL;
+ return NT_STATUS_IO_TIMEOUT;
}
/****************************************************************************
{
char addr[INET6_ADDRSTRLEN];
struct sockaddr_storage ss;
- struct node_status *status = NULL;
+ struct node_status *addrs = NULL;
struct nmb_name nname;
int count, i;
int sock;
bool result = false;
+ NTSTATUS status;
if (lp_disable_netbios()) {
DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
/* W2K PDC's seem not to respond to '*'#0. JRA */
make_nmb_name(&nname, q_name, q_type);
- status = node_status_query(sock, &nname, to_ss, &count, NULL);
+ status = node_status_query(sock, &nname, to_ss, talloc_tos(),
+ &addrs, &count, NULL);
close(sock);
- if (!status)
+ if (!NT_STATUS_IS_OK(status)) {
goto done;
+ }
for (i=0;i<count;i++) {
/* Find first one of the requested type that's not a GROUP. */
- if (status[i].type == type && ! (status[i].flags & 0x80))
+ if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
break;
}
if (i == count)
goto done;
- pull_ascii_nstring(name, sizeof(fstring), status[i].name);
+ pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
/* Store the result in the cache. */
/* but don't store an entry for 0x1c names here. Here we have
result = true;
done:
- SAFE_FREE(status);
+ TALLOC_FREE(addrs);
DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
{
struct nmb_name nname;
int count, i, j;
- struct node_status *status;
+ struct node_status *addrs;
struct node_status_extra extra;
fstring cleanname;
char addr[INET6_ADDRSTRLEN];
+ NTSTATUS status;
print_sockaddr(addr, sizeof(addr), pss);
d_printf("Looking up status of %s\n",addr);
make_nmb_name(&nname, name, type);
- status = node_status_query(fd, &nname, pss, &count, &extra);
- if (status) {
+ status = node_status_query(fd, &nname, pss, talloc_tos(),
+ &addrs, &count, &extra);
+ if (NT_STATUS_IS_OK(status)) {
for (i=0;i<count;i++) {
- pull_ascii_fstring(cleanname, status[i].name);
+ pull_ascii_fstring(cleanname, addrs[i].name);
for (j=0;cleanname[j];j++) {
if (!isprint((int)cleanname[j])) {
cleanname[j] = '.';
}
}
d_printf("\t%-15s <%02x> - %s\n",
- cleanname,status[i].type,
- node_status_flags(status[i].flags));
+ cleanname,addrs[i].type,
+ node_status_flags(addrs[i].flags));
}
d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
extra.mac_addr[0], extra.mac_addr[1],
extra.mac_addr[2], extra.mac_addr[3],
extra.mac_addr[4], extra.mac_addr[5]);
d_printf("\n");
- SAFE_FREE(status);
+ TALLOC_FREE(addrs);
} else {
d_printf("No reply from %s\n\n",addr);
}
}
-static struct node_status *lookup_byaddr_backend(const char *addr, int *count)
+static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx,
+ const char *addr, int *count)
{
int fd;
struct sockaddr_storage ss;
struct nmb_name nname;
- struct node_status *status;
+ struct node_status *result;
+ NTSTATUS status;
fd = wins_lookup_open_socket_in();
if (fd == -1)
if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
return NULL;
}
- status = node_status_query(fd, &nname, &ss, count, NULL);
-
+ status = node_status_query(fd, &nname, &ss, mem_ctx,
+ &result, count, NULL);
close(fd);
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ return NULL;
+ }
+ return result;
}
static struct sockaddr_storage *lookup_byname_backend(const char *name,
*response = '\0';
maxlen = sizeof(response) - 1;
- if ((status = lookup_byaddr_backend(state->request->data.winsreq, &count))){
+ if ((status = lookup_byaddr_backend(
+ state->mem_ctx, state->request->data.winsreq, &count))) {
size = strlen(state->request->data.winsreq);
if (size > maxlen) {
- SAFE_FREE(status);
+ TALLOC_FREE(status);
request_error(state);
return;
}
if (status[i].type == 0x20) {
size = sizeof(status[i].name) + strlen(response);
if (size > maxlen) {
- SAFE_FREE(status);
+ TALLOC_FREE(status);
request_error(state);
return;
}
}
/* make last character a newline */
response[strlen(response)-1] = '\n';
- SAFE_FREE(status);
+ TALLOC_FREE(status);
}
fstrcpy(state->response->data.winsresp,response);
request_ok(state);