Exemplo n.º 1
0
static void remove_child_pid(struct smbd_parent_context *parent,
			     pid_t pid,
			     bool unclean_shutdown)
{
	struct smbd_child_pid *child;
	struct server_id child_id;
	int ret;

	child_id = pid_to_procid(pid);

	ret = messaging_cleanup(parent->msg_ctx, pid);

	if ((ret != 0) && (ret != ENOENT)) {
		DEBUG(10, ("%s: messaging_cleanup returned %s\n",
			   __func__, strerror(ret)));
	}

	smbprofile_cleanup(pid);

	for (child = parent->children; child != NULL; child = child->next) {
		if (child->pid == pid) {
			struct smbd_child_pid *tmp = child;
			DLIST_REMOVE(parent->children, child);
			TALLOC_FREE(tmp);
			parent->num_children -= 1;
			break;
		}
	}

	if (child == NULL) {
		/* not all forked child processes are added to the children list */
		DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid));
		return;
	}

	if (unclean_shutdown) {
		/* a child terminated uncleanly so tickle all
		   processes to see if they can grab any of the
		   pending locks
                */
		DEBUG(3,(__location__ " Unclean shutdown of pid %u\n",
			(unsigned int)pid));
		if (parent->cleanup_te == NULL) {
			/* call the cleanup timer, but not too often */
			int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20);
			parent->cleanup_te = tevent_add_timer(parent->ev_ctx,
						parent,
						timeval_current_ofs(cleanup_time, 0),
						cleanup_timeout_fn,
						parent);
			DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n"));
		}
	}

	if (!serverid_deregister(child_id)) {
		DEBUG(1, ("Could not remove pid %d from serverid.tdb\n",
			  (int)pid));
	}
}
Exemplo n.º 2
0
static void remove_child_pid(struct tevent_context *ev_ctx,
			     pid_t pid,
			     bool unclean_shutdown)
{
	struct child_pid *child;
	static struct timed_event *cleanup_te;
	struct server_id child_id;

	if (unclean_shutdown) {
		/* a child terminated uncleanly so tickle all
		   processes to see if they can grab any of the
		   pending locks
                */
		DEBUG(3,(__location__ " Unclean shutdown of pid %u\n",
			(unsigned int)pid));
		if (!cleanup_te) {
			/* call the cleanup timer, but not too often */
			int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20);
			cleanup_te = event_add_timed(ev_ctx, NULL,
						timeval_current_ofs(cleanup_time, 0),
						cleanup_timeout_fn,
						&cleanup_te);
			DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n"));
		}
	}

	child_id = procid_self(); /* Just initialize pid and potentially vnn */
	child_id.pid = pid;

	if (!serverid_deregister(child_id)) {
		DEBUG(1, ("Could not remove pid %d from serverid.tdb\n",
			  (int)pid));
	}

	for (child = children; child != NULL; child = child->next) {
		if (child->pid == pid) {
			struct child_pid *tmp = child;
			DLIST_REMOVE(children, child);
			SAFE_FREE(tmp);
			num_children -= 1;
			return;
		}
	}

	/* not all forked child processes are added to the children list */
	DEBUG(1, ("Could not find child %d -- ignoring\n", (int)pid));
}
Exemplo n.º 3
0
static void terminate(bool is_parent)
{
	if (is_parent) {
		/* When parent goes away we should
		 * remove the socket file. Not so
		 * when children terminate.
		 */ 
		char *path = NULL;

		if (asprintf(&path, "%s/%s",
			get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) {
			unlink(path);
			SAFE_FREE(path);
		}
	}

	idmap_close();

	trustdom_cache_shutdown();

	gencache_stabilize();

#if 0
	if (interactive) {
		TALLOC_CTX *mem_ctx = talloc_init("end_description");
		char *description = talloc_describe_all(mem_ctx);

		DEBUG(3, ("tallocs left:\n%s\n", description));
		talloc_destroy(mem_ctx);
	}
#endif

	if (is_parent) {
		struct messaging_context *msg = winbind_messaging_context();
		struct server_id self = messaging_server_id(msg);
		serverid_deregister(self);
		pidfile_unlink(lp_piddir(), "winbindd");
	}

	exit(0);
}
Exemplo n.º 4
0
static void terminate(void)
{
	DEBUG(0,("Got SIGTERM: going down...\n"));
  
	/* Write out wins.dat file if samba is a WINS server */
	wins_write_database(0,False);
  
	/* Remove all SELF registered names from WINS */
	release_wins_names();
  
	/* Announce all server entries as 0 time-to-live, 0 type. */
	announce_my_servers_removed();

	/* If there was an async dns child - kill it. */
	kill_async_dns_child();

	gencache_stabilize();
	serverid_deregister(procid_self());

	pidfile_unlink();

	exit(0);
}
Exemplo n.º 5
0
static void exit_server_common(enum server_exit_reason how,
	const char *reason)
{
	struct smbXsrv_connection *conn = global_smbXsrv_connection;
	struct smbd_server_connection *sconn = NULL;
	struct messaging_context *msg_ctx = server_messaging_context();

	if (conn != NULL) {
		sconn = conn->sconn;
	}

	if (!exit_firsttime)
		exit(0);
	exit_firsttime = false;

	change_to_root_user();

	if (sconn) {
		NTSTATUS status;

		if (NT_STATUS_IS_OK(sconn->status)) {
			switch (how) {
			case SERVER_EXIT_ABNORMAL:
				sconn->status = NT_STATUS_INTERNAL_ERROR;
				break;
			case SERVER_EXIT_NORMAL:
				sconn->status = NT_STATUS_LOCAL_DISCONNECT;
				break;
			}
		}

		TALLOC_FREE(sconn->smb1.negprot.auth_context);

		if (lp_log_writeable_files_on_exit()) {
			bool found = false;
			files_forall(sconn, log_writeable_file_fn, &found);
		}

		/*
		 * Note: this is a no-op for smb2 as
		 * conn->tcon_table is empty
		 */
		status = smb1srv_tcon_disconnect_all(conn);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0,("Server exit (%s)\n",
				(reason ? reason : "normal exit")));
			DEBUG(0, ("exit_server_common: "
				  "smb1srv_tcon_disconnect_all() failed (%s) - "
				  "triggering cleanup\n", nt_errstr(status)));
			how = SERVER_EXIT_ABNORMAL;
			reason = "smb1srv_tcon_disconnect_all failed";
		}

		status = smbXsrv_session_logoff_all(conn);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0,("Server exit (%s)\n",
				(reason ? reason : "normal exit")));
			DEBUG(0, ("exit_server_common: "
				  "smbXsrv_session_logoff_all() failed (%s) - "
				  "triggering cleanup\n", nt_errstr(status)));
			how = SERVER_EXIT_ABNORMAL;
			reason = "smbXsrv_session_logoff_all failed";
		}

		change_to_root_user();
	}

	/* 3 second timeout. */
	print_notify_send_messages(msg_ctx, 3);

	/* delete our entry in the serverid database. */
	if (am_parent) {
		/*
		 * For children the parent takes care of cleaning up
		 */
		serverid_deregister(messaging_server_id(msg_ctx));
	}

#ifdef WITH_DFS
	if (dcelogin_atmost_once) {
		dfs_unlogin();
	}
#endif

#ifdef USE_DMAPI
	/* Destroy Samba DMAPI session only if we are master smbd process */
	if (am_parent) {
		if (!dmapi_destroy_session()) {
			DEBUG(0,("Unable to close Samba DMAPI session\n"));
		}
	}
#endif

	if (am_parent) {
		rpc_wkssvc_shutdown();
		rpc_dssetup_shutdown();
#ifdef DEVELOPER
		rpc_rpcecho_shutdown();
#endif
		rpc_netdfs_shutdown();
		rpc_initshutdown_shutdown();
		rpc_eventlog_shutdown();
		rpc_ntsvcs_shutdown();
		rpc_svcctl_shutdown();
		rpc_spoolss_shutdown();

		rpc_srvsvc_shutdown();
		rpc_winreg_shutdown();

		rpc_netlogon_shutdown();
		rpc_samr_shutdown();
		rpc_lsarpc_shutdown();
	}

	/*
	 * we need to force the order of freeing the following,
	 * because smbd_msg_ctx is not a talloc child of smbd_server_conn.
	 */
	sconn = NULL;
	conn = NULL;
	TALLOC_FREE(global_smbXsrv_connection);
	server_messaging_context_free();
	server_event_context_free();
	TALLOC_FREE(smbd_memcache_ctx);

	locking_end();
	printing_end();

	if (how != SERVER_EXIT_NORMAL) {

		smb_panic(reason);

		/* Notreached. */
		exit(1);
	} else {
		DEBUG(3,("Server exit (%s)\n",
			(reason ? reason : "normal exit")));
		if (am_parent) {
			pidfile_unlink(lp_pid_directory(), "smbd");
		}
		gencache_stabilize();
	}

	exit(0);
}
Exemplo n.º 6
0
static int smbd_scavenger_server_id_destructor(struct server_id *id)
{
	serverid_deregister(*id);
	return 0;
}
Exemplo n.º 7
0
static void exit_server_common(enum server_exit_reason how,
	const char *const reason)
{
	struct smbd_server_connection *sconn = smbd_server_conn;

	if (!exit_firsttime)
		exit(0);
	exit_firsttime = false;

	change_to_root_user();

	if (sconn && sconn->smb1.negprot.auth_context) {
		TALLOC_FREE(sconn->smb1.negprot.auth_context);
	}

	if (sconn) {
		if (lp_log_writeable_files_on_exit()) {
			bool found = false;
			files_forall(sconn, log_writeable_file_fn, &found);
		}
		(void)conn_close_all(sconn);
		invalidate_all_vuids(sconn);
	}

	/* 3 second timeout. */
	print_notify_send_messages(sconn->msg_ctx, 3);

	/* delete our entry in the serverid database. */
	if (am_parent) {
		/*
		 * For children the parent takes care of cleaning up
		 */
		serverid_deregister(sconn_server_id(sconn));
	}

#ifdef WITH_DFS
	if (dcelogin_atmost_once) {
		dfs_unlogin();
	}
#endif

#ifdef USE_DMAPI
	/* Destroy Samba DMAPI session only if we are master smbd process */
	if (am_parent) {
		if (!dmapi_destroy_session()) {
			DEBUG(0,("Unable to close Samba DMAPI session\n"));
		}
	}
#endif

	if (am_parent) {
		rpc_wkssvc_shutdown();
#ifdef ACTIVE_DIRECTORY
		rpc_dssetup_shutdown();
#endif
#ifdef DEVELOPER
		rpc_rpcecho_shutdown();
#endif
#ifdef DFS_SUPPORT
		rpc_netdfs_shutdown();
#endif
		rpc_initshutdown_shutdown();
#ifdef EXTRA_SERVICES
		rpc_eventlog_shutdown();
		rpc_svcctl_shutdown();
		rpc_ntsvcs_shutdown();
#endif
#ifdef PRINTER_SUPPORT
		rpc_spoolss_shutdown();
#endif

		rpc_srvsvc_shutdown();
#ifdef WINREG_SUPPORT
		rpc_winreg_shutdown();
#endif

#ifdef NETLOGON_SUPPORT
		rpc_netlogon_shutdown();
#endif
#ifdef SAMR_SUPPORT
		rpc_samr_shutdown();
#endif
#ifdef LSA_SUPPORT
		rpc_lsarpc_shutdown();
#endif
	}

	/*
	 * we need to force the order of freeing the following,
	 * because smbd_msg_ctx is not a talloc child of smbd_server_conn.
	 */
	sconn = NULL;
	TALLOC_FREE(smbd_server_conn);
	server_messaging_context_free();
	server_event_context_free();
	TALLOC_FREE(smbd_memcache_ctx);

	locking_end();
	printing_end();

	if (how != SERVER_EXIT_NORMAL) {
		DEBUGSEP(0);
		DEBUG(0,("Abnormal server exit: %s\n",
			reason ? reason : "no explanation provided"));
		DEBUGSEP(0);

		log_stack_trace();

		dump_core();

		/* Notreached. */
		exit(1);
	} else {
		DEBUG(3,("Server exit (%s)\n",
			(reason ? reason : "normal exit")));
		if (am_parent) {
			pidfile_unlink();
		}
		gencache_stabilize();
	}

	exit(0);
}