r4729: add dummy "winbind" service
authorStefan Metzmacher <metze@samba.org>
Fri, 14 Jan 2005 02:01:19 +0000 (02:01 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:49 +0000 (13:08 -0500)
- this creates a new task and then starts a process_model "single"
  with service "winbind_task"

- that means with -M single everything is in one process

  with - M standard winbind is a seperate process but didn't fork for each connection
  with -M thread winbind is a seperate thread but didn't thread for each connection

- the dummy server listen s on /tmp/.winbind/echo
  and for better testing with telnet also on 127.0.255.1 port 55555

metze

source/build/smb_build/main.pm
source/smbd/service.c
source/winbind/config.mk [new file with mode: 0644]
source/winbind/wb_server.c [new file with mode: 0644]

index 3911820edb5c48a7cd43caf45976e78823d7402c..2dc5c461918e4281a10d6de4534a60e95a4c416a 100644 (file)
@@ -54,7 +54,8 @@ sub smb_build_main($)
                "client/config.mk",
                "libcli/libsmb.mk",
                "libcli/config.mk",
-               "libcli/security/config.mk"
+               "libcli/security/config.mk",
+               "winbind/config.mk"
        );
 
        $| = 1;
index e0ec3cf07e2483bc3bd08a7685e0dc6d14c29b24..12aa43132c365b2c964d2f3b7e956b76a207158b 100644 (file)
@@ -349,6 +349,12 @@ const struct server_service_ops *server_service_byname(const char *name)
        if (strcmp("ldap",name)==0) {
                return ldapsrv_get_ops();
        }
+       if (strcmp("winbind",name)==0) {
+               return winbind_get_ops();
+       }
+       if (strcmp("winbind_task",name)==0) {
+               return winbind_task_get_ops();
+       }
        return NULL;
 }
 
diff --git a/source/winbind/config.mk b/source/winbind/config.mk
new file mode 100644 (file)
index 0000000..948b628
--- /dev/null
@@ -0,0 +1,12 @@
+# server subsystem
+
+################################################
+# Start MODULE server_service_auth
+[MODULE::server_service_winbind]
+INIT_FUNCTION = server_service_winbind_init
+SUBSYSTEM = SERVER_SERVICE
+INIT_OBJ_FILES = \
+               winbind/wb_server.o
+REQUIRED_SUBSYSTEMS = 
+# End MODULE server_service_winbind
+################################################
diff --git a/source/winbind/wb_server.c b/source/winbind/wb_server.c
new file mode 100644 (file)
index 0000000..b75cc89
--- /dev/null
@@ -0,0 +1,229 @@
+/* 
+   Unix SMB/CIFS implementation.
+   Main winbindd server routines
+
+   Copyright (C) Stefan Metzmacher     2005
+   
+   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 "events.h"
+#include "system/time.h"
+
+#define WINBINDD_DIR "/tmp/.winbindd/"
+#define WINBINDD_ECHO_SOCKET  WINBINDD_DIR"echo"
+#define WINBINDD_ADDR_PREFIX "127.0.255."
+#define WINBINDD_ECHO_ADDR WINBINDD_ADDR_PREFIX"1"
+#define WINBINDD_ECHO_PORT 55555
+
+static void winbind_accept(struct server_connection *conn)
+{
+       DEBUG(10,("winbind_accept:\n"));
+}
+
+static DATA_BLOB tmp_blob;
+
+static void winbind_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
+{
+
+
+       NTSTATUS status;
+       size_t nread;
+
+if (!tmp_blob.data) {
+       tmp_blob = data_blob_talloc(conn, NULL, 1024);
+       if (tmp_blob.data == NULL) {
+               return;
+       }
+}
+       tmp_blob.length = 1024;
+       status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread, 0);
+       if (NT_STATUS_IS_ERR(status)) {
+               DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
+               talloc_free(tmp_blob.data);
+               server_terminate_connection(conn, "socket_recv: failed\n");
+               return;
+       }
+       tmp_blob.length = nread;
+#if 0
+DEBUG(0,("winbind_recv:\n"));
+dump_data(0, tmp_blob.data, tmp_blob.length);
+#endif
+       conn->event.fde->flags |= EVENT_FD_WRITE;
+}
+
+static void winbind_send(struct server_connection *conn, struct timeval t, uint16_t flags)
+{
+       NTSTATUS status;
+       size_t sendlen;
+
+       if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
+
+       }
+
+       status = socket_send(conn->socket, &tmp_blob, &sendlen, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
+               server_terminate_connection(conn, "socket_send: failed\n");
+               return;
+       }
+
+       if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
+               server_terminate_connection(conn, "winbind_send: user quit\n");
+               return;
+       }
+#if 0
+DEBUG(0,("winbind_send:\n"));
+dump_data(0, tmp_blob.data, tmp_blob.length);
+#endif
+       tmp_blob.length -= sendlen;
+
+       if (tmp_blob.length == 0) {
+               conn->event.fde->flags &= ~EVENT_FD_WRITE;
+       }
+}
+
+static void winbind_idle(struct server_connection *conn, struct timeval t)
+{
+       DEBUG(1,("winbind_idle: not implemented!\n"));
+       return;
+}
+
+static void winbind_close(struct server_connection *conn, const char *reason)
+{
+       DEBUG(10,("winbind_close: %s\n", reason));
+}
+
+
+
+static int winbind_task_server_contect_destructor(void *ptr)
+{
+       struct server_context *server = ptr;
+
+       server_service_shutdown(server, "exit");
+
+       return 0;       
+}
+
+static void winbind_server_task_init(struct server_task *task)
+{
+       const char *wb_task_service[] = { "winbind_task", NULL };
+       struct server_context *server;
+
+       DEBUG(1,("winbindsrv_task_init\n"));
+       server = server_service_startup("single", wb_task_service);
+       if (!server) {
+               DEBUG(0,("Starting Services (winbind_task) failed.\n"));
+               return;
+       }
+
+       task->task.private_data = talloc_steal(task, server);
+
+       task->event.ctx = event_context_merge(task->event.ctx, server->event.ctx);
+       server->event.ctx = talloc_reference(server, task->event.ctx);
+
+       talloc_set_destructor(server, winbind_task_server_contect_destructor);
+
+       /* wait for events */
+       event_loop_wait(task->event.ctx);
+}
+
+static const struct server_task_ops winbind_srver_task_ops = {
+       .name           = "winbind_server_task",
+       .task_init      = winbind_server_task_init
+};
+
+static const struct server_task_ops *winbind_srver_task_get_ops(void)
+{
+       return &winbind_srver_task_ops;
+}
+
+static const struct server_stream_ops winbind_stream_ops = {
+       .name                   = "winbind",
+       .socket_init            = NULL,
+       .accept_connection      = winbind_accept,
+       .recv_handler           = winbind_recv,
+       .send_handler           = winbind_send,
+       .idle_handler           = winbind_idle,
+       .close_connection       = winbind_close
+};
+
+static const struct server_stream_ops *winbind_get_stream_ops(void)
+{
+       return &winbind_stream_ops;
+}
+
+static void winbind_task_init(struct server_service *service)
+{
+       struct server_stream_socket *stream_socket;
+       uint16_t port = 1;
+
+       DEBUG(1,("winbind_task_init\n"));
+
+       /* Make sure the directory for NCALRPC exists */
+       if (!directory_exist(WINBINDD_DIR, NULL)) {
+               mkdir(WINBINDD_DIR, 0755);
+       }
+
+       stream_socket = service_setup_stream_socket(service, winbind_get_stream_ops(), "unix", WINBINDD_ECHO_SOCKET, &port);
+       if (!stream_socket) {
+               DEBUG(0,("service_setup_stream_socket(path=%s) failed\n",WINBINDD_ECHO_SOCKET));
+               return;
+       }
+
+       port = WINBINDD_ECHO_PORT;
+       stream_socket = service_setup_stream_socket(service, winbind_get_stream_ops(), "ipv4", WINBINDD_ECHO_ADDR, &port);
+       if (!stream_socket) {
+               DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed\n",WINBINDD_ECHO_ADDR, port));
+               return;
+       }
+
+       return;
+}
+
+static const struct server_service_ops winbind_task_ops = {
+       .name                   = "winbind_task",
+       .service_init           = winbind_task_init,
+};
+
+const struct server_service_ops *winbind_task_get_ops(void)
+{
+       return &winbind_task_ops;
+}
+
+static void winbind_init(struct server_service *service)
+{
+       DEBUG(1,("winbind_init\n"));
+
+       server_run_task(service, winbind_srver_task_get_ops());
+
+       return;
+}
+
+static const struct server_service_ops winbind_ops = {
+       .name                   = "winbind",
+       .service_init           = winbind_init,
+};
+
+const struct server_service_ops *winbind_get_ops(void)
+{
+       return &winbind_ops;
+}
+
+NTSTATUS server_service_winbind_init(void)
+{
+       return NT_STATUS_OK;    
+}