static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
const char *domain,
const char *dc_name,
- struct in_addr dc_ip,
+ struct sockaddr_storage *dc_ss,
struct rpc_pipe_client **pipe_ret,
bool *retry)
{
/* Attempt connection */
*retry = True;
- result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0,
+ result = cli_full_connection(cli, global_myname(), dc_name, dc_ss, 0,
"IPC$", "IPC", "", "", "", 0, Undefined, retry);
if (!NT_STATUS_IS_OK(result)) {
uchar chal[8],
auth_serversupplied_info **server_info,
const char *dc_name,
- struct in_addr dc_ip)
+ struct sockaddr_storage *dc_ss)
{
NET_USER_INFO_3 info3;
nt_status = connect_to_domain_password_server(&cli,
domain,
dc_name,
- dc_ip,
+ dc_ss,
&netlogon_pipe,
&retry);
}
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
const char *domain = lp_workgroup();
fstring dc_name;
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
DEBUG(0,("check_ntdomain_security: Configuration error! Cannot use "
/* we need our DC to send the net_sam_logon() request to */
- if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n",
user_info->domain));
return NT_STATUS_NO_LOGON_SERVERS;
(uchar *)auth_context->challenge.data,
server_info,
dc_name,
- dc_ip);
+ &dc_ss);
return nt_status;
}
time_t last_change_time;
DOM_SID sid;
fstring dc_name;
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
if (!user_info || !server_info || !auth_context) {
DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n"));
/* use get_dc_name() for consistency even through we know that it will be
a netbios name */
- if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ss) ) {
DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
user_info->domain));
return NT_STATUS_NO_LOGON_SERVERS;
(uchar *)auth_context->challenge.data,
server_info,
dc_name,
- dc_ip);
+ &dc_ss);
return nt_status;
}
{
struct cli_state *cli = NULL;
fstring desthost;
- struct in_addr dest_ip;
+ struct sockaddr_storage dest_ss;
const char *p;
char *pserver;
bool connected_ok = False;
desthost, sizeof(desthost));
strupper_m(desthost);
- if(!resolve_name( desthost, &dest_ip, 0x20)) {
+ if(!resolve_name( desthost, &dest_ss, 0x20)) {
DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
continue;
}
- if (ismyip_v4(dest_ip)) {
+ if (ismyaddr(&dest_ss)) {
DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
continue;
}
return NULL;
}
- status = cli_connect(cli, desthost, &dest_ip);
+ status = cli_connect(cli, desthost, &dest_ss);
if (NT_STATUS_IS_OK(status)) {
DEBUG(3,("connected to password server %s\n",desthost));
connected_ok = True;
}
if (!attempt_netbios_session_request(&cli, global_myname(),
- desthost, &dest_ip)) {
+ desthost, &dest_ss)) {
release_server_mutex();
DEBUG(1,("password server fails session request\n"));
cli_shutdown(cli);
static bool showacls = False;
bool lowercase = False;
-static struct in_addr dest_ip;
+static struct sockaddr_storage dest_ss;
#define SEPARATORS " \t\n\r"
static int do_message_op(void)
{
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct nmb_name called, calling;
fstring server_name;
char name_type_hex[10];
snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
fstrcat(server_name, name_type_hex);
- zero_ip_v4(&ip);
- if (have_ip)
- ip = dest_ip;
+ zero_addr(&ss,AF_INET);
+ if (have_ip)
+ ss = dest_ss;
/* we can only do messages over port 139 (to windows clients at least) */
return 1;
}
- status = cli_connect(cli, server_name, &ip);
+ status = cli_connect(cli, server_name, &ss);
if (!NT_STATUS_IS_OK(status)) {
d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
return 1;
break;
case 'I':
{
- dest_ip = *interpret_addr2(poptGetOptArg(pc));
- if (is_zero_ip_v4(dest_ip))
+ if (!interpret_string_addr(&dest_ss, poptGetOptArg(pc), 0)) {
exit(1);
+ }
have_ip = True;
- cli_cm_set_dest_ip( dest_ip );
+ cli_cm_set_dest_ss(&dest_ss);
}
break;
case 'E':
#ifdef HAVE_LDAP
struct {
LDAP *ld;
- struct in_addr ip; /* the ip of the active connection, if any */
+ struct sockaddr_storage ss; /* the ip of the active connection, if any */
time_t last_attempt; /* last attempt to reconnect */
int port;
struct nmb_name called;
struct nmb_name calling;
fstring full_dest_host_name;
- struct in_addr dest_ip;
+ struct sockaddr_storage dest_ss;
DATA_BLOB secblob; /* cryptkey or negTokenInit */
uint32 sesskey;
#endif
/* Samba wrapper function for krb5 functionality. */
-void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
+void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr);
int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
gid_t gid; /* gid of user who *opened* this connection */
- char client_address[18]; /* String version of client IP address. */
+ char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */
uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
/* used by the IP comparison function */
struct ip_service {
- struct in_addr ip;
+ struct sockaddr_storage ss;
unsigned port;
};
((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
/****************************************************************************
-true if two IP addresses are equal
+true if two IPv4 addresses are equal
****************************************************************************/
-#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
-#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
+#define ip_equal_v4(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
/*****************************************************************
splits out the last subkey of a key
return True if a IP is directly reachable on one of our interfaces
*/
-bool iface_local(struct sockaddr_storage *ip)
+bool iface_local(const struct sockaddr_storage *ip)
{
return iface_find(ip, True) ? true : false;
}
if (iface_find(&ifs->ip, False)) {
DEBUG(3,("add_interface: not adding duplicate interface %s\n",
- print_sockaddr(addr, sizeof(addr),
- &ifs->ip, sizeof(struct sockaddr_storage)) ));
+ print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
return;
}
DEBUG(2,("added interface %s ip=%s ",
iface->name,
- print_sockaddr(addr, sizeof(addr),
- &iface->ip, sizeof(struct sockaddr_storage)) ));
+ print_sockaddr(addr, sizeof(addr), &iface->ip) ));
DEBUG(2,("bcast=%s ",
print_sockaddr(addr, sizeof(addr),
- &iface->bcast,
- sizeof(struct sockaddr_storage)) ));
+ &iface->bcast) ));
DEBUG(2,("netmask=%s\n",
print_sockaddr(addr, sizeof(addr),
- &iface->netmask,
- sizeof(struct sockaddr_storage)) ));
+ &iface->netmask) ));
}
/****************************************************************************
return is_ipaddress_v4(str);
}
+/****************************************************************************
+ Is a sockaddr_storage a broadcast address ?
+****************************************************************************/
+
+bool is_broadcast_addr(const struct sockaddr_storage *pss)
+{
+#if defined(HAVE_IPV6)
+ if (pss->ss_family == AF_INET6) {
+ const struct in6_addr *sin6 =
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ return IN6_IS_ADDR_MULTICAST(sin6);
+ }
+#endif
+ if (pss->ss_family == AF_INET) {
+ uint32_t addr =
+ ntohl(((const struct sockaddr_in *)pss)->sin_addr.s_addr);
+ return addr == INADDR_BROADCAST;
+ }
+ return false;
+}
+
/*******************************************************************
Wrap getaddrinfo...
******************************************************************/
{
struct addrinfo *res = NULL;
- memset(pss,'\0', sizeof(*pss));
+ zero_addr(pss, AF_INET);
if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
return false;
*ip = ipzero;
}
+/*******************************************************************
+ Set an address to INADDR_ANY, or IN6ADDR_ANY.
+******************************************************************/
+
+void zero_addr(struct sockaddr_storage *pss, int family)
+{
+ memset(pss, '\0', sizeof(*pss));
+ /* Ensure we're at least a valid sockaddr-storage. */
+ pss->ss_family = family;
+}
+
/*******************************************************************
Are two IPs on the same subnet - IPv4 version ?
********************************************************************/
return false;
}
-
/****************************************************************************
Is an IP address the INADDR_ANY or in6addr_any value ?
****************************************************************************/
Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
****************************************************************************/
-char *print_sockaddr(char *dest,
+char *print_sockaddr_len(char *dest,
size_t destlen,
const struct sockaddr_storage *psa,
socklen_t psalen)
return dest;
}
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+ size_t destlen,
+ const struct sockaddr_storage *psa)
+{
+ return print_sockaddr_len(dest, destlen, psa, sizeof(*psa));
+}
+
+/****************************************************************************
+ Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+ const struct sockaddr_storage *pss)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char *dest = NULL;
+ int ret;
+
+ ret = getnameinfo((const struct sockaddr *)pss,
+ sizeof(struct sockaddr_storage),
+ addr, sizeof(addr),
+ NULL, 0,
+ NI_NUMERICHOST);
+ if (ret) {
+ return NULL;
+ }
+ if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+ /* IPv6 */
+ const struct sockaddr_in6 *sa6 =
+ (const struct sockaddr_in6 *)pss;
+ uint16_t port = ntohs(sa6->sin6_port);
+
+ if (port) {
+ dest = talloc_asprintf(ctx,
+ "[%s]:%d",
+ addr,
+ (unsigned int)port);
+ } else {
+ dest = talloc_asprintf(ctx,
+ "[%s]",
+ addr);
+ }
+#else
+ return NULL;
+#endif
+ } else {
+ const struct sockaddr_in *sa =
+ (const struct sockaddr_in *)pss;
+ uint16_t port = ntohs(sa->sin_port);
+
+ if (port) {
+ dest = talloc_asprintf(ctx,
+ "%s:%d",
+ addr,
+ (unsigned int)port);
+ } else {
+ dest = talloc_asprintf(ctx,
+ "%s",
+ addr);
+ }
+ }
+ return dest;
+}
+
/****************************************************************************
Set the global client_fd variable.
****************************************************************************/
return addr_buf;
}
- return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length);
+ return print_sockaddr_len(addr_buf, sizeof(addr_buf), &sa, length);
}
/****************************************************************************
****************************************************************************/
int open_socket_in(int type,
- int port,
+ uint16_t port,
int dlevel,
- uint32 socket_addr, /* NETWORK BYTE ORDER */
- bool rebind )
+ const struct sockaddr_storage *psock,
+ bool rebind)
{
- struct sockaddr_in sock;
+ struct sockaddr_storage sock;
int res;
- memset( (char *)&sock, '\0', sizeof(sock) );
+ sock = *psock;
-#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
+#if defined(HAVE_IPV6)
+ if (sock.ss_family == AF_INET6) {
+ ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
+ }
#endif
- sock.sin_port = htons( port );
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = socket_addr;
+ if (sock.ss_family == AF_INET) {
+ ((struct sockaddr_in *)&sock)->sin_port = htons(port);
+ }
- res = socket( AF_INET, type, 0 );
+ res = socket(sock.ss_family, type, 0 );
if( res == -1 ) {
if( DEBUGLVL(0) ) {
dbgtext( "open_socket_in(): socket() call failed: " );
if( DEBUGLVL( dlevel ) ) {
dbgtext( "open_socket_in(): setsockopt: ");
dbgtext( "SO_REUSEPORT = %s ",
- val?"true":"false" );
- dbgtext( "on port %d failed ", port );
- dbgtext( "with error = %s\n", strerror(errno) );
+ val?"true":"false");
+ dbgtext( "on port %d failed ", port);
+ dbgtext( "with error = %s\n", strerror(errno));
}
}
#endif /* SO_REUSEPORT */
if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
port == SMB_PORT2 || port == NMB_PORT) ) {
- dbgtext( "bind failed on port %d ", port );
- dbgtext( "socket_addr = %s.\n",
- inet_ntoa( sock.sin_addr ) );
- dbgtext( "Error = %s\n", strerror(errno) );
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &sock);
+ dbgtext( "bind failed on port %d ", port);
+ dbgtext( "socket_addr = %s.\n", addr);
+ dbgtext( "Error = %s\n", strerror(errno));
}
- close( res );
+ close(res);
return -1;
}
DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
-
return( res );
}
Create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
-int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
+int open_socket_out(int type,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout)
{
- struct sockaddr_in sock_out;
+ char addr[INET6_ADDRSTRLEN];
+ struct sockaddr_storage sock_out = *pss;
int res,ret;
int connect_loop = 10;
int increment = 10;
/* create a socket to write to */
- res = socket(PF_INET, type, 0);
+ res = socket(pss->ss_family, type, 0);
if (res == -1) {
DEBUG(0,("socket error (%s)\n", strerror(errno)));
return -1;
}
- if (type != SOCK_STREAM)
- return(res);
-
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
+ if (type != SOCK_STREAM) {
+ return res;
+ }
- sock_out.sin_port = htons( port );
- sock_out.sin_family = PF_INET;
+#if defined(HAVE_IPV6)
+ if (pss->ss_family == AF_INET6) {
+ struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out;
+ psa6->sin6_port = htons(port);
+ }
+#endif
+ if (pss->ss_family == AF_INET) {
+ struct sockaddr_in *psa = (struct sockaddr_in *)&sock_out;
+ psa->sin_port = htons(port);
+ }
/* set it non-blocking */
set_blocking(res,false);
- DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
+ print_sockaddr(addr, sizeof(addr), &sock_out);
+ DEBUG(3,("Connecting to %s at port %u\n",
+ addr,
+ (unsigned int)port));
/* and connect it to the destination */
connect_again:
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%d\n",
- inet_ntoa(*addr),port));
+ DEBUG(1,("timeout connecting to %s:%u\n",
+ addr,
+ (unsigned int)port));
close(res);
return -1;
}
if (ret < 0) {
DEBUG(2,("error connecting to %s:%d (%s)\n",
- inet_ntoa(*addr),port,strerror(errno)));
+ addr,
+ (unsigned int)port,
+ strerror(errno)));
close(res);
return -1;
}
of DC's all of which are equivalent for our purposes.
**************************************************************************/
-bool open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
+bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
int timeout, int *fd_index, int *fd)
{
int i, resulting_index, res;
sockets[i] = -1;
for (i=0; i<num_addrs; i++) {
- sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
+ sockets[i] = socket(addrs[i].ss_family, SOCK_STREAM, 0);
if (sockets[i] < 0)
goto done;
set_blocking(sockets[i], false);
return addr_buf;
}
- print_sockaddr(addr_buf,
+ print_sockaddr_len(addr_buf,
sizeof(addr_buf),
pss,
*plength);
*/
DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
- print_sockaddr(addr_buf,
+ print_sockaddr_len(addr_buf,
sizeof(addr_buf),
pss,
len),
if (interpret_string_addr(&ss, servername,0)) {
print_sockaddr(name,
sizeof(name),
- &ss,
- sizeof(ss));
+ &ss);
servername = name;
}
}
* reallocated to new length
**/
-char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
+static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
{
char *new_ipstr = NULL;
+ char addr_buf[INET6_ADDRSTRLEN];
/* arguments checking */
- if (!ipstr_list || !service) return NULL;
+ if (!ipstr_list || !service) {
+ return NULL;
+ }
/* attempt to convert ip to a string and append colon separator to it */
if (*ipstr_list) {
- asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
- inet_ntoa(service->ip), service->port);
+ print_sockaddr(addr_buf,
+ sizeof(addr_buf),
+ &service->ss);
+ if (service->ss.ss_family == AF_INET) {
+ /* IPv4 */
+ asprintf(&new_ipstr, "%s%s%s:%d",
+ *ipstr_list,
+ IPSTR_LIST_SEP,
+ addr_buf,
+ service->port);
+ } else {
+ /* IPv6 */
+ asprintf(&new_ipstr, "%s%s[%s]:%d",
+ *ipstr_list,
+ IPSTR_LIST_SEP,
+ addr_buf,
+ service->port);
+ }
SAFE_FREE(*ipstr_list);
} else {
- asprintf(&new_ipstr, "%s:%d",
- inet_ntoa(service->ip), service->port);
+ if (service->ss.ss_family == AF_INET) {
+ /* IPv4 */
+ asprintf(&new_ipstr, "%s:%d",
+ addr_buf,
+ service->port);
+ } else {
+ /* IPv6 */
+ asprintf(&new_ipstr, "[%s]:%d",
+ addr_buf,
+ service->port);
+ }
}
*ipstr_list = new_ipstr;
return *ipstr_list;
}
-
/**
* Allocate and initialise an ipstr list using ip adresses
* passed as arguments.
**/
char *ipstr_list_make(char **ipstr_list,
- const struct ip_service * ip_list, int ip_count)
+ const struct ip_service *ip_list,
+ int ip_count)
{
int i;
/* arguments checking */
- if (!ip_list || !ipstr_list) return 0;
+ if (!ip_list || !ipstr_list) {
+ return 0;
+ }
*ipstr_list = NULL;
/* process ip addresses given as arguments */
- for (i = 0; i < ip_count; i++)
+ for (i = 0; i < ip_count; i++) {
*ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
+ }
return (*ipstr_list);
}
/**
* Parse given ip string list into array of ip addresses
* (as ip_service structures)
- * e.g. 192.168.1.100:389,192.168.1.78, ...
+ * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
*
* @param ipstr ip string list to be parsed
* @param ip_list pointer to array of ip addresses which is
* @return number of succesfully parsed addresses
**/
-int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
+int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
{
fstring token_str;
size_t count;
for ( i=0; next_token(&ipstr_list, token_str,
IPSTR_LIST_SEP, FSTRING_LEN) && i<count; i++ ) {
- struct in_addr addr;
- unsigned port = 0;
- char *p = strchr(token_str, ':');
+ char *s = token_str;
+ char *p = strrchr(token_str, ':');
if (p) {
*p = 0;
- port = atoi(p+1);
+ (*ip_list)[i].port = atoi(p+1);
}
/* convert single token to ip address */
- if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
- break;
-
- (*ip_list)[i].ip = addr;
- (*ip_list)[i].port = port;
+ if (token_str[0] == '[') {
+ /* IPv6 address. */
+ s++;
+ p = strchr(token_str, ']');
+ if (!p) {
+ continue;
+ }
+ *p = '\0';
+ }
+ if (!interpret_string_addr(&(*ip_list)[i].ss,
+ s,
+ AI_NUMERICHOST)) {
+ continue;
+ }
}
return count;
}
-
/**
* Safely free ip string list
*
SAFE_FREE(ipstr_list);
}
-
/**
Unescape a URL encoded string, in place.
**/
Does DNS queries.
************************************************************************/
-static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip)
+static char *get_kdc_ip_string(char *mem_ctx,
+ const char *realm,
+ const char *sitename,
+ struct sockaddr_storage *pss)
{
int i;
struct ip_service *ip_srv_site = NULL;
int count_site = 0;
int count_nonsite;
char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n",
- inet_ntoa(primary_ip));
+ print_canonical_sockaddr(mem_ctx,
+ pss));
if (kdc_str == NULL) {
return NULL;
get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
for (i = 0; i < count_site; i++) {
- if (ip_equal(ip_srv_site[i].ip, primary_ip)) {
+ if (addr_equal(&ip_srv_site[i].ss, pss)) {
continue;
}
- /* Append to the string - inefficient but not done often. */
+ /* Append to the string - inefficient
+ * but not done often. */
kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
- kdc_str, inet_ntoa(ip_srv_site[i].ip));
+ kdc_str,
+ print_canonical_sockaddr(mem_ctx,
+ &ip_srv_site[i].ss));
if (!kdc_str) {
SAFE_FREE(ip_srv_site);
return NULL;
for (i = 0; i < count_nonsite; i++) {
int j;
- if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) {
+ if (addr_equal(&ip_srv_nonsite[i].ss, pss)) {
continue;
}
/* Ensure this isn't an IP already seen (YUK! this is n*n....) */
for (j = 0; j < count_site; j++) {
- if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) {
+ if (addr_equal(&ip_srv_nonsite[i].ss,
+ &ip_srv_site[j].ss)) {
break;
}
/* As the lists are sorted we can break early if nonsite > site. */
/* Append to the string - inefficient but not done often. */
kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
- kdc_str, inet_ntoa(ip_srv_nonsite[i].ip));
+ kdc_str,
+ print_canonical_sockaddr(mem_ctx,
+ &ip_srv_nonsite[i].ss));
if (!kdc_str) {
SAFE_FREE(ip_srv_site);
SAFE_FREE(ip_srv_nonsite);
run as root or will fail (which is a good thing :-).
************************************************************************/
-bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain,
- const char *sitename, struct in_addr ip)
+bool create_local_private_krb5_conf_for_domain(const char *realm,
+ const char *domain,
+ const char *sitename,
+ struct sockaddr_storage *pss)
{
char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir());
char *tmpname = NULL;
realm_upper = talloc_strdup(fname, realm);
strupper_m(realm_upper);
- kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip);
+ kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss);
if (!kdc_ip_string) {
TALLOC_FREE(dname);
return False;
}
-
+
file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n"
"[realms]\n\t%s = {\n"
"\t%s\t}\n",
DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote "
"file %s with realm %s KDC = %s\n",
- fname, realm_upper, inet_ntoa(ip) ));
+ fname, realm_upper, print_canonical_sockaddr(dname, pss) ));
/* Set the environment variable to this file. */
setenv("KRB5_CONFIG", fname, 1);
int ret, sock;
socklen_t addr_len;
struct sockaddr remote_addr, local_addr;
- struct in_addr *addr = interpret_addr2(kdc_host);
+ struct sockaddr_storage addr;
krb5_address local_kaddr, remote_kaddr;
bool use_tcp = False;
+ if (!interpret_string_addr(&addr, kdc_host, 0)) {
+ }
+
ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
NULL, credsp, &ap_req);
if (ret) {
} else {
- sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT,
+ sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT,
LONG_CONNECT_TIMEOUT);
}
int rc = errno;
SAFE_FREE(ap_req.data);
krb5_auth_con_free(context, auth_context);
- DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
+ DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
kdc_host, strerror(errno)));
return ADS_ERROR_SYSTEM(rc);
}
-
addr_len = sizeof(remote_addr);
getpeername(sock, &remote_addr, &addr_len);
addr_len = sizeof(local_addr);
getsockname(sock, &local_addr, &addr_len);
-
- setup_kaddr(&remote_kaddr, &remote_addr);
- setup_kaddr(&local_kaddr, &local_addr);
+
+ /* FIXME ! How do we do IPv6 here ? JRA. */
+ if (remote_addr.sa_family != AF_INET ||
+ local_addr.sa_family != AF_INET) {
+ DEBUG(1,("do_krb5_kpasswd_request: "
+ "no IPv6 support (yet).\n"));
+ close(sock);
+ SAFE_FREE(ap_req.data);
+ krb5_auth_con_free(context, auth_context);
+ errno = EINVAL;
+ return ADS_ERROR_SYSTEM(EINVAL);
+ }
+
+ setup_kaddr_v4(&remote_kaddr, &remote_addr);
+ setup_kaddr_v4(&local_kaddr, &local_addr);
ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
if (ret) {
ads->config.client_site_name =
SMB_STRDUP(cldap_reply.client_site_name);
}
-
ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain);
ads->ldap.port = LDAP_PORT;
- ads->ldap.ip = *interpret_addr2(srv);
+ if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) {
+ DEBUG(1,("ads_try_connect: unable to convert %s "
+ "to an address\n",
+ srv));
+ SAFE_FREE( srv );
+ return False;
+ }
+
SAFE_FREE(srv);
-
+
/* Store our site name. */
sitename_store( cldap_reply.domain, cldap_reply.client_site_name );
/* if we fail this loop, then giveup since all the IP addresses returned were dead */
for ( i=0; i<count; i++ ) {
- fstring server;
-
- fstrcpy( server, inet_ntoa(ip_list[i].ip) );
-
+ char server[INET6_ADDRSTRLEN];
+
+ print_sockaddr(server, sizeof(server), &ip_list[i].ss);
+
if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
continue;
int version = LDAP_VERSION3;
ADS_STATUS status;
NTSTATUS ntstatus;
+ char addr[INET6_ADDRSTRLEN];
ZERO_STRUCT(ads->ldap);
ads->ldap.last_attempt = time(NULL);
/* try with a user specified server */
- if (ads->server.ldap_server &&
+ if (ads->server.ldap_server &&
ads_try_connect(ads, ads->server.ldap_server)) {
goto got_connection;
}
return ADS_ERROR_NT(ntstatus);
got_connection:
- DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip)));
+
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+ DEBUG(3,("Connected to LDAP server %s\n", addr));
if (!ads->auth.user_name) {
/* Must use the userPrincipalName value here or sAMAccountName
}
if (!ads->auth.kdc_server) {
- ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip));
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+ ads->auth.kdc_server = SMB_STRDUP(addr);
}
#if KRB5_DNS_HACK
/* cache the successful connection for workgroup and realm */
if (ads_closest_dc(ads)) {
- saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip));
- saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip));
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+ saf_store( ads->server.workgroup, addr);
+ saf_store( ads->server.realm, addr);
}
ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version);
int16 port;
};
*/
- int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+ uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+ struct in_addr dest_ip;
+
/* SESSION RETARGET */
- putip((char *)&cli->dest_ip,cli->inbuf+4);
+ putip((char *)&dest_ip,cli->inbuf+4);
+ in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
+ cli->fd = open_socket_out(SOCK_STREAM,
+ &cli->dest_ss,
+ port,
+ LONG_CONNECT_TIMEOUT);
if (cli->fd == -1)
return False;
Open the client sockets.
****************************************************************************/
-NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
+NTSTATUS cli_connect(struct cli_state *cli,
+ const char *host,
+ struct sockaddr_storage *dest_ss)
+
{
int name_type = 0x20;
char *p;
/* reasonable default hostname */
- if (!host) host = "*SMBSERVER";
+ if (!host) {
+ host = "*SMBSERVER";
+ }
fstrcpy(cli->desthost, host);
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(cli->desthost, '#'))) {
- name_type = strtol(p+1, NULL, 16);
+ name_type = strtol(p+1, NULL, 16);
*p = 0;
}
-
- if (!ip || is_zero_ip_v4(*ip)) {
- if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
+
+ if (!dest_ss || is_zero_addr(dest_ss)) {
+ if (!resolve_name(cli->desthost, &cli->dest_ss, name_type)) {
return NT_STATUS_BAD_NETWORK_NAME;
}
- if (ip) *ip = cli->dest_ip;
+ if (dest_ss) {
+ *dest_ss = cli->dest_ss;
+ }
} else {
- cli->dest_ip = *ip;
+ cli->dest_ss = *dest_ss;
}
if (getenv("LIBSMB_PROG")) {
cli->fd = sock_exec(getenv("LIBSMB_PROG"));
} else {
/* try 445 first, then 139 */
- int port = cli->port?cli->port:445;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
+ uint16_t port = cli->port?cli->port:445;
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
port, cli->timeout);
if (cli->fd == -1 && cli->port == 0) {
port = 139;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
port, cli->timeout);
}
- if (cli->fd != -1)
+ if (cli->fd != -1) {
cli->port = port;
+ }
}
if (cli->fd == -1) {
+ char addr[INET6_ADDRSTRLEN];
+ if (dest_ss) {
+ print_sockaddr(addr, sizeof(addr), dest_ss);
+ }
DEBUG(1,("Error connecting to %s (%s)\n",
- ip?inet_ntoa(*ip):host,strerror(errno)));
+ dest_ss?addr:host,strerror(errno)));
return map_nt_error_from_unix(errno);
}
establishes a connection to after the negprot.
@param output_cli A fully initialised cli structure, non-null only on success
@param dest_host The netbios name of the remote host
- @param dest_ip (optional) The the destination IP, NULL for name based lookup
+ @param dest_ss (optional) The the destination IP, NULL for name based lookup
@param port (optional) The destination port (0 for default)
@param retry bool. Did this connection fail with a retryable error ?
NTSTATUS cli_start_connection(struct cli_state **output_cli,
const char *my_name,
const char *dest_host,
- struct in_addr *dest_ip, int port,
+ struct sockaddr_storage *dest_ss, int port,
int signing_state, int flags,
bool *retry)
{
struct nmb_name calling;
struct nmb_name called;
struct cli_state *cli;
- struct in_addr ip;
+ struct sockaddr_storage ss;
if (retry)
*retry = False;
cli_set_timeout(cli, 10000); /* 10 seconds. */
- if (dest_ip)
- ip = *dest_ip;
- else
- ZERO_STRUCT(ip);
+ if (dest_ss) {
+ ss = *dest_ss;
+ } else {
+ zero_addr(&ss, AF_INET);
+ }
again:
DEBUG(3,("Connecting to host=%s\n", dest_host));
-
- nt_status = cli_connect(cli, dest_host, &ip);
+
+ nt_status = cli_connect(cli, dest_host, &ss);
if (!NT_STATUS_IS_OK(nt_status)) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ss);
DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
- nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) ));
+ nmb_namestr(&called), addr, nt_errstr(nt_status) ));
cli_shutdown(cli);
return nt_status;
}
if (!cli_session_request(cli, &calling, &called)) {
char *p;
- DEBUG(1,("session request to %s failed (%s)\n",
+ DEBUG(1,("session request to %s failed (%s)\n",
called.name, cli_errstr(cli)));
- if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) {
+ if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
*p = 0;
goto again;
}
NTSTATUS cli_full_connection(struct cli_state **output_cli,
const char *my_name,
const char *dest_host,
- struct in_addr *dest_ip, int port,
+ struct sockaddr_storage *dest_ss, int port,
const char *service, const char *service_type,
const char *user, const char *domain,
const char *password, int flags,
password = "";
}
- nt_status = cli_start_connection(&cli, my_name, dest_host,
- dest_ip, port, signing_state, flags, retry);
-
+ nt_status = cli_start_connection(&cli, my_name, dest_host,
+ dest_ss, port, signing_state,
+ flags, retry);
+
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
return nt_status;
}
}
-
+
if (service) {
if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
nt_status = cli_nt_error(cli);
****************************************************************************/
bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
- struct in_addr *pdest_ip)
+ struct sockaddr_storage *pdest_ss)
{
struct nmb_name calling, called;
* then use *SMBSERVER immediately.
*/
- if(is_ipaddress_v4(desthost)) {
+ if(is_ipaddress(desthost)) {
make_nmb_name(&called, "*SMBSERVER", 0x20);
} else {
make_nmb_name(&called, desthost, 0x20);
return False;
}
- status = cli_connect(*ppcli, desthost, pdest_ip);
+ status = cli_connect(*ppcli, desthost, pdest_ss);
if (!NT_STATUS_IS_OK(status) ||
!cli_session_request(*ppcli, &calling, &smbservername)) {
DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
return True;
}
-
-
-
-
/****************************************************************************
Send an old style tcon.
****************************************************************************/
/* Return a cli_state pointing at the IPC$ share for the given server */
-struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
- struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect(char *server,
+ struct sockaddr_storage *server_ss,
+ struct user_auth_info *user_info)
{
struct cli_state *cli;
pstring myname;
NTSTATUS nt_status;
get_myname(myname);
-
- nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC",
+
+ nt_status = cli_full_connection(&cli, myname, server, server_ss, 0, "IPC$", "IPC",
user_info->username, lp_workgroup(), user_info->password,
CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
return cli;
- } else if (is_ipaddress_v4(server)) {
+ } else if (is_ipaddress(server)) {
/* windows 9* needs a correct NMB name for connections */
fstring remote_name;
- if (name_status_find("*", 0, 0, *server_ip, remote_name)) {
- cli = get_ipc_connect(remote_name, server_ip, user_info);
+ if (name_status_find("*", 0, 0, server_ss, remote_name)) {
+ cli = get_ipc_connect(remote_name, server_ss, user_info);
if (cli)
return cli;
}
* entire network browse list)
*/
-struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info)
{
+ char addr[INET6_ADDRSTRLEN];
static fstring name;
struct cli_state *cli;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
+ print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
DEBUG(99, ("Looking up name of master browser %s\n",
- inet_ntoa(mb_ip->ip)));
+ addr));
/*
* Do a name status query to find out the name of the master browser.
* the original wildcard query as the first choice and fall back to
* MSBROWSE if the wildcard query fails.
*/
- if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) &&
- !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) {
+ if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
+ !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
DEBUG(99, ("Could not retrieve name status for %s\n",
- inet_ntoa(mb_ip->ip)));
+ addr));
return NULL;
}
- if (!find_master_ip(name, &server_ip)) {
+ if (!find_master_ip(name, &server_ss)) {
DEBUG(99, ("Could not find master ip for %s\n", name));
return NULL;
}
- pstrcpy(workgroup, name);
+ pstrcpy(workgroup, name);
- DEBUG(4, ("found master browser %s, %s\n",
- name, inet_ntoa(mb_ip->ip)));
+ DEBUG(4, ("found master browser %s, %s\n", name, addr));
- cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
+ print_sockaddr(addr, sizeof(addr), &server_ss);
+ cli = get_ipc_connect(addr, &server_ss, user_info);
- return cli;
-
+ return cli;
}
/*
DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
- /* Go looking for workgroups by broadcasting on the local network */
+ /* Go looking for workgroups by broadcasting on the local network */
if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
&count))) {
}
for (i = 0; i < count; i++) {
- DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+ DEBUG(99, ("Found master browser %s\n", addr));
- cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
- if (cli)
- return(cli);
+ cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
+ if (cli)
+ return(cli);
}
return NULL;
static int port;
static int name_type = 0x20;
static bool have_ip;
-static struct in_addr dest_ip;
+static struct sockaddr_storage dest_ss;
static struct client_connection *connections;
struct cli_state *c = NULL;
struct nmb_name called, calling;
const char *server_n;
- struct in_addr ip;
+ struct sockaddr_storage ss;
pstring servicename;
char *sharename;
fstring newserver, newshare;
server_n = server;
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
make_nmb_name(&calling, global_myname(), 0x0);
make_nmb_name(&called , server, name_type);
again:
- zero_ip_v4(&ip);
- if (have_ip)
- ip = dest_ip;
+ zero_addr(&ss, AF_INET);
+ if (have_ip)
+ ss = dest_ss;
/* have to open a new connection */
if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
d_printf("Connection to %s failed\n", server_n);
return NULL;
}
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status));
return NULL;
/****************************************************************************
****************************************************************************/
-void cli_cm_set_dest_ip(struct in_addr ip )
+void cli_cm_set_dest_ss(struct sockaddr_storage *pss)
{
- dest_ip = ip;
- have_ip = True;
+ dest_ss = *pss;
+ have_ip = true;
}
/**********************************************************************
bool unique, const char *mailslot,
uint16 priority,
char *buf, int len,
- const char *srcname, int src_type,
+ const char *srcname, int src_type,
const char *dstname, int dest_type,
- struct in_addr dest_ip)
+ const struct sockaddr_storage *dest_ss)
{
struct packet_struct p;
struct dgram_packet *dgram = &p.packet.dgram;
char *ptr, *p2;
char tmp[4];
pid_t nmbd_pid;
+ char addr[INET6_ADDRSTRLEN];
if ((nmbd_pid = pidfile_pid("nmbd")) == 0) {
DEBUG(3, ("No nmbd found\n"));
return False;
}
+ if (dest_ss->ss_family != AF_INET) {
+ DEBUG(3, ("cli_send_mailslot: can't send to IPv6 address.\n"));
+ return false;
+ }
+
memset((char *)&p, '\0', sizeof(p));
/*
*/
/* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
+ dgram->header.msg_type = unique ? 0x10 : 0x11;
dgram->header.flags.node_type = M_NODE;
dgram->header.flags.first = True;
dgram->header.flags.more = False;
/* source ip is filled by nmbd */
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
dgram->header.packet_offset = 0;
-
+
make_nmb_name(&dgram->source_name,srcname,src_type);
make_nmb_name(&dgram->dest_name,dstname,dest_type);
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
p.packet_type = DGRAM_PACKET;
- p.ip = dest_ip;
+ p.ip = ((const struct sockaddr_in *)&dest_ss)->sin_addr;
p.timestamp = time(NULL);
DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ",
mailslot, nmb_namestr(&dgram->source_name)));
- DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name),
- inet_ntoa(dest_ip)));
+ print_sockaddr(addr, sizeof(addr), dest_ss);
+
+ DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), addr));
return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx,
pid_to_procid(nmbd_pid),
{
pstring outbuf;
char *p;
- struct in_addr sendto_ip;
+ struct sockaddr_storage sendto_ss;
- if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) {
+ if (!resolve_name(send_to_name, &sendto_ss, 0x1d)) {
DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name));
return False;
cli_send_mailslot(msg_ctx, True, "\\MAILSLOT\\BROWSE", 1, outbuf,
PTR_DIFF(p, outbuf), myname, 0, send_to_name,
- 0x1d, sendto_ip);
+ 0x1d, &sendto_ss);
/* We should check the error and return if we got one */
#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS)
/* HEIMDAL */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
+ void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr)
{
pkaddr->addr_type = KRB5_ADDRESS_INET;
pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
}
#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS)
/* MIT */
- void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr)
+ void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr)
{
pkaddr->addrtype = ADDRTYPE_INET;
pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
* Connect to a server, possibly on an existing connection
*
* Here, what we want to do is: If the server and username
- * match an existing connection, reuse that, otherwise, establish a
+ * match an existing connection, reuse that, otherwise, establish a
* new connection.
*
* If we have to create a new connection, call the auth_fn to get the
smbc_server(SMBCCTX *context,
bool connect_if_not_found,
const char *server,
- const char *share,
+ const char *share,
fstring workgroup,
- fstring username,
+ fstring username,
fstring password)
{
SMBCSRV *srv=NULL;
struct nmb_name called, calling;
const char *server_n = server;
pstring ipenv;
- struct in_addr ip;
+ struct sockaddr_storage ss;
int tried_reverse = 0;
int port_try_first;
int port_try_next;
const char *username_used;
NTSTATUS status;
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
ZERO_STRUCT(c);
if (server[0] == 0) {
/* Look for a cached connection */
srv = find_server(context, server, share,
workgroup, username, password);
-
+
/*
* If we found a connection and we're only allowed one share per
* server...
if (! cli_send_tconX(srv->cli, share, "?????",
password, strlen(password)+1)) {
-
+
errno = smbc_errno(context, srv->cli);
cli_shutdown(srv->cli);
srv->cli = NULL;
}
}
}
-
+
/* If we have a connection... */
if (srv) {
make_nmb_name(&called , server, 0x20);
DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
-
+
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
again:
slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
/* have to open a new connection */
if ((c = cli_initialise()) == NULL) {
c->port = port_try_first;
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
/* First connection attempt failed. Try alternate port. */
c->port = port_try_next;
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(c);
errno = ETIMEDOUT;
/* Only try this if server is an IP address ... */
- if (is_ipaddress_v4(server) && !tried_reverse) {
+ if (is_ipaddress(server) && !tried_reverse) {
fstring remote_name;
- struct in_addr rem_ip;
+ struct sockaddr_storage rem_ss;
- if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
+ if (!interpret_string_addr(&rem_ss, server,
+ NI_NUMERICHOST)) {
DEBUG(4, ("Could not convert IP address "
- "%s to struct in_addr\n", server));
+ "%s to struct sockaddr_storage\n",
+ server));
errno = ETIMEDOUT;
return NULL;
}
tried_reverse++; /* Yuck */
- if (name_status_find("*", 0, 0, rem_ip, remote_name)) {
+ if (name_status_find("*", 0, 0, &rem_ss, remote_name)) {
make_nmb_name(&called, remote_name, 0x20);
goto again;
}
errno = ETIMEDOUT;
return NULL;
}
-
+
DEBUG(4,(" session request ok\n"));
-
+
if (!cli_negprot(c)) {
cli_shutdown(c);
errno = ETIMEDOUT;
username_used = username;
- if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
password, strlen(password),
password, strlen(password),
workgroup))) {
-
+
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = "";
cli_shutdown(c);
return NULL;
}
-
+
DEBUG(4,(" tconx ok\n"));
-
+
/*
* Ok, we have got a nice connection
* Let's allocate a server structure.
}
goto failed;
}
-
- DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
+
+ DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
server, share, srv));
DLIST_ADD(context->internal->_servers, srv);
if (!srv) {
return NULL;
}
-
+
SAFE_FREE(srv);
return NULL;
}
static SMBCSRV *
smbc_attr_server(SMBCCTX *context,
const char *server,
- const char *share,
+ const char *share,
fstring workgroup,
fstring username,
fstring password,
POLICY_HND *pol)
{
int flags;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct cli_state *ipc_cli;
struct rpc_pipe_client *pipe_hnd;
NTSTATUS nt_status;
password, sizeof(fstring));
}
}
-
+
flags = 0;
if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
}
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
nt_status = cli_full_connection(&ipc_cli,
- global_myname(), server,
- &ip, 0, "IPC$", "?????",
+ global_myname(), server,
+ &ss, 0, "IPC$", "?????",
username, workgroup,
password, flags,
Undefined, NULL);
SMBCSRV *srv = NULL;
SMBCFILE *dir = NULL;
struct _smbc_callbacks *cb;
- struct in_addr rem_ip;
+ struct sockaddr_storage rem_ss;
if (!context || !context->internal ||
!context->internal->_initialized) {
dir = SMB_MALLOC_P(SMBCFILE);
if (!dir) {
-
errno = ENOMEM;
return NULL;
-
}
ZERO_STRUCTP(dir);
SAFE_FREE(ip_list);
- if (!find_master_ip(workgroup, &server_addr.ip)) {
+ if (!find_master_ip(workgroup, &server_addr.ss)) {
if (dir) {
SAFE_FREE(dir->fname);
}
for (i = 0; i < count && i < max_lmb_count; i++) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
DEBUG(99, ("Found master browser %d of %d: %s\n",
i+1, MAX(count, max_lmb_count),
- inet_ntoa(ip_list[i].ip)));
-
+ addr));
+
cli = get_ipc_connect_master_ip(&ip_list[i],
workgroup, &u_info);
- /* cli == NULL is the master browser refused to talk or
+ /* cli == NULL is the master browser refused to talk or
could not be found */
if ( !cli )
continue;
* already have one, and determine the
* workgroups/domains that it knows about.
*/
-
+
srv = smbc_server(context, True, server, "IPC$",
workgroup, user, password);
if (!srv) {
continue;
}
-
+
dir->srv = srv;
dir->dir_type = SMBC_WORKGROUP;
/* Now, list the stuff ... */
-
+
if (!cli_NetServerEnum(srv->cli,
workgroup,
SV_TYPE_DOMAIN_ENUM,
}
SAFE_FREE(ip_list);
- } else {
+ } else {
/*
* Server not an empty string ... Check the rest and see what
* gives
* LMB or DMB
*/
if (!srv &&
- !is_ipaddress_v4(server) &&
- (resolve_name(server, &rem_ip, 0x1d) || /* LMB */
- resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */
+ !is_ipaddress(server) &&
+ (resolve_name(server, &rem_ss, 0x1d) || /* LMB */
+ resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
fstring buserver;
* Get the backup list ...
*/
if (!name_status_find(server, 0, 0,
- rem_ip, buserver)) {
+ &rem_ss, buserver)) {
DEBUG(0, ("Could not get name of "
"local/domain master browser "
return NULL;
}
} else if (srv ||
- (resolve_name(server, &rem_ip, 0x20))) {
-
+ (resolve_name(server, &rem_ss, 0x20))) {
+
/* If we hadn't found the server, get one now */
if (!srv) {
srv = smbc_server(context, True,
(void *) dir) < 0 &&
cli_RNetShareEnum(
srv->cli,
- list_fn,
+ list_fn,
(void *)dir) < 0) {
-
+
errno = cli_errno(srv->cli);
if (dir) {
SAFE_FREE(dir->fname);
}
} else {
/* Neither the workgroup nor server exists */
- errno = ECONNREFUSED;
+ errno = ECONNREFUSED;
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
-/*
+/*
Unix SMB/CIFS implementation.
NetBIOS name cache module on top of gencache mechanism.
-
+
Copyright (C) Tim Potter 2002
Copyright (C) Rafal Szczesniak 2002
-
+ Copyright (C) Jeremy Allison 2007
+
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 <http://www.gnu.org/licenses/>.
*/
#define NBTKEY_FMT "NBT/%s#%02X"
-
/**
* Initialise namecache system. Function calls gencache
* initialisation function to perform necessary actions
- *
+ *
* @return true upon successful initialisation of the cache or
* false on failure
**/
/*
* Check if name caching disabled by setting the name cache
* timeout to zero.
- */
+ */
if (lp_name_cache_timeout() == 0) {
DEBUG(5, ("namecache_enable: disabling netbios name cache\n"));
/* Init namecache by calling gencache initialisation */
if (!gencache_init()) {
- DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n"));
+ DEBUG(2, ("namecache_enable: "
+ "Couldn't initialise namecache on top of gencache.\n"));
return False;
}
- /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */
+ /* I leave it for now, though I don't think we really
+ * need this (mimir, 27.09.2002) */
DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
"seconds\n", lp_name_cache_timeout()));
return True;
}
-
/**
* Shutdown namecache. Routine calls gencache close function
* to safely close gencache file.
* @return true upon successful shutdown of the cache or
* false on failure
**/
-
+
bool namecache_shutdown(void)
{
if (!gencache_shutdown()) {
- DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n"));
+ DEBUG(2, ("namecache_shutdown: "
+ "Couldn't close namecache on top of gencache.\n"));
return False;
}
-
- DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n"));
+
+ DEBUG(5, ("namecache_shutdown: "
+ "netbios namecache closed successfully.\n"));
return True;
}
-
/**
* Generates a key for netbios name lookups on basis of
* netbios name and type.
* type number
*/
-static char* namecache_key(const char *name, int name_type)
+static char* namecache_key(const char *name,
+ int name_type)
{
char *keystr;
asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type);
return keystr;
}
-
/**
* Store a name(s) in the name cache
*
* ip addresses being stored
**/
-bool namecache_store(const char *name, int name_type,
- int num_names, struct ip_service *ip_list)
+bool namecache_store(const char *name,
+ int name_type,
+ int num_names,
+ struct ip_service *ip_list)
{
time_t expiry;
char *key, *value_string;
* we use gecache call to avoid annoying debug messages about
* initialised namecache again and again...
*/
- if (!gencache_init()) return False;
+ if (!gencache_init()) {
+ return False;
+ }
if (name_type > 255) {
return False; /* Don't store non-real name types. */
}
if ( DEBUGLEVEL >= 5 ) {
+ TALLOC_CTX *ctx = talloc_stackframe();
+ char *addr = NULL;
+
DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
num_names, num_names == 1 ? "": "es", name, name_type));
- for (i = 0; i < num_names; i++)
- DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip),
- ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
-
+ for (i = 0; i < num_names; i++) {
+ addr = print_canonical_sockaddr(ctx,
+ &ip_list[i].ss);
+ if (!addr) {
+ continue;
+ }
+ DEBUGADD(5, ("%s%s", addr,
+ (i == (num_names - 1) ? "" : ",")));
+
+ }
DEBUGADD(5, ("\n"));
+ TALLOC_FREE(ctx);
}
-
+
key = namecache_key(name, name_type);
if (!key) {
return False;
if (!ipstr_list_make(&value_string, ip_list, num_names)) {
SAFE_FREE(key);
SAFE_FREE(value_string);
- return False;
+ return false;
}
-
+
/* set the entry */
ret = gencache_set(key, value_string, expiry);
SAFE_FREE(key);
return ret;
}
-
/**
* Look up a name in the cache.
*
* false if name isn't found in the cache or has expired
**/
-bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_list,
- int *num_names)
+bool namecache_fetch(const char *name,
+ int name_type,
+ struct ip_service **ip_list,
+ int *num_names)
{
char *key, *value;
time_t timeout;
/* exit now if null pointers were passed as they're required further */
- if (!ip_list || !num_names) return False;
+ if (!ip_list || !num_names) {
+ return False;
+ }
- if (!gencache_init())
+ if (!gencache_init()) {
return False;
+ }
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
*num_names = 0;
- /*
+ /*
* Use gencache interface - lookup the key
*/
key = namecache_key(name, name_type);
} else {
DEBUG(5, ("name %s#%02X found.\n", name, name_type));
}
-
+
/*
* Split up the stored value into the list of IP adresses
*/
*num_names = ipstr_list_parse(value, ip_list);
-
+
SAFE_FREE(key);
SAFE_FREE(value);
-
- return *num_names > 0; /* true only if some ip has been fetched */
+
+ return *num_names > 0; /* true only if some ip has been fetched */
}
/**
*
**/
-static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr)
+static void flush_netbios_name(const char *key,
+ const char *value,
+ time_t timeout,
+ void *dptr)
{
gencache_del(key);
DEBUG(5, ("Deleting entry %s\n", key));
}
-
/**
* Flush all names from the name cache.
* It's done by gencache_iterate()
*
- * @return True upon successful deletion or
- * False in case of an error
+ * @return true upon successful deletion or
+ * false in case of an error
**/
void namecache_flush(void)
{
- if (!gencache_init())
+ if (!gencache_init()) {
return;
+ }
- /*
+ /*
* iterate through each NBT cache's entry and flush it
* by flush_netbios_name function
*/
/* Construct a name status record key. */
-static char *namecache_status_record_key(const char *name, int name_type1,
- int name_type2, struct in_addr keyip)
+static char *namecache_status_record_key(const char *name,
+ int name_type1,
+ int name_type2,
+ const struct sockaddr_storage *keyip)
{
+ char addr[INET6_ADDRSTRLEN];
char *keystr;
+ print_sockaddr(addr, sizeof(addr), keyip);
asprintf(&keystr, "NBT/%s#%02X.%02X.%s",
- strupper_static(name), name_type1, name_type2, inet_ntoa(keyip));
+ strupper_static(name), name_type1, name_type2, addr);
return keystr;
}
/* Store a name status record. */
bool namecache_status_store(const char *keyname, int keyname_type,
- int name_type, struct in_addr keyip,
+ int name_type, const struct sockaddr_storage *keyip,
const char *srvname)
{
char *key;
time_t expiry;
bool ret;
- if (!gencache_init())
+ if (!gencache_init()) {
return False;
+ }
- key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+ key = namecache_status_record_key(keyname, keyname_type,
+ name_type, keyip);
if (!key)
return False;
expiry = time(NULL) + lp_name_cache_timeout();
ret = gencache_set(key, srvname, expiry);
- if (ret)
- DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname ));
- else
- DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key ));
+ if (ret) {
+ DEBUG(5, ("namecache_status_store: entry %s -> %s\n",
+ key, srvname ));
+ } else {
+ DEBUG(5, ("namecache_status_store: entry %s store failed.\n",
+ key ));
+ }
SAFE_FREE(key);
return ret;
/* Fetch a name status record. */
-bool namecache_status_fetch(const char *keyname, int keyname_type,
- int name_type, struct in_addr keyip, char *srvname_out)
+bool namecache_status_fetch(const char *keyname,
+ int keyname_type,
+ int name_type,
+ const struct sockaddr_storage *keyip,
+ char *srvname_out)
{
char *key = NULL;
char *value = NULL;
if (!gencache_init())
return False;
- key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+ key = namecache_status_record_key(keyname, keyname_type,
+ name_type, keyip);
if (!key)
return False;
if (!gencache_get(key, &value, &timeout)) {
- DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key));
+ DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n",
+ key));
SAFE_FREE(key);
return False;
} else {
- DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value ));
+ DEBUG(5, ("namecache_status_fetch: key %s -> %s\n",
+ key, value ));
}
strlcpy(srvname_out, value, 16);
-/*
+/*
Unix SMB/CIFS implementation.
name query routines
Copyright (C) Andrew Tridgell 1994-1998
-
+ Copyright (C) Jeremy Allison 2007.
+
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 <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
/****************************
* SERVER AFFINITY ROUTINES *
****************************/
-
- /* Server affinity is the concept of preferring the last domain
+
+ /* Server affinity is the concept of preferring the last domain
controller with whom you had a successful conversation */
-
+
/****************************************************************************
****************************************************************************/
#define SAFKEY_FMT "SAF/DOMAIN/%s"
static char *saf_key(const char *domain)
{
char *keystr;
-
+
asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
return keystr;
char *key;
time_t expire;
bool ret = False;
-
+
if ( !domain || !servername ) {
- DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
+ DEBUG(2,("saf_store: "
+ "Refusing to store empty domain or servername!\n"));
return False;
}
if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
- DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
+ DEBUG(0,("saf_store: "
+ "refusing to store 0 length domain or servername!\n"));
return False;
}
-
- if ( !gencache_init() )
+
+ if ( !gencache_init() )
return False;
-
+
key = saf_key( domain );
expire = time( NULL ) + SAF_TTL;
-
-
+
DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
domain, servername, (unsigned int)expire ));
-
+
ret = gencache_set( key, servername, expire );
-
+
SAFE_FREE( key );
-
+
return ret;
}
{
char *key;
bool ret = False;
-
+
if ( !domain ) {
- DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
+ DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
return False;
}
-
- if ( !gencache_init() )
+
+ if ( !gencache_init() )
return False;
-
+
key = saf_key(domain);
ret = gencache_del(key);
-
+
if (ret) {
- DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
+ DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
}
SAFE_FREE( key );
DEBUG(2,("saf_fetch: Empty domain name!\n"));
return NULL;
}
-
- if ( !gencache_init() )
+
+ if ( !gencache_init() )
return False;
-
+
key = saf_key( domain );
-
+
ret = gencache_get( key, &server, &timeout );
-
+
SAFE_FREE( key );
-
+
if ( !ret ) {
- DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
+ DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
+ domain ));
} else {
- DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
+ DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
server, domain ));
}
-
+
return server;
}
Parse a node status response into an array of structures.
****************************************************************************/
-static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
+static NODE_STATUS_STRUCT *parse_node_status(char *p,
+ int *num_names,
+ struct node_status_extra *extra)
{
NODE_STATUS_STRUCT *ret;
int i;
ret[i].type = CVAL(p,15);
ret[i].flags = p[16];
p += 18;
- DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
+ DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
ret[i].type, ret[i].flags));
}
/*
structures holding the returned names or NULL if the query failed.
**************************************************************************/
-NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
- struct in_addr to_ip, int *num_names,
- struct node_status_extra *extra)
+NODE_STATUS_STRUCT *node_status_query(int fd,
+ struct nmb_name *name,
+ const struct sockaddr_storage *to_ss,
+ int *num_names,
+ struct node_status_extra *extra)
{
bool found=False;
int retries = 2;
ZERO_STRUCT(p);
+ if (to_ss->ss_family != AF_INET) {
+ /* Can't do node status to IPv6 */
+ return NULL;
+ }
nmb->header.name_trn_id = generate_trn_id();
nmb->header.opcode = 0;
- nmb->header.response = False;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
+ nmb->header.response = false;
+ nmb->header.nm_flags.bcast = false;
+ nmb->header.nm_flags.recursion_available = false;
+ nmb->header.nm_flags.recursion_desired = false;
+ nmb->header.nm_flags.trunc = false;
+ nmb->header.nm_flags.authoritative = false;
nmb->header.rcode = 0;
nmb->header.qdcount = 1;
nmb->header.ancount = 0;
nmb->question.question_type = 0x21;
nmb->question.question_class = 0x1;
- p.ip = to_ip;
+ p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
-
+
GetTimeOfDay(&tval);
-
- if (!send_packet(&p))
+
+ if (!send_packet(&p))
return NULL;
retries--;
retries--;
}
- if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
+ if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
-
+
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
nmb2->header.rcode ||
continue;
}
- ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
+ ret = parse_node_status(&nmb2->answers->rdata[0],
+ num_names, extra);
free_packet(p2);
return ret;
}
}
-
+
return NULL;
}
a servers name given its IP. Return the matched name in *name.
**************************************************************************/
-bool name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
+bool name_status_find(const char *q_name,
+ int q_type,
+ int type,
+ const struct sockaddr_storage *to_ss,
+ fstring name)
{
+ char addr[INET6_ADDRSTRLEN];
+ struct sockaddr_storage ss;
NODE_STATUS_STRUCT *status = NULL;
struct nmb_name nname;
int count, i;
int sock;
- bool result = False;
+ bool result = false;
if (lp_disable_netbios()) {
- DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
+ DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
+ q_name, q_type));
return False;
}
- DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
- q_type, inet_ntoa(to_ip)));
+ print_sockaddr(addr, sizeof(addr), to_ss);
+
+ DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
+ q_type, addr));
/* Check the cache first. */
- if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
+ if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
return True;
+ }
+
+ if (to_ss->ss_family != AF_INET) {
+ /* Can't do node status to IPv6 */
+ return false;
+ }
+
+ if (!interpret_string_addr(&ss, lp_socket_address(),
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ zero_addr(&ss, AF_INET);
+ }
- sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
+ sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
if (sock == -1)
goto done;
/* 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_ip, &count, NULL);
+ status = node_status_query(sock, &nname, to_ss, &count, NULL);
close(sock);
if (!status)
goto done;
pull_ascii_nstring(name, sizeof(fstring), status[i].name);
/* Store the result in the cache. */
- /* but don't store an entry for 0x1c names here. Here we have
+ /* but don't store an entry for 0x1c names here. Here we have
a single host and DOMAIN<0x1c> names should be a list of hosts */
-
- if ( q_type != 0x1c )
- namecache_status_store(q_name, q_type, type, to_ip, name);
- result = True;
+ if ( q_type != 0x1c ) {
+ namecache_status_store(q_name, q_type, type, to_ss, name);
+ }
+
+ result = true;
done:
SAFE_FREE(status);
DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
if (result)
- DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
+ DEBUGADD(10, (", name %s ip address is %s", name, addr));
- DEBUG(10, ("\n"));
+ DEBUG(10, ("\n"));
return result;
}
/*
- comparison function used by sort_ip_list
+ comparison function used by sort_addr_list
*/
-static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+static int addr_compare(const struct sockaddr_storage *ss1,
+ const struct sockaddr_storage *ss2)
{
int max_bits1=0, max_bits2=0;
int num_interfaces = iface_count();
- struct sockaddr_storage ss;
int i;
+ /* Sort IPv6 addresses first. */
+ if (ss1->ss_family != ss2->ss_family) {
+ if (ss2->ss_family == AF_INET) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ /* Here we know both addresses are of the same
+ * family. */
+
for (i=0;i<num_interfaces;i++) {
const struct sockaddr_storage *pss = iface_n_bcast(i);
- struct in_addr ip;
+ unsigned char *p_ss1 = NULL;
+ unsigned char *p_ss2 = NULL;
+ unsigned char *p_if = NULL;
+ size_t len = 0;
int bits1, bits2;
- if (pss->ss_family != AF_INET) {
+ if (pss->ss_family != ss1->ss_family) {
+ /* Ignore interfaces of the wrong type. */
continue;
}
- ip = ((const struct sockaddr_in *)pss)->sin_addr;
- bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
- bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
+ if (pss->ss_family == AF_INET) {
+ p_if = (unsigned char *)
+ &((const struct sockaddr_in *)pss)->sin_addr;
+ p_ss1 = (unsigned char *)
+ &((const struct sockaddr_in *)ss1)->sin_addr;
+ p_ss2 = (unsigned char *)
+ &((const struct sockaddr_in *)ss2)->sin_addr;
+ len = 4;
+ }
+#if defined(HAVE_IPV6)
+ if (pss->ss_family == AF_INET6) {
+ p_if = (unsigned char *)
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ p_ss1 = (unsigned char *)
+ &((const struct sockaddr_in6 *)ss1)->sin6_addr;
+ p_ss2 = (unsigned char *)
+ &((const struct sockaddr_in6 *)ss2)->sin6_addr;
+ len = 16;
+ }
+#endif
+ if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
+ continue;
+ }
+ bits1 = matching_len_bits(p_ss1, p_if, len);
+ bits2 = matching_len_bits(p_ss2, p_if, len);
max_bits1 = MAX(bits1, max_bits1);
max_bits2 = MAX(bits2, max_bits2);
- }
-
- /* bias towards directly reachable IPs */
- in_addr_to_sockaddr_storage(&ss, *ip1);
- if (iface_local(&ss)) {
- max_bits1 += 32;
- }
- in_addr_to_sockaddr_storage(&ss, *ip1);
- if (iface_local(&ss)) {
- max_bits2 += 32;
}
+ /* Bias towards directly reachable IPs */
+ if (iface_local(ss1)) {
+ if (ss1->ss_family == AF_INET) {
+ max_bits1 += 32;
+ } else {
+ max_bits1 += 128;
+ }
+ }
+ if (iface_local(ss2)) {
+ if (ss2->ss_family == AF_INET) {
+ max_bits2 += 32;
+ } else {
+ max_bits2 += 128;
+ }
+ }
return max_bits2 - max_bits1;
}
compare 2 ldap IPs by nearness to our interfaces - used in qsort
*******************************************************************/
-int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
+int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
{
int result;
-
- if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
+
+ if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
return result;
-
- if ( ip1->port > ip2->port )
+ }
+
+ if (ss1->port > ss2->port) {
return 1;
-
- if ( ip1->port < ip2->port )
+ }
+
+ if (ss1->port < ss2->port) {
return -1;
-
+ }
+
return 0;
}
/*
- sort an IP list so that names that are close to one of our interfaces
- are at the top. This prevents the problem where a WINS server returns an IP that
- is not reachable from our subnet as the first match
+ sort an IP list so that names that are close to one of our interfaces
+ are at the top. This prevents the problem where a WINS server returns an IP
+ that is not reachable from our subnet as the first match
*/
-static void sort_ip_list(struct in_addr *iplist, int count)
+static void sort_addr_list(struct sockaddr_storage *sslist, int count)
{
if (count <= 1) {
return;
}
- qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
+ qsort(sslist, count, sizeof(struct sockaddr_storage),
+ QSORT_CAST addr_compare);
}
-static void sort_ip_list2(struct ip_service *iplist, int count)
+static void sort_service_list(struct ip_service *servlist, int count)
{
if (count <= 1) {
return;
}
- qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
+ qsort(servlist, count, sizeof(struct ip_service),
+ QSORT_CAST ip_service_compare);
}
/**********************************************************************
- Remove any duplicate address/port pairs in the list
+ Remove any duplicate address/port pairs in the list
*********************************************************************/
-static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
+static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
{
int i, j;
-
- DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
-
+
+ DEBUG(10,("remove_duplicate_addrs2: "
+ "looking for duplicate address/port pairs\n"));
+
/* one loop to remove duplicates */
for ( i=0; i<count; i++ ) {
- if ( is_zero_ip_v4(iplist[i].ip) )
+ if ( is_zero_addr(&iplist[i].ss)) {
continue;
-
+ }
+
for ( j=i+1; j<count; j++ ) {
- if ( ip_service_equal(iplist[i], iplist[j]) )
- zero_ip_v4(&iplist[j].ip);
+ if (addr_equal(&iplist[i].ss, &iplist[j].ss) &&
+ iplist[i].port == iplist[j].port) {
+ zero_addr(&iplist[j].ss, AF_INET);
+ }
}
}
-
+
/* one loop to clean up any holes we left */
/* first ip should never be a zero_ip() */
for (i = 0; i<count; ) {
- if ( is_zero_ip_v4(iplist[i].ip) ) {
- if (i != count-1 )
- memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
+ if (is_zero_addr(&iplist[i].ss) ) {
+ if (i != count-1) {
+ memmove(&iplist[i], &iplist[i+1],
+ (count - i - 1)*sizeof(iplist[i]));
+ }
count--;
continue;
}
*timed_out is set if we failed by timing out
****************************************************************************/
-struct in_addr *name_query(int fd,const char *name,int name_type,
- bool bcast,bool recurse,
- struct in_addr to_ip, int *count, int *flags,
- bool *timed_out)
+struct sockaddr_storage *name_query(int fd,
+ const char *name,
+ int name_type,
+ bool bcast,
+ bool recurse,
+ const struct sockaddr_storage *to_ss,
+ int *count,
+ int *flags,
+ bool *timed_out)
{
- bool found=False;
+ bool found=false;
int i, retries = 3;
int retry_time = bcast?250:2000;
struct timeval tval;
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
- struct in_addr *ip_list = NULL;
+ struct sockaddr_storage *ss_list = NULL;
if (lp_disable_netbios()) {
- DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
+ DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
+ name, name_type));
+ return NULL;
+ }
+
+ if (to_ss->ss_family != AF_INET) {
return NULL;
}
if (timed_out) {
- *timed_out = False;
+ *timed_out = false;
}
-
+
memset((char *)&p,'\0',sizeof(p));
(*count) = 0;
(*flags) = 0;
-
+
nmb->header.name_trn_id = generate_trn_id();
nmb->header.opcode = 0;
- nmb->header.response = False;
+ nmb->header.response = false;
nmb->header.nm_flags.bcast = bcast;
- nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.recursion_available = false;
nmb->header.nm_flags.recursion_desired = recurse;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
+ nmb->header.nm_flags.trunc = false;
+ nmb->header.nm_flags.authoritative = false;
nmb->header.rcode = 0;
nmb->header.qdcount = 1;
nmb->header.ancount = 0;
nmb->header.nscount = 0;
nmb->header.arcount = 0;
-
+
make_nmb_name(&nmb->question.question_name,name,name_type);
-
+
nmb->question.question_type = 0x20;
nmb->question.question_class = 0x1;
-
- p.ip = to_ip;
+
+ p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
-
+
GetTimeOfDay(&tval);
-
- if (!send_packet(&p))
+
+ if (!send_packet(&p))
return NULL;
-
+
retries--;
-
+
while (1) {
struct timeval tval2;
-
+
GetTimeOfDay(&tval2);
if (TvalDiff(&tval,&tval2) > retry_time) {
if (!retries)
GetTimeOfDay(&tval);
retries--;
}
-
- if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
+
+ if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
-
+
/* If we get a Negative Name Query Response from a WINS
* server, we should report it and give up.
*/
- if( 0 == nmb2->header.opcode /* A query response */
+ if( 0 == nmb2->header.opcode /* A query response */
&& !(bcast) /* from a WINS server */
- && nmb2->header.rcode /* Error returned */
+ && nmb2->header.rcode /* Error returned */
) {
-
+
if( DEBUGLVL( 3 ) ) {
/* Only executed if DEBUGLEVEL >= 3 */
- dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
+ dbgtext( "Negative name query "
+ "response, rcode 0x%02x: ",
+ nmb2->header.rcode );
switch( nmb2->header.rcode ) {
case 0x01:
- dbgtext( "Request was invalidly formatted.\n" );
+ dbgtext( "Request "
+ "was invalidly formatted.\n" );
break;
case 0x02:
- dbgtext( "Problem with NBNS, cannot process name.\n");
+ dbgtext( "Problem with NBNS, "
+ "cannot process name.\n");
break;
case 0x03:
- dbgtext( "The name requested does not exist.\n" );
+ dbgtext( "The name requested "
+ "does not exist.\n" );
break;
case 0x04:
- dbgtext( "Unsupported request error.\n" );
+ dbgtext( "Unsupported request "
+ "error.\n" );
break;
case 0x05:
- dbgtext( "Query refused error.\n" );
+ dbgtext( "Query refused "
+ "error.\n" );
break;
default:
- dbgtext( "Unrecognized error code.\n" );
+ dbgtext( "Unrecognized error "
+ "code.\n" );
break;
}
}
free_packet(p2);
return( NULL );
}
-
+
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
nmb2->header.rcode ||
!nmb2->header.ancount) {
- /*
+ /*
* XXXX what do we do with this? Could be a
* redirect, but we'll discard it for the
* moment.
free_packet(p2);
continue;
}
-
- ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
- (*count) + nmb2->answers->rdlength/6 );
-
- if (!ip_list) {
+
+ ss_list = SMB_REALLOC_ARRAY(ss_list,
+ struct sockaddr_storage,
+ (*count) +
+ nmb2->answers->rdlength/6);
+
+ if (!ss_list) {
DEBUG(0,("name_query: Realloc failed.\n"));
free_packet(p2);
- return( NULL );
+ return NULL;
}
-
- DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
+
+ DEBUG(2,("Got a positive name query response "
+ "from %s ( ",
+ inet_ntoa(p2->ip)));
+
for (i=0;i<nmb2->answers->rdlength/6;i++) {
- putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
- DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
+ struct in_addr ip;
+ putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
+ in_addr_to_sockaddr_storage(&ss_list[(*count)],
+ ip);
+ DEBUGADD(2,("%s ",inet_ntoa(ip)));
(*count)++;
}
DEBUGADD(2,(")\n"));
-
- found=True;
+
+ found=true;
retries=0;
/* We add the flags back ... */
if (nmb2->header.response)
}
/* only set timed_out if we didn't fund what we where looking for*/
-
+
if ( !found && timed_out ) {
- *timed_out = True;
+ *timed_out = true;
}
/* sort the ip list so we choose close servers first if possible */
- sort_ip_list(ip_list, *count);
+ sort_addr_list(ss_list, *count);
- return ip_list;
+ return ss_list;
}
/********************************************************
{
XFILE *fp = x_fopen(fname,O_RDONLY, 0);
if (!fp) {
- DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
- fname, strerror(errno)));
+ DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
+ "Error was %s\n",
+ fname, strerror(errno)));
return NULL;
}
return fp;
Parse the next line in the lmhosts file.
*********************************************************/
-bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
+bool getlmhostsent(XFILE *fp, pstring name, int *name_type,
+ struct sockaddr_storage *pss)
{
pstring line;
continue;
if (count > 0 && count < 2) {
- DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
+ DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
+ line));
continue;
}
if (count >= 4) {
- DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
+ DEBUG(0,("getlmhostsent: too many columns "
+ "in lmhosts file (obsolete syntax)\n"));
continue;
}
- DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
+ DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
+ ip, name, flags));
if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
- DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
+ DEBUG(0,("getlmhostsent: group flag "
+ "in lmhosts ignored (obsolete)\n"));
continue;
}
- *ipaddr = *interpret_addr2(ip);
+ if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
+ DEBUG(0,("getlmhostsent: invalid address "
+ "%s.\n", ip));
+ }
- /* Extra feature. If the name ends in '#XX', where XX is a hex number,
- then only add that name type. */
+ /* Extra feature. If the name ends in '#XX',
+ * where XX is a hex number, then only add that name type. */
if((ptr1 = strchr_m(name, '#')) != NULL) {
char *endptr;
ptr1++;
*name_type = (int)strtol(ptr1, &endptr, 16);
if(!*ptr1 || (endptr == ptr1)) {
- DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
+ DEBUG(0,("getlmhostsent: invalid name "
+ "%s containing '#'.\n", name));
continue;
}
*(--ptr1) = '\0'; /* Truncate at the '#' */
}
- return True;
+ return true;
}
- return False;
+ return false;
}
/********************************************************
}
/********************************************************
- convert an array if struct in_addrs to struct ip_service
- return False on failure. Port is set to PORT_NONE;
+ convert an array if struct sockaddr_storage to struct ip_service
+ return false on failure. Port is set to PORT_NONE;
*********************************************************/
-static bool convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
+static bool convert_ss2service(struct ip_service **return_iplist,
+ const struct sockaddr_storage *ss_list,
+ int count)
{
int i;
- if ( count==0 || !ip_list )
+ if ( count==0 || !ss_list )
return False;
-
+
/* copy the ip address; port will be PORT_NONE */
- if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
- DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
+ if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
+ NULL) {
+ DEBUG(0,("convert_ip2service: malloc failed "
+ "for %d enetries!\n", count ));
return False;
}
-
+
for ( i=0; i<count; i++ ) {
- (*return_iplist)[i].ip = ip_list[i];
+ (*return_iplist)[i].ss = ss_list[i];
(*return_iplist)[i].port = PORT_NONE;
}
- return True;
-}
+ return true;
+}
+
/********************************************************
Resolve via "bcast" method.
*********************************************************/
-NTSTATUS name_resolve_bcast(const char *name, int name_type,
- struct ip_service **return_iplist,
- int *return_count)
+NTSTATUS name_resolve_bcast(const char *name,
+ int name_type,
+ struct ip_service **return_iplist,
+ int *return_count)
{
int sock, i;
int num_interfaces = iface_count();
- struct in_addr *ip_list;
+ struct sockaddr_storage *ss_list;
+ struct sockaddr_storage ss;
NTSTATUS status;
if (lp_disable_netbios()) {
- DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
+ DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
+ name, name_type));
return NT_STATUS_INVALID_PARAMETER;
}
*return_iplist = NULL;
*return_count = 0;
-
+
/*
* "bcast" means do a broadcast lookup on all the local interfaces.
*/
- DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
+ "for name %s<0x%x>\n", name, name_type));
- sock = open_socket_in( SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()), True );
+ if (!interpret_string_addr(&ss, lp_socket_address(),
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ zero_addr(&ss, AF_INET);
+ }
- if (sock == -1) return NT_STATUS_UNSUCCESSFUL;
+ sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
+ if (sock == -1) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
set_socket_options(sock,"SO_BROADCAST");
/*
* the first successful match.
*/
for( i = num_interfaces-1; i >= 0; i--) {
- struct in_addr sendto_ip;
- const struct sockaddr_storage *ss = iface_n_bcast(i);
+ const struct sockaddr_storage *pss = iface_n_bcast(i);
int flags;
/* Done this way to fix compiler error on IRIX 5.x */
- if (!ss || ss->ss_family != AF_INET) {
+ if (!pss) {
continue;
}
- sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr;
- ip_list = name_query(sock, name, name_type, True,
- True, sendto_ip, return_count, &flags, NULL);
- if( ip_list )
+ ss_list = name_query(sock, name, name_type, true,
+ true, pss, return_count, &flags, NULL);
+ if (ss_list) {
goto success;
+ }
}
-
+
/* failed - no response */
-
+
close(sock);
return NT_STATUS_UNSUCCESSFUL;
-
+
success:
+
status = NT_STATUS_OK;
- if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
+ if (!convert_ss2service(return_iplist, ss_list, *return_count) )
status = NT_STATUS_INVALID_PARAMETER;
-
- SAFE_FREE( ip_list );
+
+ SAFE_FREE(ss_list);
close(sock);
return status;
}
Resolve via "wins" method.
*********************************************************/
-NTSTATUS resolve_wins(const char *name, int name_type,
- struct ip_service **return_iplist,
- int *return_count)
+NTSTATUS resolve_wins(const char *name,
+ int name_type,
+ struct ip_service **return_iplist,
+ int *return_count)
{
int sock, t, i;
char **wins_tags;
- struct in_addr src_ip, *ip_list = NULL;
+ struct sockaddr_storage src_ss, *ss_list = NULL;
+ struct in_addr src_ip;
NTSTATUS status;
if (lp_disable_netbios()) {
- DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
+ DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
+ name, name_type));
return NT_STATUS_INVALID_PARAMETER;
}
*return_iplist = NULL;
*return_count = 0;
-
- DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
+
+ DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
+ name, name_type));
if (wins_srv_count() < 1) {
- DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
+ DEBUG(3,("resolve_wins: WINS server resolution selected "
+ "and no WINS servers listed.\n"));
return NT_STATUS_INVALID_PARAMETER;
}
}
/* the address we will be sending from */
- src_ip = *interpret_addr2(lp_socket_address());
+ if (!interpret_string_addr(&src_ss, lp_socket_address(),
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ zero_addr(&src_ss, AF_INET);
+ }
+
+ if (src_ss.ss_family != AF_INET) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &src_ss);
+ DEBUG(3,("resolve_wins: cannot receive WINS replies "
+ "on IPv6 address %s\n",
+ addr));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
/* in the worst case we will try every wins server with every
tag! */
for (t=0; wins_tags && wins_tags[t]; t++) {
int srv_count = wins_srv_count_tag(wins_tags[t]);
for (i=0; i<srv_count; i++) {
+ struct sockaddr_storage wins_ss;
struct in_addr wins_ip;
int flags;
bool timed_out;
continue;
}
- DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
+ DEBUG(3,("resolve_wins: using WINS server %s "
+ "and tag '%s'\n",
+ inet_ntoa(wins_ip), wins_tags[t]));
- sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
+ sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
if (sock == -1) {
continue;
}
- ip_list = name_query(sock,name,name_type, False,
- True, wins_ip, return_count, &flags,
- &timed_out);
-
+ in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
+ ss_list = name_query(sock,
+ name,
+ name_type,
+ false,
+ true,
+ &wins_ss,
+ return_count,
+ &flags,
+ &timed_out);
+
/* exit loop if we got a list of addresses */
-
- if ( ip_list )
+
+ if (ss_list)
goto success;
-
+
close(sock);
if (timed_out) {
- /* Timed out wating for WINS server to respond. Mark it dead. */
+ /* Timed out wating for WINS server to respond.
+ * Mark it dead. */
wins_srv_died(wins_ip, src_ip);
} else {
/* The name definately isn't in this
- group of WINS servers. goto the next group */
+ group of WINS servers.
+ goto the next group */
break;
}
}
return NT_STATUS_NO_LOGON_SERVERS;
success:
+
status = NT_STATUS_OK;
- if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
+ if (!convert_ss2service(return_iplist, ss_list, *return_count))
status = NT_STATUS_INVALID_PARAMETER;
-
- SAFE_FREE( ip_list );
+
+ SAFE_FREE(ss_list);
wins_srv_tags_free(wins_tags);
close(sock);
-
+
return status;
}
/*
* "lmhosts" means parse the local lmhosts file.
*/
-
+
XFILE *fp;
pstring lmhost_name;
int name_type2;
- struct in_addr return_ip;
+ struct sockaddr_storage return_ss;
NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
*return_iplist = NULL;
*return_count = 0;
- DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("resolve_lmhosts: "
+ "Attempting lmhosts lookup for name %s<0x%x>\n",
+ name, name_type));
fp = startlmhosts(dyn_LMHOSTSFILE);
if ( fp == NULL )
return NT_STATUS_NO_SUCH_FILE;
- while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip))
- {
+ while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ss)) {
if (!strequal(name, lmhost_name))
continue;
if ((name_type2 != -1) && (name_type != name_type2))
continue;
- *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
+ *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
+ struct ip_service,
(*return_count)+1);
if ((*return_iplist) == NULL) {
return NT_STATUS_NO_MEMORY;
}
- (*return_iplist)[*return_count].ip = return_ip;
+ (*return_iplist)[*return_count].ss = return_ss;
(*return_iplist)[*return_count].port = PORT_NONE;
*return_count += 1;
}
endlmhosts(fp);
-
return status;
}
int i = 0;
if ( name_type != 0x20 && name_type != 0x0) {
- DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
+ DEBUG(5, ("resolve_hosts: not appropriate "
+ "for name type <0x%x>\n",
+ name_type));
return NT_STATUS_INVALID_PARAMETER;
}
*return_iplist = NULL;
*return_count = 0;
- DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
+ name, name_type));
ZERO_STRUCT(hints);
/* By default make sure it supports TCP. */
}
for (res = ailist; res; res = res->ai_next) {
- struct in_addr return_ip;
+ struct sockaddr_storage ss;
- /* IPv4 only for now until I convert ip_service */
- if (res->ai_family != AF_INET) {
- continue;
- }
- if (!res->ai_addr) {
+ if (!res->ai_addr || res->ai_addrlen == 0) {
continue;
}
- putip((char *)&return_ip,
- &((struct sockaddr_in *)res->ai_addr)->sin_addr);
+ memset(&ss, '\0', sizeof(ss));
+ memcpy(&ss, res->ai_addr, res->ai_addrlen);
*return_count += 1;
freeaddrinfo(ailist);
return NT_STATUS_NO_MEMORY;
}
- (*return_iplist)[i].ip = return_ip;
+ (*return_iplist)[i].ss = ss;
(*return_iplist)[i].port = PORT_NONE;
-
i++;
}
if (ailist) {
Resolve via "ADS" method.
*********************************************************/
-NTSTATUS resolve_ads(const char *name, int name_type,
- const char *sitename,
- struct ip_service **return_iplist,
- int *return_count)
+NTSTATUS resolve_ads(const char *name,
+ int name_type,
+ const char *sitename,
+ struct ip_service **return_iplist,
+ int *return_count)
{
int i, j;
NTSTATUS status;
return NT_STATUS_NO_MEMORY;
}
+ /* The DNS code needs fixing to find IPv6 addresses... JRA. */
+
switch (name_type) {
case 0x1b:
DEBUG(5,("resolve_ads: Attempting to resolve "
for (i=0;i<numdcs;i++) {
numaddrs += MAX(dcs[i].num_ips,1);
}
-
- if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
- DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
+
+ if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
+ NULL ) {
+ DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
+ numaddrs ));
talloc_destroy(ctx);
return NT_STATUS_NO_MEMORY;
}
-
+
/* now unroll the list of IP addresses */
*return_count = 0;
i = 0;
j = 0;
while ( i < numdcs && (*return_count<numaddrs) ) {
+ struct in_addr ip;
struct ip_service *r = &(*return_iplist)[*return_count];
r->port = dcs[i].port;
-
+
/* If we don't have an IP list for a name, lookup it up */
-
- if ( !dcs[i].ips ) {
- r->ip = *interpret_addr2(dcs[i].hostname);
+
+ if (!dcs[i].ips) {
+ ip = *interpret_addr2(dcs[i].hostname);
i++;
j = 0;
} else {
/* use the IP addresses from the SRV sresponse */
-
+
if ( j >= dcs[i].num_ips ) {
i++;
j = 0;
continue;
}
-
- r->ip = dcs[i].ips[j];
+
+ ip = dcs[i].ips[j];
j++;
}
-
- /* make sure it is a valid IP. I considered checking the negative
- connection cache, but this is the wrong place for it. Maybe only
- as a hac. After think about it, if all of the IP addresses retuend
- from DNS are dead, what hope does a netbios name lookup have?
- The standard reason for falling back to netbios lookups is that
- our DNS server doesn't know anything about the DC's -- jerry */
-
- if ( ! is_zero_ip_v4(r->ip) )
+
+ in_addr_to_sockaddr_storage(&r->ss, ip);
+
+ /* make sure it is a valid IP. I considered checking the
+ * negative connection cache, but this is the wrong place
+ * for it. Maybe only as a hack. After think about it, if
+ * all of the IP addresses returned from DNS are dead, what
+ * hope does a netbios name lookup have ? The standard reason
+ * for falling back to netbios lookups is that our DNS server
+ * doesn't know anything about the DC's -- jerry */
+
+ if (!is_zero_addr(&r->ss)) {
(*return_count)++;
+ }
}
-
+
talloc_destroy(ctx);
return NT_STATUS_OK;
}
Use this function if the string is either an IP address, DNS
or host name or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
-
+
Added support for ip addr/port to support ADS ldap servers.
- the only place we currently care about the port is in the
+ the only place we currently care about the port is in the
resolve_hosts() when looking up DC's via SRV RR entries in DNS
**********************************************************************/
-NTSTATUS internal_resolve_name(const char *name, int name_type,
- const char *sitename,
- struct ip_service **return_iplist,
- int *return_count, const char *resolve_order)
+NTSTATUS internal_resolve_name(const char *name,
+ int name_type,
+ const char *sitename,
+ struct ip_service **return_iplist,
+ int *return_count,
+ const char *resolve_order)
{
pstring name_resolve_list;
fstring tok;
const char *ptr;
- bool allones = (strcmp(name,"255.255.255.255") == 0);
- bool allzeros = (strcmp(name,"0.0.0.0") == 0);
- bool is_address = is_ipaddress_v4(name);
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
int i;
DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
name, name_type, sitename ? sitename : NULL));
- if (allzeros || allones || is_address) {
-
- if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
+ if (is_ipaddress(name)) {
+ if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
+ NULL) {
DEBUG(0,("internal_resolve_name: malloc fail !\n"));
return NT_STATUS_NO_MEMORY;
}
-
- if(is_address) {
- /* ignore the port here */
- (*return_iplist)->port = PORT_NONE;
-
- /* if it's in the form of an IP address then get the lib to interpret it */
- if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
- DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
- SAFE_FREE(*return_iplist);
- return NT_STATUS_INVALID_PARAMETER;
- }
- } else {
- (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
+
+ /* ignore the port here */
+ (*return_iplist)->port = PORT_NONE;
+
+ /* if it's in the form of an IP address then get the lib to interpret it */
+ if (!interpret_string_addr(&(*return_iplist)->ss,
+ name, AI_NUMERICHOST)) {
+ DEBUG(1,("internal_resolve_name: interpret_string_addr "
+ "failed on %s\n",
+ name));
+ SAFE_FREE(*return_iplist);
+ return NT_STATUS_INVALID_PARAMETER;
}
*return_count = 1;
return NT_STATUS_OK;
}
-
+
/* Check name cache */
if (namecache_fetch(name, name_type, return_iplist, return_count)) {
/* set the name resolution order */
- if ( strcmp( resolve_order, "NULL") == 0 ) {
+ if (strcmp( resolve_order, "NULL") == 0) {
DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
return NT_STATUS_INVALID_PARAMETER;
}
-
- if ( !resolve_order ) {
+
+ if (!resolve_order) {
pstrcpy(name_resolve_list, lp_name_resolve_order());
} else {
pstrcpy(name_resolve_list, resolve_order);
}
- if ( !name_resolve_list[0] ) {
+ if (!name_resolve_list[0]) {
ptr = "host";
} else {
ptr = name_resolve_list;
}
/* iterate through the name resolution backends */
-
+
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
status = resolve_hosts(name, name_type, return_iplist,
goto done;
}
} else if(strequal( tok, "kdc")) {
- /* deal with KDC_NAME_TYPE names here. This will result in a
- SRV record lookup */
+ /* deal with KDC_NAME_TYPE names here.
+ * This will result in a SRV record lookup */
status = resolve_ads(name, KDC_NAME_TYPE, sitename,
return_iplist, return_count);
if (NT_STATUS_IS_OK(status)) {
- /* Ensure we don't namecache this with the KDC port. */
+ /* Ensure we don't namecache
+ * this with the KDC port. */
name_type = KDC_NAME_TYPE;
goto done;
}
} else if(strequal( tok, "ads")) {
- /* deal with 0x1c and 0x1b names here. This will result in a
- SRV record lookup */
+ /* deal with 0x1c and 0x1b names here.
+ * This will result in a SRV record lookup */
status = resolve_ads(name, name_type, sitename,
return_iplist, return_count);
if (NT_STATUS_IS_OK(status)) {
the iplist when the PDC is down will cause two sets of timeouts. */
if ( *return_count ) {
- *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
+ *return_count = remove_duplicate_addrs2(*return_iplist,
+ *return_count );
}
-
+
/* Save in name cache */
if ( DEBUGLEVEL >= 100 ) {
- for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
- DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
- name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &(*return_iplist)[i].ss);
+ DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
+ name,
+ name_type,
+ addr,
+ (*return_iplist)[i].port));
+ }
}
-
+
namecache_store(name, name_type, *return_count, *return_iplist);
/* Display some debugging info */
if ( DEBUGLEVEL >= 10 ) {
- DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
+ DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
+ *return_count));
for (i = 0; i < *return_count; i++) {
- DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &(*return_iplist)[i].ss);
+ DEBUGADD(10, ("%s:%d ",
+ addr,
+ (*return_iplist)[i].port));
}
DEBUG(10, ("\n"));
}
-
+
return status;
}
smb.conf to determine the order of name resolution.
*********************************************************/
-bool resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+bool resolve_name(const char *name,
+ struct sockaddr_storage *return_ss,
+ int name_type)
{
- struct ip_service *ip_list = NULL;
- char *sitename = sitename_fetch(lp_realm()); /* wild guess */
+ struct ip_service *ss_list = NULL;
+ char *sitename = NULL;
int count = 0;
- if (is_ipaddress_v4(name)) {
- *return_ip = *interpret_addr2(name);
- SAFE_FREE(sitename);
- return True;
+ if (is_ipaddress(name)) {
+ return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
}
+ sitename = sitename_fetch(lp_realm()); /* wild guess */
+
if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
- &ip_list, &count,
+ &ss_list, &count,
lp_name_resolve_order()))) {
int i;
-
+
/* only return valid addresses for TCP connections */
for (i=0; i<count; i++) {
- char *ip_str = inet_ntoa(ip_list[i].ip);
- if (ip_str &&
- strcmp(ip_str, "255.255.255.255") != 0 &&
- strcmp(ip_str, "0.0.0.0") != 0)
- {
- *return_ip = ip_list[i].ip;
- SAFE_FREE(ip_list);
+ if (!is_zero_addr(&ss_list[i].ss) &&
+ !is_broadcast_addr(&ss_list[i].ss)) {
+ *return_ss = ss_list[i].ss;
+ SAFE_FREE(ss_list);
SAFE_FREE(sitename);
return True;
}
}
}
-
- SAFE_FREE(ip_list);
+
+ SAFE_FREE(ss_list);
SAFE_FREE(sitename);
return False;
}
Find the IP address of the master browser or DMB for a workgroup.
*********************************************************/
-bool find_master_ip(const char *group, struct in_addr *master_ip)
+bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
{
struct ip_service *ip_list = NULL;
int count = 0;
if (lp_disable_netbios()) {
DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
- return False;
+ return false;
}
status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
lp_name_resolve_order());
if (NT_STATUS_IS_OK(status)) {
- *master_ip = ip_list[0].ip;
+ *master_ss = ip_list[0].ss;
SAFE_FREE(ip_list);
- return True;
+ return true;
}
status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
lp_name_resolve_order());
if (NT_STATUS_IS_OK(status)) {
- *master_ip = ip_list[0].ip;
+ *master_ss = ip_list[0].ss;
SAFE_FREE(ip_list);
- return True;
+ return true;
}
SAFE_FREE(ip_list);
- return False;
+ return false;
}
/********************************************************
for a domain.
*********************************************************/
-bool get_pdc_ip(const char *domain, struct in_addr *ip)
+bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
{
struct ip_service *ip_list = NULL;
int count = 0;
&count,
lp_name_resolve_order());
if (!NT_STATUS_IS_OK(status)) {
- return False;
+ return false;
}
}
multi-homed PDC and not a mess up */
if ( count > 1 ) {
- DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
- sort_ip_list2( ip_list, count );
+ DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
+ sort_service_list(ip_list, count);
}
- *ip = ip_list[0].ip;
-
+ *pss = ip_list[0].ss;
SAFE_FREE(ip_list);
-
- return True;
+ return true;
}
/* Private enum type for lookups. */
a domain.
*********************************************************/
-static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list,
- int *count, enum dc_lookup_type lookup_type, bool *ordered)
+static NTSTATUS get_dc_list(const char *domain,
+ const char *sitename,
+ struct ip_service **ip_list,
+ int *count,
+ enum dc_lookup_type lookup_type,
+ bool *ordered)
{
fstring resolve_order;
char *saf_servername;
are disabled and ads_only is True, then set the string to
NULL. */
- fstrcpy( resolve_order, lp_name_resolve_order() );
- strlower_m( resolve_order );
- if ( lookup_type == DC_ADS_ONLY) {
- if ( strstr( resolve_order, "host" ) ) {
- fstrcpy( resolve_order, "ads" );
+ fstrcpy(resolve_order, lp_name_resolve_order());
+ strlower_m(resolve_order);
+ if (lookup_type == DC_ADS_ONLY) {
+ if (strstr( resolve_order, "host")) {
+ fstrcpy( resolve_order, "ads");
/* DNS SRV lookups used by the ads resolver
are already sorted by priority and weight */
- *ordered = True;
+ *ordered = true;
} else {
- fstrcpy( resolve_order, "NULL" );
+ fstrcpy(resolve_order, "NULL");
}
} else if (lookup_type == DC_KDC_ONLY) {
/* DNS SRV lookups used by the ads/kdc resolver
are already sorted by priority and weight */
- *ordered = True;
- fstrcpy( resolve_order, "kdc" );
+ *ordered = true;
+ fstrcpy(resolve_order, "kdc");
}
- /* fetch the server we have affinity for. Add the
+ /* fetch the server we have affinity for. Add the
'password server' list to a search for our domain controllers */
-
+
saf_servername = saf_fetch( domain);
-
- if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
- pstr_sprintf( pserver, "%s, %s",
+
+ if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
+ pstr_sprintf(pserver, "%s, %s",
saf_servername ? saf_servername : "",
- lp_passwordserver() );
+ lp_passwordserver());
} else {
- pstr_sprintf( pserver, "%s, *",
- saf_servername ? saf_servername : "" );
+ pstr_sprintf(pserver, "%s, *",
+ saf_servername ? saf_servername : "");
}
SAFE_FREE( saf_servername );
/* if we are starting from scratch, just lookup DOMAIN<0x1c> */
- if ( !*pserver ) {
+ if (!*pserver ) {
DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
return internal_resolve_name(domain, 0x1C, sitename, ip_list,
count, resolve_order);
}
DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
-
+
/*
* if '*' appears in the "password server" list then add
* an auto lookup to the list of manually configured
- * DC's. If any DC is listed by name, then the list should be
- * considered to be ordered
+ * DC's. If any DC is listed by name, then the list should be
+ * considered to be ordered
*/
p = pserver;
if (NT_STATUS_IS_OK(status)) {
num_addresses += auto_count;
}
- done_auto_lookup = True;
- DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
+ done_auto_lookup = true;
+ DEBUG(8,("Adding %d DC's from auto lookup\n",
+ auto_count));
} else {
num_addresses++;
}
/* if we have no addresses and haven't done the auto lookup, then
just return the list of DC's. Or maybe we just failed. */
-
- if ( (num_addresses == 0) ) {
- if ( done_auto_lookup ) {
- DEBUG(4,("get_dc_list: no servers found\n"));
+
+ if ((num_addresses == 0)) {
+ if (done_auto_lookup) {
+ DEBUG(4,("get_dc_list: no servers found\n"));
SAFE_FREE(auto_ip_list);
return NT_STATUS_NO_LOGON_SERVERS;
}
count, resolve_order);
}
- if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
+ if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
+ num_addresses)) == NULL) {
DEBUG(3,("get_dc_list: malloc fail !\n"));
SAFE_FREE(auto_ip_list);
return NT_STATUS_NO_MEMORY;
local_count = 0;
/* fill in the return list now with real IP's */
-
- while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
- struct in_addr name_ip;
-
+
+ while ((local_count<num_addresses) &&
+ next_token(&p,name,LIST_SEP,sizeof(name))) {
+ struct sockaddr_storage name_ss;
+
/* copy any addersses from the auto lookup */
-
- if ( strequal(name, "*") ) {
- for ( j=0; j<auto_count; j++ ) {
- /* Check for and don't copy any known bad DC IP's. */
- if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
- inet_ntoa(auto_ip_list[j].ip)))) {
- DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
- inet_ntoa(auto_ip_list[j].ip) ));
+
+ if (strequal(name, "*")) {
+ for (j=0; j<auto_count; j++) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr,
+ sizeof(addr),
+ &auto_ip_list[j].ss);
+ /* Check for and don't copy any
+ * known bad DC IP's. */
+ if(!NT_STATUS_IS_OK(check_negative_conn_cache(
+ domain,
+ addr))) {
+ DEBUG(5,("get_dc_list: "
+ "negative entry %s removed "
+ "from DC list\n",
+ addr));
continue;
}
- return_iplist[local_count].ip = auto_ip_list[j].ip;
- return_iplist[local_count].port = auto_ip_list[j].port;
+ return_iplist[local_count].ss =
+ auto_ip_list[j].ss;
+ return_iplist[local_count].port =
+ auto_ip_list[j].port;
local_count++;
}
continue;
}
-
-
- /* added support for address:port syntax for ads (not that I think
- anyone will ever run the LDAP server in an AD domain on something
- other than port 389 */
-
+
+ /* added support for address:port syntax for ads
+ * (not that I think anyone will ever run the LDAP
+ * server in an AD domain on something other than
+ * port 389 */
+
port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
- if ( (port_str=strchr(name, ':')) != NULL ) {
+ if ((port_str=strchr(name, ':')) != NULL) {
*port_str = '\0';
port_str++;
- port = atoi( port_str );
+ port = atoi(port_str);
}
- /* explicit lookup; resolve_name() will handle names & IP addresses */
- if ( resolve_name( name, &name_ip, 0x20 ) ) {
+ /* explicit lookup; resolve_name() will
+ * handle names & IP addresses */
+ if (resolve_name( name, &name_ss, 0x20 )) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr,
+ sizeof(addr),
+ &name_ss);
/* Check for and don't copy any known bad DC IP's. */
- if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
- DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
+ if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
+ addr)) ) {
+ DEBUG(5,("get_dc_list: negative entry %s "
+ "removed from DC list\n",
+ name ));
continue;
}
- return_iplist[local_count].ip = name_ip;
+ return_iplist[local_count].ss = name_ss;
return_iplist[local_count].port = port;
local_count++;
- *ordered = True;
+ *ordered = true;
}
}
-
+
SAFE_FREE(auto_ip_list);
- /* need to remove duplicates in the list if we have any
+ /* need to remove duplicates in the list if we have any
explicit password servers */
-
- if ( local_count ) {
- local_count = remove_duplicate_addrs2( return_iplist, local_count );
+
+ if (local_count) {
+ local_count = remove_duplicate_addrs2(return_iplist,
+ local_count );
}
-
+
if ( DEBUGLEVEL >= 4 ) {
- DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
- *ordered ? "":"un"));
+ DEBUG(4,("get_dc_list: returning %d ip addresses "
+ "in an %sordered list\n",
+ local_count,
+ *ordered ? "":"un"));
DEBUG(4,("get_dc_list: "));
- for ( i=0; i<local_count; i++ )
- DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
+ for ( i=0; i<local_count; i++ ) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr,
+ sizeof(addr),
+ &return_iplist[i].ss);
+ DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
+ }
DEBUGADD(4,("\n"));
}
-
+
*ip_list = return_iplist;
*count = local_count;
Small wrapper function to get the DC list and sort it if neccessary.
*********************************************************************/
-NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, bool ads_only )
+NTSTATUS get_sorted_dc_list( const char *domain,
+ const char *sitename,
+ struct ip_service **ip_list,
+ int *count,
+ bool ads_only )
{
bool ordered;
NTSTATUS status;
enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
- DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
- "using [%s]\n",
+ DEBUG(8,("get_sorted_dc_list: attempting lookup "
+ "for name %s (sitename %s) using [%s]\n",
domain,
sitename ? sitename : "NULL",
(ads_only ? "ads" : lp_name_resolve_order())));
-
+
if (ads_only) {
lookup_type = DC_ADS_ONLY;
}
- status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
+ status = get_dc_list(domain, sitename, ip_list,
+ count, lookup_type, &ordered);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ return status;
}
-
+
/* only sort if we don't already have an ordered list */
- if ( !ordered ) {
- sort_ip_list2( *ip_list, *count );
+ if (!ordered) {
+ sort_service_list(*ip_list, *count);
}
-
+
return NT_STATUS_OK;
}
Get the KDC list - re-use all the logic in get_dc_list.
*********************************************************************/
-NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
+NTSTATUS get_kdc_list( const char *realm,
+ const char *sitename,
+ struct ip_service **ip_list,
+ int *count)
{
bool ordered;
NTSTATUS status;
*count = 0;
*ip_list = NULL;
- status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
+ status = get_dc_list(realm, sitename, ip_list,
+ count, DC_KDC_ONLY, &ordered);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ return status;
}
/* only sort if we don't already have an ordered list */
if ( !ordered ) {
- sort_ip_list2( *ip_list, *count );
+ sort_service_list(*ip_list, *count);
}
return NT_STATUS_OK;
static bool ads_dc_name(const char *domain,
const char *realm,
- struct in_addr *dc_ip,
+ struct sockaddr_storage *dc_ss,
fstring srv_name)
{
ADS_STRUCT *ads;
char *sitename;
int i;
+ char addr[INET6_ADDRSTRLEN];
if (!realm && strequal(domain, lp_workgroup())) {
realm = lp_realm();
create_local_private_krb5_conf_for_domain(realm,
domain,
sitename,
- ads->ldap.ip);
+ &ads->ldap.ss);
} else {
create_local_private_krb5_conf_for_domain(realm,
domain,
NULL,
- ads->ldap.ip);
+ &ads->ldap.ss);
}
}
#endif
fstrcpy(srv_name, ads->config.ldap_server_name);
strupper_m(srv_name);
#ifdef HAVE_ADS
- *dc_ip = ads->ldap.ip;
+ *dc_ss = ads->ldap.ss;
#else
- ZERO_STRUCT(*dc_ip);
+ zero_addr(dc_ss,AF_INET);
#endif
ads_destroy(&ads);
-
+
+ print_sockaddr(addr, sizeof(addr), dc_ss);
DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
- srv_name, inet_ntoa(*dc_ip)));
-
+ srv_name, addr));
+
return True;
}
/****************************************************************************
- Utility function to return the name of a DC. The name is guaranteed to be
- valid since we have already done a name_status_find on it
+ Utility function to return the name of a DC. The name is guaranteed to be
+ valid since we have already done a name_status_find on it
***************************************************************************/
-static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+static bool rpc_dc_name(const char *domain,
+ fstring srv_name,
+ struct sockaddr_storage *ss_out)
{
struct ip_service *ip_list = NULL;
- struct in_addr dc_ip, exclude_ip;
+ struct sockaddr_storage dc_ss;
int count, i;
NTSTATUS result;
-
- zero_ip_v4(&exclude_ip);
+ char addr[INET6_ADDRSTRLEN];
/* get a list of all domain controllers */
-
+
if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count,
False))) {
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
/* Remove the entry we've already failed with (should be the PDC). */
for (i = 0; i < count; i++) {
- if (is_zero_ip_v4(ip_list[i].ip))
+ if (is_zero_addr(&ip_list[i].ss))
continue;
- if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
+ if (name_status_find(domain, 0x1c, 0x20, &ip_list[i].ss, srv_name)) {
result = check_negative_conn_cache( domain, srv_name );
if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i].ip;
+ dc_ss = ip_list[i].ss;
goto done;
}
}
}
-
SAFE_FREE(ip_list);
/* No-one to talk to )-: */
return False; /* Boo-hoo */
-
+
done:
/* We have the netbios name and IP address of a domain controller.
Ideally we should sent a SAMLOGON request to determine whether
the DC is alive and kicking. If we can catch a dead DC before
performing a cli_connect() we can avoid a 30-second timeout. */
+ print_sockaddr(addr, sizeof(addr), &dc_ss);
DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
- inet_ntoa(dc_ip), domain));
-
- *ip_out = dc_ip;
+ addr, domain));
+ *ss_out = dc_ss;
SAFE_FREE(ip_list);
return True;
wrapper around ads and rpc methods of finds DC's
**********************************************************************/
-bool get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out)
+bool get_dc_name(const char *domain,
+ const char *realm,
+ fstring srv_name,
+ struct sockaddr_storage *ss_out)
{
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
bool ret;
bool our_domain = False;
- zero_ip_v4(&dc_ip);
+ zero_addr(&dc_ss, AF_INET);
ret = False;
-
+
if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) )
our_domain = True;
-
- /* always try to obey what the admin specified in smb.conf
+
+ /* always try to obey what the admin specified in smb.conf
(for the local domain) */
-
+
if ( (our_domain && lp_security()==SEC_ADS) || realm ) {
- ret = ads_dc_name(domain, realm, &dc_ip, srv_name);
+ ret = ads_dc_name(domain, realm, &dc_ss, srv_name);
}
if (!domain) {
/* if we have only the realm we can't do anything else */
return False;
}
-
+
if (!ret) {
/* fall back on rpc methods if the ADS methods fail */
- ret = rpc_dc_name(domain, srv_name, &dc_ip);
+ ret = rpc_dc_name(domain, srv_name, &dc_ss);
}
-
- *ip_out = dc_ip;
+
+ *ss_out = dc_ss;
return ret;
}
}
/****************************************************************************
- Return the number of bits that match between two 4 character buffers
+ Return the number of bits that match between two len character buffers
***************************************************************************/
-int matching_quad_bits(unsigned char *p1, unsigned char *p2)
+int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
{
- int i, j, ret = 0;
- for (i=0; i<4; i++) {
+ size_t i, j;
+ int ret = 0;
+ for (i=0; i<len; i++) {
if (p1[i] != p2[i])
break;
ret += 8;
}
- if (i==4)
+ if (i==len)
return ret;
for (j=0; j<8; j++) {
static int name_query_comp(unsigned char *p1, unsigned char *p2)
{
- return matching_quad_bits(p2+2, sort_ip) -
- matching_quad_bits(p1+2, sort_ip);
+ return matching_len_bits(p2+2, sort_ip, 4) -
+ matching_len_bits(p1+2, sort_ip, 4);
}
/****************************************************************************
struct nmb_name calling, called;
struct cli_state *cli;
struct rpc_pipe_client *pipe_hnd;
- struct in_addr ip;
+ struct sockaddr_storage ss;
NTSTATUS result;
bool pass_must_change = False;
*err_str = '\0';
- if(!resolve_name( remote_machine, &ip, 0x20)) {
+ if(!resolve_name( remote_machine, &ss, 0x20)) {
slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n",
remote_machine );
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_NO_MEMORY;
}
- result = cli_connect(cli, remote_machine, &ip);
+ result = cli_connect(cli, remote_machine, &ss);
if (!NT_STATUS_IS_OK(result)) {
slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n",
remote_machine, nt_errstr(result) );
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring dc_name;
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
uint32 enum_ctx = 0;
struct cli_state *cli = NULL;
struct rpc_pipe_client *lsa_pipe;
/* lookup a DC first */
- if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
+ if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
domain));
return False;
/* setup the anonymous connection */
- result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
+ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC",
"", "", "", 0, Undefined, &retry);
if ( !NT_STATUS_IS_OK(result) )
goto done;
if (is_loopback_addr(&iface->ip)) {
DEBUG(2,("reload_interfaces: Ignoring loopback "
"interface %s\n",
- print_sockaddr(str, sizeof(str),
- &iface->ip, sizeof(iface->ip)) ));
+ print_sockaddr(str, sizeof(str), &iface->ip) ));
continue;
}
for (subrec=subnetlist; subrec; subrec=subrec->next) {
- if (ip_equal(ip, subrec->myip) &&
- ip_equal(nmask, subrec->mask_ip)) break;
+ if (ip_equal_v4(ip, subrec->myip) &&
+ ip_equal_v4(nmask, subrec->mask_ip)) {
+ break;
+ }
}
if (!subrec) {
/* it wasn't found! add it */
- DEBUG(2,("Found new interface %s\n",
- print_sockaddr(str, sizeof(str),
- &iface->ip, sizeof(iface->ip)) ));
+ DEBUG(2,("Found new interface %s\n",
+ print_sockaddr(str,
+ sizeof(str), &iface->ip) ));
subrec = make_normal_subnet(iface);
if (subrec)
register_my_workgroup_one_subnet(subrec);
}
ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
- if (ip_equal(ip, subrec->myip) &&
- ip_equal(nmask, subrec->mask_ip)) break;
+ if (ip_equal_v4(ip, subrec->myip) &&
+ ip_equal_v4(nmask, subrec->mask_ip)) {
+ break;
+ }
}
if (n == -1) {
/* oops, an interface has disapeared. This is
instead we just wear the memory leak and
remove it from the list of interfaces without
freeing it */
- DEBUG(2,("Deleting dead interface %s\n",
+ DEBUG(2,("Deleting dead interface %s\n",
inet_ntoa(subrec->myip)));
close_subnet(subrec);
}
}
-
+
rescan_listen_set = True;
/* We need to shutdown if there are no subnets... */
for (subrec = FIRST_SUBNET; subrec != NULL;
subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if (ip_equal(*local_ip, subrec->myip)) {
+ if (ip_equal_v4(*local_ip, subrec->myip)) {
p->fd = (p->packet_type == NMB_PACKET) ?
subrec->nmb_sock : subrec->dgram_sock;
break;
static bool open_sockets(bool isdaemon, int port)
{
+ struct sockaddr_storage ss;
+ const char *sock_addr = lp_socket_address();
+
/*
* The sockets opened here will be used to receive broadcast
* packets *only*. Interface specific sockets are opened in
* now deprecated.
*/
- if ( isdaemon )
+ if (!interpret_string_addr(&ss, sock_addr,
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ DEBUG(0,("open_sockets: unable to get socket address "
+ "from string %s", sock_addr));
+ return false;
+ }
+ if (ss.ss_family != AF_INET) {
+ DEBUG(0,("open_sockets: unable to use IPv6 socket"
+ "%s in nmbd\n",
+ sock_addr));
+ return false;
+ }
+
+ if (isdaemon) {
ClientNMB = open_socket_in(SOCK_DGRAM, port,
- 0, interpret_addr(lp_socket_address()),
- True);
- else
+ 0, &ss,
+ true);
+ } else {
ClientNMB = 0;
-
+ }
+
ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
- 3, interpret_addr(lp_socket_address()),
- True);
+ 3, &ss,
+ true);
- if ( ClientNMB == -1 )
- return( False );
+ if (ClientNMB == -1) {
+ return false;
+ }
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
};
poptFreeContext(pc);
- global_in_nmbd = True;
+ global_in_nmbd = true;
StartupTime = time(NULL);
allones_ip.s_addr = htonl(INADDR_BROADCAST);
- if(ismyip_v4(ip) || ip_equal(allones_ip, ip) || is_zero_ip_v4(ip)) {
+ if(ismyip_v4(ip) || ip_equal_v4(allones_ip, ip) || is_zero_ip_v4(ip)) {
if( DEBUGLVL( 3 ) ) {
dbgtext( "become_domain_master_query_success():\n" );
dbgtext( "Our address (%s) ", inet_ntoa(ip) );
/* First check if we already have a dmb for this workgroup. */
- if(!is_zero_ip_v4(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) {
+ if(!is_zero_ip_v4(work->dmb_addr) && ip_equal_v4(work->dmb_addr, answer_ip)) {
/* Do the local master browser announcement to the domain
master browser name and IP. */
announce_local_master_browser_to_domain_master_browser( work );
{
pstring name;
int name_type;
- struct in_addr ipaddr;
+ struct sockaddr_storage ss;
XFILE *fp = startlmhosts( fname );
if (!fp) {
return;
}
- while (getlmhostsent(fp, name, &name_type, &ipaddr) ) {
+ while (getlmhostsent(fp, name, &name_type, &ss) ) {
+ struct in_addr ipaddr;
struct subnet_record *subrec = NULL;
enum name_source source = LMHOSTS_NAME;
+ if (ss.ss_family != AF_INET) {
+ continue;
+ }
+
+ ipaddr = ((struct sockaddr_in *)&ss)->sin_addr;
+
/* We find a relevent subnet to put this entry on, then add it. */
/* Go through all the broadcast subnets and see if the mask matches. */
for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
int i;
for(i = 0; i < namerec->data.num_ips; i++) {
- if(ip_equal( namerec->data.ip[i], ip)) {
+ if(ip_equal_v4( namerec->data.ip[i], ip)) {
return True;
}
}
int orig_num = namerec->data.num_ips;
for(i = 0; i < orig_num; i++) {
- if( ip_equal( remove_ip, namerec->data.ip[i]) ) {
+ if( ip_equal_v4( remove_ip, namerec->data.ip[i]) ) {
remove_nth_ip_in_record( namerec, i);
break;
}
tag = (const char *)userdata->data;
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
- if (ip_equal(last_ip, subrec->myip)) {
+ if (ip_equal_v4(last_ip, subrec->myip)) {
subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
break;
}
struct subnet_record *subrec;
for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
+ if(ip_equal_v4(local_ip, subrec->myip))
return subrec->nmb_sock;
return ClientNMB;
struct subnet_record *subrec;
for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
+ if(ip_equal_v4(local_ip, subrec->myip))
return subrec->dgram_sock;
return ClientDGRAM;
nmb_sock = -1;
dgram_sock = -1;
} else {
+ struct sockaddr_storage ss;
+
+ in_addr_to_sockaddr_storage(&ss, myip);
+
/*
* Attempt to open the sockets on port 137/138 for this interface
* and bind them.
* Fail the subnet creation if this fails.
*/
- if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
+ if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, &ss,true)) == -1) {
if( DEBUGLVL( 0 ) ) {
Debug1( "nmbd_subnetdb:make_subnet()\n" );
Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
return NULL;
}
- if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
+ if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, &ss, true)) == -1) {
if( DEBUGLVL( 0 ) ) {
Debug1( "nmbd_subnetdb:make_subnet()\n" );
Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
struct cli_state *cli;
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
struct nmb_name called, calling;
+ struct sockaddr_storage ss;
NTSTATUS status;
/* W2K DMB's return empty browse lists on port 445. Use 139.
return;
}
- status = cli_connect(cli, name, &ip);
+ in_addr_to_sockaddr_storage(&ss, ip);
+ status = cli_connect(cli, name, &ss);
if (!NT_STATUS_IS_OK(status)) {
return;
}
* if the record is a replica:
* we take ownership and update the version ID.
*/
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
update_wins_owner(namerec, our_fake_ip);
get_global_id_and_update(&namerec->data.id, True);
}
namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
- ip_equal(rrec->packet->ip, *namerec->data.ip)) {
+ ip_equal_v4(rrec->packet->ip, *namerec->data.ip)) {
remove_name_from_namelist( subrec, namerec);
namerec = NULL;
}
if( !registering_group_name
&& (namerec != NULL)
&& (namerec->data.num_ips == 1)
- && ip_equal( namerec->data.ip[0], from_ip )
- && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
+ && ip_equal_v4( namerec->data.ip[0], from_ip )
+ && ip_equal_v4(namerec->data.wins_ip, our_fake_ip) ) {
update_name_ttl( namerec, ttl );
wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response( 0, ttl, p );
* If it's a replica, we need to become the wins owner
* to force the replication
*/
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
get_global_id_and_update(&namerec->data.id, True);
update_wins_owner(namerec, our_fake_ip);
update_wins_flag(namerec, WINS_ACTIVE);
}
/* handle records, samba is the wins owner */
- if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
switch (namerec->data.wins_flags & WINS_STATE_MASK) {
case WINS_ACTIVE:
namerec->data.wins_flags&=~WINS_STATE_MASK;
if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
/* the database record is a replica */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
- if (ip_equal(namerec->data.wins_ip, record->wins_ip))
+ if (ip_equal_v4(namerec->data.wins_ip, record->wins_ip))
overwrite=True;
} else
overwrite=True;
} else {
/* we are the wins owner of the database record */
/* the 2 records have the same IP address */
- if (ip_equal(namerec->data.ip[0], record->ip[0])) {
+ if (ip_equal_v4(namerec->data.ip[0], record->ip[0])) {
if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
get_global_id_and_update(&namerec->data.id, True);
else
overwrite=True;
}
else {
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+ if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
overwrite=True;
- if (ip_equal(namerec->data.wins_ip, our_fake_ip))
+ if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip))
if (namerec->data.wins_flags&WINS_UNIQUE)
get_global_id_and_update(&namerec->data.id, True);
if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
if (namerec->data.wins_flags&WINS_UNIQUE ||
namerec->data.wins_flags&WINS_MHOMED)
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+ if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
overwrite=True;
}
return "AF_UNSPEC";
case AF_INET:
return "AF_INET";
+#if defined(HAVE_IPv6)
case AF_INET6:
return "AF_INET6";
+#endif
default:
break;
}
case AF_UNSPEC:
case AF_INET:
break;
+#if defined(HAVE_IPv6)
case AF_INET6: /* not yet */
return KRB5_PLUGIN_NO_HANDLE;
+#endif
default:
return EINVAL;
}
free( address );
return NULL;
}
- *ret = address[0].ip;
+ if (address[0].ss.ss_family != AF_INET) {
+ free(address);
+ return NULL;
+ }
+ *ret = ((struct sockaddr_in *)&address[0].ss)->sin_addr;
free( address );
return ret;
}
/* uggh, we have to broadcast to each interface in turn */
for (j=iface_count() - 1;j >= 0;j--) {
const struct in_addr *bcast = iface_n_bcast_v4(j);
+ struct sockaddr_storage ss;
+ struct sockaddr_storage *pss;
if (!bcast) {
continue;
}
- ret = name_query(fd,name,0x00,True,True,*bcast,count, &flags, NULL);
- if (ret) break;
+ in_addr_to_sockaddr_storage(&ss, *bcast);
+ pss = name_query(fd,name,0x00,True,True,&ss,count, &flags, NULL);
+ if (pss) {
+ *ret = ((struct sockaddr_in *)pss)->sin_addr;
+ break;
+ }
}
close(fd);
uint32 logon_attempts = 0x0;
uint32 tc_status;
fstring servername, domain, dc_name, dc_name2;
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
/* this should be \\global_myname() */
unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername));
if ( !is_trusted_domain( domain ) )
break;
- if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) {
+ if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) {
tc_status = ERROR_NO_LOGON_SERVERS;
break;
}
if ( !is_trusted_domain( domain ) )
break;
- if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) {
+ if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) {
tc_status = ERROR_NO_LOGON_SERVERS;
break;
}
**********************************************************/
static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
- struct in_addr *client_ip, const char *remote_machine)
+ struct sockaddr_storage *client_ss, const char *remote_machine)
{
NTSTATUS ret;
struct cli_state *the_cli;
- struct in_addr rm_addr;
+ struct sockaddr_storage rm_addr;
- if ( is_zero_ip_v4(*client_ip) ) {
+ if ( is_zero_addr(client_ss) ) {
if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
return False;
}
- if ( ismyip_v4( rm_addr )) {
+ if (ismyaddr(&rm_addr)) {
DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
return False;
}
} else {
- rm_addr.s_addr = client_ip->s_addr;
+ char addr[INET6_ADDRSTRLEN];
+ rm_addr = *client_ss;
+ print_sockaddr(addr, sizeof(addr), &rm_addr);
DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
- inet_ntoa(*client_ip) ));
+ addr));
}
/* setup the connection */
static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
uint32 localprinter, uint32 type,
- POLICY_HND *handle, struct in_addr *client_ip)
+ POLICY_HND *handle, struct sockaddr_storage *client_ss)
{
WERROR result;
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
- if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ip, unix_printer ))
+ if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
return False;
messaging_register(smbd_messaging_context(), NULL,
uint32 printerlocal = q_u->printerlocal;
int snum = -1;
SPOOL_NOTIFY_OPTION *option = q_u->option;
- struct in_addr client_ip;
+ struct sockaddr_storage client_ss;
/* store the notify value in the printer struct */
else if ( (Printer->printer_type == SPLHND_PRINTER) &&
!get_printer_snum(p, handle, &snum, NULL) )
return WERR_BADFID;
-
- client_ip.s_addr = inet_addr(p->conn->client_address);
+
+ if (!interpret_string_addr(&client_ss,
+ p->conn->client_address,
+ AI_NUMERICHOST)) {
+ return WERR_SERVER_UNAVAILABLE;
+ }
if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
Printer->notify.printerlocal, 1,
- &Printer->notify.client_hnd, &client_ip))
+ &Printer->notify.client_hnd, &client_ss))
return WERR_SERVER_UNAVAILABLE;
Printer->notify.client_connected=True;
* enough to release it -- we don't free the
* individual strings. rtfm. */
free(argv);
-
+
return result;
}
struct cli_state *cli;
static char *opt_ipaddr=NULL;
struct cmd_set **cmd_set;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
NTSTATUS nt_status;
static int opt_port = 0;
fstring new_workgroup;
load_case_tables();
- ZERO_STRUCT(server_ip);
+ zero_addr(&server_ss, AF_INET);
setlinebuf(stdout);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
setup_logging("rpcclient", True);
-
+
/* Parse options */
pc = poptGetContext("rpcclient", argc, (const char **) argv,
poptPrintHelp(pc, stderr, 0);
return 0;
}
-
+
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'I':
- if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) {
+ if (!interpret_string_addr(&server_ss,
+ opt_ipaddr,
+ AI_NUMERICHOST)) {
fprintf(stderr, "%s not a valid IP address\n",
opt_ipaddr);
return 1;
than one unparsed argument is present. */
server = poptGetArg(pc);
-
+
if (!server || poptGetArg(pc)) {
poptPrintHelp(pc, stderr, 0);
return 1;
return 1;
/* save the workgroup...
-
- FIXME!! do we need to do this for other options as well
- (or maybe a generic way to keep lp_load() from overwriting
+
+ FIXME!! do we need to do this for other options as well
+ (or maybe a generic way to keep lp_load() from overwriting
everything)? */
-
+
fstrcpy( new_workgroup, lp_workgroup() );
/* Load smb.conf file */
pstrcpy(cmdline_auth_info.password, pass);
}
}
-
+
if ((server[0] == '/' && server[1] == '/') ||
(server[0] == '\\' && server[1] == '\\')) {
server += 2;
}
- nt_status = cli_full_connection(&cli, global_myname(), server,
- opt_ipaddr ? &server_ip : NULL, opt_port,
- "IPC$", "IPC",
- cmdline_auth_info.username,
+ nt_status = cli_full_connection(&cli, global_myname(), server,
+ opt_ipaddr ? &server_ss : NULL, opt_port,
+ "IPC$", "IPC",
+ cmdline_auth_info.username,
lp_workgroup(),
- cmdline_auth_info.password,
+ cmdline_auth_info.password,
cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
cmdline_auth_info.signing_state,NULL);
-
+
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
return 1;
}
fetch_machine_sid(cli);
-
+
/* Do anything specified with -c */
if (cmdstr && cmdstr[0]) {
char *cmd;
char *p = cmdstr;
int result = 0;
-
+
while((cmd=next_command(&p)) != NULL) {
NTSTATUS cmd_result = process_cmd(cli, cmd);
SAFE_FREE(cmd);
result = NT_STATUS_IS_ERR(cmd_result);
}
-
+
cli_shutdown(cli);
return result;
}
if (line[0] != '\n')
process_cmd(cli, line);
}
-
+
cli_shutdown(cli);
return 0;
}
NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct in_addr pdc_ip;
+ struct sockaddr_storage pdc_ss;
fstring dc_name;
struct cli_state *cli = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
/* Use the PDC *only* for this */
- if ( !get_pdc_ip(domain, &pdc_ip) ) {
+ if ( !get_pdc_ip(domain, &pdc_ss) ) {
DEBUG(0,("Can't get IP for PDC for domain %s\n", domain));
goto failed;
}
- if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
+ if ( !name_status_find( domain, 0x1b, 0x20, &pdc_ss, dc_name) )
goto failed;
} else {
/* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
return open_sockets_inetd();
}
-
#ifdef HAVE_ATEXIT
{
static int atexit_set;
/* Stop zombies */
CatchSignal(SIGCLD, sig_cld);
-
+
FD_ZERO(&listen_set);
/* use a reasonable default set of ports - listing on 445 and 139 */
}
if (lp_interfaces() && lp_bind_interfaces_only()) {
- /* We have been given an interfaces line, and been
+ /* We have been given an interfaces line, and been
told to only bind to those interfaces. Create a
socket per interface and bind to only these.
*/
-
+
/* Now open a listen socket for each of the
interfaces. */
for(i = 0; i < num_interfaces; i++) {
const struct sockaddr_storage *ifss =
iface_n_sockaddr_storage(i);
- const struct in_addr *ifip;
fstring tok;
const char *ptr;
if (ifss == NULL) {
- DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
+ DEBUG(0,("open_sockets_smbd: "
+ "interface %d has NULL IP address !\n",
+ i));
continue;
}
- /* For now only deal with IPv4. */
- if (ifss->ss_family != AF_INET) {
- continue;
- }
-
- ifip = &((const struct sockaddr_in *)ifss)->sin_addr;
-
- for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+ for (ptr=ports; next_token(&ptr, tok, " \t,",
+ sizeof(tok)); ) {
unsigned port = atoi(tok);
if (port == 0 || port > 0xffff) {
continue;
}
- s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
+ s = fd_listenset[num_sockets] =
+ open_socket_in(SOCK_STREAM, port, 0,
+ ifss, True);
+ if(s == -1) {
+ return false;
+ }
/* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,"SO_KEEPALIVE");
set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
+
+ /* Set server socket to
+ * non-blocking for the accept. */
+ set_blocking(s,False);
+
if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
+ DEBUG(0,("open_sockets_smbd: listen: "
+ "%s\n", strerror(errno)));
close(s);
return False;
}
num_sockets++;
if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
+ DEBUG(0,("open_sockets_smbd: Too "
+ "many sockets to bind to\n"));
return False;
}
}
fstring tok;
const char *ptr;
+ const char *sock_addr = lp_socket_address();
+ fstring sock_tok;
+ const char *sock_ptr;
+
+ if (strequal(sock_addr, "0.0.0.0") ||
+ strequal(sock_addr, "::")) {
+#if HAVE_IPV6
+ sock_addr = "::,0.0.0.0";
+#else
+ sock_addr = "0.0.0.0";
+#endif
+ }
- num_interfaces = 1;
-
- for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0 || port > 0xffff) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return(False);
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return False;
- }
+ for (sock_ptr=sock_addr; next_token(&sock_ptr, sock_tok, " \t,",
+ sizeof(sock_tok)); ) {
+ for (ptr=ports; next_token(&ptr, tok, " \t,",
+ sizeof(tok)); ) {
+ struct sockaddr_storage ss;
+
+ unsigned port = atoi(tok);
+ if (port == 0 || port > 0xffff) {
+ continue;
+ }
+ /* open an incoming socket */
+ if (!interpret_string_addr(&ss, sock_tok,
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ return false;
+ }
- fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
- maxfd = MAX( maxfd, s);
+ s = open_socket_in(SOCK_STREAM, port, 0,
+ &ss, true);
+ if (s == -1) {
+ return false;
+ }
+
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
- num_sockets++;
+ /* Set server socket to non-blocking
+ * for the accept. */
+ set_blocking(s,False);
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("open_sockets_smbd: "
+ "listen: %s\n",
+ strerror(errno)));
+ close(s);
+ return False;
+ }
+
+ fd_listenset[num_sockets] = s;
+ FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
+
+ num_sockets++;
+
+ if (num_sockets >= FD_SETSIZE) {
+ DEBUG(0,("open_sockets_smbd: Too "
+ "many sockets to bind to\n"));
+ return False;
+ }
}
}
- }
+ }
SAFE_FREE(ports);
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_FILE_RENAME, msg_file_was_renamed);
messaging_register(smbd_messaging_context(), NULL,
- MSG_SMB_CONF_UPDATED, smb_conf_updated);
+ MSG_SMB_CONF_UPDATED, smb_conf_updated);
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete);
brl_register_msgs(smbd_messaging_context());
struct timeval now, idle_timeout;
fd_set r_fds, w_fds;
int num;
-
+
/* Ensure we respond to PING and DEBUG messages from the main smbd. */
message_dispatch(smbd_messaging_context());
idle_timeout = timeval_zero();
- memcpy((char *)&r_fds, (char *)&listen_set,
+ memcpy((char *)&r_fds, (char *)&listen_set,
sizeof(listen_set));
FD_ZERO(&w_fds);
GetTimeOfDay(&now);
continue;
}
-
+
if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
continue;
}
}
smbd_set_server_fd(accept(s,&addr,&in_addrlen));
-
+
if (smbd_server_fd() == -1 && errno == EINTR)
continue;
-
+
if (smbd_server_fd() == -1) {
DEBUG(0,("open_sockets_smbd: accept: %s\n",
strerror(errno)));
if (smbd_server_fd() != -1 && interactive)
return True;
-
+
if (allowable_number_of_smbd_processes() &&
smbd_server_fd() != -1 &&
((child = sys_fork())==0)) {
/* Stop zombies, the parent explicitly handles
* them, counting worker smbds. */
CatchChild();
-
+
/* close the listening socket(s) */
for(i = 0; i < num_sockets; i++)
close(fd_listenset[i]);
-
+
/* close our standard file
descriptors */
close_low_fds(False);
am_parent = 0;
-
+
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
set_socket_options(smbd_server_fd(),user_socket_options);
-
+
/* this is needed so that we get decent entries
in smbstatus for port 445 connects */
set_remote_machine_name(get_peer_addr(smbd_server_fd()),
False);
-
+
/* Reset the state of the random
* number generation system, so
* children do not get the same random
smb_panic("tdb_reopen_all failed");
}
- return True;
+ return True;
}
/* The parent doesn't need this socket */
- close(smbd_server_fd());
+ close(smbd_server_fd());
/* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
Clear the closed fd info out of server_fd --
* (ca. 100kb).
* */
force_check_log_size();
-
+
} /* end for num */
} /* end while 1 */
struct nmb_name called, calling;
char *server_n;
fstring server;
- struct in_addr ip;
+ struct sockaddr_storage ss;
fstring myname;
static int count;
NTSTATUS status;
share++;
server_n = server;
-
- zero_ip_v4(&ip);
+
+ zero_addr(&ss, AF_INET);
slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
make_nmb_name(&called , server, 0x20);
again:
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
/* have to open a new connection */
if (!(c=cli_initialise())) {
return NULL;
}
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
return NULL;
struct nmb_name called, calling;
char *server_n;
char *server;
- struct in_addr ip;
+ struct sockaddr_storage ss;
NTSTATUS status;
server = share+2;
share++;
server_n = server;
-
- zero_ip_v4(&ip);
+
+ zero_addr(&ss, AF_INET);
make_nmb_name(&calling, "masktest", 0x0);
make_nmb_name(&called , server, 0x20);
again:
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
/* have to open a new connection */
if (!(c=cli_initialise())) {
return NULL;
}
- status = cli_connect(c, server_n, &ip);
+ status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
return NULL;
static struct cli_state *open_nbt_connection(void)
{
struct nmb_name called, calling;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct cli_state *c;
NTSTATUS status;
make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , host, 0x20);
- zero_ip_v4(&ip);
+ zero_addr(&ss, AF_INET);
if (!(c = cli_initialise())) {
printf("Failed initialize cli_struct to connect with %s\n", host);
c->port = port_to_use;
- status = cli_connect(c, host, &ip);
+ status = cli_connect(c, host, &ss);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
return NULL;
if (!cli_session_request(c, &calling, &called)) {
/*
- * Well, that failed, try *SMBSERVER ...
+ * Well, that failed, try *SMBSERVER ...
* However, we must reconnect as well ...
*/
- status = cli_connect(c, host, &ip);
+ status = cli_connect(c, host, &ss);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
return NULL;
/* Yes, these buggers are globals.... */
const char *opt_requester_name = NULL;
-const char *opt_host = NULL;
+const char *opt_host = NULL;
const char *opt_password = NULL;
const char *opt_user_name = NULL;
bool opt_user_specified = False;
int opt_testmode = False;
int opt_have_ip = False;
-struct in_addr opt_dest_ip;
+struct sockaddr_storage opt_dest_ip;
extern bool AllowDebugChange;
}
/****************************************************************************
-connect to \\server\service
+ Connect to \\server\service.
****************************************************************************/
-NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
- const char *server_name,
- const char *service_name,
+NTSTATUS connect_to_service(struct cli_state **c,
+ struct sockaddr_storage *server_ss,
+ const char *server_name,
+ const char *service_name,
const char *service_type)
{
NTSTATUS nt_status;
return NT_STATUS_NO_MEMORY;
}
- nt_status = cli_full_connection(c, NULL, server_name,
- server_ip, opt_port,
- service_name, service_type,
+ nt_status = cli_full_connection(c, NULL, server_name,
+ server_ss, opt_port,
+ service_name, service_type,
opt_user_name, opt_workgroup,
opt_password, 0, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
/* Display a nicer message depending on the result */
- if (NT_STATUS_V(nt_status) ==
+ if (NT_STATUS_V(nt_status) ==
NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
d_fprintf(stderr, "The username or password was not correct.\n");
- if (NT_STATUS_V(nt_status) ==
+ if (NT_STATUS_V(nt_status) ==
NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
d_fprintf(stderr, "The account was locked out.\n");
- if (NT_STATUS_V(nt_status) ==
+ if (NT_STATUS_V(nt_status) ==
NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
d_fprintf(stderr, "The account was disabled.\n");
}
}
-
/****************************************************************************
-connect to \\server\ipc$
+ Connect to \\server\ipc$.
****************************************************************************/
-NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
- const char *server_name)
+
+NTSTATUS connect_to_ipc(struct cli_state **c,
+ struct sockaddr_storage *server_ss,
+ const char *server_name)
{
- return connect_to_service(c, server_ip, server_name, "IPC$", "IPC");
+ return connect_to_service(c, server_ss, server_name, "IPC$", "IPC");
}
/****************************************************************************
-connect to \\server\ipc$ anonymously
+ Connect to \\server\ipc$ anonymously.
****************************************************************************/
+
NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
- struct in_addr *server_ip, const char *server_name)
+ struct sockaddr_storage *server_ss,
+ const char *server_name)
{
NTSTATUS nt_status;
- nt_status = cli_full_connection(c, opt_requester_name, server_name,
- server_ip, opt_port,
- "IPC$", "IPC",
+ nt_status = cli_full_connection(c, opt_requester_name, server_name,
+ server_ss, opt_port,
+ "IPC$", "IPC",
"", "",
"", 0, Undefined, NULL);
-
+
if (NT_STATUS_IS_OK(nt_status)) {
return nt_status;
} else {
}
/****************************************************************************
-connect to \\server\ipc$ using KRB5
+ Connect to \\server\ipc$ using KRB5.
****************************************************************************/
NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
- struct in_addr *server_ip, const char *server_name)
+ struct sockaddr_storage *server_ss,
+ const char *server_name)
{
NTSTATUS nt_status;
char *user_and_realm = NULL;
return NT_STATUS_NO_MEMORY;
}
- nt_status = cli_full_connection(c, NULL, server_name,
- server_ip, opt_port,
- "IPC$", "IPC",
+ nt_status = cli_full_connection(c, NULL, server_name,
+ server_ss, opt_port,
+ "IPC$", "IPC",
user_and_realm, opt_workgroup,
opt_password, CLI_FULL_CONNECTION_USE_KERBEROS,
Undefined, NULL);
-
+
SAFE_FREE(user_and_realm);
if (NT_STATUS_IS_OK(nt_status)) {
int net_use_machine_account(void)
{
char *user_name = NULL;
-
+
if (!secrets_init()) {
d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
exit(1);
return 0;
}
-bool net_find_server(const char *domain, unsigned flags, struct in_addr *server_ip, char **server_name)
+bool net_find_server(const char *domain,
+ unsigned flags,
+ struct sockaddr_storage *server_ss,
+ char **server_name)
{
const char *d = domain ? domain : opt_target_workgroup;
if (opt_host) {
*server_name = SMB_STRDUP(opt_host);
- }
+ }
if (opt_have_ip) {
- *server_ip = opt_dest_ip;
+ *server_ss = opt_dest_ip;
if (!*server_name) {
- *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &opt_dest_ip);
+ *server_name = SMB_STRDUP(addr);
}
} else if (*server_name) {
/* resolve the IP address */
- if (!resolve_name(*server_name, server_ip, 0x20)) {
+ if (!resolve_name(*server_name, server_ss, 0x20)) {
DEBUG(1,("Unable to resolve server name\n"));
- return False;
+ return false;
}
} else if (flags & NET_FLAGS_PDC) {
- struct in_addr pdc_ip;
-
- if (get_pdc_ip(d, &pdc_ip)) {
- fstring dc_name;
-
- if (is_zero_ip_v4(pdc_ip))
- return False;
-
- if ( !name_status_find(d, 0x1b, 0x20, pdc_ip, dc_name) )
- return False;
-
- *server_name = SMB_STRDUP(dc_name);
- *server_ip = pdc_ip;
+ fstring dc_name;
+ struct sockaddr_storage pdc_ss;
+
+ if (get_pdc_ip(d, &pdc_ss)) {
+ DEBUG(1,("Unable to resolve PDC server address\n"));
+ return false;
+ }
+
+ if (is_zero_addr(&pdc_ss)) {
+ return false;
}
+
+ if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
+ return False;
+ }
+
+ *server_name = SMB_STRDUP(dc_name);
+ *server_ss = pdc_ss;
} else if (flags & NET_FLAGS_DMB) {
- struct in_addr msbrow_ip;
+ struct sockaddr_storage msbrow_ss;
+ char addr[INET6_ADDRSTRLEN];
+
/* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
- if (!resolve_name(d, &msbrow_ip, 0x1B)) {
+ if (!resolve_name(d, &msbrow_ss, 0x1B)) {
DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
- return False;
- } else {
- *server_ip = msbrow_ip;
+ return false;
}
- *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+ *server_ss = msbrow_ss;
+ print_sockaddr(addr, sizeof(addr), server_ss);
+ *server_name = SMB_STRDUP(addr);
} else if (flags & NET_FLAGS_MASTER) {
- struct in_addr brow_ips;
- if (!resolve_name(d, &brow_ips, 0x1D)) {
+ struct sockaddr_storage brow_ss;
+ char addr[INET6_ADDRSTRLEN];
+ if (!resolve_name(d, &brow_ss, 0x1D)) {
/* go looking for workgroups */
DEBUG(1,("Unable to resolve master browser via name lookup\n"));
- return False;
- } else {
- *server_ip = brow_ips;
+ return false;
}
- *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
+ *server_ss = brow_ss;
+ print_sockaddr(addr, sizeof(addr), server_ss);
+ *server_name = SMB_STRDUP(addr);
} else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
- (*server_ip).s_addr = htonl(INADDR_LOOPBACK);
+ if (!interpret_string_addr(server_ss,
+ "127.0.0.1", AI_NUMERICHOST)) {
+ DEBUG(1,("Unable to resolve 127.0.0.1\n"));
+ return false;
+ }
*server_name = SMB_STRDUP("127.0.0.1");
}
return True;
}
-
-bool net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
+bool net_find_pdc(struct sockaddr_storage *server_ss,
+ fstring server_name,
+ const char *domain_name)
{
- if (get_pdc_ip(domain_name, server_ip)) {
- if (is_zero_ip_v4(*server_ip))
- return False;
-
- if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
- return False;
-
- return True;
- }
- else
- return False;
+ if (!get_pdc_ip(domain_name, server_ss)) {
+ return false;
+ }
+ if (is_zero_addr(server_ss)) {
+ return false;
+ }
+
+ if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
+ return false;
+ }
+
+ return true;
}
NTSTATUS net_make_ipc_connection(unsigned flags, struct cli_state **pcli)
}
NTSTATUS net_make_ipc_connection_ex(const char *domain, const char *server,
- struct in_addr *ip, unsigned flags,
+ struct sockaddr_storage *pss, unsigned flags,
struct cli_state **pcli)
{
char *server_name = NULL;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
struct cli_state *cli = NULL;
NTSTATUS nt_status;
- if ( !server || !ip ) {
- if (!net_find_server(domain, flags, &server_ip, &server_name)) {
+ if ( !server || !pss ) {
+ if (!net_find_server(domain, flags, &server_ss, &server_name)) {
d_fprintf(stderr, "Unable to find a suitable server\n");
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
} else {
server_name = SMB_STRDUP( server );
- server_ip = *ip;
+ server_ss = *pss;
}
if (flags & NET_FLAGS_ANONYMOUS) {
- nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name);
+ nt_status = connect_to_ipc_anonymous(&cli, &server_ss, server_name);
} else {
- nt_status = connect_to_ipc(&cli, &server_ip, server_name);
+ nt_status = connect_to_ipc(&cli, &server_ss, server_name);
}
/* store the server in the affinity cache if it was a PDC */
TALLOC_CTX *frame = talloc_stackframe();
- zero_ip_v4(&opt_dest_ip);
+ zero_addr(&opt_dest_ip, AF_INET);
load_case_tables();
exit(0);
break;
case 'I':
- opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
- if (is_zero_ip_v4(opt_dest_ip))
+ if (!interpret_string_addr(&opt_dest_ip,
+ poptGetOptArg(pc), 0)) {
d_fprintf(stderr, "\nInvalid ip address specified\n");
- else
+ } else {
opt_have_ip = True;
+ }
break;
case 'U':
opt_user_specified = True;
extern int opt_testmode;
extern int opt_have_ip;
-extern struct in_addr opt_dest_ip;
+extern struct sockaddr_storage opt_dest_ip;
extern const char *share_type[];
*/
static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
{
+ char addr[INET6_ADDRSTRLEN];
struct cldap_netlogon_reply reply;
- if ( !ads_cldap_netlogon( inet_ntoa(ads->ldap.ip), ads->server.realm, &reply ) ) {
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+ if ( !ads_cldap_netlogon(addr, ads->server.realm, &reply ) ) {
d_fprintf(stderr, "CLDAP query failed!\n");
return -1;
}
d_printf("Information for Domain Controller: %s\n\n",
- inet_ntoa(ads->ldap.ip));
+ addr);
d_printf("Response Type: ");
switch (reply.type) {
return 0;
}
-
/*
this implements the CLDAP based netlogon lookup requests
for finding the domain controller of a ADS domain
static int net_ads_info(int argc, const char **argv)
{
ADS_STRUCT *ads;
+ char addr[INET6_ADDRSTRLEN];
if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
d_fprintf(stderr, "Didn't find the ldap server!\n");
d_fprintf( stderr, "Failed to get server's current time!\n");
}
- d_printf("LDAP server: %s\n", inet_ntoa(ads->ldap.ip));
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+
+ d_printf("LDAP server: %s\n", addr);
d_printf("LDAP server name: %s\n", ads->config.ldap_server_name);
d_printf("Realm: %s\n", ads->config.realm);
d_printf("Bind Path: %s\n", ads->config.bind_path);
static int net_ads_workgroup(int argc, const char **argv)
{
ADS_STRUCT *ads;
+ char addr[INET6_ADDRSTRLEN];
struct cldap_netlogon_reply reply;
if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
ads->ldap.port = 389;
}
- if ( !ads_cldap_netlogon( inet_ntoa(ads->ldap.ip), ads->server.realm, &reply ) ) {
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+ if ( !ads_cldap_netlogon(addr, ads->server.realm, &reply ) ) {
d_fprintf(stderr, "CLDAP query failed!\n");
return -1;
}
/* make RPC calls here */
- if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ip,
+ if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ss,
ads->config.ldap_server_name)) )
{
goto done;
********************************************************************/
static NTSTATUS net_join_domain(TALLOC_CTX *ctx, const char *servername,
- struct in_addr *ip, char **domain,
+ struct sockaddr_storage *pss, char **domain,
DOM_SID **dom_sid,
const char *password)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
struct cli_state *cli = NULL;
- ret = connect_to_ipc_krb5(&cli, ip, servername);
+ ret = connect_to_ipc_krb5(&cli, pss, servername);
if ( !NT_STATUS_IS_OK(ret) ) {
goto done;
}
const char *create_in_ou = NULL;
int i;
fstring dc_name;
- struct in_addr dcip;
+ struct sockaddr_storage dcss;
const char *os_name = NULL;
const char *os_version = NULL;
/* find a DC to initialize the server affinity cache */
- get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcip );
+ get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcss );
status = ads_startup(True, &ads);
if (!ADS_ERR_OK(status)) {
password = talloc_strdup(ctx, tmp_password);
nt_status = net_join_domain(ctx, ads->config.ldap_server_name,
- &ads->ldap.ip, &short_domain_name, &domain_sid, password);
+ &ads->ldap.ss, &short_domain_name, &domain_sid, password);
if ( !NT_STATUS_IS_OK(nt_status) ) {
DEBUG(1, ("call of net_join_domain failed: %s\n",
get_friendly_nt_error_msg(nt_status)));
/* Verify that everything is ok */
nt_status = net_rpc_join_ok(short_domain_name,
- ads->config.ldap_server_name, &ads->ldap.ip);
+ ads->config.ldap_server_name, &ads->ldap.ss);
if (!NT_STATUS_IS_OK(nt_status)) {
d_fprintf(stderr,
"Failed to verify membership in domain: %s!\n",
const char *servername, *printername;
struct cli_state *cli;
struct rpc_pipe_client *pipe_hnd;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
NTSTATUS nt_status;
TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish");
ADS_MODLIST mods = ads_init_mods(mem_ctx);
/* Get printer data from SPOOLSS */
- resolve_name(servername, &server_ip, 0x20);
+ resolve_name(servername, &server_ss, 0x20);
nt_status = cli_full_connection(&cli, global_myname(), servername,
- &server_ip, 0,
+ &server_ss, 0,
"IPC$", "IPC",
opt_user_name, opt_workgroup,
opt_password ? opt_password : "",
-/*
- Samba Unix/Linux SMB client library
+/*
+ Samba Unix/Linux SMB client library
net lookup command
Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
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 <http://www.gnu.org/licenses/>. */
/* lookup a hostname giving an IP */
static int net_lookup_host(int argc, const char **argv)
{
- struct in_addr ip;
+ struct sockaddr_storage ss;
int name_type = 0x20;
+ char addr[INET6_ADDRSTRLEN];
const char *name = argv[0];
char *p;
- if (argc == 0)
+ if (argc == 0)
return net_lookup_usage(argc, argv);
p = strchr_m(name,'#');
*p = '\0';
sscanf(++p,"%x",&name_type);
}
-
- if (!resolve_name(name, &ip, name_type)) {
- /* we deliberately use DEBUG() here to send it to stderr
+
+ if (!resolve_name(name, &ss, name_type)) {
+ /* we deliberately use DEBUG() here to send it to stderr
so scripts aren't mucked up */
DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
return -1;
}
- d_printf("%s\n", inet_ntoa(ip));
+ print_sockaddr(addr, sizeof(addr), &ss);
+ d_printf("%s\n", addr);
return 0;
}
#ifdef HAVE_ADS
static void print_ldap_srvlist(struct dns_rr_srv *dclist, int numdcs )
{
- struct in_addr ip;
+ struct sockaddr_storage ss;
int i;
for ( i=0; i<numdcs; i++ ) {
- if ( resolve_name(dclist[i].hostname, &ip, 0x20) ) {
- d_printf("%s:%d\n", inet_ntoa(ip), dclist[i].port);
+ if (resolve_name(dclist[i].hostname, &ss, 0x20) ) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ss);
+#ifdef HAVE_IPV6
+ if (ss.ss_family == AF_INET6) {
+ d_printf("[%s]:%d\n", addr, dclist[i].port);
+ }
+#endif
+ if (ss.ss_family == AF_INET) {
+ d_printf("%s:%d\n", addr, dclist[i].port);
+ }
}
}
}
{
#ifdef HAVE_ADS
const char *domain;
- struct in_addr addr;
- struct hostent *hostent;
+ struct sockaddr_storage ss;
struct dns_rr_srv *dcs = NULL;
int numdcs = 0;
char *sitename;
TALLOC_CTX *ctx;
NTSTATUS status;
+ int ret;
+ char h_name[HOST_NAME_MAX];
if (argc > 0)
domain = argv[0];
}
DEBUG(9, ("Looking up PDC for domain %s\n", domain));
- if (!get_pdc_ip(domain, &addr)) {
+ if (!get_pdc_ip(domain, &ss)) {
TALLOC_FREE( ctx );
SAFE_FREE(sitename);
return -1;
}
- hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr),
- AF_INET);
- if (!hostent) {
+ ret = getnameinfo((struct sockaddr *)&ss,
+ sizeof(struct sockaddr_storage),
+ h_name, sizeof(h_name),
+ NULL, 0,
+ NI_NAMEREQD);
+
+ if (ret) {
TALLOC_FREE( ctx );
SAFE_FREE(sitename);
return -1;
}
- DEBUG(9, ("Found PDC with DNS name %s\n", hostent->h_name));
- domain = strchr(hostent->h_name, '.');
+ DEBUG(9, ("Found PDC with DNS name %s\n", h_name));
+ domain = strchr(h_name, '.');
if (!domain) {
TALLOC_FREE( ctx );
SAFE_FREE(sitename);
static int net_lookup_dc(int argc, const char **argv)
{
struct ip_service *ip_list;
- struct in_addr addr;
+ struct sockaddr_storage ss;
char *pdc_str = NULL;
const char *domain = NULL;
char *sitename = NULL;
int count, i;
+ char addr[INET6_ADDRSTRLEN];
bool sec_ads = (lp_security() == SEC_ADS);
if (sec_ads) {
domain=argv[0];
/* first get PDC */
- if (!get_pdc_ip(domain, &addr))
+ if (!get_pdc_ip(domain, &ss))
return -1;
- asprintf(&pdc_str, "%s", inet_ntoa(addr));
+ print_sockaddr(addr, sizeof(addr), &ss);
+ asprintf(&pdc_str, "%s", addr);
d_printf("%s\n", pdc_str);
sitename = sitename_fetch(domain);
- if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename, &ip_list, &count, sec_ads))) {
+ if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename,
+ &ip_list, &count, sec_ads))) {
SAFE_FREE(pdc_str);
SAFE_FREE(sitename);
return 0;
}
SAFE_FREE(sitename);
for (i=0;i<count;i++) {
- char *dc_str = inet_ntoa(ip_list[i].ip);
- if (!strequal(pdc_str, dc_str))
- d_printf("%s\n", dc_str);
+ print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+ if (!strequal(pdc_str, addr))
+ d_printf("%s\n", addr);
}
SAFE_FREE(pdc_str);
return 0;
static int net_lookup_pdc(int argc, const char **argv)
{
- struct in_addr addr;
+ struct sockaddr_storage ss;
char *pdc_str = NULL;
const char *domain;
-
+ char addr[INET6_ADDRSTRLEN];
+
if (lp_security() == SEC_ADS) {
domain = lp_realm();
} else {
domain=argv[0];
/* first get PDC */
- if (!get_pdc_ip(domain, &addr))
+ if (!get_pdc_ip(domain, &ss))
return -1;
- asprintf(&pdc_str, "%s", inet_ntoa(addr));
+ print_sockaddr(addr, sizeof(addr), &ss);
+ asprintf(&pdc_str, "%s", addr);
d_printf("%s\n", pdc_str);
SAFE_FREE(pdc_str);
return 0;
static int net_lookup_master(int argc, const char **argv)
{
- struct in_addr master_ip;
+ struct sockaddr_storage master_ss;
const char *domain=opt_target_workgroup;
+ char addr[INET6_ADDRSTRLEN];
if (argc > 0)
domain=argv[0];
- if (!find_master_ip(domain, &master_ip))
+ if (!find_master_ip(domain, &master_ss))
return -1;
- d_printf("%s\n", inet_ntoa(master_ip));
+ print_sockaddr(addr, sizeof(addr), &master_ss);
+ d_printf("%s\n", addr);
return 0;
}
/* open share source */
nt_status = connect_to_service(&cp_clistate.cli_share_src,
- &cli->dest_ip, cli->desthost,
+ &cli->dest_ss, cli->desthost,
netname, "A:");
if (!NT_STATUS_IS_OK(nt_status))
goto done;
static int rpc_trustdom_establish(int argc, const char **argv)
{
struct cli_state *cli = NULL;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
struct rpc_pipe_client *pipe_hnd = NULL;
POLICY_HND connect_hnd;
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
-
+
char* domain_name;
char* domain_name_pol;
char* acct_name;
/* account name used at first is our domain's name with '$' */
asprintf(&acct_name, "%s$", lp_workgroup());
strupper_m(acct_name);
-
+
/*
* opt_workgroup will be used by connection functions further,
* hence it should be set to remote domain name instead of ours
if (opt_workgroup) {
opt_workgroup = smb_xstrdup(domain_name);
};
-
+
opt_user_name = acct_name;
/* find the domain controller */
- if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
+ if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
return -1;
}
/* connect to ipc$ as username/password */
- nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
+ nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
/* Is it trusting domain account for sure ? */
/* store who we connected to */
saf_store( domain_name, pdc_name );
-
+
/*
* Connect to \\server\ipc$ again (this time anonymously)
*/
-
- nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
+
+ nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
{
struct cli_state *cli;
bool ret = False;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
char *server_name = NULL;
NTSTATUS status;
/* flags (i.e. server type) may depend on command */
- if (!net_find_server(NULL, flags, &server_ip, &server_name))
+ if (!net_find_server(NULL, flags, &server_ss, &server_name))
return False;
if ((cli = cli_initialise()) == NULL) {
return False;
}
- status = cli_connect(cli, server_name, &server_ip);
+ status = cli_connect(cli, server_name, &server_ss);
if (!NT_STATUS_IS_OK(status))
goto done;
- if (!attempt_netbios_session_request(&cli, global_myname(),
- server_name, &server_ip))
+ if (!attempt_netbios_session_request(&cli, global_myname(),
+ server_name, &server_ss))
goto done;
if (!cli_negprot(cli))
goto done;
*
**/
NTSTATUS net_rpc_join_ok(const char *domain, const char *server,
- struct in_addr *ip)
+ struct sockaddr_storage *pss)
{
enum security_types sec;
unsigned int conn_flags = NET_FLAGS_PDC;
}
/* Connect to remote machine */
- ntret = net_make_ipc_connection_ex(domain, server, ip, conn_flags, &cli);
+ ntret = net_make_ipc_connection_ex(domain, server, pss, conn_flags, &cli);
if (!NT_STATUS_IS_OK(ntret)) {
return ntret;
}
}
/* double-check, connection from scratch */
- result = net_rpc_join_ok(domain, cli->desthost, &cli->dest_ip);
+ result = net_rpc_join_ok(domain, cli->desthost, &cli->dest_ss);
retval = NT_STATUS_IS_OK(result) ? 0 : -1;
done:
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i, p;
uint32 num_printers;
- uint32 level = 3;
+ uint32 level = 3;
pstring printername = "", sharename = "";
bool got_hnd_src = False;
bool got_hnd_dst = False;
struct cli_state *cli_share_src = NULL;
struct cli_state *cli_share_dst = NULL;
fstring drivername = "";
-
+
ZERO_STRUCT(drv_ctr_src);
ZERO_STRUCT(drv_ctr_dst);
ZERO_STRUCT(info_ctr_enum);
nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
-
/* open print$-share on the src server */
- nt_status = connect_to_service(&cli_share_src, &cli->dest_ip,
+ nt_status = connect_to_service(&cli_share_src, &cli->dest_ss,
cli->desthost, "print$", "A:");
- if (!NT_STATUS_IS_OK(nt_status))
+ if (!NT_STATUS_IS_OK(nt_status))
goto done;
got_src_driver_share = True;
/* open print$-share on the dst server */
- nt_status = connect_to_service(&cli_share_dst, &cli_dst->dest_ip,
+ nt_status = connect_to_service(&cli_share_dst, &cli_dst->dest_ss,
cli_dst->desthost, "print$", "A:");
- if (!NT_STATUS_IS_OK(nt_status))
+ if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
got_dst_driver_share = True;
/*
return the time on a server. This does not require any authentication
*/
-static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
+static time_t cli_servertime(const char *host, struct sockaddr_storage *pss, int *zone)
{
struct nmb_name calling, called;
time_t ret = 0;
goto done;
}
- status = cli_connect(cli, host, ip);
+ status = cli_connect(cli, host, pss);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,"Can't contact server %s. Error %s\n", host, nt_errstr(status));
goto done;
if (!tm) {
return "unknown";
}
-
- fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
- tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
+
+ fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
+ tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
return s;
}
int result;
if (t == 0) return -1;
-
- /* yes, I know this is cheesy. Use "net time system" if you want to
+
+ /* yes, I know this is cheesy. Use "net time system" if you want to
roll your own. I'm putting this in as it works on a large number
of systems and the user has a choice in whether its used or not */
asprintf(&cmd, "/bin/date %s", systime(t));
static struct con_struct *create_cs(TALLOC_CTX *ctx, NTSTATUS *perr)
{
NTSTATUS nt_status;
- struct in_addr loopback_ip;
+ struct sockaddr_storage loopback_ss;
- loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
*perr = NT_STATUS_OK;
+ if (!interpret_string_addr(&loopback_ss, "127.0.0.1", AI_NUMERICHOST)) {
+ *perr = NT_STATUS_INVALID_PARAMETER;
+ return NULL;
+ }
+
if (cs) {
if (cs->failed_connect) {
*perr = cs->err;
#endif
nt_status = cli_full_connection(&cs->cli, global_myname(), global_myname(),
- &loopback_ip, 0,
+ &loopback_ss, 0,
"IPC$", "IPC",
#if 0
opt_user_name,
-/*
+/*
Unix SMB/CIFS implementation.
NBT client - used to lookup netbios names
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Jelmer Vernooij 2003 (Conversion to popt)
-
+
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 <http://www.gnu.org/licenses/>.
-
+
*/
#include "includes.h"
extern bool AllowDebugChange;
-static bool give_flags = False;
-static bool use_bcast = True;
-static bool got_bcast = False;
-static struct in_addr bcast_addr;
-static bool recursion_desired = False;
-static bool translate_addresses = False;
+static bool give_flags = false;
+static bool use_bcast = true;
+static bool got_bcast = false;
+static struct sockaddr_storage bcast_addr;
+static bool recursion_desired = false;
+static bool translate_addresses = false;
static int ServerFD= -1;
-static bool RootPort = False;
-static bool find_status=False;
+static bool RootPort = false;
+static bool find_status = false;
/****************************************************************************
- open the socket communication
- **************************************************************************/
+ Open the socket communication.
+**************************************************************************/
+
static bool open_sockets(void)
{
- ServerFD = open_socket_in( SOCK_DGRAM,
- (RootPort ? 137 : 0),
- (RootPort ? 0 : 3),
- interpret_addr(lp_socket_address()), True );
+ struct sockaddr_storage ss;
+ const char *sock_addr = lp_socket_address();
+
+ if (!interpret_string_addr(&ss, sock_addr,
+ AI_NUMERICHOST|AI_PASSIVE)) {
+ DEBUG(0,("open_sockets: unable to get socket address "
+ "from string %s", sock_addr));
+ return false;
+ }
+ ServerFD = open_socket_in( SOCK_DGRAM,
+ (RootPort ? 137 : 0),
+ (RootPort ? 0 : 3),
+ &ss, true );
- if (ServerFD == -1)
- return(False);
+ if (ServerFD == -1) {
+ return false;
+ }
- set_socket_options( ServerFD, "SO_BROADCAST" );
+ set_socket_options( ServerFD, "SO_BROADCAST" );
- DEBUG(3, ("Socket opened.\n"));
- return True;
+ DEBUG(3, ("Socket opened.\n"));
+ return true;
}
/****************************************************************************
{
static fstring ret;
fstrcpy(ret,"");
-
+
fstrcat(ret, (flags & 0x80) ? "<GROUP> " : " ");
if ((flags & 0x60) == 0x00) fstrcat(ret,"B ");
if ((flags & 0x60) == 0x20) fstrcat(ret,"P ");
if (flags & 0x08) fstrcat(ret,"<CONFLICT> ");
if (flags & 0x04) fstrcat(ret,"<ACTIVE> ");
if (flags & 0x02) fstrcat(ret,"<PERMANENT> ");
-
+
return ret;
}
/****************************************************************************
-turn the NMB Query flags into a string
+ Turn the NMB Query flags into a string.
****************************************************************************/
+
static char *query_flags(int flags)
{
static fstring ret1;
}
/****************************************************************************
-do a node status query
+ Do a node status query.
****************************************************************************/
-static void do_node_status(int fd, const char *name, int type, struct in_addr ip)
+
+static void do_node_status(int fd,
+ const char *name,
+ int type,
+ struct sockaddr_storage *pss)
{
struct nmb_name nname;
int count, i, j;
NODE_STATUS_STRUCT *status;
struct node_status_extra extra;
fstring cleanname;
+ char addr[INET6_ADDRSTRLEN];
- d_printf("Looking up status of %s\n",inet_ntoa(ip));
+ 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,ip, &count, &extra);
+ status = node_status_query(fd, &nname, pss, &count, &extra);
if (status) {
for (i=0;i<count;i++) {
pull_ascii_fstring(cleanname, status[i].name);
for (j=0;cleanname[j];j++) {
- if (!isprint((int)cleanname[j])) cleanname[j] = '.';
+ if (!isprint((int)cleanname[j])) {
+ cleanname[j] = '.';
+ }
}
d_printf("\t%-15s <%02x> - %s\n",
cleanname,status[i].type,
d_printf("\n");
SAFE_FREE(status);
} else {
- d_printf("No reply from %s\n\n",inet_ntoa(ip));
+ d_printf("No reply from %s\n\n",addr);
}
}
/****************************************************************************
-send out one query
+ Send out one query.
****************************************************************************/
+
static bool query_one(const char *lookup, unsigned int lookup_type)
{
int j, count, flags = 0;
- struct in_addr *ip_list=NULL;
+ struct sockaddr_storage *ip_list=NULL;
if (got_bcast) {
- d_printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &bcast_addr);
+ d_printf("querying %s on %s\n", lookup, addr);
ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
- use_bcast?True:recursion_desired,
- bcast_addr,&count, &flags, NULL);
+ use_bcast?true:recursion_desired,
+ &bcast_addr, &count, &flags, NULL);
} else {
const struct in_addr *bcast;
for (j=iface_count() - 1;
!ip_list && j >= 0;
j--) {
+ char addr[INET6_ADDRSTRLEN];
+ struct sockaddr_storage bcast_ss;
+
bcast = iface_n_bcast_v4(j);
if (!bcast) {
continue;
}
- d_printf("querying %s on %s\n",
- lookup, inet_ntoa(*bcast));
+ in_addr_to_sockaddr_storage(&bcast_ss, *bcast);
+ print_sockaddr(addr, sizeof(addr), &bcast_ss);
+ d_printf("querying %s on %s\n",
+ lookup, addr);
ip_list = name_query(ServerFD,lookup,lookup_type,
use_bcast,
use_bcast?True:recursion_desired,
- *bcast,&count, &flags, NULL);
+ &bcast_ss,&count, &flags, NULL);
}
}
- if (!ip_list) return False;
+ if (!ip_list) {
+ return false;
+ }
- if (give_flags)
- d_printf("Flags: %s\n", query_flags(flags));
+ if (give_flags) {
+ d_printf("Flags: %s\n", query_flags(flags));
+ }
for (j=0;j<count;j++) {
+ char addr[INET6_ADDRSTRLEN];
if (translate_addresses) {
- struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
- if (host) {
- d_printf("%s, ", host -> h_name);
+ char h_name[HOST_NAME_MAX];
+ h_name[0] = '\0';
+ if (getnameinfo((const struct sockaddr *)&ip_list[j],
+ sizeof(struct sockaddr_storage),
+ h_name, sizeof(h_name),
+ NULL, 0,
+ NI_NAMEREQD)) {
+ continue;
}
+ d_printf("%s, ", h_name);
}
- d_printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
+ print_sockaddr(addr, sizeof(addr), &ip_list[j]);
+ d_printf("%s %s<%02x>\n", addr,lookup, lookup_type);
/* We can only do find_status if the ip address returned
was valid - ie. name_query returned true.
*/
if (find_status) {
- do_node_status(ServerFD, lookup, lookup_type, ip_list[j]);
+ do_node_status(ServerFD, lookup,
+ lookup_type, &ip_list[j]);
}
}
****************************************************************************/
int main(int argc,char *argv[])
{
- int opt;
- unsigned int lookup_type = 0x0;
- fstring lookup;
- static bool find_master=False;
- static bool lookup_by_ip = False;
- poptContext pc;
- TALLOC_CTX *frame = talloc_stackframe();
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
- { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" },
- { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
- { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" },
- { "recursion", 'R', POPT_ARG_VAL, NULL, 'R', "Set recursion desired in package" },
- { "status", 'S', POPT_ARG_VAL, NULL, 'S', "Lookup node status as well" },
- { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
- { "root-port", 'r', POPT_ARG_VAL, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
- { "lookup-by-ip", 'A', POPT_ARG_VAL, NULL, 'A', "Do a node status on <name> as an IP Address" },
- POPT_COMMON_SAMBA
- POPT_COMMON_CONNECTION
- { 0, 0, 0, 0 }
- };
-
- *lookup = 0;
-
- load_case_tables();
-
- setup_logging(argv[0],True);
-
- pc = poptGetContext("nmblookup", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- poptSetOtherOptionHelp(pc, "<NODE> ...");
-
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'f':
- give_flags = true;
- break;
- case 'M':
- find_master = true;
- break;
- case 'R':
- recursion_desired = true;
- break;
- case 'S':
- find_status = true;
- break;
- case 'r':
- RootPort = true;
- break;
- case 'A':
- lookup_by_ip = true;
- break;
- case 'B':
- bcast_addr = *interpret_addr2(poptGetOptArg(pc));
- got_bcast = True;
- use_bcast = True;
- break;
- case 'U':
- bcast_addr = *interpret_addr2(poptGetOptArg(pc));
- got_bcast = True;
- use_bcast = False;
- break;
- case 'T':
- translate_addresses = !translate_addresses;
- break;
- }
- }
-
- poptGetArg(pc); /* Remove argv[0] */
-
- if(!poptPeekArg(pc)) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
- }
-
- if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
- }
-
- load_interfaces();
- if (!open_sockets()) return(1);
-
- while(poptPeekArg(pc))
- {
- char *p;
- struct in_addr ip;
-
- fstrcpy(lookup,poptGetArg(pc));
-
- if(lookup_by_ip)
- {
- ip = *interpret_addr2(lookup);
- fstrcpy(lookup,"*");
- do_node_status(ServerFD, lookup, lookup_type, ip);
- continue;
- }
-
- if (find_master) {
- if (*lookup == '-') {
- fstrcpy(lookup,"\01\02__MSBROWSE__\02");
- lookup_type = 1;
- } else {
- lookup_type = 0x1d;
- }
- }
-
- p = strchr_m(lookup,'#');
- if (p) {
- *p = '\0';
- sscanf(++p,"%x",&lookup_type);
- }
-
- if (!query_one(lookup, lookup_type)) {
- d_printf( "name_query failed to find name %s", lookup );
- if( 0 != lookup_type )
- d_printf( "#%02x", lookup_type );
- d_printf( "\n" );
- }
- }
-
- poptFreeContext(pc);
- TALLOC_FREE(frame);
- return(0);
+ int opt;
+ unsigned int lookup_type = 0x0;
+ fstring lookup;
+ static bool find_master=False;
+ static bool lookup_by_ip = False;
+ poptContext pc;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
+ { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" },
+ { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
+ { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" },
+ { "recursion", 'R', POPT_ARG_VAL, NULL, 'R', "Set recursion desired in package" },
+ { "status", 'S', POPT_ARG_VAL, NULL, 'S', "Lookup node status as well" },
+ { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
+ { "root-port", 'r', POPT_ARG_VAL, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
+ { "lookup-by-ip", 'A', POPT_ARG_VAL, NULL, 'A', "Do a node status on <name> as an IP Address" },
+ POPT_COMMON_SAMBA
+ POPT_COMMON_CONNECTION
+ { 0, 0, 0, 0 }
+ };
+
+ *lookup = 0;
+
+ load_case_tables();
+
+ setup_logging(argv[0],True);
+
+ pc = poptGetContext("nmblookup", argc, (const char **)argv,
+ long_options, POPT_CONTEXT_KEEP_FIRST);
+
+ poptSetOtherOptionHelp(pc, "<NODE> ...");
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ case 'f':
+ give_flags = true;
+ break;
+ case 'M':
+ find_master = true;
+ break;
+ case 'R':
+ recursion_desired = true;
+ break;
+ case 'S':
+ find_status = true;
+ break;
+ case 'r':
+ RootPort = true;
+ break;
+ case 'A':
+ lookup_by_ip = true;
+ break;
+ case 'B':
+ if (interpret_string_addr(&bcast_addr,
+ poptGetOptArg(pc),
+ NI_NUMERICHOST)) {
+ got_bcast = True;
+ use_bcast = True;
+ }
+ break;
+ case 'U':
+ if (interpret_string_addr(&bcast_addr,
+ poptGetOptArg(pc),
+ 0)) {
+ got_bcast = True;
+ use_bcast = False;
+ }
+ break;
+ case 'T':
+ translate_addresses = !translate_addresses;
+ break;
+ }
+ }
+
+ poptGetArg(pc); /* Remove argv[0] */
+
+ if(!poptPeekArg(pc)) {
+ poptPrintUsage(pc, stderr, 0);
+ exit(1);
+ }
+
+ if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ dyn_CONFIGFILE);
+ }
+
+ load_interfaces();
+ if (!open_sockets()) {
+ return(1);
+ }
+
+ while(poptPeekArg(pc)) {
+ char *p;
+ struct in_addr ip;
+
+ fstrcpy(lookup,poptGetArg(pc));
+
+ if(lookup_by_ip) {
+ struct sockaddr_storage ss;
+ ip = *interpret_addr2(lookup);
+ in_addr_to_sockaddr_storage(&ss, ip);
+ fstrcpy(lookup,"*");
+ do_node_status(ServerFD, lookup, lookup_type, &ss);
+ continue;
+ }
+
+ if (find_master) {
+ if (*lookup == '-') {
+ fstrcpy(lookup,"\01\02__MSBROWSE__\02");
+ lookup_type = 1;
+ } else {
+ lookup_type = 0x1d;
+ }
+ }
+
+ p = strchr_m(lookup,'#');
+ if (p) {
+ *p = '\0';
+ sscanf(++p,"%x",&lookup_type);
+ }
+
+ if (!query_one(lookup, lookup_type)) {
+ d_printf( "name_query failed to find name %s", lookup );
+ if( 0 != lookup_type ) {
+ d_printf( "#%02x", lookup_type );
+ }
+ d_printf( "\n" );
+ }
+ }
+
+ poptFreeContext(pc);
+ TALLOC_FREE(frame);
+ return(0);
}
}
-/*****************************************************
-return a connection to a server
+/*****************************************************
+ Return a connection to a server.
*******************************************************/
+
static struct cli_state *connect_one(const char *share)
{
struct cli_state *c;
- struct in_addr ip;
+ struct sockaddr_storage ss;
NTSTATUS nt_status;
- zero_ip_v4(&ip);
-
+ zero_addr(&ss, AF_INET);
+
if (!cmdline_auth_info.got_pass) {
char *pass = getpass("Password: ");
if (pass) {
}
if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,
- &ip, 0,
- share, "?????",
+ &ss, 0,
+ share, "?????",
cmdline_auth_info.username, lp_workgroup(),
cmdline_auth_info.password, 0,
cmdline_auth_info.signing_state, NULL))) {
return 0;
}
-/*****************************************************
-return a connection to a server
+/*****************************************************
+ Return a connection to a server.
*******************************************************/
+
static struct cli_state *connect_one(const char *share)
{
struct cli_state *c;
- struct in_addr ip;
+ struct sockaddr_storage ss;
NTSTATUS nt_status;
- zero_ip_v4(&ip);
-
+ zero_addr(&ss, AF_INET);
+
if (!cmdline_auth_info.got_pass) {
char *pass = getpass("Password: ");
if (pass) {
}
if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server,
- &ip, 0,
- share, "?????",
+ &ss, 0,
+ share, "?????",
cmdline_auth_info.username, lp_workgroup(),
cmdline_auth_info.password, 0,
cmdline_auth_info.signing_state, NULL))) {
{
struct in_addr loopback_ip;
int fd, count, flags;
- struct in_addr *ip_list;
+ struct sockaddr_storage *ss_list;
+ struct sockaddr_storage ss;
loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+ in_addr_to_sockaddr_storage(&ss, loopback_ip);
if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
- interpret_addr("127.0.0.1"), True)) != -1) {
- if ((ip_list = name_query(fd, "__SAMBA__", 0,
- True, True, loopback_ip,
+ &ss, True)) != -1) {
+ if ((ss_list = name_query(fd, "__SAMBA__", 0,
+ True, True, &ss,
&count, &flags, NULL)) != NULL) {
- SAFE_FREE(ip_list);
+ SAFE_FREE(ss_list);
close(fd);
return True;
}
struct in_addr loopback_ip;
NTSTATUS status;
struct cli_state *cli;
+ struct sockaddr_storage ss;
loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
+ in_addr_to_sockaddr_storage(&ss, loopback_ip);
if ((cli = cli_initialise()) == NULL)
return False;
- status = cli_connect(cli, global_myname(), &loopback_ip);
+ status = cli_connect(cli, global_myname(), &ss);
if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(cli);
return False;
/* A working DC */
fstring dcname;
- struct sockaddr_in dcaddr;
+ struct sockaddr_storage dcaddr;
/* Sequence number stuff */
ADS_STRUCT *ads;
ADS_STATUS status;
fstring dc_name;
- struct in_addr dc_ip;
+ struct sockaddr_storage dc_ss;
DEBUG(10,("ads_cached_connection\n"));
ads_destroy( &ads );
ads_kdestroy("MEMORY:winbind_ccache");
domain->private_data = NULL;
- }
+ }
}
/* we don't want this to affect the users ccache */
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
- /* always give preference to the alt_name in our
+ /* always give preference to the alt_name in our
primary domain if possible */
if ( !domain->primary )
ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME;
/* Setup the server affinity cache. We don't reaally care
- about the name. Just setup affinity and the KRB5_CONFIG
+ about the name. Just setup affinity and the KRB5_CONFIG
file. */
- get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ip );
-
+ get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss );
+
status = ads_connect(ads);
if (!ADS_ERR_OK(status) || !ads->config.realm) {
- DEBUG(1,("ads_connect for domain %s failed: %s\n",
+ DEBUG(1,("ads_connect for domain %s failed: %s\n",
domain->name, ads_errstr(status)));
ads_destroy(&ads);
return NULL;
}
- /* set the flag that says we don't own the memory even
- though we do so that ads_destroy() won't destroy the
+ /* set the flag that says we don't own the memory even
+ though we do so that ads_destroy() won't destroy the
structure we pass back by reference */
ads->is_mine = False;
struct dc_name_ip {
fstring name;
- struct in_addr ip;
+ struct sockaddr_storage ss;
};
extern struct winbindd_methods reconnect_methods;
}
static bool get_dc_name_via_netlogon(const struct winbindd_domain *domain,
- fstring dcname, struct in_addr *dc_ip)
+ fstring dcname,
+ struct sockaddr_storage *dc_ss)
{
struct winbindd_domain *our_domain = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname));
- if (!resolve_name(dcname, dc_ip, 0x20)) {
+ if (!resolve_name(dcname, dc_ss, 0x20)) {
return False;
}
}
static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
- const char *dcname, struct in_addr ip,
+ const char *dcname, struct sockaddr_storage *pss,
struct dc_name_ip **dcs, int *num)
{
if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
return False;
fstrcpy((*dcs)[*num].name, dcname);
- (*dcs)[*num].ip = ip;
+ (*dcs)[*num].ss = *pss;
*num += 1;
return True;
}
static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
- struct in_addr ip, uint16 port,
- struct sockaddr_in **addrs, int *num)
+ struct sockaddr_storage *pss, uint16 port,
+ struct sockaddr_storage **addrs, int *num)
{
- *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
+ *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
if (*addrs == NULL) {
*num = 0;
return False;
}
- (*addrs)[*num].sin_family = PF_INET;
- putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
- (*addrs)[*num].sin_port = htons(port);
-
+ (*addrs)[*num] = *pss;
*num += 1;
return True;
}
fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
}
-static bool send_getdc_request(struct in_addr dc_ip,
+static bool send_getdc_request(struct sockaddr_storage *dc_ss,
const char *domain_name,
const DOM_SID *sid)
{
- pstring outbuf;
+ char outbuf[1024];
+ struct in_addr dc_ip;
char *p;
fstring my_acct_name;
fstring my_mailslot;
+ if (dc_ss->ss_family != AF_INET) {
+ return false;
+ }
+
+ dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr;
mailslot_name(dc_ip, my_mailslot);
memset(outbuf, '\0', sizeof(outbuf));
SIVAL(p, 0, 0); /* The sender's token ... */
p += 2;
- p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
+ p += dos_PutUniCode(p, global_myname(),
+ sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
fstr_sprintf(my_acct_name, "%s$", global_myname());
- p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
+ p += dos_PutUniCode(p, my_acct_name,
+ sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
+
+ if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+ return false;
+ }
memcpy(p, my_mailslot, strlen(my_mailslot)+1);
p += strlen(my_mailslot)+1;
+ if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) {
+ return false;
+ }
+
SIVAL(p, 0, 0x80);
p+=4;
p+=4;
p = ALIGN4(p, outbuf);
+ if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) {
+ return false;
+ }
sid_linearize(p, sid_size(sid), sid);
+ if (sid_size(sid) + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+ return false;
+ }
+
p += sid_size(sid);
SIVAL(p, 0, 1);
False, "\\MAILSLOT\\NET\\NTLOGON", 0,
outbuf, PTR_DIFF(p, outbuf),
global_myname(), 0, domain_name, 0x1c,
- dc_ip);
+ dc_ss);
}
-static bool receive_getdc_response(struct in_addr dc_ip,
+static bool receive_getdc_response(struct sockaddr_storage *dc_ss,
const char *domain_name,
fstring dc_name)
{
char *buf, *p;
fstring dcname, user, domain;
int len;
+ struct in_addr dc_ip;
+ if (dc_ss->ss_family != AF_INET) {
+ return false;
+ }
+ dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr;
mailslot_name(dc_ip, my_mailslot);
packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
convert an ip to a name
*******************************************************************/
-static bool dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip, fstring name )
+static bool dcip_to_name(const struct winbindd_domain *domain,
+ struct sockaddr_storage *pss,
+ fstring name )
{
struct ip_service ip_list;
- ip_list.ip = ip;
+ ip_list.ss = *pss;
ip_list.port = 0;
#ifdef WITH_ADS
if (lp_security() == SEC_ADS) {
ADS_STRUCT *ads;
+ char addr[INET6_ADDRSTRLEN];
+
+ print_sockaddr(addr, sizeof(addr), pss);
ads = ads_init(domain->alt_name, domain->name, NULL);
ads->auth.flags |= ADS_AUTH_NO_BIND;
- if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
+ if (ads_try_connect(ads, addr)) {
/* We got a cldap packet. */
fstrcpy(name, ads->config.ldap_server_name);
namecache_store(name, 0x20, 1, &ip_list);
create_local_private_krb5_conf_for_domain(domain->alt_name,
domain->name,
sitename,
- ip);
+ pss);
SAFE_FREE(sitename);
} else {
create_local_private_krb5_conf_for_domain(domain->alt_name,
domain->name,
NULL,
- ip);
+ pss);
}
winbindd_set_locator_kdc_envs(domain);
#endif
/* try GETDC requests next */
-
- if (send_getdc_request(ip, domain->name, &domain->sid)) {
+
+ if (send_getdc_request(pss, domain->name, &domain->sid)) {
int i;
smb_msleep(100);
for (i=0; i<5; i++) {
- if (receive_getdc_response(ip, domain->name, name)) {
+ if (receive_getdc_response(pss, domain->name, name)) {
namecache_store(name, 0x20, 1, &ip_list);
return True;
}
/* try node status request */
- if ( name_status_find(domain->name, 0x1c, 0x20, ip, name) ) {
+ if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
namecache_store(name, 0x20, 1, &ip_list);
return True;
}
struct dc_name_ip **dcs, int *num_dcs)
{
fstring dcname;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct ip_service *ip_list = NULL;
int iplist_size = 0;
int i;
is_our_domain = strequal(domain->name, lp_workgroup());
- if ( !is_our_domain
- && get_dc_name_via_netlogon(domain, dcname, &ip)
- && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
+ if ( !is_our_domain
+ && get_dc_name_via_netlogon(domain, dcname, &ss)
+ && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs, num_dcs) )
{
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ss);
DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
- dcname, inet_ntoa(ip)));
+ dcname, addr));
return True;
}
We deliberately don't care about the
return here. */
- get_dc_name(domain->name, domain->alt_name, dcname, &ip);
+ get_dc_name(domain->name, domain->alt_name, dcname, &ss);
sitename = sitename_fetch(domain->alt_name);
if (sitename) {
get_sorted_dc_list(domain->alt_name, sitename, &ip_list, &iplist_size, True);
for ( i=0; i<iplist_size; i++ ) {
- add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
- ip_list[i].ip, dcs, num_dcs);
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &ip_list[i].ss);
+ add_one_dc_unique(mem_ctx,
+ domain->name,
+ addr,
+ &ip_list[i].ss,
+ dcs,
+ num_dcs);
}
SAFE_FREE(ip_list);
get_sorted_dc_list(domain->alt_name, NULL, &ip_list, &iplist_size, True);
for ( i=0; i<iplist_size; i++ ) {
- add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
- ip_list[i].ip, dcs, num_dcs);
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &ip_list[i].ss);
+ add_one_dc_unique(mem_ctx,
+ domain->name,
+ addr,
+ &ip_list[i].ss,
+ dcs,
+ num_dcs);
}
}
the ip now in to make the failed connection cache work */
for ( i=0; i<iplist_size; i++ ) {
- add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
- ip_list[i].ip, dcs, num_dcs);
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr),
+ &ip_list[i].ss);
+ add_one_dc_unique(mem_ctx, domain->name, addr,
+ &ip_list[i].ss, dcs, num_dcs);
}
SAFE_FREE( ip_list );
static bool find_new_dc(TALLOC_CTX *mem_ctx,
const struct winbindd_domain *domain,
- fstring dcname, struct sockaddr_in *addr, int *fd)
+ fstring dcname, struct sockaddr_storage *pss, int *fd)
{
struct dc_name_ip *dcs = NULL;
int num_dcs = 0;
const char **dcnames = NULL;
int num_dcnames = 0;
- struct sockaddr_in *addrs = NULL;
+ struct sockaddr_storage *addrs = NULL;
int num_addrs = 0;
int i, fd_index;
&dcnames, &num_dcnames)) {
return False;
}
- if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
+ if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
&addrs, &num_addrs)) {
return False;
}
&dcnames, &num_dcnames)) {
return False;
}
- if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
+ if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 139,
&addrs, &num_addrs)) {
return False;
}
return False;
/* 5 second timeout. */
- if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
- {
+ if (!open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) {
for (i=0; i<num_dcs; i++) {
+ char ab[INET6_ADDRSTRLEN];
+ print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
"domain %s address %s. Error was %s\n",
- domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
+ domain->name, ab, strerror(errno) ));
winbind_add_failed_connection_entry(domain,
dcs[i].name, NT_STATUS_UNSUCCESSFUL);
}
return False;
}
- *addr = addrs[fd_index];
+ *pss = addrs[fd_index];
- if (*dcnames[fd_index] != '\0' && !is_ipaddress_v4(dcnames[fd_index])) {
+ if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
/* Ok, we've got a name for the DC */
fstrcpy(dcname, dcnames[fd_index]);
return True;
}
/* Try to figure out the name */
- if (dcip_to_name( domain, addr->sin_addr, dcname )) {
+ if (dcip_to_name(domain, pss, dcname)) {
return True;
}
saf_servername, domain->name ));
/* convert an ip address to a name */
- if ( is_ipaddress_v4( saf_servername ) ) {
+ if (is_ipaddress( saf_servername ) ) {
fstring saf_name;
- struct in_addr ip;
+ struct sockaddr_storage ss;
- ip = *interpret_addr2( saf_servername );
- if (dcip_to_name( domain, ip, saf_name )) {
+ if (!interpret_string_addr(&ss, saf_servername,
+ AI_NUMERICHOST)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (dcip_to_name( domain, &ss, saf_name )) {
fstrcpy( domain->dcname, saf_name );
} else {
winbind_add_failed_connection_entry(
}
for (retries = 0; retries < 3; retries++) {
-
int fd = -1;
bool retry = False;
if (*domain->dcname
&& NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
- && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
+ && (resolve_name(domain->dcname, &domain->dcaddr, 0x20)))
{
- struct sockaddr_in *addrs = NULL;
+ struct sockaddr_storage *addrs = NULL;
int num_addrs = 0;
int dummy = 0;
- if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
+ if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 445, &addrs, &num_addrs)) {
set_domain_offline(domain);
talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
- if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
+ if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 139, &addrs, &num_addrs)) {
set_domain_offline(domain);
talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
/**********************************************************************
Get the sequence number for a Windows AD native mode domain using
- LDAP queries.
+ LDAP queries.
**********************************************************************/
static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
{
int ret = -1;
- fstring ipstr;
+ char addr[INET6_ADDRSTRLEN];
- fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
- if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
+ print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
+ if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
- "number for Domain (%s) from DC (%s)\n",
- domain->name, ipstr));
- }
+ "number for Domain (%s) from DC (%s)\n",
+ domain->name, addr));
+ }
return ret;
}
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
domain->name));
- *seq = time(NULL);
+ *seq = time(NULL);
return NT_STATUS_OK;
}
static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain)
{
char *var = NULL;
+ char addr[INET6_ADDRSTRLEN];
const char *kdc = NULL;
int lvl = 11;
return;
}
- kdc = inet_ntoa(domain->dcaddr.sin_addr);
- if (!kdc) {
+ print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
+ kdc = addr;
+ if (!*kdc) {
DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n",
domain->alt_name));
kdc = domain->dcname;
}
-static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
+static NODE_STATUS_STRUCT *lookup_byaddr_backend(const char *addr, int *count)
{
int fd;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct nmb_name nname;
NODE_STATUS_STRUCT *status;
return NULL;
make_nmb_name(&nname, "*", 0);
- ip = *interpret_addr2(addr);
- status = node_status_query(fd,&nname,ip, count, NULL);
+ if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
+ return NULL;
+ }
+ status = node_status_query(fd, &nname, &ss, count, NULL);
close(fd);
return status;
}
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
+static struct sockaddr_storage *lookup_byname_backend(const char *name,
+ int *count)
{
int fd;
struct ip_service *ret = NULL;
- struct in_addr *return_ip = NULL;
+ struct sockaddr_storage *return_ss = NULL;
int j, i, flags = 0;
*count = 0;
if (NT_STATUS_IS_OK(resolve_wins(name,0x20,&ret,count))) {
if ( *count == 0 )
return NULL;
- if ( (return_ip = SMB_MALLOC_ARRAY(struct in_addr, *count)) == NULL ) {
+ if ( (return_ss = SMB_MALLOC_ARRAY(struct sockaddr_storage, *count)) == NULL ) {
free( ret );
return NULL;
}
/* copy the IP addresses */
- for ( i=0; i<(*count); i++ )
- return_ip[i] = ret[i].ip;
-
+ for ( i=0; i<(*count); i++ )
+ return_ss[i] = ret[i].ss;
+
free( ret );
- return return_ip;
+ return return_ss;
}
fd = wins_lookup_open_socket_in();
for (j=iface_count() - 1;
j >= 0;
j--) {
- const struct in_addr *bcast = iface_n_bcast_v4(j);
- if (!bcast) {
+ const struct sockaddr_storage *bcast_ss = iface_n_bcast(j);
+ if (!bcast_ss) {
continue;
}
- return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (return_ip) {
+ return_ss = name_query(fd,name,0x20,True,True,bcast_ss,count, &flags, NULL);
+ if (return_ss) {
break;
}
}
close(fd);
- return return_ip;
+ return return_ss;
}
/* Get hostname from IP */
void winbindd_wins_byname(struct winbindd_cli_state *state)
{
- struct in_addr *ip_list;
+ struct sockaddr_storage *ip_list = NULL;
int i, count, maxlen, size;
fstring response;
- char * addr;
+ char addr[INET6_ADDRSTRLEN];
/* Ensure null termination */
state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
if ((ip_list = lookup_byname_backend(state->request.data.winsreq,&count))){
for (i = count; i ; i--) {
- addr = inet_ntoa(ip_list[i-1]);
- size = strlen(addr);
- if (size > maxlen) {
- SAFE_FREE(ip_list);
- request_error(state);
- return;
- }
- if (i != 0) {
- /* Clear out the newline character */
- /* But only if there is something in there,
- otherwise we clobber something in the stack */
- if (strlen(response))
- response[strlen(response)-1] = ' ';
- }
- fstrcat(response,addr);
- fstrcat(response,"\t");
+ print_sockaddr(addr, sizeof(addr), &ip_list[i-1]);
+ size = strlen(addr);
+ if (size > maxlen) {
+ SAFE_FREE(ip_list);
+ request_error(state);
+ return;
+ }
+ if (i != 0) {
+ /* Clear out the newline character */
+ /* But only if there is something in there,
+ otherwise we clobber something in the stack */
+ if (strlen(response)) {
+ response[strlen(response)-1] = ' ';
+ }
+ }
+ fstrcat(response,addr);
+ fstrcat(response,"\t");
}
size = strlen(state->request.data.winsreq) + strlen(response);
if (size > maxlen) {
SAFE_FREE(ip_list);
request_error(state);
return;
- }
+ }
fstrcat(response,state->request.data.winsreq);
fstrcat(response,"\n");
SAFE_FREE(ip_list);