~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/winbind/wb_server.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
   Main winbindd server routines
 
4
 
 
5
   Copyright (C) Stefan Metzmacher      2005
 
6
   Copyright (C) Andrew Tridgell        2005
 
7
   
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
   
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
   
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "lib/socket/socket.h"
 
24
#include "../lib/util/dlinklist.h"
 
25
#include "lib/events/events.h"
 
26
#include "smbd/service_task.h"
 
27
#include "smbd/process_model.h"
 
28
#include "smbd/service_stream.h"
 
29
#include "nsswitch/winbind_nss_config.h"
 
30
#include "winbind/wb_server.h"
 
31
#include "lib/stream/packet.h"
 
32
#include "smbd/service.h"
 
33
#include "param/secrets.h"
 
34
#include "param/param.h"
 
35
 
 
36
void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *reason)
 
37
{
 
38
        stream_terminate_connection(wbconn->conn, reason);
 
39
}
 
40
 
 
41
/*
 
42
  called on a tcp recv error
 
43
*/
 
44
static void wbsrv_recv_error(void *private_data, NTSTATUS status)
 
45
{
 
46
        struct wbsrv_connection *wbconn = talloc_get_type(private_data, struct wbsrv_connection);
 
47
        wbsrv_terminate_connection(wbconn, nt_errstr(status));
 
48
}
 
49
 
 
50
static void wbsrv_accept(struct stream_connection *conn)
 
51
{
 
52
        struct wbsrv_listen_socket *listen_socket = talloc_get_type(conn->private_data,
 
53
                                                                    struct wbsrv_listen_socket);
 
54
        struct wbsrv_connection *wbconn;
 
55
 
 
56
        wbconn = talloc_zero(conn, struct wbsrv_connection);
 
57
        if (!wbconn) {
 
58
                stream_terminate_connection(conn, "wbsrv_accept: out of memory");
 
59
                return;
 
60
        }
 
61
        wbconn->conn          = conn;
 
62
        wbconn->listen_socket = listen_socket;
 
63
        wbconn->lp_ctx        = listen_socket->service->task->lp_ctx;
 
64
        conn->private_data    = wbconn;
 
65
 
 
66
        wbconn->packet = packet_init(wbconn);
 
67
        if (wbconn->packet == NULL) {
 
68
                wbsrv_terminate_connection(wbconn, "wbsrv_accept: out of memory");
 
69
                return;
 
70
        }
 
71
        packet_set_private(wbconn->packet, wbconn);
 
72
        packet_set_socket(wbconn->packet, conn->socket);
 
73
        packet_set_callback(wbconn->packet, wbsrv_samba3_process);
 
74
        packet_set_full_request(wbconn->packet, wbsrv_samba3_packet_full_request);
 
75
        packet_set_error_handler(wbconn->packet, wbsrv_recv_error);
 
76
        packet_set_event_context(wbconn->packet, conn->event.ctx);
 
77
        packet_set_fde(wbconn->packet, conn->event.fde);
 
78
        packet_set_serialise(wbconn->packet);
 
79
}
 
80
 
 
81
/*
 
82
  receive some data on a winbind connection
 
83
*/
 
84
static void wbsrv_recv(struct stream_connection *conn, uint16_t flags)
 
85
{
 
86
        struct wbsrv_connection *wbconn = talloc_get_type(conn->private_data,
 
87
                                                          struct wbsrv_connection);
 
88
        packet_recv(wbconn->packet);
 
89
 
 
90
}
 
91
 
 
92
/*
 
93
  called when we can write to a connection
 
94
*/
 
95
static void wbsrv_send(struct stream_connection *conn, uint16_t flags)
 
96
{
 
97
        struct wbsrv_connection *wbconn = talloc_get_type(conn->private_data,
 
98
                                                          struct wbsrv_connection);
 
99
        packet_queue_run(wbconn->packet);
 
100
}
 
101
 
 
102
static const struct stream_server_ops wbsrv_ops = {
 
103
        .name                   = "winbind samba3 protocol",
 
104
        .accept_connection      = wbsrv_accept,
 
105
        .recv_handler           = wbsrv_recv,
 
106
        .send_handler           = wbsrv_send
 
107
};
 
108
 
 
109
/*
 
110
  startup the winbind task
 
111
*/
 
112
static void winbind_task_init(struct task_server *task)
 
113
{
 
114
        uint16_t port = 1;
 
115
        const struct model_ops *model_ops;
 
116
        NTSTATUS status;
 
117
        struct wbsrv_service *service;
 
118
        struct wbsrv_listen_socket *listen_socket;
 
119
 
 
120
        task_server_set_title(task, "task[winbind]");
 
121
 
 
122
        /* within the winbind task we want to be a single process, so
 
123
           ask for the single process model ops and pass these to the
 
124
           stream_setup_socket() call. */
 
125
        model_ops = process_model_startup(task->event_ctx, "single");
 
126
        if (!model_ops) {
 
127
                task_server_terminate(task,
 
128
                                      "Can't find 'single' process model_ops");
 
129
                return;
 
130
        }
 
131
 
 
132
        /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
 
133
        if (!directory_create_or_exist(lp_winbindd_socket_directory(task->lp_ctx), geteuid(), 0755)) {
 
134
                task_server_terminate(task,
 
135
                                      "Cannot create winbindd pipe directory");
 
136
                return;
 
137
        }
 
138
 
 
139
        /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
 
140
        if (!directory_create_or_exist(lp_winbindd_privileged_socket_directory(task->lp_ctx), geteuid(), 0750)) {
 
141
                task_server_terminate(task,
 
142
                                      "Cannot create winbindd privileged pipe directory");
 
143
                return;
 
144
        }
 
145
 
 
146
        service = talloc_zero(task, struct wbsrv_service);
 
147
        if (!service) goto nomem;
 
148
        service->task   = task;
 
149
 
 
150
        status = wbsrv_setup_domains(service);
 
151
        if (!NT_STATUS_IS_OK(status)) {
 
152
                task_server_terminate(task, nt_errstr(status));
 
153
                return;
 
154
        }
 
155
 
 
156
        service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx);
 
157
        if (service->idmap_ctx == NULL) {
 
158
                task_server_terminate(task, "Failed to load idmap database");
 
159
                return;
 
160
        }
 
161
 
 
162
        /* setup the unprivileged samba3 socket */
 
163
        listen_socket = talloc(service, struct wbsrv_listen_socket);
 
164
        if (!listen_socket) goto nomem;
 
165
        listen_socket->socket_path      = talloc_asprintf(listen_socket, "%s/%s", 
 
166
                                                          lp_winbindd_socket_directory(task->lp_ctx), 
 
167
                                                          WINBINDD_SAMBA3_SOCKET);
 
168
        if (!listen_socket->socket_path) goto nomem;
 
169
        listen_socket->service          = service;
 
170
        listen_socket->privileged       = false;
 
171
        status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops,
 
172
                                     &wbsrv_ops, "unix",
 
173
                                     listen_socket->socket_path, &port,
 
174
                                     lp_socket_options(task->lp_ctx), 
 
175
                                     listen_socket);
 
176
        if (!NT_STATUS_IS_OK(status)) goto listen_failed;
 
177
 
 
178
        /* setup the privileged samba3 socket */
 
179
        listen_socket = talloc(service, struct wbsrv_listen_socket);
 
180
        if (!listen_socket) goto nomem;
 
181
        listen_socket->socket_path 
 
182
                = service->priv_socket_path 
 
183
                = talloc_asprintf(listen_socket, "%s/%s", 
 
184
                                                          lp_winbindd_privileged_socket_directory(task->lp_ctx), 
 
185
                                                          WINBINDD_SAMBA3_SOCKET);
 
186
        if (!listen_socket->socket_path) goto nomem;
 
187
        if (!listen_socket->socket_path) goto nomem;
 
188
        listen_socket->service          = service;
 
189
        listen_socket->privileged       = true;
 
190
        status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops,
 
191
                                     &wbsrv_ops, "unix",
 
192
                                     listen_socket->socket_path, &port,
 
193
                                     lp_socket_options(task->lp_ctx), 
 
194
                                     listen_socket);
 
195
        if (!NT_STATUS_IS_OK(status)) goto listen_failed;
 
196
 
 
197
        status = wbsrv_init_irpc(service);
 
198
        if (!NT_STATUS_IS_OK(status)) goto irpc_failed;
 
199
 
 
200
        return;
 
201
 
 
202
listen_failed:
 
203
        DEBUG(0,("stream_setup_socket(path=%s) failed - %s\n",
 
204
                 listen_socket->socket_path, nt_errstr(status)));
 
205
        task_server_terminate(task, nt_errstr(status));
 
206
        return;
 
207
irpc_failed:
 
208
        DEBUG(0,("wbsrv_init_irpc() failed - %s\n",
 
209
                 nt_errstr(status)));
 
210
        task_server_terminate(task, nt_errstr(status));
 
211
        return;
 
212
nomem:
 
213
        task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY));
 
214
        return;
 
215
}
 
216
 
 
217
/*
 
218
  register ourselves as a available server
 
219
*/
 
220
NTSTATUS server_service_winbind_init(void)
 
221
{
 
222
        return register_server_service("winbind", winbind_task_init);
 
223
}