Changeset 745 for trunk/server/source4/winbind/wb_server.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/winbind/wb_server.c
r414 r745 3 3 Main winbindd server routines 4 4 5 Copyright (C) Stefan Metzmacher 2005 5 Copyright (C) Stefan Metzmacher 2005-2008 6 6 Copyright (C) Andrew Tridgell 2005 7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2010 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 21 22 22 23 #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 24 #include "smbd/process_model.h" 28 #include "smbd/service_stream.h"29 #include "nsswitch/winbind_nss_config.h"30 25 #include "winbind/wb_server.h" 31 26 #include "lib/stream/packet.h" 32 #include "smbd/service.h" 27 #include "lib/tsocket/tsocket.h" 28 #include "libcli/util/tstream.h" 29 #include "param/param.h" 33 30 #include "param/secrets.h" 34 #include "param/param.h"35 31 36 32 void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *reason) … … 39 35 } 40 36 37 static void wbsrv_call_loop(struct tevent_req *subreq) 38 { 39 struct wbsrv_connection *wbsrv_conn = tevent_req_callback_data(subreq, 40 struct wbsrv_connection); 41 struct wbsrv_samba3_call *call; 42 NTSTATUS status; 43 44 call = talloc_zero(wbsrv_conn, struct wbsrv_samba3_call); 45 if (call == NULL) { 46 wbsrv_terminate_connection(wbsrv_conn, "wbsrv_call_loop: " 47 "no memory for wbsrv_samba3_call"); 48 return; 49 } 50 call->wbconn = wbsrv_conn; 51 52 status = tstream_read_pdu_blob_recv(subreq, 53 call, 54 &call->in); 55 TALLOC_FREE(subreq); 56 if (!NT_STATUS_IS_OK(status)) { 57 const char *reason; 58 59 reason = talloc_asprintf(call, "wbsrv_call_loop: " 60 "tstream_read_pdu_blob_recv() - %s", 61 nt_errstr(status)); 62 if (!reason) { 63 reason = nt_errstr(status); 64 } 65 66 wbsrv_terminate_connection(wbsrv_conn, reason); 67 return; 68 } 69 70 DEBUG(10,("Received winbind TCP packet of length %lu from %s\n", 71 (long) call->in.length, 72 tsocket_address_string(wbsrv_conn->conn->remote_address, call))); 73 74 status = wbsrv_samba3_process(call); 75 if (!NT_STATUS_IS_OK(status)) { 76 const char *reason; 77 78 reason = talloc_asprintf(call, "wbsrv_call_loop: " 79 "tstream_read_pdu_blob_recv() - %s", 80 nt_errstr(status)); 81 if (!reason) { 82 reason = nt_errstr(status); 83 } 84 85 wbsrv_terminate_connection(wbsrv_conn, reason); 86 return; 87 } 88 89 /* 90 * The winbind pdu's has the length as 4 byte (initial_read_size), 91 * wbsrv_samba3_packet_full_request provides the pdu length then. 92 */ 93 subreq = tstream_read_pdu_blob_send(wbsrv_conn, 94 wbsrv_conn->conn->event.ctx, 95 wbsrv_conn->tstream, 96 4, /* initial_read_size */ 97 wbsrv_samba3_packet_full_request, 98 wbsrv_conn); 99 if (subreq == NULL) { 100 wbsrv_terminate_connection(wbsrv_conn, "wbsrv_call_loop: " 101 "no memory for tstream_read_pdu_blob_send"); 102 return; 103 } 104 tevent_req_set_callback(subreq, wbsrv_call_loop, wbsrv_conn); 105 } 106 107 static void wbsrv_accept(struct stream_connection *conn) 108 { 109 struct wbsrv_listen_socket *wbsrv_socket = talloc_get_type(conn->private_data, 110 struct wbsrv_listen_socket); 111 struct wbsrv_connection *wbsrv_conn; 112 struct tevent_req *subreq; 113 int rc; 114 115 wbsrv_conn = talloc_zero(conn, struct wbsrv_connection); 116 if (wbsrv_conn == NULL) { 117 stream_terminate_connection(conn, "wbsrv_accept: out of memory"); 118 return; 119 } 120 121 wbsrv_conn->send_queue = tevent_queue_create(conn, "wbsrv_accept"); 122 if (wbsrv_conn->send_queue == NULL) { 123 stream_terminate_connection(conn, 124 "wbsrv_accept: out of memory"); 125 return; 126 } 127 128 TALLOC_FREE(conn->event.fde); 129 130 rc = tstream_bsd_existing_socket(wbsrv_conn, 131 socket_get_fd(conn->socket), 132 &wbsrv_conn->tstream); 133 if (rc < 0) { 134 stream_terminate_connection(conn, 135 "wbsrv_accept: out of memory"); 136 return; 137 } 138 139 wbsrv_conn->conn = conn; 140 wbsrv_conn->listen_socket = wbsrv_socket; 141 wbsrv_conn->lp_ctx = wbsrv_socket->service->task->lp_ctx; 142 conn->private_data = wbsrv_conn; 143 144 /* 145 * The winbind pdu's has the length as 4 byte (initial_read_size), 146 * wbsrv_samba3_packet_full_request provides the pdu length then. 147 */ 148 subreq = tstream_read_pdu_blob_send(wbsrv_conn, 149 wbsrv_conn->conn->event.ctx, 150 wbsrv_conn->tstream, 151 4, /* initial_read_size */ 152 wbsrv_samba3_packet_full_request, 153 wbsrv_conn); 154 if (subreq == NULL) { 155 wbsrv_terminate_connection(wbsrv_conn, "wbsrv_accept: " 156 "no memory for tstream_read_pdu_blob_send"); 157 return; 158 } 159 tevent_req_set_callback(subreq, wbsrv_call_loop, wbsrv_conn); 160 } 161 41 162 /* 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 163 called on a tcp recv 83 164 */ 84 165 static void wbsrv_recv(struct stream_connection *conn, uint16_t flags) 85 166 { 86 struct wbsrv_connection *wbconn = talloc_get_type(conn->private_data, 87 struct wbsrv_connection); 88 packet_recv(wbconn->packet); 89 167 struct wbsrv_connection *wbsrv_conn = talloc_get_type(conn->private_data, 168 struct wbsrv_connection); 169 wbsrv_terminate_connection(wbsrv_conn, "wbsrv_recv: called"); 90 170 } 91 171 … … 95 175 static void wbsrv_send(struct stream_connection *conn, uint16_t flags) 96 176 { 97 struct wbsrv_connection *wbconn = talloc_get_type(conn->private_data, 98 struct wbsrv_connection); 99 packet_queue_run(wbconn->packet); 177 struct wbsrv_connection *wbsrv_conn = talloc_get_type(conn->private_data, 178 struct wbsrv_connection); 179 /* this should never be triggered! */ 180 wbsrv_terminate_connection(wbsrv_conn, "wbsrv_send: called"); 100 181 } 101 182 … … 117 198 struct wbsrv_service *service; 118 199 struct wbsrv_listen_socket *listen_socket; 200 char *errstring; 201 struct dom_sid *primary_sid; 119 202 120 203 task_server_set_title(task, "task[winbind]"); … … 123 206 ask for the single process model ops and pass these to the 124 207 stream_setup_socket() call. */ 125 model_ops = process_model_startup( task->event_ctx,"single");208 model_ops = process_model_startup("single"); 126 209 if (!model_ops) { 127 210 task_server_terminate(task, … … 131 214 132 215 /* 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)) {216 if (!directory_create_or_exist(lpcfg_winbindd_socket_directory(task->lp_ctx), geteuid(), 0755)) { 134 217 task_server_terminate(task, 135 218 "Cannot create winbindd pipe directory", true); … … 138 221 139 222 /* 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)) {223 if (!directory_create_or_exist(lpcfg_winbindd_privileged_socket_directory(task->lp_ctx), geteuid(), 0750)) { 141 224 task_server_terminate(task, 142 225 "Cannot create winbindd privileged pipe directory", true); … … 148 231 service->task = task; 149 232 150 status = wbsrv_setup_domains(service); 151 if (!NT_STATUS_IS_OK(status)) { 152 task_server_terminate(task, nt_errstr(status), true); 153 return; 154 } 233 234 /* Find the primary SID, depending if we are a standalone 235 * server (what good is winbind in this case, but anyway...), 236 * or are in a domain as a member or a DC */ 237 switch (lpcfg_server_role(service->task->lp_ctx)) { 238 case ROLE_STANDALONE: 239 primary_sid = secrets_get_domain_sid(service, 240 service->task->lp_ctx, 241 lpcfg_netbios_name(service->task->lp_ctx), 242 &service->sec_channel_type, 243 &errstring); 244 if (!primary_sid) { 245 char *message = talloc_asprintf(task, 246 "Cannot start Winbind (standalone configuration): %s: " 247 "Have you provisioned this server (%s) or changed it's name?", 248 errstring, lpcfg_netbios_name(service->task->lp_ctx)); 249 task_server_terminate(task, message, true); 250 return; 251 } 252 break; 253 case ROLE_DOMAIN_MEMBER: 254 primary_sid = secrets_get_domain_sid(service, 255 service->task->lp_ctx, 256 lpcfg_workgroup(service->task->lp_ctx), 257 &service->sec_channel_type, 258 &errstring); 259 if (!primary_sid) { 260 char *message = talloc_asprintf(task, "Cannot start Winbind (domain member): %s: " 261 "Have you joined the %s domain?", 262 errstring, lpcfg_workgroup(service->task->lp_ctx)); 263 task_server_terminate(task, message, true); 264 return; 265 } 266 break; 267 case ROLE_DOMAIN_CONTROLLER: 268 primary_sid = secrets_get_domain_sid(service, 269 service->task->lp_ctx, 270 lpcfg_workgroup(service->task->lp_ctx), 271 &service->sec_channel_type, 272 &errstring); 273 if (!primary_sid) { 274 char *message = talloc_asprintf(task, "Cannot start Winbind (domain controller): %s: " 275 "Have you provisioned the %s domain?", 276 errstring, lpcfg_workgroup(service->task->lp_ctx)); 277 task_server_terminate(task, message, true); 278 return; 279 } 280 break; 281 } 282 service->primary_sid = primary_sid; 155 283 156 284 service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx); … … 159 287 return; 160 288 } 289 290 service->priv_pipe_dir = lpcfg_winbindd_privileged_socket_directory(task->lp_ctx); 291 service->pipe_dir = lpcfg_winbindd_socket_directory(task->lp_ctx); 161 292 162 293 /* setup the unprivileged samba3 socket */ … … 164 295 if (!listen_socket) goto nomem; 165 296 listen_socket->socket_path = talloc_asprintf(listen_socket, "%s/%s", 166 lp_winbindd_socket_directory(task->lp_ctx),167 WINBINDD_S AMBA3_SOCKET);297 service->pipe_dir, 298 WINBINDD_SOCKET_NAME); 168 299 if (!listen_socket->socket_path) goto nomem; 169 300 listen_socket->service = service; 170 301 listen_socket->privileged = false; 171 status = stream_setup_socket(task ->event_ctx, task->lp_ctx, model_ops,302 status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, 172 303 &wbsrv_ops, "unix", 173 304 listen_socket->socket_path, &port, 174 lp _socket_options(task->lp_ctx),305 lpcfg_socket_options(task->lp_ctx), 175 306 listen_socket); 176 307 if (!NT_STATUS_IS_OK(status)) goto listen_failed; … … 180 311 if (!listen_socket) goto nomem; 181 312 listen_socket->socket_path 182 = service->priv_socket_path183 313 = 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; 314 service->priv_pipe_dir, 315 WINBINDD_SOCKET_NAME); 187 316 if (!listen_socket->socket_path) goto nomem; 188 317 listen_socket->service = service; 189 318 listen_socket->privileged = true; 190 status = stream_setup_socket(task ->event_ctx, task->lp_ctx, model_ops,319 status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, 191 320 &wbsrv_ops, "unix", 192 321 listen_socket->socket_path, &port, 193 lp _socket_options(task->lp_ctx),322 lpcfg_socket_options(task->lp_ctx), 194 323 listen_socket); 195 324 if (!NT_STATUS_IS_OK(status)) goto listen_failed;
Note:
See TracChangeset
for help on using the changeset viewer.