Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/winbind/wb_server.c

    r414 r745  
    33   Main winbindd server routines
    44
    5    Copyright (C) Stefan Metzmacher      2005
     5   Copyright (C) Stefan Metzmacher      2005-2008
    66   Copyright (C) Andrew Tridgell        2005
     7   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2010
    78   
    89   This program is free software; you can redistribute it and/or modify
     
    2122
    2223#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"
    2724#include "smbd/process_model.h"
    28 #include "smbd/service_stream.h"
    29 #include "nsswitch/winbind_nss_config.h"
    3025#include "winbind/wb_server.h"
    3126#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"
    3330#include "param/secrets.h"
    34 #include "param/param.h"
    3531
    3632void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *reason)
     
    3935}
    4036
     37static 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
     107static 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
    41162/*
    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
    83164*/
    84165static void wbsrv_recv(struct stream_connection *conn, uint16_t flags)
    85166{
    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");
    90170}
    91171
     
    95175static void wbsrv_send(struct stream_connection *conn, uint16_t flags)
    96176{
    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");
    100181}
    101182
     
    117198        struct wbsrv_service *service;
    118199        struct wbsrv_listen_socket *listen_socket;
     200        char *errstring;
     201        struct dom_sid *primary_sid;
    119202
    120203        task_server_set_title(task, "task[winbind]");
     
    123206           ask for the single process model ops and pass these to the
    124207           stream_setup_socket() call. */
    125         model_ops = process_model_startup(task->event_ctx, "single");
     208        model_ops = process_model_startup("single");
    126209        if (!model_ops) {
    127210                task_server_terminate(task,
     
    131214
    132215        /* 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)) {
    134217                task_server_terminate(task,
    135218                                      "Cannot create winbindd pipe directory", true);
     
    138221
    139222        /* 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)) {
    141224                task_server_terminate(task,
    142225                                      "Cannot create winbindd privileged pipe directory", true);
     
    148231        service->task   = task;
    149232
    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;
    155283
    156284        service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx);
     
    159287                return;
    160288        }
     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);
    161292
    162293        /* setup the unprivileged samba3 socket */
     
    164295        if (!listen_socket) goto nomem;
    165296        listen_socket->socket_path      = talloc_asprintf(listen_socket, "%s/%s",
    166                                                           lp_winbindd_socket_directory(task->lp_ctx),
    167                                                           WINBINDD_SAMBA3_SOCKET);
     297                                                          service->pipe_dir,
     298                                                          WINBINDD_SOCKET_NAME);
    168299        if (!listen_socket->socket_path) goto nomem;
    169300        listen_socket->service          = service;
    170301        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,
    172303                                     &wbsrv_ops, "unix",
    173304                                     listen_socket->socket_path, &port,
    174                                      lp_socket_options(task->lp_ctx),
     305                                     lpcfg_socket_options(task->lp_ctx),
    175306                                     listen_socket);
    176307        if (!NT_STATUS_IS_OK(status)) goto listen_failed;
     
    180311        if (!listen_socket) goto nomem;
    181312        listen_socket->socket_path
    182                 = service->priv_socket_path
    183313                = 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);
    187316        if (!listen_socket->socket_path) goto nomem;
    188317        listen_socket->service          = service;
    189318        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,
    191320                                     &wbsrv_ops, "unix",
    192321                                     listen_socket->socket_path, &port,
    193                                      lp_socket_options(task->lp_ctx),
     322                                     lpcfg_socket_options(task->lp_ctx),
    194323                                     listen_socket);
    195324        if (!NT_STATUS_IS_OK(status)) goto listen_failed;
Note: See TracChangeset for help on using the changeset viewer.