diff options
-rw-r--r-- | libcli/nbt/libnbt.h | 6 | ||||
-rw-r--r-- | libcli/nbt/lmhosts.c | 79 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 60 |
3 files changed, 100 insertions, 45 deletions
diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h index 2abcb56971..6d6a4a4696 100644 --- a/libcli/nbt/libnbt.h +++ b/libcli/nbt/libnbt.h @@ -360,4 +360,10 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, struct sockaddr_storage *pss); void endlmhosts(XFILE *fp); +NTSTATUS resolve_lmhosts_file_as_sockaddr(const char *lmhosts_file, + const char *name, int name_type, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count); + #endif /* __LIBNBT_H__ */ diff --git a/libcli/nbt/lmhosts.c b/libcli/nbt/lmhosts.c index 11703a27e8..317ccc556c 100644 --- a/libcli/nbt/lmhosts.c +++ b/libcli/nbt/lmhosts.c @@ -155,3 +155,82 @@ void endlmhosts(XFILE *fp) x_fclose(fp); } +/******************************************************** + Resolve via "lmhosts" method. +*********************************************************/ + +NTSTATUS resolve_lmhosts_file_as_sockaddr(const char *lmhosts_file, + const char *name, int name_type, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count) +{ + /* + * "lmhosts" means parse the local lmhosts file. + */ + + XFILE *fp; + char *lmhost_name = NULL; + int name_type2; + struct sockaddr_storage return_ss; + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + TALLOC_CTX *ctx = NULL; + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_lmhosts: " + "Attempting lmhosts lookup for name %s<0x%x>\n", + name, name_type)); + + fp = startlmhosts(lmhosts_file); + + if ( fp == NULL ) + return NT_STATUS_NO_SUCH_FILE; + + ctx = talloc_new(mem_ctx); + if (!ctx) { + endlmhosts(fp); + return NT_STATUS_NO_MEMORY; + } + + while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { + + if (!strequal(name, lmhost_name)) { + TALLOC_FREE(lmhost_name); + continue; + } + + if ((name_type2 != -1) && (name_type != name_type2)) { + TALLOC_FREE(lmhost_name); + continue; + } + + *return_iplist = talloc_realloc(ctx, (*return_iplist), + struct sockaddr_storage, + (*return_count)+1); + + if ((*return_iplist) == NULL) { + TALLOC_FREE(ctx); + endlmhosts(fp); + DEBUG(3,("resolve_lmhosts: talloc_realloc fail !\n")); + return NT_STATUS_NO_MEMORY; + } + + (*return_iplist)[*return_count] = return_ss; + *return_count += 1; + + /* we found something */ + status = NT_STATUS_OK; + + /* Multiple names only for DC lookup */ + if (name_type != 0x1c) + break; + } + + talloc_steal(mem_ctx, *return_iplist); + TALLOC_FREE(ctx); + endlmhosts(fp); + return status; +} + diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 930f0a54f4..a6fc612a0f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1101,11 +1101,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, /* * "lmhosts" means parse the local lmhosts file. */ - - XFILE *fp; - char *lmhost_name = NULL; - int name_type2; - struct sockaddr_storage return_ss; + struct sockaddr_storage *ss_list; NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; TALLOC_CTX *ctx = NULL; @@ -1116,54 +1112,28 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, "Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); - fp = startlmhosts(get_dyn_LMHOSTSFILE()); - - if ( fp == NULL ) - return NT_STATUS_NO_SUCH_FILE; - ctx = talloc_init("resolve_lmhosts"); if (!ctx) { - endlmhosts(fp); return NT_STATUS_NO_MEMORY; } - while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { - - if (!strequal(name, lmhost_name)) { - TALLOC_FREE(lmhost_name); - continue; - } - - if ((name_type2 != -1) && (name_type != name_type2)) { - TALLOC_FREE(lmhost_name); - continue; - } - - *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), - struct ip_service, - (*return_count)+1); - - if ((*return_iplist) == NULL) { - TALLOC_FREE(ctx); - endlmhosts(fp); - DEBUG(3,("resolve_lmhosts: malloc fail !\n")); + status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(), + name, name_type, + ctx, + &ss_list, + return_count); + if (NT_STATUS_IS_OK(status)) { + if (convert_ss2service(return_iplist, + ss_list, + *return_count)) { + talloc_free(ctx); + return NT_STATUS_OK; + } else { + talloc_free(ctx); return NT_STATUS_NO_MEMORY; } - - (*return_iplist)[*return_count].ss = return_ss; - (*return_iplist)[*return_count].port = PORT_NONE; - *return_count += 1; - - /* we found something */ - status = NT_STATUS_OK; - - /* Multiple names only for DC lookup */ - if (name_type != 0x1c) - break; } - - TALLOC_FREE(ctx); - endlmhosts(fp); + talloc_free(ctx); return status; } |