summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in9
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/messages.h27
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/lib/debug.c61
-rw-r--r--source3/lib/messages.c237
-rw-r--r--source3/locking/locking.c2
-rw-r--r--source3/nmbd/nmbd.c19
-rw-r--r--source3/nmbd/nmbd_packets.c12
-rw-r--r--source3/nsswitch/winbindd.c8
-rw-r--r--source3/smbd/process.c3
-rw-r--r--source3/smbd/server.c18
12 files changed, 306 insertions, 101 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 018086b40b..7d242ea569 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -108,7 +108,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/util_unistr.o lib/util_file.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
- lib/ms_fnmatch.o lib/select.o lib/error.o \
+ lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \
$(TDB_OBJ)
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
@@ -226,6 +226,9 @@ MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \
STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+MSGTEST_OBJ = utils/msgtest.o $(LOCKING_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+
TESTPARM_OBJ = utils/testparm.o \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -467,6 +470,10 @@ bin/smbstatus: $(STATUS_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(LIBS)
+bin/msgtest: $(MSGTEST_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS)
+
bin/smbpasswd: $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(LIBS)
diff --git a/source3/include/includes.h b/source3/include/includes.h
index eb2f23b6fe..a18c8b6d5c 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -612,6 +612,7 @@ extern int errno;
#include "trans2.h"
#include "nterr.h"
#include "secrets.h"
+#include "messages.h"
#include "util_list.h"
#ifndef UBI_BINTREE_H
diff --git a/source3/include/messages.h b/source3/include/messages.h
new file mode 100644
index 0000000000..4bc4014ca0
--- /dev/null
+++ b/source3/include/messages.h
@@ -0,0 +1,27 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ messages.c header
+ Copyright (C) Andrew Tridgell 2000
+
+ 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.
+*/
+
+#ifndef _MESSAGES_H_
+#define _MESSAGES_H_
+
+enum message_type {MSG_DEBUG};
+
+#endif
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 737053a2a3..754c51ee9d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -59,8 +59,8 @@ uint32 crc32_calc_buffer( char *buffer, uint32 count);
/*The following definitions come from lib/debug.c */
-void sig_usr2( int sig );
-void sig_usr1( int sig );
+void debug_message(pid_t src, void *buf, int len);
+void debug_message_send(pid_t pid, int level);
void setup_logging( char *pname, BOOL interactive );
void reopen_logs( void );
void force_check_log_size( void );
@@ -150,6 +150,12 @@ void initialize_multibyte_vectors( int client_codepage);
void mdfour(unsigned char *out, unsigned char *in, int n);
+/*The following definitions come from lib/messages.c */
+
+BOOL message_init(void);
+BOOL message_send_pid(pid_t pid, enum message_type msg_type, void *buf, size_t len);
+void message_dispatch(void);
+
/*The following definitions come from lib/ms_fnmatch.c */
int ms_fnmatch(char *pattern, char *string);
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index bfb638a38a..5279dda2e3 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -119,51 +119,24 @@ static size_t format_pos = 0;
* Functions...
*/
-#if defined(SIGUSR2)
-/* ************************************************************************** **
- * catch a sigusr2 - decrease the debug log level.
- * ************************************************************************** **
- */
-void sig_usr2( int sig )
- {
- DEBUGLEVEL--;
- if( DEBUGLEVEL < 0 )
- DEBUGLEVEL = 0;
-
- DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) );
-
- sys_select_signal();
-
-#if !defined(HAVE_SIGACTION)
- CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif
-
- } /* sig_usr2 */
-#endif /* SIGUSR2 */
-
-#if defined(SIGUSR1)
-/* ************************************************************************** **
- * catch a sigusr1 - increase the debug log level.
- * ************************************************************************** **
- */
-void sig_usr1( int sig )
- {
-
- DEBUGLEVEL++;
-
- if( DEBUGLEVEL > 10 )
- DEBUGLEVEL = 10;
-
- DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
-
- sys_select_signal();
-
-#if !defined(HAVE_SIGACTION)
- CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif
+/****************************************************************************
+receive a "set debug level" message
+****************************************************************************/
+void debug_message(pid_t src, void *buf, int len)
+{
+ int level;
+ memcpy(&level, buf, sizeof(int));
+ DEBUGLEVEL = level;
+ DEBUG(1,("Debug level set to %d from pid %d\n", level, (int)src));
+}
- } /* sig_usr1 */
-#endif /* SIGUSR1 */
+/****************************************************************************
+send a "set debug level" message
+****************************************************************************/
+void debug_message_send(pid_t pid, int level)
+{
+ message_send_pid(pid, MSG_DEBUG, &level, sizeof(int));
+}
/* ************************************************************************** **
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
new file mode 100644
index 0000000000..30eef40ec9
--- /dev/null
+++ b/source3/lib/messages.c
@@ -0,0 +1,237 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba internal messaging functions
+ Copyright (C) Andrew Tridgell 2000
+
+ 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.
+*/
+
+/* this module is used for internal messaging between Samba daemons. */
+
+#include "includes.h"
+
+/* the locking database handle */
+static TDB_CONTEXT *tdb;
+static int received_signal;
+
+/* change the message version with any incompatible changes in the protocol */
+#define MESSAGE_VERSION 1
+
+struct message_rec {
+ int msg_version;
+ enum message_type msg_type;
+ pid_t dest;
+ pid_t src;
+ size_t len;
+};
+
+/****************************************************************************
+notifications come in as signals
+****************************************************************************/
+static void sig_usr1(void)
+{
+ received_signal = 1;
+ sys_select_signal();
+}
+
+/****************************************************************************
+ Initialise the messaging functions.
+****************************************************************************/
+BOOL message_init(void)
+{
+ if (tdb) return True;
+
+ tdb = tdb_open(lock_path("messages.tdb"),
+ 0, TDB_CLEAR_IF_FIRST,
+ O_RDWR|O_CREAT,0600);
+
+ if (!tdb) {
+ DEBUG(0,("ERROR: Failed to initialise messages database\n"));
+ return False;
+ }
+
+ CatchSignal(SIGUSR1, sig_usr1);
+
+ return True;
+}
+
+
+/*******************************************************************
+ form a static tdb key from a pid
+******************************************************************/
+static TDB_DATA message_key_pid(pid_t pid)
+{
+ static char key[20];
+ TDB_DATA kbuf;
+
+ slprintf(key, sizeof(key), "PID/%d", (int)pid);
+
+ kbuf.dptr = (char *)key;
+ kbuf.dsize = sizeof(key);
+ return kbuf;
+}
+
+
+/****************************************************************************
+notify a process that it has a message. If the process doesn't exist
+then delete its record in the database
+****************************************************************************/
+static BOOL message_notify(pid_t pid)
+{
+ if (kill(pid, SIGUSR1) == -1) {
+ if (errno == ESRCH) {
+ DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
+ tdb_delete(tdb, message_key_pid(pid));
+ } else {
+ DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));
+ }
+ return False;
+ }
+ return True;
+}
+
+/****************************************************************************
+send a message to a particular pid
+****************************************************************************/
+BOOL message_send_pid(pid_t pid, enum message_type msg_type, void *buf, size_t len)
+{
+ TDB_DATA kbuf;
+ TDB_DATA dbuf;
+ struct message_rec rec;
+ void *p;
+
+ rec.msg_version = MESSAGE_VERSION;
+ rec.msg_type = msg_type;
+ rec.dest = pid;
+ rec.src = sys_getpid();
+ rec.len = len;
+
+ kbuf = message_key_pid(pid);
+
+ /* lock the record for the destination */
+ tdb_lockchain(tdb, kbuf);
+
+ dbuf = tdb_fetch(tdb, kbuf);
+
+ if (!dbuf.dptr) {
+ /* its a new record */
+ p = (void *)malloc(len + sizeof(rec));
+ if (!p) goto failed;
+
+ memcpy(p, &rec, sizeof(rec));
+ memcpy(p+sizeof(rec), buf, len);
+
+ dbuf.dptr = p;
+ dbuf.dsize = len + sizeof(rec);
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ free(p);
+ goto ok;
+ }
+
+ /* we're adding to an existing entry */
+ p = (void *)malloc(dbuf.dsize + len + sizeof(rec));
+ if (!p) goto failed;
+
+ memcpy(p, dbuf.dptr, dbuf.dsize);
+ memcpy(p+dbuf.dsize, &rec, sizeof(rec));
+ memcpy(p+dbuf.dsize+sizeof(rec), buf, len);
+
+ dbuf.dptr = p;
+ dbuf.dsize += len + sizeof(rec);
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ free(dbuf.dptr);
+ free(p);
+
+ ok:
+ tdb_unlockchain(tdb, kbuf);
+ return message_notify(pid);
+
+ failed:
+ tdb_unlockchain(tdb, kbuf);
+ return False;
+}
+
+
+
+/****************************************************************************
+retrieve the next message for the current process
+****************************************************************************/
+static BOOL message_recv(enum message_type *msg_type, pid_t *src, void **buf, size_t *len)
+{
+ TDB_DATA kbuf;
+ TDB_DATA dbuf;
+ struct message_rec rec;
+
+ kbuf = message_key_pid(sys_getpid());
+
+ tdb_lockchain(tdb, kbuf);
+
+ dbuf = tdb_fetch(tdb, kbuf);
+ if (dbuf.dptr == NULL || dbuf.dsize == 0) goto failed;
+
+ memcpy(&rec, dbuf.dptr, sizeof(rec));
+
+ if (rec.msg_version != MESSAGE_VERSION) {
+ DEBUG(0,("message version %d received (expected %d)\n", rec.msg_version, MESSAGE_VERSION));
+ goto failed;
+ }
+
+ (*buf) = (void *)malloc(rec.len);
+ if (!(*buf)) goto failed;
+
+ memcpy(*buf, dbuf.dptr+sizeof(rec), rec.len);
+ *len = rec.len;
+ *msg_type = rec.msg_type;
+ *src = rec.src;
+
+ memmove(dbuf.dptr, dbuf.dptr+sizeof(rec)+rec.len, dbuf.dsize - (sizeof(rec)+rec.len));
+ dbuf.dsize -= sizeof(rec)+rec.len;
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+
+ free(dbuf.dptr);
+ tdb_unlockchain(tdb, kbuf);
+ return True;
+
+ failed:
+ tdb_unlockchain(tdb, kbuf);
+ return False;
+}
+
+
+/****************************************************************************
+receive and dispatch any messages pending for this process
+****************************************************************************/
+void message_dispatch(void)
+{
+ enum message_type msg_type;
+ pid_t src;
+ void *buf;
+ size_t len;
+
+ if (!received_signal) return;
+ received_signal = 0;
+
+ while (message_recv(&msg_type, &src, &buf, &len)) {
+ switch (msg_type) {
+ case MSG_DEBUG:
+ debug_message(src, buf, len);
+ break;
+ default:
+ DEBUG(0,("Unknown message type %d from %d\n", msg_type, (int)src));
+ break;
+ }
+ }
+}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 8fc1c4a4bc..58e6b06e66 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -229,7 +229,7 @@ BOOL locking_init(int read_only)
0644);
if (!tdb) {
- DEBUG(0,("ERROR: Failed to initialise share modes\n"));
+ DEBUG(0,("ERROR: Failed to initialise locking database\n"));
return False;
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index af78af756e..cd47296774 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -682,19 +682,6 @@ static void usage(char *pname)
BlockSignals(True,SIGFPE);
#endif
- /* Setup the signals that allow the debug log level
- to by dynamically changed. */
-
- /* If we are using the malloc debug code we can't use
- SIGUSR1 and SIGUSR2 to do debug level changes. */
-#if defined(SIGUSR1)
- CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif /* SIGUSR1 */
-
-#if defined(SIGUSR2)
- CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif /* SIGUSR2 */
-
while( EOF !=
(opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
{
@@ -850,12 +837,6 @@ static void usage(char *pname)
/* We can only take signals in the select. */
BlockSignals( True, SIGTERM );
-#if defined(SIGUSR1)
- BlockSignals( True, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
- BlockSignals( True, SIGUSR2);
-#endif /* SIGUSR2 */
process();
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index cf00dc9083..605233f40d 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1808,24 +1808,12 @@ BOOL listen_for_packets(BOOL run_election)
/* Prepare for the select - allow certain signals. */
BlockSignals(False, SIGTERM);
-#if defined(SIGUSR1)
- BlockSignals(False, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
- BlockSignals(False, SIGUSR2);
-#endif /* SIGUSR2 */
selrtn = sys_select_intr(FD_SETSIZE,&fds,&timeout);
/* We can only take signals when we are in the select - block them again here. */
BlockSignals(True, SIGTERM);
-#if defined(SIGUSR1)
- BlockSignals(True, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
- BlockSignals(True, SIGUSR2);
-#endif /* SIGUSR2 */
if(selrtn > 0)
{
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index e05166e716..7af1d09723 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -91,13 +91,6 @@ static void termination_handler(int signum)
static BOOL print_client_info;
-static void sigusr1_handler(int signum)
-{
- BlockSignals(True, SIGUSR1);
- print_client_info = True;
- BlockSignals(False, SIGUSR1);
-}
-
static BOOL flush_cache;
static void sighup_handler(int signum)
@@ -645,7 +638,6 @@ int main(int argc, char **argv)
CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
- CatchSignal(SIGUSR1, sigusr1_handler); /* Debugging sigs */
CatchSignal(SIGHUP, sighup_handler);
/* Create UNIX domain socket */
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 37d8f8dd73..1599ade12d 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -131,6 +131,9 @@ static void async_processing(fd_set *fds, char *buffer, int buffer_len)
reload_services(False);
reload_after_sighup = False;
}
+
+ /* check for any pending internal messages */
+ message_dispatch();
}
/****************************************************************************
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8691603eb3..4442a1f71f 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -685,20 +685,6 @@ static void usage(char *pname)
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
- /* Setup the signals that allow the debug log level
- to by dynamically changed. */
-
- /* If we are using the malloc debug code we can't use
- SIGUSR1 and SIGUSR2 to do debug level changes. */
-
-#if defined(SIGUSR1)
- CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif /* SIGUSR1 */
-
-#if defined(SIGUSR2)
- CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif /* SIGUSR2 */
-
DEBUG(3,( "loaded services\n"));
if (!is_daemon && !is_a_socket(0)) {
@@ -726,6 +712,10 @@ static void usage(char *pname)
* everything after this point is run after the fork()
*/
+ if (!message_init()) {
+ exit(1);
+ }
+
if (!locking_init(0)) {
exit(1);
}