r4729: add dummy "winbind" service
[abartlet/samba.git/.git] / source4 / winbind / wb_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Main winbindd server routines
4
5    Copyright (C) Stefan Metzmacher      2005
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23 #include "events.h"
24 #include "system/time.h"
25
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
31
32 static void winbind_accept(struct server_connection *conn)
33 {
34         DEBUG(10,("winbind_accept:\n"));
35 }
36
37 static DATA_BLOB tmp_blob;
38
39 static void winbind_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
40 {
41
42
43         NTSTATUS status;
44         size_t nread;
45
46 if (!tmp_blob.data) {
47         tmp_blob = data_blob_talloc(conn, NULL, 1024);
48         if (tmp_blob.data == NULL) {
49                 return;
50         }
51 }
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");
58                 return;
59         }
60         tmp_blob.length = nread;
61 #if 0
62 DEBUG(0,("winbind_recv:\n"));
63 dump_data(0, tmp_blob.data, tmp_blob.length);
64 #endif
65         conn->event.fde->flags |= EVENT_FD_WRITE;
66 }
67
68 static void winbind_send(struct server_connection *conn, struct timeval t, uint16_t flags)
69 {
70         NTSTATUS status;
71         size_t sendlen;
72
73         if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
74
75         }
76
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");
81                 return;
82         }
83
84         if (tmp_blob.length > 1 && tmp_blob.data[0] == (uint8_t)'q') {
85                 server_terminate_connection(conn, "winbind_send: user quit\n");
86                 return;
87         }
88 #if 0
89 DEBUG(0,("winbind_send:\n"));
90 dump_data(0, tmp_blob.data, tmp_blob.length);
91 #endif
92         tmp_blob.length -= sendlen;
93
94         if (tmp_blob.length == 0) {
95                 conn->event.fde->flags &= ~EVENT_FD_WRITE;
96         }
97 }
98
99 static void winbind_idle(struct server_connection *conn, struct timeval t)
100 {
101         DEBUG(1,("winbind_idle: not implemented!\n"));
102         return;
103 }
104
105 static void winbind_close(struct server_connection *conn, const char *reason)
106 {
107         DEBUG(10,("winbind_close: %s\n", reason));
108 }
109
110
111
112 static int winbind_task_server_contect_destructor(void *ptr)
113 {
114         struct server_context *server = ptr;
115
116         server_service_shutdown(server, "exit");
117
118         return 0;       
119 }
120
121 static void winbind_server_task_init(struct server_task *task)
122 {
123         const char *wb_task_service[] = { "winbind_task", NULL };
124         struct server_context *server;
125
126         DEBUG(1,("winbindsrv_task_init\n"));
127         server = server_service_startup("single", wb_task_service);
128         if (!server) {
129                 DEBUG(0,("Starting Services (winbind_task) failed.\n"));
130                 return;
131         }
132
133         task->task.private_data = talloc_steal(task, server);
134
135         task->event.ctx = event_context_merge(task->event.ctx, server->event.ctx);
136         server->event.ctx = talloc_reference(server, task->event.ctx);
137
138         talloc_set_destructor(server, winbind_task_server_contect_destructor);
139
140         /* wait for events */
141         event_loop_wait(task->event.ctx);
142 }
143
144 static const struct server_task_ops winbind_srver_task_ops = {
145         .name           = "winbind_server_task",
146         .task_init      = winbind_server_task_init
147 };
148
149 static const struct server_task_ops *winbind_srver_task_get_ops(void)
150 {
151         return &winbind_srver_task_ops;
152 }
153
154 static const struct server_stream_ops winbind_stream_ops = {
155         .name                   = "winbind",
156         .socket_init            = NULL,
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
162 };
163
164 static const struct server_stream_ops *winbind_get_stream_ops(void)
165 {
166         return &winbind_stream_ops;
167 }
168
169 static void winbind_task_init(struct server_service *service)
170 {
171         struct server_stream_socket *stream_socket;
172         uint16_t port = 1;
173
174         DEBUG(1,("winbind_task_init\n"));
175
176         /* Make sure the directory for NCALRPC exists */
177         if (!directory_exist(WINBINDD_DIR, NULL)) {
178                 mkdir(WINBINDD_DIR, 0755);
179         }
180
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));
184                 return;
185         }
186
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));
191                 return;
192         }
193
194         return;
195 }
196
197 static const struct server_service_ops winbind_task_ops = {
198         .name                   = "winbind_task",
199         .service_init           = winbind_task_init,
200 };
201
202 const struct server_service_ops *winbind_task_get_ops(void)
203 {
204         return &winbind_task_ops;
205 }
206
207 static void winbind_init(struct server_service *service)
208 {
209         DEBUG(1,("winbind_init\n"));
210
211         server_run_task(service, winbind_srver_task_get_ops());
212
213         return;
214 }
215
216 static const struct server_service_ops winbind_ops = {
217         .name                   = "winbind",
218         .service_init           = winbind_init,
219 };
220
221 const struct server_service_ops *winbind_get_ops(void)
222 {
223         return &winbind_ops;
224 }
225
226 NTSTATUS server_service_winbind_init(void)
227 {
228         return NT_STATUS_OK;    
229 }