root/source4/winbind/wb_server.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wbsrv_terminate_connection
  2. wbsrv_recv_error
  3. wbsrv_accept
  4. wbsrv_recv
  5. wbsrv_send
  6. winbind_task_init
  7. server_service_winbind_init

   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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 221 {
 222         return register_server_service("winbind", winbind_task_init);
 223 }

/* [<][>][^][v][top][bottom][index][help] */