[REVIEW] launchd support for smbd and winbindd
James Peach
jpeach at samba.org
Mon Oct 15 20:44:20 GMT 2007
Hi all,
The series of patches below are the changes for launchd support ported
from the SAMBA_3_2 svn branch to the v3-2-test git branch. I believe
that I have preserved Jeremy's IPv6 changes. Note that while the
cherry-picked changes in the early patches are marked GPL2, this is
corrected to GPL3 in subsequent patches.
These changes are available in the "feature/launchd" branch of git://
git.samba.org/jpeach/samba.git. You should be able to apply them to a
local branch by sending this message into some form of git-am
invocation.
If there are no dissenting voices, I'll merge this to v3-2-test before
the end of this week.
thanks,
James
From c8b3db77716b424a73be32b0d73227b006619b1b Mon Sep 17 00:00:00 2001
From: James Peach <jpeach at samba.org>
Date: Sat, 13 Oct 2007 18:12:34 -0700
Subject: [PATCH] Refactor the various daemon run-mode options.
This makes the semantics of the different daemon run modes explicit
and normalizes the commandline options of nmbd, smbd and winbindd
as much as possible.
---
source/include/popt_common.h | 11 +++++
source/nmbd/nmbd.c | 60 ++++++++++++++--------------
source/smbd/server.c | 89 ++++++++++++++++++++++
+-------------------
source/winbindd/winbindd.c | 45 ++++++++++++---------
4 files changed, 116 insertions(+), 89 deletions(-)
diff --git a/source/include/popt_common.h b/source/include/popt_common.h
index 24c0bbf..9944610 100644
--- a/source/include/popt_common.h
+++ b/source/include/popt_common.h
@@ -49,6 +49,17 @@ struct user_auth_info {
int signing_state;
};
+enum smb_server_mode {
+ /* Daemonize and manage our own sockets */
+ SERVER_MODE_DAEMON,
+ /* Don't daemonize or manage sockets */
+ SERVER_MODE_INETD,
+ /* Don't daemonize, but do manage sockets */
+ SERVER_MODE_FOREGROUND,
+ /* Run in the foreground, log to stdout, don't fork children */
+ SERVER_MODE_INTERACTIVE
+};
+
extern struct user_auth_info cmdline_auth_info;
#endif /* _POPT_COMMON_H */
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index f0de0b8..28a6b25 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -31,15 +31,6 @@ extern BOOL global_in_nmbd;
extern BOOL override_logfile;
-/* are we running as a daemon ? */
-static BOOL is_daemon;
-
-/* fork or run in foreground ? */
-static BOOL Fork = True;
-
-/* log to standard output ? */
-static BOOL log_stdout;
-
/* have we found LanMan clients yet? */
BOOL found_lm_clients = False;
@@ -649,7 +640,7 @@ static void process(void)
Open the socket communication.
**************************************************************************** */
-static BOOL open_sockets(BOOL isdaemon, int port)
+static BOOL open_sockets(enum smb_server_mode server_mode, int port)
{
/*
* The sockets opened here will be used to receive broadcast
@@ -659,12 +650,13 @@ static BOOL open_sockets(BOOL isdaemon, int port)
* now deprecated.
*/
- if ( isdaemon )
+ if ( server_mode == SERVER_MODE_INETD ) {
+ ClientNMB = 0;
+ } else {
ClientNMB = open_socket_in(SOCK_DGRAM, port,
0, interpret_addr(lp_socket_address()),
True);
- else
- ClientNMB = 0;
+ }
ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
3, interpret_addr(lp_socket_address()),
@@ -693,16 +685,20 @@ static BOOL open_sockets(BOOL isdaemon, int port)
int main(int argc, const char *argv[])
{
pstring logfile;
- static BOOL opt_interactive;
poptContext pc;
- static char *p_lmhosts = dyn_LMHOSTSFILE;
- static BOOL no_process_group = False;
int opt;
+ const char *p_lmhosts = dyn_LMHOSTSFILE;
+ BOOL no_process_group = False;
+ BOOL log_stdout = False;
+ enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
struct poptOption long_options[] = {
POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a
daemon(default)" },
- {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run
interactive (not a daemon)" },
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in
foreground (for daemontools & etc)" },
+ {"daemon", 'D', POPT_ARG_VAL, &server_mode, SERVER_MODE_DAEMON,
+ "Become a daemon(default)" },
+ {"interactive", 'i', POPT_ARG_VAL, &server_mode,
+ SERVER_MODE_INTERACTIVE, "Run interactive (not a daemon)" },
+ {"foreground", 'F', POPT_ARG_VAL, &server_mode,
+ SERVER_MODE_FOREGROUND, "Run daemon in foreground (for daemontools
& etc)" },
{"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True,
"Don't create a new process group" },
{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to
stdout" },
{"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios
hosts file"},
@@ -760,12 +756,11 @@ static BOOL open_sockets(BOOL isdaemon, int port)
BlockSignals(True, SIGUSR2);
#endif
- if ( opt_interactive ) {
- Fork = False;
+ if (server_mode == SERVER_MODE_INTERACTIVE) {
log_stdout = True;
}
- if ( log_stdout && Fork ) {
+ if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in
foreground (-F) or interactive (-i)\n"));
exit(1);
}
@@ -792,14 +787,19 @@ static BOOL open_sockets(BOOL isdaemon, int port)
set_samba_nb_type();
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
+ if (is_a_socket(0)) {
+ if (server_mode == SERVER_MODE_DAEMON) {
+ DEBUG(0,("standard input is a socket, "
+ "assuming -F option\n"));
+ }
+ server_mode = SERVER_MODE_INETD;
}
-
- if (is_daemon && !opt_interactive) {
+
+ if (server_mode == SERVER_MODE_DAEMON) {
DEBUG( 2, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork, no_process_group);
+ become_daemon(True, no_process_group);
+ } else if (server_mode == SERVER_MODE_FOREGROUND) {
+ become_daemon(False, no_process_group);
}
#if HAVE_SETPGID
@@ -807,7 +807,7 @@ static BOOL open_sockets(BOOL isdaemon, int port)
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (opt_interactive && !no_process_group)
+ if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group)
setpgid( (pid_t)0, (pid_t)0 );
#endif
@@ -846,7 +846,7 @@ static BOOL open_sockets(BOOL isdaemon, int port)
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
- if ( !open_sockets( is_daemon, global_nmb_port ) ) {
+ if ( !open_sockets( server_mode, global_nmb_port ) ) {
kill_async_dns_child();
return 1;
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 8c92c91..ccef37c 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -296,7 +296,7 @@ static BOOL allowable_number_of_smbd_processes(void)
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const
char *smb_ports)
+static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const
char *smb_ports)
{
int num_interfaces = iface_count();
int num_sockets = 0;
@@ -307,11 +307,10 @@ static BOOL open_sockets_smbd(BOOL is_daemon,
BOOL interactive, const char *smb_
int i;
char *ports;
- if (!is_daemon) {
+ if (server_mode == SERVER_MODE_INETD) {
return open_sockets_inetd();
}
-
#ifdef HAVE_ATEXIT
{
static int atexit_set;
@@ -561,8 +560,13 @@ static BOOL open_sockets_smbd(BOOL is_daemon,
BOOL interactive, const char *smb_
/* Ensure child is set to blocking mode */
set_blocking(smbd_server_fd(),True);
- if (smbd_server_fd() != -1 && interactive)
+ /* In interactive mode, return with a connected socket.
+ * Foreground and daemon modes should fork worker
+ * processes.
+ */
+ if (server_mode == SERVER_MODE_INTERACTIVE) {
return True;
+ }
if (allowable_number_of_smbd_processes() &&
smbd_server_fd() != -1 &&
@@ -882,23 +886,26 @@ extern void build_options(BOOL screen);
int main(int argc,const char *argv[])
{
/* shall I run as a daemon */
- static BOOL is_daemon = False;
- static BOOL interactive = False;
- static BOOL Fork = True;
- static BOOL no_process_group = False;
- static BOOL log_stdout = False;
- static char *ports = NULL;
- static char *profile_level = NULL;
+ BOOL no_process_group = False;
+ BOOL log_stdout = False;
+ const char *ports = NULL;
+ const char *profile_level = NULL;
int opt;
poptContext pc;
BOOL print_build_options = False;
+ enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
+
struct poptOption long_options[] = {
POPT_AUTOHELP
- {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon
(default)" },
- {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run
interactive (not a daemon)"},
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in
foreground (for daemontools, etc.)" },
- {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True,
"Don't create a new process group" },
+ {"daemon", 'D', POPT_ARG_VAL, &server_mode, SERVER_MODE_DAEMON,
+ "Become a daemon (default)" },
+ {"interactive", 'i', POPT_ARG_VAL, &server_mode,
SERVER_MODE_INTERACTIVE,
+ "Run interactive (not a daemon)"},
+ {"foreground", 'F', POPT_ARG_VAL, &server_mode,
SERVER_MODE_FOREGROUND,
+ "Run daemon in foreground (for daemontools, etc.)" },
+ {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True,
+ "Don't create a new process group" },
{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to
stdout" },
{"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build
options" },
{"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified
ports"},
@@ -945,16 +952,14 @@ extern void build_options(BOOL screen);
set_remote_machine_name("smbd", False);
- if (interactive) {
- Fork = False;
+ if (server_mode == SERVER_MODE_INTERACTIVE) {
log_stdout = True;
+ if (DEBUGLEVEL >= 9) {
+ talloc_enable_leak_report();
+ }
}
- if (interactive && (DEBUGLEVEL >= 9)) {
- talloc_enable_leak_report();
- }
-
- if (log_stdout && Fork) {
+ if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in
foreground (-F) or interactive (-i)\n"));
exit(1);
}
@@ -1044,21 +1049,19 @@ extern void build_options(BOOL screen);
DEBUG(3,( "loaded services\n"));
- if (!is_daemon && !is_a_socket(0)) {
- if (!interactive)
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
-
- /*
- * Setting is_daemon here prevents us from eventually calling
- * the open_sockets_inetd()
- */
-
- is_daemon = True;
+ if (is_a_socket(0)) {
+ if (server_mode == SERVER_MODE_DAEMON) {
+ DEBUG(0,("standard input is a socket, "
+ "assuming -F option\n"));
+ }
+ server_mode = SERVER_MODE_INETD;
}
- if (is_daemon && !interactive) {
+ if (server_mode == SERVER_MODE_DAEMON) {
DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(Fork, no_process_group);
+ become_daemon(True, no_process_group);
+ } else if (server_mode == SERVER_MODE_FOREGROUND) {
+ become_daemon(False, no_process_group);
}
#if HAVE_SETPGID
@@ -1066,15 +1069,18 @@ extern void build_options(BOOL screen);
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (interactive && !no_process_group)
+ if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group) {
setpgid( (pid_t)0, (pid_t)0);
+ }
#endif
if (!directory_exist(lp_lockdir(), NULL))
mkdir(lp_lockdir(), 0755);
- if (is_daemon)
+ if (server_mode != SERVER_MODE_INETD &&
+ server_mode != SERVER_MODE_INTERACTIVE) {
pidfile_create("smbd");
+ }
/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
@@ -1128,9 +1134,10 @@ extern void build_options(BOOL screen);
running as a daemon -- bad things will happen if
smbd is launched via inetd and we fork a copy of
ourselves here */
-
- if ( is_daemon && !interactive )
+ if (server_mode != SERVER_MODE_INETD &&
+ server_mode != SERVER_MODE_INTERACTIVE) {
start_background_queue();
+ }
/* Always attempt to initialize DMAPI. We will only use it later if
* lp_dmapi_support is set on the share, but we need a single global
@@ -1138,8 +1145,9 @@ extern void build_options(BOOL screen);
*/
dmapi_init_session();
- if (!open_sockets_smbd(is_daemon, interactive, ports))
+ if (!open_sockets_smbd(server_mode, ports)) {
exit(1);
+ }
/*
* everything after this point is run after the fork()
@@ -1152,7 +1160,8 @@ extern void build_options(BOOL screen);
/* Possibly reload the services file. Only worth doing in
* daemon mode. In inetd mode, we know we only just loaded this.
*/
- if (is_daemon) {
+ if (server_mode != SERVER_MODE_INETD &&
+ server_mode != SERVER_MODE_INTERACTIVE) {
reload_services(True);
}
diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c
index 81f07c4..fce422d 100644
--- a/source/winbindd/winbindd.c
+++ b/source/winbindd/winbindd.c
@@ -29,7 +29,6 @@
#define DBGC_CLASS DBGC_WINBIND
BOOL opt_nocache = False;
-static BOOL interactive = False;
extern BOOL override_logfile;
@@ -984,17 +983,21 @@ static void process_loop(void)
int main(int argc, char **argv, char **envp)
{
pstring logfile;
- static BOOL is_daemon = False;
- static BOOL Fork = True;
- static BOOL log_stdout = False;
- static BOOL no_process_group = False;
+ BOOL log_stdout = False;
+ BOOL no_process_group = False;
+
+ enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
+
+ /* XXX nmbd and smbd use --log-stdout, but winbindd uses --stdout.
+ * Resolving this inconsistency would break compatibility :(
+ */
+
struct poptOption long_options[] = {
POPT_AUTOHELP
{ "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in
foreground mode" },
+ { "foreground", 'F', POPT_ARG_VAL, &server_mode,
SERVER_MODE_FOREGROUND, "Daemon in foreground mode" },
{ "no-process-group", 0, POPT_ARG_VAL, &no_process_group, True,
"Don't create a new process group" },
- { "daemon", 'D', POPT_ARG_NONE, NULL, 'D', "Become a daemon
(default)" },
- { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
+ { "interactive", 'i', POPT_ARG_VAL, &server_mode,
SERVER_MODE_INTERACTIVE, "Interactive mode" },
{ "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable
caching" },
POPT_COMMON_SAMBA
POPT_TABLEEND
@@ -1050,16 +1053,15 @@ int main(int argc, char **argv, char **envp)
}
}
- if (is_daemon && interactive) {
- d_fprintf(stderr,"\nERROR: "
- "Option -i|--interactive is not allowed together with -D|--daemon
\n\n");
- poptPrintUsage(pc, stderr, 0);
- exit(1);
+ if (server_mode == SERVER_MODE_INTERACTIVE) {
+ log_stdout = True;
+ if (DEBUGLEVEL >= 9) {
+ talloc_enable_leak_report();
+ }
}
- if (log_stdout && Fork) {
- d_fprintf(stderr, "\nERROR: "
- "Can't log to stdout (-S) unless daemon is in foreground +(-F)
or interactive (-i)\n\n");
+ if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
+ printf("Can't log to stdout (-S) unless daemon is in foreground (-
F) or interactive (-i)\n");
poptPrintUsage(pc, stderr, 0);
exit(1);
}
@@ -1132,8 +1134,12 @@ int main(int argc, char **argv, char **envp)
CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
CatchSignal(SIGHUP, sighup_handler);
- if (!interactive)
- become_daemon(Fork, no_process_group);
+ if (server_mode == SERVER_MODE_DAEMON) {
+ DEBUG( 3, ( "Becoming a daemon.\n" ) );
+ become_daemon(True, no_process_group);
+ } else if (server_mode == SERVER_MODE_FOREGROUND) {
+ become_daemon(False, no_process_group);
+ }
pidfile_create("winbindd");
@@ -1156,8 +1162,9 @@ int main(int argc, char **argv, char **envp)
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (interactive && !no_process_group)
+ if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group) {
setpgid( (pid_t)0, (pid_t)0);
+ }
#endif
TimeInit();
--
1.5.3.4
From 764e7451e4bbe922431df892af2ee56a633d7048 Mon Sep 17 00:00:00 2001
From: James Peach <jpeach at samba.org>
Date: Sat, 13 Oct 2007 19:15:15 -0700
Subject: [PATCH] Support running under launchd.
We abstract the method of obtaining sockets to listen on a little,
because in the launchd case these are provided for us. We also add
an idle timeout so that a daemon can exit after a period of inactivity.
---
source/Makefile.in | 4 +-
source/configure.in | 29 +++++
source/include/smb_launchd.h | 43 ++++++++
source/lib/launchd.c | 242 +++++++++++++++++++++++++++++++++
+++++++++
source/smbd/connection.c | 29 +++++-
source/smbd/server.c | 191 ++++++++++++++++++++++++---------
source/winbindd/winbindd.c | 122 ++++++++++++++++++----
7 files changed, 584 insertions(+), 76 deletions(-)
create mode 100644 source/include/smb_launchd.h
create mode 100644 source/lib/launchd.c
diff --git a/source/Makefile.in b/source/Makefile.in
index 4d261d3..8558d81 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -529,7 +529,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/
connection.o \
smbd/change_trust_pw.o smbd/fake_file.o \
smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
$(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
- smbd/dmapi.o \
+ smbd/dmapi.o lib/launchd.o \
$(MANGLE_OBJ) @VFS_STATIC@
SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $
(LIBSMB_OBJ) \
@@ -874,7 +874,7 @@ WINBINDD_OBJ = \
$(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
$(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
$(DCUTIL_OBJ) $(IDMAP_OBJ) $(NSS_INFO_OBJ) \
- $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) \
+ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) lib/launchd.o \
$(LIBADS_SERVER_OBJ) $(SERVER_MUTEX_OBJ) $(LDB_OBJ)
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $
(LIB_NONSMBD_OBJ) \
diff --git a/source/configure.in b/source/configure.in
index d1a05d1..14db3b6 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -394,6 +394,35 @@ AC_ARG_WITH(selftest-prefix,
esac
])
+AC_ARG_ENABLE(launchd,
+[ --enable-launchd Support running under launchd
(default=auto)])
+
+if test x"$enable_launchd" != x"no" ; then
+ AC_CACHE_CHECK([whether to include launchd support],
+ samba_cv_launchd_support,
+ [
+ AC_TRY_COMPILE(
+ [
+#include <launch.h>
+ ],
+ [
+ launchd_msg(NULL);
+ launchd_data_get_fd(NULL);
+ ],
+ samba_cv_launchd_support=yes,
+ samba_cv_launchd_support=no)
+ ])
+
+ if test x"$samba_cv_launchd_support" = x"yes" ; then
+ AC_DEFINE(WITH_LAUNCHD_SUPPORT, 1,
+ [Whether launchd support should be enabled])
+ else
+ if test x"$enable_launchd" = x"yes" ; then
+ AC_ERROR(launchd support is not available)
+ fi
+ fi
+fi
+
#################################################
# set path of samba4's smbtorture
smbtorture4_path=""
diff --git a/source/include/smb_launchd.h b/source/include/smb_launchd.h
new file mode 100644
index 0000000..2e758a4
--- /dev/null
+++ b/source/include/smb_launchd.h
@@ -0,0 +1,43 @@
+/*
+ Unix SMB/CIFS implementation.
+ Launchd integration wrapper API
+
+ Copyright (C) James Peach 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+struct smb_launch_info
+{
+ int idle_timeout_secs;
+ int num_sockets;
+ int *socket_list;
+};
+
+/* Retrieve launchd configuration. Returns True if we are running under
+ * launchd, False otherwise. NOTE this does not guarantee to provide
a list of
+ * sockets since this is a user configuration option.
+ */
+BOOL smb_launchd_checkin(struct smb_launch_info *linfo);
+
+/* Retrieve launchd configuration. The variadic arguments are a list of
+ * constant null-terminated strings. The strings are the names of the
socket
+ * dictionaries to retrieve sockets from. The list of names is
terminated by a
+ * NULL.
+ */
+BOOL smb_launchd_checkin_names(struct smb_launch_info *linfo, ...);
+
+/* Free any data or state associated with a successful launchd
checkin. */
+void smb_launchd_checkout(struct smb_launch_info *linfo);
diff --git a/source/lib/launchd.c b/source/lib/launchd.c
new file mode 100644
index 0000000..1fd5a33
--- /dev/null
+++ b/source/lib/launchd.c
@@ -0,0 +1,242 @@
+/*
+ Unix SMB/CIFS implementation.
+ Launchd integration wrapper API
+
+ Copyright (C) 2007 James Peach
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb_launchd.h"
+
+/* launchd source code and documentation is available here:
+ * http://launchd.macosforge.org/
+ */
+
+#if defined(WITH_LAUNCHD_SUPPORT)
+
+#include <launch.h>
+#include <stdarg.h>
+
+typedef void (*launchd_iterator)(launch_data_t, const char*, void*);
+
+#define LAUNCHD_TRACE_LEVEL 10
+
+ void smb_launchd_checkout(struct smb_launch_info *linfo)
+{
+ talloc_free(linfo->socket_list);
+}
+
+static void pull_launch_sockets(launch_data_t key,
+ const char *name,
+ struct smb_launch_info *linfo)
+{
+ launch_data_type_t type;
+
+ type = launch_data_get_type(key);
+ DEBUG(LAUNCHD_TRACE_LEVEL,
+ ("Searching item name='%s' type=%d for sockets\n",
+ name ? name : "", (int)type));
+
+ switch (type) {
+ case LAUNCH_DATA_FD:
+ if (!linfo->socket_list) {
+ /* We are counting the number of sockets. */
+ linfo->num_sockets++;
+ } else {
+ /* We are collecting the socket fds. */
+ int fd = launch_data_get_fd(key);
+
+ linfo->socket_list[linfo->num_sockets] = fd;
+ linfo->num_sockets++;
+ DEBUG(LAUNCHD_TRACE_LEVEL,
+ ("Added fd=%d to launchd set\n", fd));
+ }
+ return;
+ case LAUNCH_DATA_ARRAY:
+ {
+ int i;
+ launch_data_t item;
+
+ for (i = 0; i < launch_data_array_get_count(key); ++i) {
+ item = launch_data_array_get_index(key, i);
+ pull_launch_sockets(item, name, linfo);
+ }
+ return;
+ }
+ case LAUNCH_DATA_DICTIONARY:
+ launch_data_dict_iterate(key,
+ (launchd_iterator)pull_launch_sockets, linfo);
+ return;
+ default:
+ return;
+ }
+}
+
+ BOOL smb_launchd_checkin_names(struct smb_launch_info *linfo, ...)
+{
+ launch_data_t msg;
+ launch_data_t resp;
+ launch_data_t item;
+ BOOL is_launchd = False;
+
+ ZERO_STRUCTP(linfo);
+
+ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+ resp = launch_msg(msg);
+ if (resp == NULL) {
+ /* IPC to launchd failed. */
+ launch_data_free(msg);
+ return is_launchd;
+ }
+
+ if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
+ errno = launch_data_get_errno(resp);
+ goto done;
+ }
+
+ /* At this point, we know we are running under launchd. */
+ linfo->idle_timeout_secs = 600;
+ is_launchd = True;
+
+ if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
+ linfo->idle_timeout_secs = launch_data_get_integer(item);
+ }
+
+ if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
+ int count = 0;
+ const char * sockname = NULL;
+ launch_data_t sockdata;
+ va_list args;
+
+ /* Figure out the maximum number of sockets. */
+ va_start(args, linfo);
+ while ((sockname = va_arg(args, const char *))) {
+ ++count;
+ }
+ va_end(args);
+
+ DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
+ linfo->num_sockets));
+
+ if (launch_data_dict_get_count(item) < count) {
+ DEBUG(0, ("%d launchd sockets requested, "
+ "but only %d are available\n",
+ count, launch_data_dict_get_count(item)));
+ }
+
+ linfo->socket_list = talloc_array(NULL, int, count);
+ if (linfo->socket_list == NULL) {
+ goto done;
+ }
+
+ linfo->num_sockets = 0;
+ va_start(args, linfo);
+ while ((sockname = va_arg(args, const char *))) {
+ sockdata = launch_data_dict_lookup(item, sockname);
+
+ pull_launch_sockets(sockdata, sockname, linfo);
+ DEBUG(LAUNCHD_TRACE_LEVEL,
+ ("Added launchd socket \"%s\"\n", sockname));
+ }
+
+ SMB_ASSERT(count >= linfo->num_sockets);
+ }
+
+done:
+ launch_data_free(msg);
+ launch_data_free(resp);
+ return is_launchd;
+}
+
+ BOOL smb_launchd_checkin(struct smb_launch_info *linfo)
+{
+ launch_data_t msg;
+ launch_data_t resp;
+ launch_data_t item;
+ BOOL is_launchd = False;
+
+ ZERO_STRUCTP(linfo);
+
+ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+ resp = launch_msg(msg);
+ if (resp == NULL) {
+ /* IPC to launchd failed. */
+ launch_data_free(msg);
+ return is_launchd;
+ }
+
+ if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) {
+ errno = launch_data_get_errno(resp);
+ goto done;
+ }
+
+ /* At this point, we know we are running under launchd. */
+ linfo->idle_timeout_secs = 600;
+ is_launchd = True;
+
+ if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) {
+ linfo->idle_timeout_secs = launch_data_get_integer(item);
+ }
+
+ if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) {
+ int count;
+
+ pull_launch_sockets(item, NULL, linfo);
+ DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n",
+ linfo->num_sockets));
+
+ count = linfo->num_sockets;
+ linfo->socket_list = talloc_array(NULL, int, count);
+ if (linfo->socket_list == NULL) {
+ goto done;
+ }
+
+ linfo->num_sockets = 0;
+ pull_launch_sockets(item, NULL, linfo);
+
+ DEBUG(LAUNCHD_TRACE_LEVEL, ("Added %d launchd sockets\n",
+ linfo->num_sockets));
+
+ SMB_ASSERT(count == linfo->num_sockets);
+ }
+
+done:
+ launch_data_free(msg);
+ launch_data_free(resp);
+ return is_launchd;
+}
+
+#else /* defined(WITH_LAUNCHD_SUPPORT) */
+
+ BOOL smb_launchd_checkin(struct smb_launch_info * UNUSED(linfo))
+{
+ ZERO_STRUCTP(linfo);
+ return False;
+}
+
+ BOOL smb_launchd_checkin_names(struct smb_launch_info *
UNUSED(linfo), ...)
+{
+ ZERO_STRUCTP(linfo);
+ return False;
+}
+
+ void smb_launchd_checkout(struct smb_launch_info * UNUSED(linfo))
+{
+}
+
+#endif /* defined(WITH_LAUNCHD_SUPPORT) */
+
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index 65b7c35..65e394c 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -83,9 +83,19 @@ static int count_fn(struct db_record *rec,
}
return 0;
}
-
- if (strequal(crec->servicename, cs->name))
+
+ if (cs->name) {
+ /* We are counting all the connections to a given share. */
+ if (strequal(crec->servicename, cs->name)) {
+ cs->curr_connections++;
+ }
+ } else {
+ /* We are counting all the connections. Static registrations
+ * like the lpq backgroud process and the smbd daemon process
+ * have a cnum of -1, so won't be counted here.
+ */
cs->curr_connections++;
+ }
return 0;
}
@@ -111,13 +121,26 @@ int count_current_connections( const char
*sharename, BOOL clear )
if (connections_forall(count_fn, &cs) == -1) {
DEBUG(0,("count_current_connections: traverse of "
"connections.tdb failed\n"));
- return False;
}
+ /* If the traverse failed part-way through, we at least return
+ * as many connections as we had already counted. If it failed
+ * right at the start, we will return 0, which is about all we
+ * can do anywway.
+ */
return cs.curr_connections;
}
/
****************************************************************************
+ Count the number of connections open across all shares.
+
****************************************************************************/
+
+int count_all_current_connections(void)
+{
+ return count_current_connections(NULL, True /* clear stale entries
*/);
+}
+
+/
****************************************************************************
Claim an entry in the connections database.
****************************************************************************/
diff --git a/source/smbd/server.c b/source/smbd/server.c
index ccef37c..fbf2a39 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Martin Pool 2002
Copyright (C) Jelmer Vernooij 2002-2003
+ Copyright (C) James Peach 2007
This program is free software; you can redistribute it and/or
modify
it under the terms of the GNU General Public License as published
by
@@ -20,6 +21,7 @@
*/
#include "includes.h"
+#include "smb_launchd.h"
static_decl_rpc;
@@ -292,39 +294,13 @@ static BOOL
allowable_number_of_smbd_processes(void)
return num_children < max_processes;
}
-/
****************************************************************************
- Open the socket communication.
-
****************************************************************************/
-
-static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const
char *smb_ports)
+static int init_sockets_smbd(const char *smb_ports,
+ int fd_listenset[FD_SETSIZE])
{
int num_interfaces = iface_count();
+ char * ports;
int num_sockets = 0;
- int fd_listenset[FD_SETSIZE];
- fd_set listen_set;
- int s;
- int maxfd = 0;
- int i;
- char *ports;
-
- if (server_mode == SERVER_MODE_INETD) {
- return open_sockets_inetd();
- }
-
-#ifdef HAVE_ATEXIT
- {
- static int atexit_set;
- if(atexit_set == 0) {
- atexit_set=1;
- atexit(killkids);
- }
- }
-#endif
-
- /* Stop zombies */
- CatchSignal(SIGCLD, sig_cld);
-
- FD_ZERO(&listen_set);
+ int i, s;
/* use a reasonable default set of ports - listing on 445 and 139 */
if (!smb_ports) {
@@ -372,7 +348,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode
server_mode, const char *smb_
}
s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM,
port, 0, ifip->s_addr, True);
if(s == -1)
- return False;
+ return 0;
/* ready to listen */
set_socket_options(s,"SO_KEEPALIVE");
@@ -384,15 +360,13 @@ static BOOL open_sockets_smbd(enum
smb_server_mode server_mode, const char *smb_
if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
DEBUG(0,("listen: %s\n",strerror(errno)));
close(s);
- return False;
+ return 0;
}
- FD_SET(s,&listen_set);
- maxfd = MAX( maxfd, s);
num_sockets++;
if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
+ DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+ return 0;
}
}
}
@@ -412,7 +386,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode
server_mode, const char *smb_
s = open_socket_in(SOCK_STREAM, port, 0,
interpret_addr(lp_socket_address()),True);
if (s == -1)
- return(False);
+ return 0;
/* ready to listen */
set_socket_options(s,"SO_KEEPALIVE");
@@ -422,26 +396,122 @@ static BOOL open_sockets_smbd(enum
smb_server_mode server_mode, const char *smb_
set_blocking(s,False);
if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: %s\n",
+ DEBUG(0,("init_sockets_smbd: listen: %s\n",
strerror(errno)));
close(s);
- return False;
+ return 0;
}
fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
- maxfd = MAX( maxfd, s);
-
num_sockets++;
if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
- return False;
+ DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+ return 0;
}
}
}
SAFE_FREE(ports);
+ return num_sockets;
+}
+
+static int init_sockets_launchd(const struct smb_launch_info *linfo,
+ const char * smb_ports,
+ int fd_listenset[FD_SETSIZE])
+{
+ int num_sockets;
+ int i;
+
+ /* The launchd service configuration does not have to provide sockets,
+ * even though it's basically useless without it.
+ */
+ if (!linfo->num_sockets) {
+ return init_sockets_smbd(smb_ports, fd_listenset);
+ }
+
+ /* Make sure we don't get more sockets than we can handle. */
+ num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
+ memcpy(fd_listenset, linfo->socket_list, num_sockets * sizeof(int));
+
+ /* Get the sockets ready. This could be hoisted into
+ * open_sockets_smbd(), but the order of socket operations might
+ * matter for some platforms, so this approach seems less risky.
+ * --jpeach
+ */
+ for (i = 0; i < num_sockets; ++i) {
+ set_socket_options(fd_listenset[i], "SO_KEEPALIVE");
+ set_socket_options(fd_listenset[i], user_socket_options);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(fd_listenset[i], False);
+ }
+
+ return num_sockets;
+}
+
+/
****************************************************************************
+ Open the socket communication.
+
****************************************************************************/
+
+static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const
char *smb_ports)
+{
+ int num_sockets = 0;
+ int fd_listenset[FD_SETSIZE];
+ fd_set listen_set;
+ int s;
+ int maxfd = 0;
+ int i;
+ struct timeval idle_timeout = {0, 0};
+ struct smb_launch_info linfo;
+
+ if (server_mode == SERVER_MODE_INETD) {
+ return open_sockets_inetd();
+ }
+
+#ifdef HAVE_ATEXIT
+ {
+ static int atexit_set;
+ if(atexit_set == 0) {
+ atexit_set=1;
+ atexit(killkids);
+ }
+ }
+#endif
+
+ /* Stop zombies */
+ CatchSignal(SIGCLD, sig_cld);
+
+ FD_ZERO(&listen_set);
+
+ /* At this point, it doesn't matter what daemon mode we are in, we
+ * need some sockets to listen on. If we are in FOREGROUND mode,
+ * the launchd checkin might succeed. If we are in DAEMON or
+ * INTERACTIVE modes, it will fail and we will open the sockets
+ * ourselves.
+ */
+ if (smb_launchd_checkin(&linfo)) {
+ /* We are running under launchd and launchd has
+ * opened some sockets for us.
+ */
+ num_sockets = init_sockets_launchd(&linfo,
+ smb_ports,
+ fd_listenset);
+ idle_timeout.tv_sec = linfo.idle_timeout_secs;
+ smb_launchd_checkout(&linfo);
+ } else {
+ num_sockets = init_sockets_smbd(smb_ports,
+ fd_listenset);
+ }
+
+ if (num_sockets == 0) {
+ return False;
+ }
+
+ for (i = 0; i < num_sockets; ++i) {
+ FD_SET(fd_listenset[i], &listen_set);
+ maxfd = MAX(maxfd, fd_listenset[i]);
+ }
/* Setup the main smbd so that we can get messages. Note that
@@ -474,7 +544,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode
server_mode, const char *smb_
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
while (1) {
- struct timeval now, idle_timeout;
+ struct timeval now, event_timeout;
fd_set r_fds, w_fds;
int num;
@@ -490,7 +560,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode
server_mode, const char *smb_
}
}
- idle_timeout = timeval_zero();
+ event_timeout = timeval_zero();
memcpy((char *)&r_fds, (char *)&listen_set,
sizeof(listen_set));
@@ -498,12 +568,19 @@ static BOOL open_sockets_smbd(enum
smb_server_mode server_mode, const char *smb_
GetTimeOfDay(&now);
event_add_to_select_args(smbd_event_context(), &now,
- &r_fds, &w_fds, &idle_timeout,
+ &r_fds, &w_fds, &event_timeout,
&maxfd);
- num = sys_select(maxfd+1,&r_fds,&w_fds,NULL,
- timeval_is_zero(&idle_timeout) ?
- NULL : &idle_timeout);
+ /* The event timeout has precedence over the idle timeout,
+ * We expect that the event timeout will be shorter.
+ */
+ if (timeval_is_zero(&event_timeout)) {
+ event_timeout = idle_timeout;
+ }
+
+ num = sys_select(maxfd+ 1, &r_fds, &w_fds, NULL,
+ timeval_is_zero(&event_timeout) ?
+ NULL : &event_timeout);
if (num == -1 && errno == EINTR) {
if (got_sig_term) {
@@ -520,11 +597,23 @@ static BOOL open_sockets_smbd(enum
smb_server_mode server_mode, const char *smb_
continue;
}
-
+
+ /* At this point we don't know whether we woke up because of
+ * the idle timeout or the event timeout. If we can run events,
+ * then it was probably the latter.
+ */
if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
continue;
}
+ /* If the idle timeout fired and we don't have any connected
+ * users, exit gracefully. We should be running under a process
+ * controller that will restart us if necessry.
+ */
+ if (num == 0 && count_all_current_connections() == 0) {
+ exit_server_cleanly("idle timeout");
+ }
+
/* check if we need to reload services */
check_reload(time(NULL));
diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c
index fce422d..4bea622 100644
--- a/source/winbindd/winbindd.c
+++ b/source/winbindd/winbindd.c
@@ -7,6 +7,7 @@
Copyright (C) Andrew Tridgell 2002
Copyright (C) Jelmer Vernooij 2003
Copyright (C) Volker Lendecke 2004
+ Copyright (C) James Peach 2007
This program is free software; you can redistribute it and/or
modify
it under the terms of the GNU General Public License as published
by
@@ -24,6 +25,7 @@
#include "includes.h"
#include "winbindd.h"
+#include "smb_launchd.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -31,6 +33,7 @@
BOOL opt_nocache = False;
extern BOOL override_logfile;
+static BOOL unlink_winbindd_socket = True;
struct event_context *winbind_event_context(void)
{
@@ -131,9 +134,11 @@ static void terminate(void)
pstring path;
/* Remove socket file */
- pstr_sprintf(path, "%s/%s",
- get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME);
- unlink(path);
+ if (unlink_winbindd_socket) {
+ pstr_sprintf(path, "%s/%s",
+ get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME);
+ unlink(path);
+ }
idmap_close();
@@ -790,28 +795,56 @@ static BOOL remove_idle_client(void)
return False;
}
+static BOOL winbindd_init_sockets(int *public_sock, int *priv_sock,
+ int *idle_timeout_sec)
+{
+ struct smb_launch_info linfo;
+
+ if (smb_launchd_checkin_names(&linfo, "WinbindPublicPipe",
+ "WinbindPrivilegedPipe", NULL)) {
+ if (linfo.num_sockets != 2) {
+ DEBUG(0, ("invalid launchd configuration, "
+ "expected 2 sockets but got %d\n",
+ linfo.num_sockets));
+ return False;
+ }
+
+ *public_sock = linfo.socket_list[0];
+ *priv_sock = linfo.socket_list[1];
+ *idle_timeout_sec = linfo.idle_timeout_secs;
+
+ unlink_winbindd_socket = False;
+
+ smb_launchd_checkout(&linfo);
+ return True;
+ } else {
+ *public_sock = open_winbindd_socket();
+ *priv_sock = open_winbindd_priv_socket();
+ *idle_timeout_sec = -1;
+
+ if (*public_sock == -1 || *priv_sock == -1) {
+ DEBUG(0, ("failed to open winbindd pipes: %s\n",
+ errno ? strerror(errno) : "unknown error"));
+ return False;
+ }
+
+ return True;
+ }
+}
+
/* Process incoming clients on listen_sock. We use a tricky non-
blocking,
non-forking, non-threaded model which allows us to handle many
simultaneous connections while remaining impervious to many
denial of
service attacks. */
-static void process_loop(void)
+static int process_loop(int listen_sock, int listen_priv_sock)
{
struct winbindd_cli_state *state;
struct fd_event *ev;
fd_set r_fds, w_fds;
- int maxfd, listen_sock, listen_priv_sock, selret;
+ int maxfd, selret;
struct timeval timeout, ev_timeout;
- /* Open Sockets here to get stuff going ASAP */
- listen_sock = open_winbindd_socket();
- listen_priv_sock = open_winbindd_priv_socket();
-
- if (listen_sock == -1 || listen_priv_sock == -1) {
- perror("open_winbind_socket");
- exit(1);
- }
-
/* We'll be doing this a lot */
/* Handle messages */
@@ -976,6 +1009,60 @@ static void process_loop(void)
winbind_child_died(pid);
}
}
+
+
+ return winbindd_num_clients();
+}
+
+static void winbindd_process_loop(enum smb_server_mode server_mode)
+{
+ int idle_timeout_sec;
+ struct timeval starttime;
+ int listen_public, listen_priv;
+
+ errno = 0;
+ if (!winbindd_init_sockets(&listen_public, &listen_priv,
+ &idle_timeout_sec)) {
+ terminate();
+ }
+
+ starttime = timeval_current();
+
+ if (listen_public == -1 || listen_priv == -1) {
+ DEBUG(0, ("failed to open winbindd pipes: %s\n",
+ errno ? strerror(errno) : "unknown error"));
+ terminate();
+ }
+
+ for (;;) {
+ int clients = 0;
+ TALLOC_CTX *frame = NULL;
+
+ frame = talloc_stackframe();
+ clients = process_loop(listen_public, listen_priv);
+ TALLOC_FREE(frame);
+
+ /* Don't bother figuring out the idle time if we won't be
+ * timing out anyway.
+ */
+ if (idle_timeout_sec < 0) {
+ continue;
+ }
+
+ if (clients == 0 && server_mode == SERVER_MODE_FOREGROUND) {
+ struct timeval now;
+
+ now = timeval_current();
+ if (timeval_elapsed2(&starttime, &now) >
+ (double)idle_timeout_sec) {
+ DEBUG(0, ("idle for %d secs, exitting\n",
+ idle_timeout_sec));
+ terminate();
+ }
+ } else {
+ starttime = timeval_current();
+ }
+ }
}
/* Main function */
@@ -1221,12 +1308,7 @@ int main(int argc, char **argv, char **envp)
smb_nscd_flush_group_cache();
/* Loop waiting for requests */
-
- while (1) {
- TALLOC_CTX *frame = talloc_stackframe();
- process_loop();
- TALLOC_FREE(frame);
- }
+ winbindd_process_loop(server_mode);
return 0;
}
--
1.5.3.4
From 714d5622aea999e35786334f848aebb59c1f9c6a Mon Sep 17 00:00:00 2001
From: James Peach <jpeach at samba.org>
Date: Sun, 14 Oct 2007 15:36:37 -0700
Subject: [PATCH] Update license headers.
---
source/include/smb_launchd.h | 12 +++++++-----
source/lib/launchd.c | 11 +++++------
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/source/include/smb_launchd.h b/source/include/smb_launchd.h
index 2e758a4..6376f07 100644
--- a/source/include/smb_launchd.h
+++ b/source/include/smb_launchd.h
@@ -6,19 +6,21 @@
This program is free software; you can redistribute it and/or
modify
it under the terms of the GNU General Public License as published
by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/
>.
*/
+#include "includes.h"
+#include "smb_launchd.h"
+
struct smb_launch_info
{
int idle_timeout_secs;
diff --git a/source/lib/launchd.c b/source/lib/launchd.c
index 1fd5a33..bfabaef 100644
--- a/source/lib/launchd.c
+++ b/source/lib/launchd.c
@@ -2,21 +2,20 @@
Unix SMB/CIFS implementation.
Launchd integration wrapper API
- Copyright (C) 2007 James Peach
+ Copyright (C) James Peach 2007
This program is free software; you can redistribute it and/or
modify
it under the terms of the GNU General Public License as published
by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/
>.
*/
#include "includes.h"
--
1.5.3.4
From 7b0a4f56f00923b37e669270fc3fa0042ebcfb43 Mon Sep 17 00:00:00 2001
From: James Peach <jpeach at samba.org>
Date: Sun, 14 Oct 2007 16:18:15 -0700
Subject: [PATCH] Wrap smbd socket initializaion.
Create small wrapper API to hide the details of obtaining a set of
sockets to listen on. We can currently either create these ourselves
or be given them by launchd.
---
source/Makefile.in | 2 +-
source/include/smb_launchd.h | 3 -
source/smbd/server.c | 178
+-----------------------------------
source/smbd/sockinit.c | 212 +++++++++++++++++++++++++++++++++
+++++++++
4 files changed, 215 insertions(+), 180 deletions(-)
create mode 100644 source/smbd/sockinit.c
diff --git a/source/Makefile.in b/source/Makefile.in
index 8558d81..dcb88fe 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -529,7 +529,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/
connection.o \
smbd/change_trust_pw.o smbd/fake_file.o \
smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
$(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
- smbd/dmapi.o lib/launchd.o \
+ smbd/dmapi.o lib/launchd.o smbd/sockinit.o \
$(MANGLE_OBJ) @VFS_STATIC@
SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $
(LIBSMB_OBJ) \
diff --git a/source/include/smb_launchd.h b/source/include/smb_launchd.h
index 6376f07..6d6394f 100644
--- a/source/include/smb_launchd.h
+++ b/source/include/smb_launchd.h
@@ -18,9 +18,6 @@
along with this program. If not, see <http://www.gnu.org/
licenses/>.
*/
-#include "includes.h"
-#include "smb_launchd.h"
-
struct smb_launch_info
{
int idle_timeout_secs;
diff --git a/source/smbd/server.c b/source/smbd/server.c
index fbf2a39..6564267 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "smb_launchd.h"
static_decl_rpc;
@@ -294,162 +293,6 @@ static BOOL
allowable_number_of_smbd_processes(void)
return num_children < max_processes;
}
-static int init_sockets_smbd(const char *smb_ports,
- int fd_listenset[FD_SETSIZE])
-{
- int num_interfaces = iface_count();
- char * ports;
- int num_sockets = 0;
- int i, s;
-
- /* use a reasonable default set of ports - listing on 445 and 139 */
- if (!smb_ports) {
- ports = lp_smb_ports();
- if (!ports || !*ports) {
- ports = smb_xstrdup(SMB_PORTS);
- } else {
- ports = smb_xstrdup(ports);
- }
- } else {
- ports = smb_xstrdup(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);
- const struct in_addr *ifip;
- fstring tok;
- const char *ptr;
-
- if (ifss == NULL) {
- DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !
\n", i));
- continue;
- }
-
- /* For now only deal with IPv4. */
- if (ifss->ss_family != AF_INET) {
- continue;
- }
-
- ifip = &((const struct sockaddr_in *)ifss)->sin_addr;
-
- for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0 || port > 0xffff) {
- continue;
- }
- s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port,
0, ifip->s_addr, True);
- if(s == -1)
- return 0;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return 0;
- }
-
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
- return 0;
- }
- }
- }
- } else {
- /* Just bind to 0.0.0.0 - accept connections
- from anywhere. */
-
- fstring tok;
- const char *ptr;
-
- num_interfaces = 1;
-
- for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
- unsigned port = atoi(tok);
- if (port == 0 || port > 0xffff) continue;
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
- if (s == -1)
- return 0;
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("init_sockets_smbd: listen: %s\n",
- strerror(errno)));
- close(s);
- return 0;
- }
-
- fd_listenset[num_sockets] = s;
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
- return 0;
- }
- }
- }
-
- SAFE_FREE(ports);
- return num_sockets;
-}
-
-static int init_sockets_launchd(const struct smb_launch_info *linfo,
- const char * smb_ports,
- int fd_listenset[FD_SETSIZE])
-{
- int num_sockets;
- int i;
-
- /* The launchd service configuration does not have to provide sockets,
- * even though it's basically useless without it.
- */
- if (!linfo->num_sockets) {
- return init_sockets_smbd(smb_ports, fd_listenset);
- }
-
- /* Make sure we don't get more sockets than we can handle. */
- num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
- memcpy(fd_listenset, linfo->socket_list, num_sockets * sizeof(int));
-
- /* Get the sockets ready. This could be hoisted into
- * open_sockets_smbd(), but the order of socket operations might
- * matter for some platforms, so this approach seems less risky.
- * --jpeach
- */
- for (i = 0; i < num_sockets; ++i) {
- set_socket_options(fd_listenset[i], "SO_KEEPALIVE");
- set_socket_options(fd_listenset[i], user_socket_options);
-
- /* Set server socket to non-blocking for the accept. */
- set_blocking(fd_listenset[i], False);
- }
-
- return num_sockets;
-}
-
/
****************************************************************************
Open the socket communication.
****************************************************************************/
@@ -463,7 +306,6 @@ static BOOL open_sockets_smbd(enum smb_server_mode
server_mode, const char *smb_
int maxfd = 0;
int i;
struct timeval idle_timeout = {0, 0};
- struct smb_launch_info linfo;
if (server_mode == SERVER_MODE_INETD) {
return open_sockets_inetd();
@@ -485,25 +327,9 @@ static BOOL open_sockets_smbd(enum
smb_server_mode server_mode, const char *smb_
FD_ZERO(&listen_set);
/* At this point, it doesn't matter what daemon mode we are in, we
- * need some sockets to listen on. If we are in FOREGROUND mode,
- * the launchd checkin might succeed. If we are in DAEMON or
- * INTERACTIVE modes, it will fail and we will open the sockets
- * ourselves.
+ * need some sockets to listen on.
*/
- if (smb_launchd_checkin(&linfo)) {
- /* We are running under launchd and launchd has
- * opened some sockets for us.
- */
- num_sockets = init_sockets_launchd(&linfo,
- smb_ports,
- fd_listenset);
- idle_timeout.tv_sec = linfo.idle_timeout_secs;
- smb_launchd_checkout(&linfo);
- } else {
- num_sockets = init_sockets_smbd(smb_ports,
- fd_listenset);
- }
-
+ num_sockets = smbd_sockinit(smb_ports, fd_listenset, &idle_timeout);
if (num_sockets == 0) {
return False;
}
diff --git a/source/smbd/sockinit.c b/source/smbd/sockinit.c
new file mode 100644
index 0000000..6473b5c
--- /dev/null
+++ b/source/smbd/sockinit.c
@@ -0,0 +1,212 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) James Peach 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/
>.
+*/
+
+#include "includes.h"
+#include "smb_launchd.h"
+
+extern pstring user_socket_options;
+
+static int init_sockets_smbd(const char *smb_ports,
+ int fd_listenset[FD_SETSIZE])
+{
+ int num_interfaces = iface_count();
+ char * ports;
+ int num_sockets = 0;
+ int i, s;
+
+ /* use a reasonable default set of ports - listing on 445 and 139 */
+ if (!smb_ports) {
+ ports = lp_smb_ports();
+ if (!ports || !*ports) {
+ ports = smb_xstrdup(SMB_PORTS);
+ } else {
+ ports = smb_xstrdup(ports);
+ }
+ } else {
+ ports = smb_xstrdup(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);
+ const struct in_addr *ifip;
+ fstring tok;
+ const char *ptr;
+
+ if (ifss == NULL) {
+ DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !
\n", i));
+ continue;
+ }
+
+ /* For now only deal with IPv4. */
+ if (ifss->ss_family != AF_INET) {
+ continue;
+ }
+
+ ifip = &((const struct sockaddr_in *)ifss)->sin_addr;
+
+ for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+ unsigned port = atoi(tok);
+ if (port == 0 || port > 0xffff) {
+ continue;
+ }
+ s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port,
0, ifip->s_addr, True);
+ if(s == -1) {
+ return 0;
+ }
+
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(s,False);
+
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("listen: %s\n",strerror(errno)));
+ close(s);
+ return 0;
+ }
+
+ num_sockets++;
+ if (num_sockets >= FD_SETSIZE) {
+ DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+ return 0;
+ }
+ }
+ }
+ } else {
+ /* Just bind to 0.0.0.0 - accept connections
+ from anywhere. */
+
+ fstring tok;
+ const char *ptr;
+
+ num_interfaces = 1;
+
+ for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
+ unsigned port = atoi(tok);
+ if (port == 0 || port > 0xffff) continue;
+ /* open an incoming socket */
+ s = open_socket_in(SOCK_STREAM, port, 0,
+ interpret_addr(lp_socket_address()),True);
+ if (s == -1) {
+ return 0;
+ }
+
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(s,False);
+
+ if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("init_sockets_smbd: listen: %s\n",
+ strerror(errno)));
+ close(s);
+ return 0;
+ }
+
+ fd_listenset[num_sockets] = s;
+ num_sockets++;
+
+ if (num_sockets >= FD_SETSIZE) {
+ DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
+ return 0;
+ }
+ }
+ }
+
+ SAFE_FREE(ports);
+ return num_sockets;
+}
+
+static int init_sockets_launchd(const struct smb_launch_info *linfo,
+ const char * smb_ports,
+ int listenset[FD_SETSIZE])
+{
+ int num_sockets;
+ int i;
+
+ /* The launchd service configuration does not have to provide sockets,
+ * even though it's basically useless without it.
+ */
+ if (!linfo->num_sockets) {
+ return init_sockets_smbd(smb_ports, listenset);
+ }
+
+ /* Make sure we don't get more sockets than we can handle. */
+ num_sockets = MIN(FD_SETSIZE, linfo->num_sockets);
+ memcpy(listenset, linfo->socket_list, num_sockets * sizeof(int));
+
+ /* Get the sockets ready. This could be hoisted into
+ * open_sockets_smbd(), but the order of socket operations might
+ * matter for some platforms, so this approach seems less risky.
+ * --jpeach
+ */
+ for (i = 0; i < num_sockets; ++i) {
+ set_socket_options(listenset[i], "SO_KEEPALIVE");
+ set_socket_options(listenset[i], user_socket_options);
+
+ /* Set server socket to non-blocking for the accept. */
+ set_blocking(listenset[i], False);
+ }
+
+ return num_sockets;
+}
+
+/* This function is responsible for opening (or retrieving) all the
sockets we
+ * smbd will be listening on. It should apply all the configured
socket options
+ * and return the number of valid sockets in listenset.
+ */
+int smbd_sockinit(const char *cmdline_ports, int listenset[FD_SETSIZE],
+ struct timeval *idle)
+{
+ int num_sockets;
+ struct smb_launch_info linfo;
+
+ ZERO_STRUCTP(idle);
+
+ if (smb_launchd_checkin(&linfo)) {
+ /* We are running under launchd and launchd has
+ * opened some sockets for us.
+ */
+ num_sockets = init_sockets_launchd(&linfo,
+ cmdline_ports,
+ listenset);
+ idle->tv_sec = linfo.idle_timeout_secs;
+ smb_launchd_checkout(&linfo);
+ } else {
+ num_sockets = init_sockets_smbd(cmdline_ports,
+ listenset);
+ }
+
+ return num_sockets;
+}
+
--
1.5.3.4
From e20a8c521d7860d9b7bd724ed5ea19c7306530ab Mon Sep 17 00:00:00 2001
From: James Peach <jpeach at samba.org>
Date: Sun, 14 Oct 2007 17:02:02 -0700
Subject: [PATCH] Wrap winbindd socket initialization.
Create small wrapper API to hide the details of obtaining a set
of sockets to listen on. We can currently either create these
ourselves or be given them by launchd.
---
source/Makefile.in | 1 +
source/winbindd/winbindd.c | 48 +-------------
source/winbindd/winbindd_sockinit.c | 126 ++++++++++++++++++++++++++
+++++++++
source/winbindd/winbindd_util.c | 47 -------------
4 files changed, 128 insertions(+), 94 deletions(-)
create mode 100644 source/winbindd/winbindd_sockinit.c
diff --git a/source/Makefile.in b/source/Makefile.in
index dcb88fe..f1d41e9 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -847,6 +847,7 @@ NSS_INFO_OBJ = winbindd/nss_info.o @NSS_INFO_STATIC@
WINBINDD_OBJ1 = \
winbindd/winbindd.o \
+ winbindd/winbindd_sockinit.o \
winbindd/winbindd_user.o \
winbindd/winbindd_group.o \
winbindd/winbindd_util.o \
diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c
index 4bea622..61d3080 100644
--- a/source/winbindd/winbindd.c
+++ b/source/winbindd/winbindd.c
@@ -25,7 +25,6 @@
#include "includes.h"
#include "winbindd.h"
-#include "smb_launchd.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -33,7 +32,6 @@
BOOL opt_nocache = False;
extern BOOL override_logfile;
-static BOOL unlink_winbindd_socket = True;
struct event_context *winbind_event_context(void)
{
@@ -131,15 +129,8 @@ static void flush_caches(void)
static void terminate(void)
{
- pstring path;
-
- /* Remove socket file */
- if (unlink_winbindd_socket) {
- pstr_sprintf(path, "%s/%s",
- get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME);
- unlink(path);
- }
+ winbindd_release_sockets();
idmap_close();
trustdom_cache_shutdown();
@@ -795,43 +786,6 @@ static BOOL remove_idle_client(void)
return False;
}
-static BOOL winbindd_init_sockets(int *public_sock, int *priv_sock,
- int *idle_timeout_sec)
-{
- struct smb_launch_info linfo;
-
- if (smb_launchd_checkin_names(&linfo, "WinbindPublicPipe",
- "WinbindPrivilegedPipe", NULL)) {
- if (linfo.num_sockets != 2) {
- DEBUG(0, ("invalid launchd configuration, "
- "expected 2 sockets but got %d\n",
- linfo.num_sockets));
- return False;
- }
-
- *public_sock = linfo.socket_list[0];
- *priv_sock = linfo.socket_list[1];
- *idle_timeout_sec = linfo.idle_timeout_secs;
-
- unlink_winbindd_socket = False;
-
- smb_launchd_checkout(&linfo);
- return True;
- } else {
- *public_sock = open_winbindd_socket();
- *priv_sock = open_winbindd_priv_socket();
- *idle_timeout_sec = -1;
-
- if (*public_sock == -1 || *priv_sock == -1) {
- DEBUG(0, ("failed to open winbindd pipes: %s\n",
- errno ? strerror(errno) : "unknown error"));
- return False;
- }
-
- return True;
- }
-}
-
/* Process incoming clients on listen_sock. We use a tricky non-
blocking,
non-forking, non-threaded model which allows us to handle many
simultaneous connections while remaining impervious to many
denial of
diff --git a/source/winbindd/winbindd_sockinit.c b/source/winbindd/
winbindd_sockinit.c
new file mode 100644
index 0000000..27060fd
--- /dev/null
+++ b/source/winbindd/winbindd_sockinit.c
@@ -0,0 +1,126 @@
+/*
+ Unix SMB/CIFS implementation.
+ Copyright (C) Tim Potter 2000-2001
+ Copyright (C) 2001 by Martin Pool <mbp at samba.org>
+ Copyright (C) James Peach 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/
>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "smb_launchd.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_WINBIND
+
+/* Open the winbindd socket */
+
+static int _winbindd_socket = -1;
+static int _winbindd_priv_socket = -1;
+static BOOL unlink_winbindd_socket = True;
+
+static int open_winbindd_socket(void)
+{
+ if (_winbindd_socket == -1) {
+ _winbindd_socket = create_pipe_sock(
+ WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);
+ DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
+ _winbindd_socket));
+ }
+
+ return _winbindd_socket;
+}
+
+static int open_winbindd_priv_socket(void)
+{
+ if (_winbindd_priv_socket == -1) {
+ _winbindd_priv_socket = create_pipe_sock(
+ get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
+ DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
+ _winbindd_priv_socket));
+ }
+
+ return _winbindd_priv_socket;
+}
+
+/* Close the winbindd socket */
+
+static void close_winbindd_socket(void)
+{
+ if (_winbindd_socket != -1) {
+ DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
+ _winbindd_socket));
+ close(_winbindd_socket);
+ _winbindd_socket = -1;
+ }
+ if (_winbindd_priv_socket != -1) {
+ DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
+ _winbindd_priv_socket));
+ close(_winbindd_priv_socket);
+ _winbindd_priv_socket = -1;
+ }
+}
+
+BOOL winbindd_init_sockets(int *public_sock, int *priv_sock,
+ int *idle_timeout_sec)
+{
+ struct smb_launch_info linfo;
+
+ if (smb_launchd_checkin_names(&linfo, "WinbindPublicPipe",
+ "WinbindPrivilegedPipe", NULL)) {
+ if (linfo.num_sockets != 2) {
+ DEBUG(0, ("invalid launchd configuration, "
+ "expected 2 sockets but got %d\n",
+ linfo.num_sockets));
+ return False;
+ }
+
+ *public_sock = _winbindd_socket = linfo.socket_list[0];
+ *priv_sock = _winbindd_priv_socket = linfo.socket_list[1];
+ *idle_timeout_sec = linfo.idle_timeout_secs;
+
+ unlink_winbindd_socket = False;
+
+ smb_launchd_checkout(&linfo);
+ return True;
+ } else {
+ *public_sock = open_winbindd_socket();
+ *priv_sock = open_winbindd_priv_socket();
+ *idle_timeout_sec = -1;
+
+ if (*public_sock == -1 || *priv_sock == -1) {
+ DEBUG(0, ("failed to open winbindd pipes: %s\n",
+ errno ? strerror(errno) : "unknown error"));
+ return False;
+ }
+
+ return True;
+ }
+}
+
+void winbindd_release_sockets(void)
+{
+ pstring path;
+
+ close_winbindd_socket();
+
+ /* Remove socket file */
+ if (unlink_winbindd_socket) {
+ pstr_sprintf(path, "%s/%s",
+ WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
+ unlink(path);
+ }
+}
+
diff --git a/source/winbindd/winbindd_util.c b/source/winbindd/
winbindd_util.c
index c2fe09e..e5fdb14 100644
--- a/source/winbindd/winbindd_util.c
+++ b/source/winbindd/winbindd_util.c
@@ -1165,53 +1165,6 @@ char *get_winbind_priv_pipe_dir(void)
return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
}
-/* Open the winbindd socket */
-
-static int _winbindd_socket = -1;
-static int _winbindd_priv_socket = -1;
-
-int open_winbindd_socket(void)
-{
- if (_winbindd_socket == -1) {
- _winbindd_socket = create_pipe_sock(
- get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
- DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
- _winbindd_socket));
- }
-
- return _winbindd_socket;
-}
-
-int open_winbindd_priv_socket(void)
-{
- if (_winbindd_priv_socket == -1) {
- _winbindd_priv_socket = create_pipe_sock(
- get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
- DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
- _winbindd_priv_socket));
- }
-
- return _winbindd_priv_socket;
-}
-
-/* Close the winbindd socket */
-
-void close_winbindd_socket(void)
-{
- if (_winbindd_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_socket));
- close(_winbindd_socket);
- _winbindd_socket = -1;
- }
- if (_winbindd_priv_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_priv_socket));
- close(_winbindd_priv_socket);
- _winbindd_priv_socket = -1;
- }
-}
-
/*
* Client list accessor functions
*/
--
1.5.3.4
More information about the samba-technical
mailing list