Ejemplo n.º 1
0
bool run_smb_any_connect(int dummy)
{
	int fd;
	NTSTATUS status;
	struct sockaddr_storage addrs[5];
	size_t chosen_index;
	uint16_t port;

	interpret_string_addr(&addrs[0], "192.168.99.5", 0);
	interpret_string_addr(&addrs[1], "192.168.99.6", 0);
	interpret_string_addr(&addrs[2], "192.168.99.7", 0);
	interpret_string_addr(&addrs[3], "192.168.99.8", 0);
	interpret_string_addr(&addrs[4], "192.168.99.9", 0);

	status = smbsock_any_connect(addrs, NULL, NULL, NULL, NULL,
				     ARRAY_SIZE(addrs), 0, 0,
				     &fd, &chosen_index, &port);

	d_printf("smbsock_any_connect returned %s (fd %d)\n",
		 nt_errstr(status), NT_STATUS_IS_OK(status) ? fd : -1);
	if (NT_STATUS_IS_OK(status)) {
		close(fd);
	}
	return true;
}
Ejemplo n.º 2
0
/* masked_match - match address against netnumber/netmask */
static bool masked_match(const char *tok, const char *slash, const char *s)
{
	struct sockaddr_storage ss_mask;
	struct sockaddr_storage ss_tok;
	struct sockaddr_storage ss_host;
	char *tok_copy = NULL;

	if (!interpret_string_addr(&ss_host, s, 0)) {
		return false;
	}

	if (*tok == '[') {
		/* IPv6 address - remove braces. */
		tok_copy = SMB_STRDUP(tok+1);
		if (!tok_copy) {
			return false;
		}
		/* Remove the terminating ']' */
		tok_copy[PTR_DIFF(slash,tok)-1] = '\0';
	} else {
		tok_copy = SMB_STRDUP(tok);
		if (!tok_copy) {
			return false;
		}
		/* Remove the terminating '/' */
		tok_copy[PTR_DIFF(slash,tok)] = '\0';
	}

	if (!interpret_string_addr(&ss_tok, tok_copy, 0)) {
		SAFE_FREE(tok_copy);
		return false;
	}

	SAFE_FREE(tok_copy);

        if (strlen(slash + 1) > 2) {
		if (!interpret_string_addr(&ss_mask, slash+1, 0)) {
			return false;
		}
        } else {
		char *endp = NULL;
		unsigned long val = strtoul(slash+1, &endp, 0);
		if (slash+1 == endp || (endp && *endp != '\0')) {
			return false;
		}
		if (!make_netmask(&ss_mask, &ss_tok, val)) {
			return false;
		}
        }

	return same_net((struct sockaddr *)(void *)&ss_host,
			(struct sockaddr *)(void *)&ss_tok,
			(struct sockaddr *)(void *)&ss_mask);
}
Ejemplo n.º 3
0
static bool open_sockets(void)
{
	struct sockaddr_storage ss;
	const char *sock_addr = lp_nbt_client_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;
	}

	set_socket_options( ServerFD, "SO_BROADCAST" );

	DEBUG(3, ("Socket opened.\n"));
	return true;
}
Ejemplo n.º 4
0
/**
  return true if a IP matches a IP/netmask pair
*/
bool iface_list_same_net(const char *ip1, const char *ip2, const char *netmask)
{
    struct sockaddr_storage ip1_ss, ip2_ss, nm_ss;

    if (!interpret_string_addr(&ip1_ss, ip1, AI_NUMERICHOST)) {
        return false;
    }
    if (!interpret_string_addr(&ip2_ss, ip2, AI_NUMERICHOST)) {
        return false;
    }
    if (!interpret_string_addr(&nm_ss, netmask, AI_NUMERICHOST)) {
        return false;
    }

    return same_net((struct sockaddr *)&ip1_ss,
                    (struct sockaddr *)&ip2_ss,
                    (struct sockaddr *)&nm_ss);
}
Ejemplo n.º 5
0
/**
  return true if an IP is one one of our local networks
*/
bool iface_list_is_local(struct interface *ifaces, const char *dest)
{
    struct sockaddr_storage ss;

    if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) {
        return false;
    }
    if (iface_list_find(ifaces, (const struct sockaddr *)&ss, true)) {
        return true;
    }
    return false;
}
Ejemplo n.º 6
0
static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx,
						 const char *addr, int *count)
{
	struct sockaddr_storage ss;
	struct nmb_name nname;
	struct node_status *result;
	NTSTATUS status;

	make_nmb_name(&nname, "*", 0);
	if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
		return NULL;
	}
	status = node_status_query(mem_ctx, &nname, &ss,
				   &result, count, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}
	return result;
}
Ejemplo n.º 7
0
/**
  return the local IP address that best matches a destination IP, or
  our first interface if none match
*/
const char *iface_list_best_ip(struct interface *ifaces, const char *dest)
{
    struct interface *iface;
    struct sockaddr_storage ss;

    if (!interpret_string_addr(&ss, dest, AI_NUMERICHOST)) {
        return iface_list_n_ip(ifaces, 0);
    }
    iface = iface_list_find(ifaces, (const struct sockaddr *)&ss, true);
    if (iface) {
        return iface->ip_s;
    }
#ifdef HAVE_IPV6
    if (ss.ss_family == AF_INET6) {
        return iface_list_first_v6(ifaces);
    }
#endif
    return iface_list_first_v4(ifaces);
}
Ejemplo n.º 8
0
bool net_find_server(struct net_context *c,
			const char *domain,
			unsigned flags,
			struct sockaddr_storage *server_ss,
			char **server_name)
{
	const char *d = domain ? domain : c->opt_target_workgroup;

	if (c->opt_host) {
		*server_name = SMB_STRDUP(c->opt_host);
	}

	if (c->opt_have_ip) {
		*server_ss = c->opt_dest_ip;
		if (!*server_name) {
			char addr[INET6_ADDRSTRLEN];
			print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip);
			*server_name = SMB_STRDUP(addr);
		}
	} else if (*server_name) {
		/* resolve the IP address */
		if (!resolve_name(*server_name, server_ss, 0x20, false))  {
			DEBUG(1,("Unable to resolve server name\n"));
			return false;
		}
	} else if (flags & NET_FLAGS_PDC) {
		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 sockaddr_storage msbrow_ss;
		char addr[INET6_ADDRSTRLEN];

		/*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */
		if (!resolve_name(d, &msbrow_ss, 0x1B, false))  {
			DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
			return false;
		}
		*server_ss = msbrow_ss;
		print_sockaddr(addr, sizeof(addr), server_ss);
		*server_name = SMB_STRDUP(addr);
	} else if (flags & NET_FLAGS_MASTER) {
		struct sockaddr_storage brow_ss;
		char addr[INET6_ADDRSTRLEN];
		if (!resolve_name(d, &brow_ss, 0x1D, false))  {
				/* go looking for workgroups */
			DEBUG(1,("Unable to resolve master browser via name lookup\n"));
			return false;
		}
		*server_ss = brow_ss;
		print_sockaddr(addr, sizeof(addr), server_ss);
		*server_name = SMB_STRDUP(addr);
	} else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
		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");
	}

	if (!*server_name) {
		DEBUG(1,("no server to connect to\n"));
		return false;
	}

	return true;
}
Ejemplo n.º 9
0
bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
		struct sockaddr_storage *pss)
{
	char line[1024];

	*pp_name = NULL;

	while(!x_feof(fp) && !x_ferror(fp)) {
		char *ip = NULL;
		char *flags = NULL;
		char *extra = NULL;
		char *name = NULL;
		const char *ptr;
		char *ptr1 = NULL;
		int count = 0;

		*name_type = -1;

		if (!fgets_slash(line,sizeof(line),fp)) {
			continue;
		}

		if (*line == '#') {
			continue;
		}

		ptr = line;

		if (next_token_talloc(ctx, &ptr, &ip, NULL))
			++count;
		if (next_token_talloc(ctx, &ptr, &name, NULL))
			++count;
		if (next_token_talloc(ctx, &ptr, &flags, NULL))
			++count;
		if (next_token_talloc(ctx, &ptr, &extra, NULL))
			++count;

		if (count <= 0)
			continue;

		if (count > 0 && count < 2) {
			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"));
			continue;
		}

		if (!flags) {
			flags = talloc_strdup(ctx, "");
			if (!flags) {
				continue;
			}
		}

		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"));
			continue;
		}

		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. */
		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));
				continue;
			}

			*(--ptr1) = '\0'; /* Truncate at the '#' */
		}

		*pp_name = talloc_strdup(ctx, name);
		if (!*pp_name) {
			return false;
		}
		return true;
	}

	return false;
}
Ejemplo n.º 10
0
static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
				   struct messaging_context *msg_ctx,
				   const char *domain_name,
				   uint32_t flags,
				   struct ip_service_name *dclist,
				   int num_dcs,
				   struct netr_DsRGetDCNameInfo **info)
{
	struct sockaddr_storage ss;
	struct ip_service ip_list;
	enum nbt_name_type name_type = NBT_NAME_LOGON;
	NTSTATUS status;
	int i;
	const char *dc_name = NULL;
	fstring tmp_dc_name;
	struct netlogon_samlogon_response *r = NULL;
	bool store_cache = false;
	uint32_t nt_version = NETLOGON_NT_VERSION_1 |
			      NETLOGON_NT_VERSION_5 |
			      NETLOGON_NT_VERSION_5EX_WITH_IP;

	if (!msg_ctx) {
		msg_ctx = msg_context(mem_ctx);
	}

	if (flags & DS_PDC_REQUIRED) {
		name_type = NBT_NAME_PDC;
	}

	nt_version |= map_ds_flags_to_nt_version(flags);

	DEBUG(10,("process_dc_netbios\n"));

	for (i=0; i<num_dcs; i++) {

		ip_list.ss = dclist[i].ss;
		ip_list.port = 0;

		if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
			return NT_STATUS_UNSUCCESSFUL;
		}

		if (send_getdc_request(mem_ctx, msg_ctx,
				       &dclist[i].ss, domain_name,
				       NULL, nt_version))
		{
			int k;
			smb_msleep(300);
			for (k=0; k<5; k++) {
				if (receive_getdc_response(mem_ctx,
							   &dclist[i].ss,
							   domain_name,
							   &nt_version,
							   &dc_name,
							   &r)) {
					store_cache = true;
					namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list);
					goto make_reply;
				}
				smb_msleep(1500);
			}
		}

		if (name_status_find(domain_name,
				     name_type,
				     NBT_NAME_SERVER,
				     &dclist[i].ss,
				     tmp_dc_name))
		{
			struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1;

			r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response);
			NT_STATUS_HAVE_NO_MEMORY(r);

			ZERO_STRUCT(logon1);

			nt_version = NETLOGON_NT_VERSION_1;

			logon1.nt_version = nt_version;
			logon1.server = tmp_dc_name;
			logon1.domain = talloc_strdup_upper(mem_ctx, domain_name);
			NT_STATUS_HAVE_NO_MEMORY(logon1.domain);

			r->data.nt4 = logon1;
			r->ntver = nt_version;

			map_netlogon_samlogon_response(r);

			namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);

			goto make_reply;
		}
	}

	return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;

 make_reply:

	status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					       &r->data.nt5_ex, info);
	if (NT_STATUS_IS_OK(status) && store_cache) {
		return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					 nt_version, &r->data.nt5_ex);
	}

	return status;
}
Ejemplo n.º 11
0
static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
				const char *domain_name,
				struct GUID *domain_guid,
				uint32_t flags,
				const char *site_name,
				struct ip_service_name **returned_dclist,
				int *return_count)
{
	int i, j;
	NTSTATUS status;
	struct dns_rr_srv *dcs = NULL;
	int numdcs = 0;
	int numaddrs = 0;
	struct ip_service_name *dclist = NULL;
	int count = 0;

	if (flags & DS_PDC_REQUIRED) {
		status = ads_dns_query_pdc(mem_ctx, domain_name,
					   &dcs, &numdcs);
	} else if (flags & DS_GC_SERVER_REQUIRED) {
		status = ads_dns_query_gcs(mem_ctx, domain_name, site_name,
					   &dcs, &numdcs);
	} else if (flags & DS_KDC_REQUIRED) {
		status = ads_dns_query_kdcs(mem_ctx, domain_name, site_name,
					    &dcs, &numdcs);
	} else if (flags & DS_DIRECTORY_SERVICE_REQUIRED) {
		status = ads_dns_query_dcs(mem_ctx, domain_name, site_name,
					   &dcs, &numdcs);
	} else if (domain_guid) {
		status = ads_dns_query_dcs_guid(mem_ctx, domain_name,
						domain_guid, &dcs, &numdcs);
	} else {
		status = ads_dns_query_dcs(mem_ctx, domain_name, site_name,
					   &dcs, &numdcs);
	}

	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (numdcs == 0) {
		return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
	}

	for (i=0;i<numdcs;i++) {
		numaddrs += MAX(dcs[i].num_ips,1);
	}

	dclist = TALLOC_ZERO_ARRAY(mem_ctx,
				   struct ip_service_name,
				   numaddrs);
	if (!dclist) {
		return NT_STATUS_NO_MEMORY;
	}

	/* now unroll the list of IP addresses */

	*return_count = 0;
	i = 0;
	j = 0;

	while ((i < numdcs) && (count < numaddrs)) {

		struct ip_service_name *r = &dclist[count];

		r->port = dcs[i].port;
		r->hostname = dcs[i].hostname;

		/* If we don't have an IP list for a name, lookup it up */

		if (!dcs[i].ss_s) {
			interpret_string_addr(&r->ss, dcs[i].hostname, 0);
			i++;
			j = 0;
		} else {
			/* use the IP addresses from the SRV sresponse */

			if (j >= dcs[i].num_ips) {
				i++;
				j = 0;
				continue;
			}

			r->ss = dcs[i].ss_s[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_addr(&r->ss)) {
			count++;
			continue;
		}
	}

	*returned_dclist = dclist;
	*return_count = count;

	if (count > 0) {
		return NT_STATUS_OK;
	}

	return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
}
Ejemplo n.º 12
0
/*
  setup a listen stream socket
  if you pass *port == 0, then a port > 1024 is used

  FIXME: This function is TCP/IP specific - uses an int rather than 
  	 a string for the port. Should leave allocating a port nr 
         to the socket implementation - JRV20070903
 */
NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx,
			     struct tevent_context *event_context,
			     struct loadparm_context *lp_ctx,
			     const struct model_ops *model_ops,
			     const struct stream_server_ops *stream_ops,
			     const char *family,
			     const char *sock_addr,
			     uint16_t *port,
			     const char *socket_options,
			     void *private_data)
{
	NTSTATUS status;
	struct stream_socket *stream_socket;
	struct socket_address *socket_address;
	struct tevent_fd *fde;
	int i;
	struct sockaddr_storage ss;

	stream_socket = talloc_zero(mem_ctx, struct stream_socket);
	NT_STATUS_HAVE_NO_MEMORY(stream_socket);

	if (strcmp(family, "ip") == 0) {
		/* we will get the real family from the address itself */
		if (!interpret_string_addr(&ss, sock_addr, 0)) {
			talloc_free(stream_socket);
			return NT_STATUS_INVALID_ADDRESS;
		}

		socket_address = socket_address_from_sockaddr_storage(stream_socket, &ss, port?*port:0);
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(socket_address, stream_socket);

		status = socket_create(socket_address->family, SOCKET_TYPE_STREAM, &stream_socket->sock, 0);
		NT_STATUS_NOT_OK_RETURN(status);
	} else {
		status = socket_create(family, SOCKET_TYPE_STREAM, &stream_socket->sock, 0);
		NT_STATUS_NOT_OK_RETURN(status);

		/* this is for non-IP sockets, eg. unix domain sockets */
		socket_address = socket_address_from_strings(stream_socket,
							     stream_socket->sock->backend_name,
							     sock_addr, port?*port:0);
		NT_STATUS_HAVE_NO_MEMORY(socket_address);
	}


	talloc_steal(stream_socket, stream_socket->sock);

	stream_socket->lp_ctx = talloc_reference(stream_socket, lp_ctx);

	/* ready to listen */
	status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE", NULL);
	NT_STATUS_NOT_OK_RETURN(status);

	if (socket_options != NULL) {
		status = socket_set_option(stream_socket->sock, socket_options, NULL);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	/* TODO: set socket ACL's (host allow etc) here when they're
	 * implemented */

	/* Some sockets don't have a port, or are just described from
	 * the string.  We are indicating this by having port == NULL */
	if (!port) {
		status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0);
	} else if (*port == 0) {
		for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) {
			socket_address->port = i;
			status = socket_listen(stream_socket->sock, socket_address, 
					       SERVER_LISTEN_BACKLOG, 0);
			if (NT_STATUS_IS_OK(status)) {
				*port = i;
				break;
			}
		}
	} else {
		status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0);
	}

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Failed to listen on %s:%u - %s\n",
			 sock_addr, port ? (unsigned int)(*port) : 0,
			 nt_errstr(status)));
		talloc_free(stream_socket);
		return status;
	}

	/* Add the FD from the newly created socket into the event
	 * subsystem.  it will call the accept handler whenever we get
	 * new connections */

	fde = tevent_add_fd(event_context, stream_socket->sock,
			    socket_get_fd(stream_socket->sock),
			    TEVENT_FD_READ,
			    stream_accept_handler, stream_socket);
	if (!fde) {
		DEBUG(0,("Failed to setup fd event\n"));
		talloc_free(stream_socket);
		return NT_STATUS_NO_MEMORY;
	}

	/* we let events system to the close on the socket. This avoids
	 * nasty interactions with waiting for talloc to close the socket. */
	tevent_fd_set_close_fn(fde, socket_tevent_fd_close_fn);
	socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);

	stream_socket->private_data     = talloc_reference(stream_socket, private_data);
	stream_socket->ops              = stream_ops;
	stream_socket->event_ctx	= event_context;
	stream_socket->model_ops        = model_ops;

	return NT_STATUS_OK;
}
Ejemplo n.º 13
0
static bool open_sockets_smbd(struct smbd_parent_context *parent,
			      struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx,
			      const char *smb_ports)
{
	int num_interfaces = iface_count();
	int i,j;
	const char **ports;
	unsigned dns_port = 0;

#ifdef HAVE_ATEXIT
	atexit(killkids);
#endif

	/* Stop zombies */
	smbd_setup_sig_chld_handler(parent);

	ports = lp_smb_ports();

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (smb_ports) {
		char **l;
		l = str_list_make_v3(talloc_tos(), smb_ports, NULL);
		ports = discard_const_p(const char *, l);
	}

	for (j = 0; ports && ports[j]; j++) {
		unsigned port = atoi(ports[j]);

		if (port == 0 || port > 0xffff) {
			exit_server_cleanly("Invalid port in the config or on "
					    "the commandline specified!");
		}
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* 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);
			if (ifss == NULL) {
				DEBUG(0,("open_sockets_smbd: "
					"interface %d has NULL IP address !\n",
					i));
				continue;
			}

			for (j = 0; ports && ports[j]; j++) {
				unsigned port = atoi(ports[j]);

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				if (!smbd_open_one_socket(parent,
							  ev_ctx,
							  ifss,
							  port)) {
					return false;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		const char *sock_addr;
		char *sock_tok;
		const char *sock_ptr;

#if HAVE_IPV6
		sock_addr = "::,0.0.0.0";
#else
		sock_addr = "0.0.0.0";
#endif

		for (sock_ptr=sock_addr;
		     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
			for (j = 0; ports && ports[j]; j++) {
				struct sockaddr_storage ss;
				unsigned port = atoi(ports[j]);

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				/* open an incoming socket */
				if (!interpret_string_addr(&ss, sock_tok,
						AI_NUMERICHOST|AI_PASSIVE)) {
					continue;
				}

				/*
				 * If we fail to open any sockets
				 * in this loop the parent-sockets == NULL
				 * case below will prevent us from starting.
				 */

				(void)smbd_open_one_socket(parent,
						  ev_ctx,
						  &ss,
						  port);
			}
		}
	}

	if (parent->sockets == NULL) {
		DEBUG(0,("open_sockets_smbd: No "
			"sockets available to bind to.\n"));
		return false;
	}

	/* Setup the main smbd so that we can get messages. Note that
	   do this after starting listening. This is needed as when in
	   clustered mode, ctdb won't allow us to start doing database
	   operations until it has gone thru a full startup, which
	   includes checking to see that smbd is listening. */

	if (!serverid_register(messaging_server_id(msg_ctx),
			       FLAG_MSG_GENERAL|FLAG_MSG_SMBD
			       |FLAG_MSG_PRINT_GENERAL
			       |FLAG_MSG_DBWRAP)) {
		DEBUG(0, ("open_sockets_smbd: Failed to register "
			  "myself in serverid.tdb\n"));
		return false;
	}

        /* Listen to messages */

	messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
	messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
			   smbd_parent_conf_updated);
	messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
			   smb_stat_cache_delete);
	messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
	messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE,
			   brl_revalidate);
	messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
			   smb_parent_send_to_children);
	messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
			   smb_parent_send_to_children);
	messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,
			   smb_tell_num_children);

	messaging_register(msg_ctx, NULL,
			   ID_CACHE_DELETE, smbd_parent_id_cache_delete);
	messaging_register(msg_ctx, NULL,
			   ID_CACHE_KILL, smbd_parent_id_cache_kill);

	if (lp_clustering()) {
		struct ctdbd_connection *conn = messaging_ctdbd_connection();

		register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE,
				    smbd_parent_ctdb_reconfigured, msg_ctx);
		register_with_ctdbd(conn, CTDB_SRVID_SAMBA_NOTIFY,
				    smbd_parent_ctdb_reconfigured, msg_ctx);
	}

#ifdef DEVELOPER
	messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
			   msg_inject_fault);
#endif

	if (lp_multicast_dns_register() && (dns_port != 0)) {
#ifdef WITH_DNSSD_SUPPORT
		smbd_setup_mdns_registration(ev_ctx,
					     parent, dns_port);
#endif
#ifdef WITH_AVAHI_SUPPORT
		void *avahi_conn;

		avahi_conn = avahi_start_register(ev_ctx,
						  ev_ctx,
						  dns_port);
		if (avahi_conn == NULL) {
			DEBUG(10, ("avahi_start_register failed\n"));
		}
#endif
	}

	return true;
}
Ejemplo n.º 14
0
/****************************************************************************
  main program
****************************************************************************/
int main(int argc, const char *argv[])
{
	int opt;
	unsigned int lookup_type = 0x0;
	fstring lookup;
	static bool find_master=False;
	static bool lookup_by_ip = False;
	poptContext pc = NULL;
	TALLOC_CTX *frame = talloc_stackframe();
	int rc = 0;

	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_NONE, NULL, 'R', "Set recursion desired in package" },
		{ "status", 'S', POPT_ARG_NONE, NULL, 'S', "Lookup node status as well" },
		{ "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
		{ "root-port", 'r', POPT_ARG_NONE, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
		{ "lookup-by-ip", 'A', POPT_ARG_NONE, 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], DEBUG_STDOUT);

	pc = poptGetContext("nmblookup", argc, 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);
		rc = 1;
		goto out;
	}

	if (!lp_load_global(get_dyn_CONFIGFILE())) {
		fprintf(stderr, "Can't load %s - run testparm to debug it\n",
				get_dyn_CONFIGFILE());
	}

	load_interfaces();
	if (!open_sockets()) {
		rc = 1;
		goto out;
	}

	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,"*");
			if (!do_node_status(lookup, lookup_type, &ss)) {
				rc = 1;
			}
			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)) {
			rc = 1;
			d_printf( "name_query failed to find name %s", lookup );
			if( 0 != lookup_type ) {
				d_printf( "#%02x", lookup_type );
			}
			d_printf( "\n" );
		}
	}

out:
	poptFreeContext(pc);
	TALLOC_FREE(frame);
	return rc;
}
Ejemplo n.º 15
0
/****************************************************************************
  main program
****************************************************************************/
 int main(int argc, const char **argv)
{
	int opt,i;
	char *p;
	int rc = 0;
	int argc_new = 0;
	const char ** argv_new;
	poptContext pc;
	TALLOC_CTX *frame = talloc_stackframe();
	struct net_context *c = talloc_zero(frame, struct net_context);

	struct poptOption long_options[] = {
		{"help",	'h', POPT_ARG_NONE,   0, 'h'},
		{"workgroup",	'w', POPT_ARG_STRING, &c->opt_target_workgroup},
		{"user",	'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
		{"ipaddress",	'I', POPT_ARG_STRING, 0,'I'},
		{"port",	'p', POPT_ARG_INT,    &c->opt_port},
		{"myname",	'n', POPT_ARG_STRING, &c->opt_requester_name},
		{"server",	'S', POPT_ARG_STRING, &c->opt_host},
		{"encrypt",	'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
		{"container",	'c', POPT_ARG_STRING, &c->opt_container},
		{"comment",	'C', POPT_ARG_STRING, &c->opt_comment},
		{"maxusers",	'M', POPT_ARG_INT,    &c->opt_maxusers},
		{"flags",	'F', POPT_ARG_INT,    &c->opt_flags},
		{"long",	'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
		{"reboot",	'r', POPT_ARG_NONE,   &c->opt_reboot},
		{"force",	'f', POPT_ARG_NONE,   &c->opt_force},
		{"stdin",	'i', POPT_ARG_NONE,   &c->opt_stdin},
		{"timeout",	't', POPT_ARG_INT,    &c->opt_timeout},
		{"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
		{"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
		{"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
		{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
		{"verbose",	'v', POPT_ARG_NONE,   &c->opt_verbose},
		{"test",	'T', POPT_ARG_NONE,   &c->opt_testmode},
		/* Options for 'net groupmap set' */
		{"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
		{"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
		{"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
		{"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
		/* Options for 'net rpc share migrate' */
		{"acls",	0, POPT_ARG_NONE,     &c->opt_acls},
		{"attrs",	0, POPT_ARG_NONE,     &c->opt_attrs},
		{"timestamps",	0, POPT_ARG_NONE,     &c->opt_timestamps},
		{"exclude",	'X', POPT_ARG_STRING, &c->opt_exclude},
		{"destination",	0, POPT_ARG_STRING,   &c->opt_destination},
		{"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
		/* Options for 'net rpc vampire (keytab)' */
		{"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
		{"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
		{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},

		POPT_COMMON_SAMBA
		{ 0, 0, 0, 0}
	};


	zero_sockaddr(&c->opt_dest_ip);

	load_case_tables();

	/* set default debug level to 0 regardless of what smb.conf sets */
	DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
	dbf = x_stderr;
	c->private_data = net_func;

	pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 'h':
			c->display_usage = true;
			break;
		case 'e':
			c->smb_encrypt = true;
			break;
		case 'I':
			if (!interpret_string_addr(&c->opt_dest_ip,
						poptGetOptArg(pc), 0)) {
				d_fprintf(stderr, "\nInvalid ip address specified\n");
			} else {
				c->opt_have_ip = true;
			}
			break;
		case 'U':
			c->opt_user_specified = true;
			c->opt_user_name = SMB_STRDUP(c->opt_user_name);
			p = strchr(c->opt_user_name,'%');
			if (p) {
				*p = 0;
				c->opt_password = p+1;
			}
			break;
		default:
			d_fprintf(stderr, "\nInvalid option %s: %s\n",
				 poptBadOption(pc, 0), poptStrerror(opt));
			net_help(c, argc, argv);
			exit(1);
		}
	}

	/*
	 * Don't load debug level from smb.conf. It should be
	 * set by cmdline arg or remain default (0)
	 */
	AllowDebugChange = false;
	lp_load(get_dyn_CONFIGFILE(), true, false, false, true);

 	argv_new = (const char **)poptGetArgs(pc);

	argc_new = argc;
	for (i=0; i<argc; i++) {
		if (argv_new[i] == NULL) {
			argc_new = i;
			break;
		}
	}

	if (c->do_talloc_report) {
		talloc_enable_leak_report();
	}

	if (c->opt_requester_name) {
		set_global_myname(c->opt_requester_name);
	}

	if (!c->opt_user_name && getenv("LOGNAME")) {
		c->opt_user_name = getenv("LOGNAME");
	}

	if (!c->opt_workgroup) {
		c->opt_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!c->opt_target_workgroup) {
		c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!init_names())
		exit(1);

	load_interfaces();

	/* this makes sure that when we do things like call scripts,
	   that it won't assert becouse we are not root */
	sec_init();

	if (c->opt_machine_pass) {
		/* it is very useful to be able to make ads queries as the
		   machine account for testing purposes and for domain leave */

		net_use_krb_machine_account(c);
	}

	if (!c->opt_password) {
		c->opt_password = getenv("PASSWD");
	}

	rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);

	DEBUG(2,("return code = %d\n", rc));

	libnetapi_free(c->netapi_ctx);

	poptFreeContext(pc);

	TALLOC_FREE(frame);
	return rc;
}
Ejemplo n.º 16
0
static bool epmd_open_sockets(struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx)
{
	uint32_t num_ifs = iface_count();
	uint16_t port;
	uint32_t i;

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/*
		 * 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_ifs; i++) {
			const struct sockaddr_storage *ifss =
					iface_n_sockaddr_storage(i);

			port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
							       msg_ctx,
							       ndr_table_epmapper.syntax_id,
							       ifss,
							       135);
			if (port == 0) {
				return false;
			}
		}
	} else {
		const char *sock_addr = lp_socket_address();
		const char *sock_ptr;
		char *sock_tok;

		if (strequal(sock_addr, "0.0.0.0") ||
		    strequal(sock_addr, "::")) {
#if HAVE_IPV6
			sock_addr = "::";
#else
			sock_addr = "0.0.0.0";
#endif
		}

		for (sock_ptr = sock_addr;
		     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
		    ) {
			struct sockaddr_storage ss;

			/* open an incoming socket */
			if (!interpret_string_addr(&ss,
						   sock_tok,
						   AI_NUMERICHOST|AI_PASSIVE)) {
				continue;
			}

			port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
							       msg_ctx,
							       ndr_table_epmapper.syntax_id,
							       &ss,
							       135);
			if (port == 0) {
				return false;
			}
		}
	}

	return true;
}
Ejemplo n.º 17
0
static SMBCSRV *
SMBC_server_internal(TALLOC_CTX *ctx,
            SMBCCTX *context,
            bool connect_if_not_found,
            const char *server,
            const char *share,
            char **pp_workgroup,
            char **pp_username,
            char **pp_password,
	    bool *in_cache)
{
	SMBCSRV *srv=NULL;
	char *workgroup = NULL;
	struct cli_state *c;
	struct nmb_name called, calling;
	const char *server_n = server;
	struct sockaddr_storage ss;
	int tried_reverse = 0;
        int port_try_first;
        int port_try_next;
        int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
	uint32 fs_attrs = 0;
        const char *username_used;
 	NTSTATUS status;
	char *newserver, *newshare;
	
	zero_sockaddr(&ss);
	ZERO_STRUCT(c);
	*in_cache = false;

	if (server[0] == 0) {
		errno = EPERM;
		return NULL;
	}
	
        /* Look for a cached connection */
        srv = SMBC_find_server(ctx, context, server, share,
                               pp_workgroup, pp_username, pp_password);

        /*
         * If we found a connection and we're only allowed one share per
         * server...
         */
        if (srv &&
            *share != '\0' &&
            smbc_getOptionOneSharePerServer(context)) {
			
                /*
                 * ... then if there's no current connection to the share,
                 * connect to it.  SMBC_find_server(), or rather the function
                 * pointed to by context->get_cached_srv_fn which
                 * was called by SMBC_find_server(), will have issued a tree
                 * disconnect if the requested share is not the same as the
                 * one that was already connected.
                 */

		/*
		 * Use srv->cli->desthost and srv->cli->share instead of
		 * server and share below to connect to the actual share,
		 * i.e., a normal share or a referred share from
		 * 'msdfs proxy' share.
		 */
                if (srv->cli->cnum == (uint16) -1) {
                        /* Ensure we have accurate auth info */
			SMBC_call_auth_fn(ctx, context,
					  srv->cli->desthost,
					  srv->cli->share,
                                          pp_workgroup,
                                          pp_username,
                                          pp_password);

			if (!*pp_workgroup || !*pp_username || !*pp_password) {
				errno = ENOMEM;
				cli_shutdown(srv->cli);
				srv->cli = NULL;
				smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
				return NULL;
			}

			/*
			 * We don't need to renegotiate encryption
			 * here as the encryption context is not per
			 * tid.
			 */

			status = cli_tcon_andx(srv->cli, srv->cli->share, "?????",
					       *pp_password,
					       strlen(*pp_password)+1);
			if (!NT_STATUS_IS_OK(status)) {
                                errno = map_errno_from_nt_status(status);
                                cli_shutdown(srv->cli);
				srv->cli = NULL;
                                smbc_getFunctionRemoveCachedServer(context)(context,
                                                                            srv);
                                srv = NULL;
                        }

                        /* Determine if this share supports case sensitivity */
                        if (is_ipc) {
                                DEBUG(4,
                                      ("IPC$ so ignore case sensitivity\n"));
                        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
                                DEBUG(4, ("Could not retrieve "
                                          "case sensitivity flag: %s.\n",
                                          cli_errstr(c)));

                                /*
                                 * We can't determine the case sensitivity of
                                 * the share. We have no choice but to use the
                                 * user-specified case sensitivity setting.
                                 */
                                if (smbc_getOptionCaseSensitive(context)) {
                                        cli_set_case_sensitive(c, True);
                                } else {
                                        cli_set_case_sensitive(c, False);
                                }
                        } else {
                                DEBUG(4,
                                      ("Case sensitive: %s\n",
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? "True"
                                        : "False")));
                                cli_set_case_sensitive(
                                        c,
                                        (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                         ? True
                                         : False));
                        }

                        /*
                         * Regenerate the dev value since it's based on both
                         * server and share
                         */
                        if (srv) {
                                srv->dev = (dev_t)(str_checksum(srv->cli->desthost) ^
                                                   str_checksum(srv->cli->share));
                        }
                }
        }
	
        /* If we have a connection... */
        if (srv) {
                /* ... then we're done here.  Give 'em what they came for. */
		*in_cache = true;
                goto done;
        }

        /* If we're not asked to connect when a connection doesn't exist... */
        if (! connect_if_not_found) {
                /* ... then we're done here. */
                return NULL;
        }

	if (!*pp_workgroup || !*pp_username || !*pp_password) {
		errno = ENOMEM;
		return NULL;
	}

	make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0);
	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:

	zero_sockaddr(&ss);

	/* have to open a new connection */
	if ((c = cli_initialise()) == NULL) {
		errno = ENOMEM;
		return NULL;
	}

        if (smbc_getOptionUseKerberos(context)) {
		c->use_kerberos = True;
	}

        if (smbc_getOptionFallbackAfterKerberos(context)) {
		c->fallback_after_kerberos = True;
	}

        if (smbc_getOptionUseCCache(context)) {
		c->use_ccache = True;
	}

	c->timeout = smbc_getTimeout(context);

        /*
         * Force use of port 139 for first try if share is $IPC, empty, or
         * null, so browse lists can work
         */
       if (share == NULL || *share == '\0' || is_ipc) {
                port_try_first = 139;
                port_try_next = 445;
       } else {
                port_try_first = 445;
                port_try_next = 139;
       }

	c->port = port_try_first;
	
	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, &ss);
		if (!NT_STATUS_IS_OK(status)) {
			cli_shutdown(c);
			errno = ETIMEDOUT;
			return NULL;
		}
	}
	
	if (!cli_session_request(c, &calling, &called)) {
		cli_shutdown(c);
		if (strcmp(called.name, "*SMBSERVER")) {
			make_nmb_name(&called , "*SMBSERVER", 0x20);
			goto again;
		} else {  /* Try one more time, but ensure we don't loop */

			/* Only try this if server is an IP address ... */

			if (is_ipaddress(server) && !tried_reverse) {
				fstring remote_name;
				struct sockaddr_storage rem_ss;

				if (!interpret_string_addr(&rem_ss, server,
                                                           NI_NUMERICHOST)) {
					DEBUG(4, ("Could not convert IP address "
                                                  "%s to struct sockaddr_storage\n",
                                                  server));
					errno = ETIMEDOUT;
					return NULL;
				}

				tried_reverse++; /* Yuck */

				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"));
	

	status = cli_negprot(c);

	if (!NT_STATUS_IS_OK(status)) {
		cli_shutdown(c);
		errno = ETIMEDOUT;
		return NULL;
	}

        username_used = *pp_username;

	if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_password,
                                               strlen(*pp_password),
					       *pp_workgroup))) {
fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_session_setup fail with username=[%s], password=[%s]\n", username_used, *pp_password);
                /* Failed.  Try an anonymous login, if allowed by flags. */
                username_used = "";

                if (smbc_getOptionNoAutoAnonymousLogin(context) ||
                    !NT_STATUS_IS_OK(cli_session_setup(c, username_used,
                                                       *pp_password, 1,
                                                       *pp_password, 0,
                                                       *pp_workgroup))) {

                        cli_shutdown(c);
                        errno = EPERM;
                        return NULL;
                }
	}
	
	status = cli_init_creds(c, username_used,
				*pp_workgroup, *pp_password);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		cli_shutdown(c);
		return NULL;
	}

	DEBUG(4,(" session setup ok\n"));
	
	/* here's the fun part....to support 'msdfs proxy' shares
	   (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL
	   here before trying to connect to the original share.
	   cli_check_msdfs_proxy() will fail if it is a normal share. */

	if ((c->capabilities & CAP_DFS) &&
			cli_check_msdfs_proxy(ctx, c, share,
				&newserver, &newshare,
				/* FIXME: cli_check_msdfs_proxy() does
				   not support smbc_smb_encrypt_level type */
				context->internal->smb_encryption_level ?
					true : false,
				*pp_username,
				*pp_password,
				*pp_workgroup)) {
		cli_shutdown(c);
		srv = SMBC_server_internal(ctx, context, connect_if_not_found,
				newserver, newshare, pp_workgroup,
				pp_username, pp_password, in_cache);
		TALLOC_FREE(newserver);
		TALLOC_FREE(newshare);
		return srv;
	}
	
	/* must be a normal share */
	status = cli_tcon_andx(c, share, "?????", *pp_password,
			       strlen(*pp_password)+1);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_tcon_andx return %08X, errno=[%d]\n", NT_STATUS_V(status), errno);
		cli_shutdown(c);
		return NULL;
	}
	
	DEBUG(4,(" tconx ok\n"));

        /* Determine if this share supports case sensitivity */
	if (is_ipc) {
                DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
        } else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
                DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
                          cli_errstr(c)));

                /*
                 * We can't determine the case sensitivity of the share. We
                 * have no choice but to use the user-specified case
                 * sensitivity setting.
                 */
                if (smbc_getOptionCaseSensitive(context)) {
                        cli_set_case_sensitive(c, True);
                } else {
                        cli_set_case_sensitive(c, False);
                }
	} else {
                DEBUG(4, ("Case sensitive: %s\n",
                          (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                           ? "True"
                           : "False")));
                cli_set_case_sensitive(c,
                                       (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
                                        ? True
                                        : False));
        }
	

	if (context->internal->smb_encryption_level) {
		/* Attempt UNIX smb encryption. */
		if (!NT_STATUS_IS_OK(cli_force_encryption(c,
                                                          username_used,
                                                          *pp_password,
                                                          *pp_workgroup))) {

			/*
			 * context->smb_encryption_level == 1
			 * means don't fail if encryption can't be negotiated,
			 * == 2 means fail if encryption can't be negotiated.
			 */

			DEBUG(4,(" SMB encrypt failed\n"));

			if (context->internal->smb_encryption_level == 2) {
	                        cli_shutdown(c);
				errno = EPERM;
				return NULL;
			}
		}
		DEBUG(4,(" SMB encrypt ok\n"));
	}

	/*
	 * Ok, we have got a nice connection
	 * Let's allocate a server structure.
	 */

	srv = SMB_MALLOC_P(SMBCSRV);
	if (!srv) {
		cli_shutdown(c);
		errno = ENOMEM;
		return NULL;
	}

	ZERO_STRUCTP(srv);
	srv->cli = c;
	srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
        srv->no_pathinfo = False;
        srv->no_pathinfo2 = False;
        srv->no_nt_session = False;

done:
	if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
		workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
	} else {
		workgroup = *pp_workgroup;
	}
	if(!workgroup) {
		return NULL;
	}

	/* set the credentials to make DFS work */
	smbc_set_credentials_with_fallback(context,
					   workgroup,
				    	   *pp_username,
				   	   *pp_password);

	return srv;
}
Ejemplo n.º 18
0
/****************************************************************************
  main program
****************************************************************************/
 int main(int argc, const char **argv)
{
	int opt,i;
	char *p;
	int rc = 0;
	int argc_new = 0;
	const char ** argv_new;
	poptContext pc;
	TALLOC_CTX *frame = talloc_stackframe();
	struct net_context *c = talloc_zero(frame, struct net_context);

	struct poptOption long_options[] = {
		{"help",	'h', POPT_ARG_NONE,   0, 'h'},
		{"workgroup",	'w', POPT_ARG_STRING, &c->opt_target_workgroup},
		{"user",	'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
		{"ipaddress",	'I', POPT_ARG_STRING, 0,'I'},
		{"port",	'p', POPT_ARG_INT,    &c->opt_port},
		{"myname",	'n', POPT_ARG_STRING, &c->opt_requester_name},
		{"server",	'S', POPT_ARG_STRING, &c->opt_host},
		{"encrypt",	'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport (UNIX extended servers only)") },
		{"container",	'c', POPT_ARG_STRING, &c->opt_container},
		{"comment",	'C', POPT_ARG_STRING, &c->opt_comment},
		{"maxusers",	'M', POPT_ARG_INT,    &c->opt_maxusers},
		{"flags",	'F', POPT_ARG_INT,    &c->opt_flags},
		{"long",	'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
		{"reboot",	'r', POPT_ARG_NONE,   &c->opt_reboot},
		{"force",	'f', POPT_ARG_NONE,   &c->opt_force},
		{"stdin",	'i', POPT_ARG_NONE,   &c->opt_stdin},
		{"timeout",	't', POPT_ARG_INT,    &c->opt_timeout},
		{"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
		{"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
		{"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
		{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
		{"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
		{"verbose",	'v', POPT_ARG_NONE,   &c->opt_verbose},
		{"test",	'T', POPT_ARG_NONE,   &c->opt_testmode},
		/* Options for 'net groupmap set' */
		{"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
		{"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
		{"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
		{"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
		/* Options for 'net rpc share migrate' */
		{"acls",	0, POPT_ARG_NONE,     &c->opt_acls},
		{"attrs",	0, POPT_ARG_NONE,     &c->opt_attrs},
		{"timestamps",	0, POPT_ARG_NONE,     &c->opt_timestamps},
		{"exclude",	'X', POPT_ARG_STRING, &c->opt_exclude},
		{"destination",	0, POPT_ARG_STRING,   &c->opt_destination},
		{"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
		/* Options for 'net rpc vampire (keytab)' */
		{"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
		{"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
		{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
		/* Options for 'net idmap'*/
		{"db", 0, POPT_ARG_STRING, &c->opt_db},
		{"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
		{"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
		{"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
		/* Options for 'net registry check'*/
		{"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
		{"output", 'o', POPT_ARG_STRING, &c->opt_output},
		{"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
		POPT_COMMON_SAMBA
		{ 0, 0, 0, 0}
	};

	zero_sockaddr(&c->opt_dest_ip);

	setup_logging(argv[0], DEBUG_STDERR);

	load_case_tables();

	setlocale(LC_ALL, "");
#if defined(HAVE_BINDTEXTDOMAIN)
	bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
#endif
#if defined(HAVE_TEXTDOMAIN)
	textdomain(MODULE_NAME);
#endif

	/* set default debug level to 0 regardless of what smb.conf sets */
	lp_set_cmdline("log level", "0");
	c->private_data = net_func;

	pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 'h':
			c->display_usage = true;
			break;
		case 'e':
			c->smb_encrypt = true;
			break;
		case 'I':
			if (!interpret_string_addr(&c->opt_dest_ip,
						poptGetOptArg(pc), 0)) {
				d_fprintf(stderr, _("\nInvalid ip address specified\n"));
			} else {
				c->opt_have_ip = true;
			}
			break;
		case 'U':
			c->opt_user_specified = true;
			c->opt_user_name = SMB_STRDUP(c->opt_user_name);
			p = strchr(c->opt_user_name,'%');
			if (p) {
				*p = 0;
				c->opt_password = p+1;
			}
			break;
		default:
			d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
				 poptBadOption(pc, 0), poptStrerror(opt));
			net_help(c, argc, argv);
			exit(1);
		}
	}

	lp_load_global(get_dyn_CONFIGFILE());

#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
	/* Bind our gettext results to 'unix charset'
	   
	   This ensures that the translations and any embedded strings are in the
	   same charset.  It won't be the one from the user's locale (we no
	   longer auto-detect that), but it will be self-consistent.
	*/
	bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
#endif

 	argv_new = (const char **)poptGetArgs(pc);

	argc_new = argc;
	for (i=0; i<argc; i++) {
		if (argv_new[i] == NULL) {
			argc_new = i;
			break;
		}
	}

	if (c->do_talloc_report) {
		talloc_enable_leak_report();
	}

	if (c->opt_requester_name) {
		lp_set_cmdline("netbios name", c->opt_requester_name);
	}

	if (!c->opt_user_name && getenv("LOGNAME")) {
		c->opt_user_name = getenv("LOGNAME");
	}

	if (!c->opt_workgroup) {
		c->opt_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!c->opt_target_workgroup) {
		c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!init_names())
		exit(1);

	load_interfaces();

	/* this makes sure that when we do things like call scripts,
	   that it won't assert because we are not root */
	sec_init();

	if (c->opt_machine_pass) {
		/* it is very useful to be able to make ads queries as the
		   machine account for testing purposes and for domain leave */

		net_use_krb_machine_account(c);
	}

	if (!c->opt_password) {
		c->opt_password = getenv("PASSWD");
	}

	/* Failing to init the msg_ctx isn't a fatal error. Only
	   root-level things (joining/leaving domains etc.) will be denied. */

	c->msg_ctx = messaging_init(c, procid_self(),
				    event_context_init(c));

	rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);

	DEBUG(2,("return code = %d\n", rc));

	gencache_stabilize();

	libnetapi_free(c->netapi_ctx);

	poptFreeContext(pc);

	TALLOC_FREE(frame);
	return rc;
}
Ejemplo n.º 19
0
static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
					  const char *kdc_host,
					  uint16 pversion,
					  krb5_creds *credsp,
					  const char *princ,
					  const char *newpw)
{
	krb5_auth_context auth_context = NULL;
	krb5_data ap_req, chpw_req, chpw_rep;
	int ret, sock;
	socklen_t addr_len;
	struct sockaddr_storage remote_addr, local_addr;
	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) {
		DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	do {

		if (!use_tcp) {

			sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
			if (sock == -1) {
				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", kdc_host, strerror(errno)));
				return ADS_ERROR_SYSTEM(rc);
			}
		} else {
			NTSTATUS status;
			status = open_socket_out(&addr, DEFAULT_KPASSWD_PORT,
						 LONG_CONNECT_TIMEOUT, &sock);
			if (!NT_STATUS_IS_OK(status)) {
				SAFE_FREE(ap_req.data);
				krb5_auth_con_free(context, auth_context);
				DEBUG(1,("failed to open kpasswd socket to %s "
					 "(%s)\n", kdc_host,
					 nt_errstr(status)));
				return ADS_ERROR_NT(status);
			}
		}

		addr_len = sizeof(remote_addr);
		if (getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len) != 0) {
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("getpeername() failed (%s)\n", error_message(errno)));
			return ADS_ERROR_SYSTEM(errno);
		}
		addr_len = sizeof(local_addr);
		if (getsockname(sock, (struct sockaddr *)&local_addr, &addr_len) != 0) {
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("getsockname() failed (%s)\n", error_message(errno)));
			return ADS_ERROR_SYSTEM(errno);
		}
		if (!setup_kaddr(&remote_kaddr, &remote_addr) ||
				!setup_kaddr(&local_kaddr, &local_addr)) {
			DEBUG(1,("do_krb5_kpasswd_request: "
				"Failed to setup addresses.\n"));
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			errno = EINVAL;
			return ADS_ERROR_SYSTEM(EINVAL);
		}

		ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
		if (ret) {
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret)));
			return ADS_ERROR_KRB5(ret);
		}

		ret = build_kpasswd_request(pversion, context, auth_context, &ap_req,
					  princ, newpw, use_tcp, &chpw_req);
		if (ret) {
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret)));
			return ADS_ERROR_KRB5(ret);
		}

		ret = write(sock, chpw_req.data, chpw_req.length); 

		if (ret != chpw_req.length) {
			close(sock);
			SAFE_FREE(chpw_req.data);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
			return ADS_ERROR_SYSTEM(errno);
		}
	
		SAFE_FREE(chpw_req.data);
	
		chpw_rep.length = 1500;
		chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length);
		if (!chpw_rep.data) {
			close(sock);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
			errno = ENOMEM;
			return ADS_ERROR_SYSTEM(errno);
		}
	
		ret = read(sock, chpw_rep.data, chpw_rep.length);
		if (ret < 0) {
			close(sock);
			SAFE_FREE(chpw_rep.data);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno)));
			return ADS_ERROR_SYSTEM(errno);
		}
	
		close(sock);
		chpw_rep.length = ret;
	
		ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr);
		if (ret) {
			SAFE_FREE(chpw_rep.data);
			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", 
				 error_message(ret)));
			return ADS_ERROR_KRB5(ret);
		}
	
		ret = parse_setpw_reply(context, use_tcp, auth_context, &chpw_rep);
		SAFE_FREE(chpw_rep.data);
	
		if (ret) {
			
			if (ret == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) {
				DEBUG(5, ("Trying setpw with TCP!!!\n"));
				use_tcp = True;
				continue;
			}

			SAFE_FREE(ap_req.data);
			krb5_auth_con_free(context, auth_context);
			DEBUG(1,("parse_setpw_reply failed (%s)\n", 
				 error_message(ret)));
			return ADS_ERROR_KRB5(ret);
		}
	
		SAFE_FREE(ap_req.data);
		krb5_auth_con_free(context, auth_context);
	} while ( ret );

	return ADS_SUCCESS;
}
Ejemplo n.º 20
0
/**
interpret a single element from a interfaces= config line

This handles the following different forms:

1) wildcard interface name
2) DNS name
3) IP/masklen
4) ip/mask
5) bcast/mask
**/
static void interpret_interface(TALLOC_CTX *mem_ctx,
                                const char *token,
                                struct iface_struct *probed_ifaces,
                                int total_probed,
                                struct interface **local_interfaces,
                                bool enable_ipv6)
{
    struct sockaddr_storage ss;
    struct sockaddr_storage ss_mask;
    struct sockaddr_storage ss_net;
    struct sockaddr_storage ss_bcast;
    struct iface_struct ifs;
    char *p;
    int i;
    bool added=false;
    bool goodaddr = false;

    /* first check if it is an interface name */
    for (i=0; i<total_probed; i++) {
        if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
            add_interface(mem_ctx, &probed_ifaces[i],
                          local_interfaces, enable_ipv6);
            added = true;
        }
    }
    if (added) {
        return;
    }

    /* maybe it is a DNS name */
    p = strchr_m(token,'/');
    if (p == NULL) {
        if (!interpret_string_addr(&ss, token, 0)) {
            DEBUG(2, ("interpret_interface: Can't find address "
                      "for %s\n", token));
            return;
        }

        for (i=0; i<total_probed; i++) {
            if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&probed_ifaces[i].ip)) {
                add_interface(mem_ctx, &probed_ifaces[i],
                              local_interfaces, enable_ipv6);
                return;
            }
        }
        DEBUG(2,("interpret_interface: "
                 "can't determine interface for %s\n",
                 token));
        return;
    }

    /* parse it into an IP address/netmasklength pair */
    *p = 0;
    goodaddr = interpret_string_addr(&ss, token, 0);
    *p++ = '/';

    if (!goodaddr) {
        DEBUG(2,("interpret_interface: "
                 "can't determine interface for %s\n",
                 token));
        return;
    }

    if (strlen(p) > 2) {
        goodaddr = interpret_string_addr(&ss_mask, p, 0);
        if (!goodaddr) {
            DEBUG(2,("interpret_interface: "
                     "can't determine netmask from %s\n",
                     p));
            return;
        }
    } else {
        char *endp = NULL;
        unsigned long val = strtoul(p, &endp, 0);
        if (p == endp || (endp && *endp != '\0')) {
            DEBUG(2,("interpret_interface: "
                     "can't determine netmask value from %s\n",
                     p));
            return;
        }
        if (!make_netmask(&ss_mask, &ss, val)) {
            DEBUG(2,("interpret_interface: "
                     "can't apply netmask value %lu from %s\n",
                     val,
                     p));
            return;
        }
    }

    make_bcast(&ss_bcast, &ss, &ss_mask);
    make_net(&ss_net, &ss, &ss_mask);

    /* Maybe the first component was a broadcast address. */
    if (sockaddr_equal((struct sockaddr *)&ss_bcast, (struct sockaddr *)&ss) ||
            sockaddr_equal((struct sockaddr *)&ss_net, (struct sockaddr *)&ss)) {
        for (i=0; i<total_probed; i++) {
            if (same_net((struct sockaddr *)&ss,
                         (struct sockaddr *)&probed_ifaces[i].ip,
                         (struct sockaddr *)&ss_mask)) {
                /* Temporarily replace netmask on
                 * the detected interface - user knows
                 * best.... */
                struct sockaddr_storage saved_mask =
                        probed_ifaces[i].netmask;
                probed_ifaces[i].netmask = ss_mask;
                DEBUG(2,("interpret_interface: "
                         "using netmask value %s from "
                         "config file on interface %s\n",
                         p,
                         probed_ifaces[i].name));
                add_interface(mem_ctx, &probed_ifaces[i],
                              local_interfaces, enable_ipv6);
                probed_ifaces[i].netmask = saved_mask;
                return;
            }
        }
        DEBUG(2,("interpret_interface: Can't determine ip for "
                 "broadcast address %s\n",
                 token));
        return;
    }

    /* Just fake up the interface definition. User knows best. */

    DEBUG(2,("interpret_interface: Adding interface %s\n",
             token));

    ZERO_STRUCT(ifs);
    (void)strlcpy(ifs.name, token, sizeof(ifs.name));
    ifs.flags = IFF_BROADCAST;
    ifs.ip = ss;
    ifs.netmask = ss_mask;
    ifs.bcast = ss_bcast;
    add_interface(mem_ctx, &ifs,
                  local_interfaces, enable_ipv6);
}
Ejemplo n.º 21
0
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
	 * make_subnet() in namedbsubnet.c. Thus we bind to the
	 * address "0.0.0.0". The parameter 'socket address' is
	 * now deprecated.
	 */

	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, &ss,
					   true);
	} else {
		ClientNMB = 0;
	}

	if (ClientNMB == -1) {
		return false;
	}

	ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					   3, &ss,
					   true);

	if (ClientDGRAM == -1) {
		if (ClientNMB != 0) {
			close(ClientNMB);
		}
		return false;
	}

	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);

	set_socket_options( ClientNMB,   "SO_BROADCAST" );
	set_socket_options( ClientDGRAM, "SO_BROADCAST" );

	/* Ensure we're non-blocking. */
	set_blocking( ClientNMB, False);
	set_blocking( ClientDGRAM, False);

	DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
	return( True );
}
Ejemplo n.º 22
0
static struct con_struct *create_cs(struct net_context *c,
				    TALLOC_CTX *ctx, NTSTATUS *perr)
{
	NTSTATUS nt_status;
	struct sockaddr_storage loopback_ss;

	*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;
			return NULL;
		}
		return cs;
	}

	cs = talloc(ctx, struct con_struct);
	if (!cs) {
		*perr = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	ZERO_STRUCTP(cs);
	talloc_set_destructor(cs, cs_destructor);

	/* Connect to localhost with given username/password. */
	/* JRA. Pretty sure we can just do this anonymously.... */
#if 0
	if (!opt_password && !opt_machine_pass) {
		char *pass = getpass("Password:"******"IPC$", "IPC",
#if 0
					c->opt_user_name,
					c->opt_workgroup,
					c->opt_password,
#else
					"",
					c->opt_workgroup,
					"",
#endif
					0,
					SMB_SIGNING_DEFAULT);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status)));
		cs->failed_connect = true;
		cs->err = nt_status;
		*perr = nt_status;
		return NULL;
	}

	nt_status = cli_rpc_pipe_open_noauth(cs->cli,
					&ndr_table_lsarpc.syntax_id,
					&cs->lsapipe);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(2,("create_cs: open LSA pipe failed. Error was %s\n", nt_errstr(nt_status)));
		cs->failed_connect = true;
		cs->err = nt_status;
		*perr = nt_status;
		return NULL;
	}

	nt_status = rpccli_lsa_open_policy(cs->lsapipe, ctx, true,
				SEC_FLAG_MAXIMUM_ALLOWED,
				&cs->pol);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(2,("create_cs: rpccli_lsa_open_policy failed. Error was %s\n", nt_errstr(nt_status)));
		cs->failed_connect = true;
		cs->err = nt_status;
		*perr = nt_status;
		return NULL;
	}

	return cs;
}
Ejemplo n.º 23
0
static bool open_sockets_smbd(struct smbd_parent_context *parent,
			      struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx,
			      const char *smb_ports)
{
	int num_interfaces = iface_count();
	int i;
	const char *ports;
	unsigned dns_port = 0;

#ifdef HAVE_ATEXIT
	atexit(killkids);
#endif

	/* Stop zombies */
	smbd_setup_sig_chld_handler(ev_ctx);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = talloc_strdup(talloc_tos(), SMB_PORTS);
		} else {
			ports = talloc_strdup(talloc_tos(), ports);
		}
	} else {
		ports = talloc_strdup(talloc_tos(), smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* 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);
			char *tok;
			const char *ptr;

			if (ifss == NULL) {
				DEBUG(0,("open_sockets_smbd: "
					"interface %d has NULL IP address !\n",
					i));
				continue;
			}

			for (ptr=ports;
			     next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) {
				unsigned port = atoi(tok);
				if (port == 0 || port > 0xffff) {
					continue;
				}

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				if (!smbd_open_one_socket(parent,
							  ev_ctx,
							  msg_ctx,
							  ifss,
							  port)) {
					return false;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		char *tok;
		const char *ptr;
		const char *sock_addr = lp_socket_address();
		char *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
		}

		for (sock_ptr=sock_addr;
		     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
			for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) {
				struct sockaddr_storage ss;

				unsigned port = atoi(tok);
				if (port == 0 || port > 0xffff) {
					continue;
				}

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				/* open an incoming socket */
				if (!interpret_string_addr(&ss, sock_tok,
						AI_NUMERICHOST|AI_PASSIVE)) {
					continue;
				}

				if (!smbd_open_one_socket(parent,
							  ev_ctx,
							  msg_ctx,
							  &ss,
							  port)) {
					return false;
				}
			}
		}
	}

	if (parent->sockets == NULL) {
		DEBUG(0,("open_sockets_smbd: No "
			"sockets available to bind to.\n"));
		return false;
	}

	/* Setup the main smbd so that we can get messages. Note that
	   do this after starting listening. This is needed as when in
	   clustered mode, ctdb won't allow us to start doing database
	   operations until it has gone thru a full startup, which
	   includes checking to see that smbd is listening. */

	if (!serverid_register(procid_self(),
			       FLAG_MSG_GENERAL|FLAG_MSG_SMBD
			       |FLAG_MSG_PRINT_GENERAL
			       |FLAG_MSG_DBWRAP)) {
		DEBUG(0, ("open_sockets_smbd: Failed to register "
			  "myself in serverid.tdb\n"));
		return false;
	}

        /* Listen to messages */

	messaging_register(msg_ctx, NULL, MSG_SMB_SAM_SYNC, msg_sam_sync);
	messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
	messaging_register(msg_ctx, NULL, MSG_SMB_FILE_RENAME,
			   msg_file_was_renamed);
	messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
			   smb_conf_updated);
	messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
			   smb_stat_cache_delete);
	messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
	messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP,
			   smb_pcap_updated);
	brl_register_msgs(msg_ctx);

	msg_idmap_register_msg(msg_ctx);

#ifdef CLUSTER_SUPPORT
	if (lp_clustering()) {
		ctdbd_register_reconfigure(messaging_ctdbd_connection());
	}
#endif

#ifdef DEVELOPER
	messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
			   msg_inject_fault);
#endif

	if (lp_multicast_dns_register() && (dns_port != 0)) {
#ifdef WITH_DNSSD_SUPPORT
		smbd_setup_mdns_registration(ev_ctx,
					     parent, dns_port);
#endif
#ifdef WITH_AVAHI_SUPPORT
		void *avahi_conn;

		avahi_conn = avahi_start_register(ev_ctx,
						  ev_ctx,
						  dns_port);
		if (avahi_conn == NULL) {
			DEBUG(10, ("avahi_start_register failed\n"));
		}
#endif
	}

	return true;
}