2 Unix SMB/CIFS implementation.
3 Main winbindd server routines
5 Copyright (C) Stefan Metzmacher 2005
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "system/time.h"
26 #define WINBINDD_DIR "/tmp/.winbindd/"
27 #define WINBINDD_ECHO_SOCKET WINBINDD_DIR"echo"
28 #define WINBINDD_ADDR_PREFIX "127.0.255."
29 #define WINBINDD_ECHO_ADDR WINBINDD_ADDR_PREFIX"1"
30 #define WINBINDD_ECHO_PORT 55555
32 static void winbind_accept(struct server_connection *conn)
34 DEBUG(10,("winbind_accept:\n"));
37 static DATA_BLOB tmp_blob;
39 static void winbind_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
47 tmp_blob = data_blob_talloc(conn, NULL, 1024);
48 if (tmp_blob.data == NULL) {
52 tmp_blob.length = 1024;
53 status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread, 0);
54 if (NT_STATUS_IS_ERR(status)) {
55 DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
56 talloc_free(tmp_blob.data);
57 server_terminate_connection(conn, "socket_recv: failed\n");
60 tmp_blob.length = nread;
62 DEBUG(0,("winbind_recv:\n"));
63 dump_data(0, tmp_blob.data, tmp_blob.length);
65 conn->event.fde->flags |= EVENT_FD_WRITE;
68 static void winbind_send(struct server_connection *conn, struct timeval t, uint16_t flags)
73 if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
77 status = socket_send(conn->socket, &tmp_blob, &sendlen, 0);
78 if (!NT_STATUS_IS_OK(status)) {
79 DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
80 server_terminate_connection(conn, "socket_send: failed\n");
84 if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
85 server_terminate_connection(conn, "winbind_send: user quit\n");
89 DEBUG(0,("winbind_send:\n"));
90 dump_data(0, tmp_blob.data, tmp_blob.length);
92 tmp_blob.length -= sendlen;
94 if (tmp_blob.length == 0) {
95 conn->event.fde->flags &= ~EVENT_FD_WRITE;
99 static void winbind_idle(struct server_connection *conn, struct timeval t)
101 DEBUG(1,("winbind_idle: not implemented!\n"));
105 static void winbind_close(struct server_connection *conn, const char *reason)
107 DEBUG(10,("winbind_close: %s\n", reason));
112 static int winbind_task_server_contect_destructor(void *ptr)
114 struct server_context *server = ptr;
116 server_service_shutdown(server, "exit");
121 static void winbind_server_task_init(struct server_task *task)
123 const char *wb_task_service[] = { "winbind_task", NULL };
124 struct server_context *server;
126 DEBUG(1,("winbindsrv_task_init\n"));
127 server = server_service_startup("single", wb_task_service);
129 DEBUG(0,("Starting Services (winbind_task) failed.\n"));
133 task->task.private_data = talloc_steal(task, server);
135 task->event.ctx = event_context_merge(task->event.ctx, server->event.ctx);
136 server->event.ctx = talloc_reference(server, task->event.ctx);
138 talloc_set_destructor(server, winbind_task_server_contect_destructor);
140 /* wait for events */
141 event_loop_wait(task->event.ctx);
144 static const struct server_task_ops winbind_srver_task_ops = {
145 .name = "winbind_server_task",
146 .task_init = winbind_server_task_init
149 static const struct server_task_ops *winbind_srver_task_get_ops(void)
151 return &winbind_srver_task_ops;
154 static const struct server_stream_ops winbind_stream_ops = {
157 .accept_connection = winbind_accept,
158 .recv_handler = winbind_recv,
159 .send_handler = winbind_send,
160 .idle_handler = winbind_idle,
161 .close_connection = winbind_close
164 static const struct server_stream_ops *winbind_get_stream_ops(void)
166 return &winbind_stream_ops;
169 static void winbind_task_init(struct server_service *service)
171 struct server_stream_socket *stream_socket;
174 DEBUG(1,("winbind_task_init\n"));
176 /* Make sure the directory for NCALRPC exists */
177 if (!directory_exist(WINBINDD_DIR, NULL)) {
178 mkdir(WINBINDD_DIR, 0755);
181 stream_socket = service_setup_stream_socket(service, winbind_get_stream_ops(), "unix", WINBINDD_ECHO_SOCKET, &port);
182 if (!stream_socket) {
183 DEBUG(0,("service_setup_stream_socket(path=%s) failed\n",WINBINDD_ECHO_SOCKET));
187 port = WINBINDD_ECHO_PORT;
188 stream_socket = service_setup_stream_socket(service, winbind_get_stream_ops(), "ipv4", WINBINDD_ECHO_ADDR, &port);
189 if (!stream_socket) {
190 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed\n",WINBINDD_ECHO_ADDR, port));
197 static const struct server_service_ops winbind_task_ops = {
198 .name = "winbind_task",
199 .service_init = winbind_task_init,
202 const struct server_service_ops *winbind_task_get_ops(void)
204 return &winbind_task_ops;
207 static void winbind_init(struct server_service *service)
209 DEBUG(1,("winbind_init\n"));
211 server_run_task(service, winbind_srver_task_get_ops());
216 static const struct server_service_ops winbind_ops = {
218 .service_init = winbind_init,
221 const struct server_service_ops *winbind_get_ops(void)
226 NTSTATUS server_service_winbind_init(void)