--- source/Makefile.in
+++ source/Makefile.in
@@ -144,7 +144,7 @@
 
 # Note that all executable programs now provide for an optional executable suffix.
 
-SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@
+SBIN_PROGS = bin/samba_multicall@EXEEXT@ bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@
 
 ROOT_SBIN_PROGS = @CIFSMOUNT_PROGS@
 
@@ -963,6 +963,31 @@
 	  dir=bin $(MAKEDIR); fi
 	@: >> $@ || : > $@ # what a fancy emoticon!
 
+smbd/server_multicall.o: smbd/server.c smbd/server.o
+	@echo "Compiling $< (multicall)"
+	@$(CC) -Dmain=smbd_main -I. -I$(srcdir) $(FLAGS) $(PICFLAG) -c $< -o $@
+
+nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/nmbd.o
+	@echo "Compiling $< (multicall)"
+	@$(CC) -Dmain=nmbd_main -I. -I$(srcdir) $(FLAGS) $(PICFLAG) -c $< -o $@
+
+utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o
+	@echo "Compiling $< (multicall)"
+	@$(CC) -Dmain=smbpasswd_main -I. -I$(srcdir) $(FLAGS) $(PICFLAG) -c $< -o $@
+
+SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
+NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
+SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
+MULTI_O = multi.o
+
+MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O))
+
+bin/samba_multicall@EXEEXT@: proto_exists $(MULTICALL_O) @BUILD_POPT@ bin/.dummy
+	@echo Linking $@
+	@$(CC) $(FLAGS) -o $@ $(MULTICALL_O) $(LDFLAGS) $(LDAP_LIBS) \
+		$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
+		$(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @SMBD_LIBS@
+
 bin/smbd@EXEEXT@: proto_exists $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
 	@echo Linking $@
 	@$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
--- /dev/null
+++ source/multi.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+
+extern int smbd_main(int argc, char **argv);
+extern int nmbd_main(int argc, char **argv);
+extern int smbpasswd_main(int argc, char **argv);
+
+static struct {
+	const char *name;
+	int (*func)(int argc, char **argv);
+} multicall[] = {
+	{ "smbd", smbd_main },
+	{ "nmbd", nmbd_main },
+	{ "smbpasswd", smbpasswd_main },
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+int main(int argc, char **argv)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(multicall); i++) {
+		if (strstr(argv[0], multicall[i].name))
+			return multicall[i].func(argc, argv);
+	}
+
+	fprintf(stderr, "Invalid multicall command, available commands:");
+	for (i = 0; i < ARRAY_SIZE(multicall); i++)
+		fprintf(stderr, " %s", multicall[i].name);
+
+	fprintf(stderr, "\n");
+
+	return 1;
+}
