Example #1
0
bool serverid_register(const struct server_id id, uint32_t msg_flags)
{
	struct db_context *db;
	struct serverid_key key;
	struct serverid_data data;
	struct db_record *rec;
	TDB_DATA tdbkey, tdbdata;
	NTSTATUS status;
	bool ret = false;

	db = serverid_db();
	if (db == NULL) {
		return false;
	}

	serverid_fill_key(&id, &key);
	tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));

	rec = dbwrap_fetch_locked(db, talloc_tos(), tdbkey);
	if (rec == NULL) {
		DEBUG(1, ("Could not fetch_lock serverid.tdb record\n"));
		return false;
	}

	ZERO_STRUCT(data);
	data.unique_id = id.unique_id;
	data.msg_flags = msg_flags;

	tdbdata = make_tdb_data((uint8_t *)&data, sizeof(data));
	status = dbwrap_record_store(rec, tdbdata, 0);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, ("Storing serverid.tdb record failed: %s\n",
			  nt_errstr(status)));
		goto done;
	}

	if (lp_clustering() &&
	    ctdb_serverids_exist_supported(messaging_ctdbd_connection()))
	{
		register_with_ctdbd(messaging_ctdbd_connection(), id.unique_id,
				    NULL, NULL);
	}

	ret = true;
done:
	TALLOC_FREE(rec);
	return ret;
}
Example #2
0
bool serverids_exist(const struct server_id *ids, int num_ids, bool *results)
{
	struct db_context *db;
	int i;

#ifdef HAVE_CTDB_CONTROL_CHECK_SRVIDS_DECL
	if (lp_clustering()) {
		return ctdb_serverids_exist(messaging_ctdbd_connection(),
					    ids, num_ids, results);
	}
#endif
	if (!processes_exist(ids, num_ids, results)) {
		return false;
	}

	db = serverid_db();
	if (db == NULL) {
		return false;
	}

	for (i=0; i<num_ids; i++) {
		struct serverid_exists_state state;
		struct serverid_key key;
		TDB_DATA tdbkey;

		if (ids[i].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
			results[i] = true;
			continue;
		}
		if (!results[i]) {
			continue;
		}

		serverid_fill_key(&ids[i], &key);
		tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));

		state.id = &ids[i];
		state.exists = false;
		dbwrap_parse_record(db, tdbkey, server_exists_parse, &state);
		results[i] = state.exists;
	}
	return true;
}
Example #3
0
static struct tevent_req *notifyd_req(struct messaging_context *msg_ctx,
				      struct tevent_context *ev)
{
	struct tevent_req *req;
	sys_notify_watch_fn sys_notify_watch = NULL;
	struct sys_notify_context *sys_notify_ctx = NULL;

	if (lp_kernel_change_notify()) {

#ifdef HAVE_INOTIFY
		if (lp_parm_bool(-1, "notify", "inotify", true)) {
			sys_notify_watch = inotify_watch;
		}
#endif

#ifdef HAVE_FAM
		if (lp_parm_bool(-1, "notify", "fam",
				 (sys_notify_watch == NULL))) {
			sys_notify_watch = fam_watch;
		}
#endif
	}

	if (sys_notify_watch != NULL) {
		sys_notify_ctx = sys_notify_context_create(msg_ctx, ev);
		if (sys_notify_ctx == NULL) {
			return NULL;
		}
	}

	req = notifyd_send(msg_ctx, ev, msg_ctx,
			   messaging_ctdbd_connection(),
			   sys_notify_watch, sys_notify_ctx);
	if (req == NULL) {
		TALLOC_FREE(sys_notify_ctx);
		return NULL;
	}
	tevent_req_set_callback(req, notifyd_stopped, msg_ctx);

	return req;
}
Example #4
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;
}
Example #5
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;
}
Example #6
0
bool serverids_exist(const struct server_id *ids, int num_ids, bool *results)
{
	int *todo_idx = NULL;
	struct server_id *todo_ids = NULL;
	bool *todo_results = NULL;
	int todo_num = 0;
	int *remote_idx = NULL;
	int remote_num = 0;
	int *verify_idx = NULL;
	int verify_num = 0;
	int t, idx;
	bool result = false;
	struct db_context *db;

	db = serverid_db();
	if (db == NULL) {
		return false;
	}

	todo_idx = talloc_array(talloc_tos(), int, num_ids);
	if (todo_idx == NULL) {
		goto fail;
	}
	todo_ids = talloc_array(talloc_tos(), struct server_id, num_ids);
	if (todo_ids == NULL) {
		goto fail;
	}
	todo_results = talloc_array(talloc_tos(), bool, num_ids);
	if (todo_results == NULL) {
		goto fail;
	}

	remote_idx = talloc_array(talloc_tos(), int, num_ids);
	if (remote_idx == NULL) {
		goto fail;
	}
	verify_idx = talloc_array(talloc_tos(), int, num_ids);
	if (verify_idx == NULL) {
		goto fail;
	}

	for (idx=0; idx<num_ids; idx++) {
		results[idx] = false;

		if (server_id_is_disconnected(&ids[idx])) {
			continue;
		}

		if (procid_is_me(&ids[idx])) {
			results[idx] = true;
			continue;
		}

		if (procid_is_local(&ids[idx])) {
			bool exists = process_exists_by_pid(ids[idx].pid);

			if (!exists) {
				continue;
			}

			if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
				results[idx] = true;
				continue;
			}

			verify_idx[verify_num] = idx;
			verify_num += 1;
			continue;
		}

		if (!lp_clustering()) {
			continue;
		}

		remote_idx[remote_num] = idx;
		remote_num += 1;
	}

	if (remote_num != 0 &&
	    ctdb_serverids_exist_supported(messaging_ctdbd_connection()))
	{
		int old_remote_num = remote_num;

		remote_num = 0;
		todo_num = 0;

		for (t=0; t<old_remote_num; t++) {
			idx = remote_idx[t];

			if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
				remote_idx[remote_num] = idx;
				remote_num += 1;
				continue;
			}

			todo_idx[todo_num] = idx;
			todo_ids[todo_num] = ids[idx];
			todo_results[todo_num] = false;
			todo_num += 1;
		}

		/*
		 * Note: this only uses CTDB_CONTROL_CHECK_SRVIDS
		 * to verify that the server_id still exists,
		 * which means only the server_id.unique_id and
		 * server_id.vnn are verified, while server_id.pid
		 * is not verified at all.
		 *
		 * TODO: do we want to verify server_id.pid somehow?
		 */
		if (!ctdb_serverids_exist(messaging_ctdbd_connection(),
					  todo_ids, todo_num, todo_results))
		{
			goto fail;
		}

		for (t=0; t<todo_num; t++) {
			idx = todo_idx[t];

			results[idx] = todo_results[t];
		}
	}

	if (remote_num != 0) {
		todo_num = 0;

		for (t=0; t<remote_num; t++) {
			idx = remote_idx[t];
			todo_idx[todo_num] = idx;
			todo_ids[todo_num] = ids[idx];
			todo_results[todo_num] = false;
			todo_num += 1;
		}

		if (!ctdb_processes_exist(messaging_ctdbd_connection(),
					  todo_ids, todo_num,
					  todo_results)) {
			goto fail;
		}

		for (t=0; t<todo_num; t++) {
			idx = todo_idx[t];

			if (!todo_results[t]) {
				continue;
			}

			if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
				results[idx] = true;
				continue;
			}

			verify_idx[verify_num] = idx;
			verify_num += 1;
		}
	}

	for (t=0; t<verify_num; t++) {
		struct serverid_exists_state state;
		struct serverid_key key;
		TDB_DATA tdbkey;
		NTSTATUS status;

		idx = verify_idx[t];

		serverid_fill_key(&ids[idx], &key);
		tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));

		state.id = &ids[idx];
		state.exists = false;
		status = dbwrap_parse_record(db, tdbkey, server_exists_parse, &state);
		if (!NT_STATUS_IS_OK(status)) {
			results[idx] = false;
			continue;
		}
		results[idx] = state.exists;
	}

	result = true;
fail:
	TALLOC_FREE(verify_idx);
	TALLOC_FREE(remote_idx);
	TALLOC_FREE(todo_results);
	TALLOC_FREE(todo_ids);
	TALLOC_FREE(todo_idx);
	return result;
}