~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source4/smbd/service_named_pipe.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <tevent.h>
24
24
#include "smbd/service.h"
25
25
#include "param/param.h"
 
26
#include "auth/auth.h"
26
27
#include "auth/session.h"
27
28
#include "auth/auth_sam_reply.h"
28
 
#include "lib/stream/packet.h"
 
29
#include "lib/socket/socket.h"
 
30
#include "lib/tsocket/tsocket.h"
 
31
#include "libcli/util/tstream.h"
29
32
#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
30
33
#include "system/passwd.h"
 
34
#include "system/network.h"
31
35
#include "libcli/raw/smb.h"
32
 
#include "auth/credentials/credentials.h"
33
 
#include "auth/credentials/credentials_krb5.h"
 
36
#include "auth/session.h"
 
37
#include "libcli/security/security.h"
 
38
#include "libcli/named_pipe_auth/npa_tstream.h"
34
39
 
35
40
struct named_pipe_socket {
36
41
        const char *pipe_name;
39
44
        void *private_data;
40
45
};
41
46
 
42
 
struct named_pipe_connection {
43
 
        struct stream_connection *connection;
44
 
        struct packet_context *packet;
45
 
        const struct named_pipe_socket *pipe_sock;
46
 
        NTSTATUS status;
47
 
};
48
 
 
49
 
static void named_pipe_handover_connection(void *private_data)
50
 
{
51
 
        struct named_pipe_connection *pipe_conn = talloc_get_type(
52
 
                private_data, struct named_pipe_connection);
53
 
        struct stream_connection *conn = pipe_conn->connection;
54
 
 
55
 
        TEVENT_FD_NOT_WRITEABLE(conn->event.fde);
56
 
 
57
 
        packet_set_socket(pipe_conn->packet, NULL);
58
 
        packet_set_event_context(pipe_conn->packet, NULL);
59
 
        packet_set_fde(pipe_conn->packet, NULL);
60
 
        TALLOC_FREE(pipe_conn->packet);
61
 
 
62
 
        if (!NT_STATUS_IS_OK(pipe_conn->status)) {
63
 
                stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
64
 
                return;
65
 
        }
66
 
 
67
 
        /*
68
 
         * remove the named_pipe layer together with its packet layer
69
 
         */
70
 
        conn->ops               = pipe_conn->pipe_sock->ops;
71
 
        conn->private_data      = pipe_conn->pipe_sock->private_data;
72
 
        talloc_unlink(conn, pipe_conn);
73
 
 
74
 
        /* we're now ready to start receiving events on this stream */
75
 
        TEVENT_FD_READABLE(conn->event.fde);
 
47
static void named_pipe_accept_done(struct tevent_req *subreq);
 
48
 
 
49
static void named_pipe_accept(struct stream_connection *conn)
 
50
{
 
51
        struct tstream_context *plain_tstream;
 
52
        int fd;
 
53
        struct tevent_req *subreq;
 
54
        int ret;
 
55
 
 
56
        /* Let tstream take over fd operations */
 
57
 
 
58
        fd = socket_get_fd(conn->socket);
 
59
        socket_set_flags(conn->socket, SOCKET_FLAG_NOCLOSE);
 
60
        TALLOC_FREE(conn->event.fde);
 
61
        TALLOC_FREE(conn->socket);
 
62
 
 
63
        ret = tstream_bsd_existing_socket(conn, fd, &plain_tstream);
 
64
        if (ret != 0) {
 
65
                stream_terminate_connection(conn,
 
66
                                "named_pipe_accept: out of memory");
 
67
                return;
 
68
        }
 
69
 
 
70
        subreq = tstream_npa_accept_existing_send(conn, conn->event.ctx,
 
71
                                                  plain_tstream,
 
72
                                                  FILE_TYPE_MESSAGE_MODE_PIPE,
 
73
                                                  0xff | 0x0400 | 0x0100,
 
74
                                                  4096);
 
75
        if (subreq == NULL) {
 
76
                stream_terminate_connection(conn,
 
77
                        "named_pipe_accept: "
 
78
                        "no memory for tstream_npa_accept_existing_send");
 
79
                return;
 
80
        }
 
81
        tevent_req_set_callback(subreq, named_pipe_accept_done, conn);
 
82
}
 
83
 
 
84
static void named_pipe_accept_done(struct tevent_req *subreq)
 
85
{
 
86
        struct stream_connection *conn = tevent_req_callback_data(subreq,
 
87
                                                struct stream_connection);
 
88
        struct named_pipe_socket *pipe_sock =
 
89
                                talloc_get_type(conn->private_data,
 
90
                                                struct named_pipe_socket);
 
91
        struct tsocket_address *client;
 
92
        char *client_name;
 
93
        struct tsocket_address *server;
 
94
        char *server_name;
 
95
        struct auth_session_info_transport *session_info_transport;
 
96
        const char *reason = NULL;
 
97
        TALLOC_CTX *tmp_ctx;
 
98
        int error;
 
99
        int ret;
 
100
 
 
101
        tmp_ctx = talloc_new(conn);
 
102
        if (!tmp_ctx) {
 
103
                reason = "Out of memory!\n";
 
104
                goto out;
 
105
        }
 
106
 
 
107
        ret = tstream_npa_accept_existing_recv(subreq, &error, tmp_ctx,
 
108
                                               &conn->tstream,
 
109
                                               &client,
 
110
                                               &client_name,
 
111
                                               &server,
 
112
                                               &server_name,
 
113
                                               &session_info_transport);
 
114
        TALLOC_FREE(subreq);
 
115
        if (ret != 0) {
 
116
                reason = talloc_asprintf(conn,
 
117
                                         "tstream_npa_accept_existing_recv()"
 
118
                                         " failed: %s", strerror(error));
 
119
                goto out;
 
120
        }
 
121
 
 
122
        DEBUG(10, ("Accepted npa connection from %s. "
 
123
                   "Client: %s (%s). Server: %s (%s)\n",
 
124
                   tsocket_address_string(conn->remote_address, tmp_ctx),
 
125
                   client_name, tsocket_address_string(client, tmp_ctx),
 
126
                   server_name, tsocket_address_string(server, tmp_ctx)));
 
127
 
 
128
        conn->session_info = auth_session_info_from_transport(conn, session_info_transport,
 
129
                                                              conn->lp_ctx,
 
130
                                                              &reason);
 
131
        if (!conn->session_info) {
 
132
                goto out;
 
133
        }
76
134
 
77
135
        /*
78
136
         * hand over to the real pipe implementation,
79
137
         * now that we have setup the transport session_info
80
138
         */
 
139
        conn->ops = pipe_sock->ops;
 
140
        conn->private_data = pipe_sock->private_data;
81
141
        conn->ops->accept_connection(conn);
82
142
 
83
 
        DEBUG(10,("named_pipe_handover_connection[%s]: succeeded\n",
84
 
              conn->ops->name));
85
 
}
86
 
 
87
 
static NTSTATUS named_pipe_recv_auth_request(void *private_data,
88
 
                                             DATA_BLOB req_blob)
89
 
{
90
 
        struct named_pipe_connection *pipe_conn = talloc_get_type(
91
 
                private_data, struct named_pipe_connection);
92
 
        struct stream_connection *conn = pipe_conn->connection;
93
 
        enum ndr_err_code ndr_err;
94
 
        struct named_pipe_auth_req req;
95
 
        union netr_Validation val;
96
 
        struct auth_serversupplied_info *server_info;
97
 
        struct named_pipe_auth_rep rep;
98
 
        DATA_BLOB rep_blob;
99
 
        NTSTATUS status;
100
 
 
101
 
        /*
102
 
         * make sure nothing happens on the socket untill the
103
 
         * real implemenation takes over
104
 
         */
105
 
        packet_recv_disable(pipe_conn->packet);
106
 
 
107
 
        /*
108
 
         * TODO: check it's a root (uid == 0) pipe
109
 
         */
110
 
 
111
 
        ZERO_STRUCT(rep);
112
 
        rep.level = 0;
113
 
        rep.status = NT_STATUS_INTERNAL_ERROR;
114
 
 
115
 
        DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n",
116
 
                  (unsigned int)req_blob.length));
117
 
        dump_data(11, req_blob.data, req_blob.length);
118
 
 
119
 
        /* parse the passed credentials */
120
 
        ndr_err = ndr_pull_struct_blob_all(
121
 
                        &req_blob,
122
 
                        pipe_conn,
123
 
                        lp_iconv_convenience(conn->lp_ctx),
124
 
                        &req,
125
 
                        (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req);
126
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
127
 
                rep.status = ndr_map_error2ntstatus(ndr_err);
128
 
                DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n",
129
 
                          nt_errstr(rep.status)));
130
 
                goto reply;
131
 
        }
132
 
 
133
 
        if (DEBUGLVL(10)) {
134
 
                NDR_PRINT_DEBUG(named_pipe_auth_req, &req);
135
 
        }
136
 
 
137
 
        if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) {
138
 
                DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n",
139
 
                          req.magic, NAMED_PIPE_AUTH_MAGIC));
140
 
                rep.status = NT_STATUS_INVALID_PARAMETER;
141
 
                goto reply;
142
 
        }
143
 
 
144
 
        switch (req.level) {
145
 
        case 0:
146
 
                /*
147
 
                 * anon connection, we don't create a session info
148
 
                 * and leave it NULL
149
 
                 */
150
 
                rep.level = 0;
151
 
                rep.status = NT_STATUS_OK;
152
 
                break;
153
 
        case 1:
154
 
                val.sam3 = &req.info.info1;
155
 
 
156
 
                rep.level = 1;
157
 
                rep.status = make_server_info_netlogon_validation(pipe_conn,
158
 
                                                                  "TODO",
159
 
                                                                  3, &val,
160
 
                                                                  &server_info);
161
 
                if (!NT_STATUS_IS_OK(rep.status)) {
162
 
                        DEBUG(2, ("make_server_info_netlogon_validation returned "
163
 
                                  "%s\n", nt_errstr(rep.status)));
164
 
                        goto reply;
165
 
                }
166
 
 
167
 
                /* setup the session_info on the connection */
168
 
                rep.status = auth_generate_session_info(conn,
169
 
                                                        conn->event.ctx,
170
 
                                                        conn->lp_ctx,
171
 
                                                        server_info,
172
 
                                                        &conn->session_info);
173
 
                if (!NT_STATUS_IS_OK(rep.status)) {
174
 
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
175
 
                                  nt_errstr(rep.status)));
176
 
                        goto reply;
177
 
                }
178
 
 
179
 
                break;
180
 
        case 2:
181
 
                rep.level = 2;
182
 
                rep.info.info2.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
183
 
                rep.info.info2.device_state = 0xff | 0x0400 | 0x0100;
184
 
                rep.info.info2.allocation_size = 4096;
185
 
 
186
 
                if (!req.info.info2.sam_info3) {
187
 
                        /*
188
 
                         * anon connection, we don't create a session info
189
 
                         * and leave it NULL
190
 
                         */
191
 
                        rep.status = NT_STATUS_OK;
192
 
                        break;
193
 
                }
194
 
 
195
 
                val.sam3 = req.info.info2.sam_info3;
196
 
 
197
 
                rep.status = make_server_info_netlogon_validation(pipe_conn,
198
 
                                                val.sam3->base.account_name.string,
199
 
                                                3, &val, &server_info);
200
 
                if (!NT_STATUS_IS_OK(rep.status)) {
201
 
                        DEBUG(2, ("make_server_info_netlogon_validation returned "
202
 
                                  "%s\n", nt_errstr(rep.status)));
203
 
                        goto reply;
204
 
                }
205
 
 
206
 
                /* setup the session_info on the connection */
207
 
                rep.status = auth_generate_session_info(conn,
208
 
                                                        conn->event.ctx,
209
 
                                                        conn->lp_ctx,
210
 
                                                        server_info,
211
 
                                                        &conn->session_info);
212
 
                if (!NT_STATUS_IS_OK(rep.status)) {
213
 
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
214
 
                                  nt_errstr(rep.status)));
215
 
                        goto reply;
216
 
                }
217
 
 
218
 
                conn->session_info->session_key = data_blob_const(req.info.info2.session_key,
219
 
                                                        req.info.info2.session_key_length);
220
 
                talloc_steal(conn->session_info, req.info.info2.session_key);
221
 
 
222
 
                break;
223
 
        case 3:
224
 
                rep.level = 3;
225
 
                rep.info.info3.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
226
 
                rep.info.info3.device_state = 0xff | 0x0400 | 0x0100;
227
 
                rep.info.info3.allocation_size = 4096;
228
 
 
229
 
                if (!req.info.info3.sam_info3) {
230
 
                        /*
231
 
                         * anon connection, we don't create a session info
232
 
                         * and leave it NULL
233
 
                         */
234
 
                        rep.status = NT_STATUS_OK;
235
 
                        break;
236
 
                }
237
 
 
238
 
                val.sam3 = req.info.info3.sam_info3;
239
 
 
240
 
                rep.status = make_server_info_netlogon_validation(pipe_conn,
241
 
                                                val.sam3->base.account_name.string,
242
 
                                                3, &val, &server_info);
243
 
                if (!NT_STATUS_IS_OK(rep.status)) {
244
 
                        DEBUG(2, ("make_server_info_netlogon_validation returned "
245
 
                                  "%s\n", nt_errstr(rep.status)));
246
 
                        goto reply;
247
 
                }
248
 
 
249
 
                /* setup the session_info on the connection */
250
 
                rep.status = auth_generate_session_info(conn,
251
 
                                                        conn->event.ctx,
252
 
                                                        conn->lp_ctx,
253
 
                                                        server_info,
254
 
                                                        &conn->session_info);
255
 
                if (!NT_STATUS_IS_OK(rep.status)) {
256
 
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
257
 
                                  nt_errstr(rep.status)));
258
 
                        goto reply;
259
 
                }
260
 
 
261
 
                if (req.info.info3.gssapi_delegated_creds_length) {
262
 
                        OM_uint32 minor_status;
263
 
                        gss_buffer_desc cred_token;
264
 
                        gss_cred_id_t cred_handle;
265
 
                        int ret;
266
 
 
267
 
                        DEBUG(10, ("named_pipe_auth: delegated credentials supplied by client\n"));
268
 
 
269
 
                        cred_token.value = req.info.info3.gssapi_delegated_creds;
270
 
                        cred_token.length = req.info.info3.gssapi_delegated_creds_length;
271
 
 
272
 
                        ret = gss_import_cred(&minor_status,
273
 
                                               &cred_token,
274
 
                                               &cred_handle);
275
 
                        if (ret != GSS_S_COMPLETE) {
276
 
                                rep.status = NT_STATUS_INTERNAL_ERROR;
277
 
                                goto reply;
278
 
                        }
279
 
 
280
 
                        conn->session_info->credentials = cli_credentials_init(conn->session_info);
281
 
                        if (!conn->session_info->credentials) {
282
 
                                rep.status = NT_STATUS_NO_MEMORY;
283
 
                                goto reply;
284
 
                        }
285
 
 
286
 
                        cli_credentials_set_conf(conn->session_info->credentials,
287
 
                                                 conn->lp_ctx);
288
 
                        /* Just so we don't segfault trying to get at a username */
289
 
                        cli_credentials_set_anonymous(conn->session_info->credentials);
290
 
 
291
 
                        ret = cli_credentials_set_client_gss_creds(conn->session_info->credentials,
292
 
                                                                   conn->event.ctx,
293
 
                                                                   conn->lp_ctx,
294
 
                                                                   cred_handle,
295
 
                                                                   CRED_SPECIFIED);
296
 
                        if (ret) {
297
 
                                rep.status = NT_STATUS_INTERNAL_ERROR;
298
 
                                goto reply;
299
 
                        }
300
 
 
301
 
                        /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
302
 
                        cli_credentials_set_kerberos_state(conn->session_info->credentials,
303
 
                                                           CRED_MUST_USE_KERBEROS);
304
 
                }
305
 
 
306
 
                conn->session_info->session_key = data_blob_const(req.info.info3.session_key,
307
 
                                                        req.info.info3.session_key_length);
308
 
                talloc_steal(conn->session_info, req.info.info3.session_key);
309
 
 
310
 
                break;
311
 
        default:
312
 
                DEBUG(2, ("named_pipe_auth_req: unknown level %u\n",
313
 
                          req.level));
314
 
                rep.level = 0;
315
 
                rep.status = NT_STATUS_INVALID_LEVEL;
316
 
                goto reply;
317
 
        }
318
 
 
319
 
reply:
320
 
        /* create the output */
321
 
        ndr_err = ndr_push_struct_blob(&rep_blob, pipe_conn,
322
 
                        lp_iconv_convenience(conn->lp_ctx),
323
 
                        &rep,
324
 
                        (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
325
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326
 
                status = ndr_map_error2ntstatus(ndr_err);
327
 
                DEBUG(2, ("Could not marshall named_pipe_auth_rep: %s\n",
328
 
                          nt_errstr(status)));
329
 
                return status;
330
 
        }
331
 
 
332
 
        DEBUG(10,("named_pipe_auth reply[%u]\n", (unsigned)rep_blob.length));
333
 
        dump_data(11, rep_blob.data, rep_blob.length);
334
 
        if (DEBUGLVL(10)) {
335
 
                NDR_PRINT_DEBUG(named_pipe_auth_rep, &rep);
336
 
        }
337
 
 
338
 
        pipe_conn->status = rep.status;
339
 
        status = packet_send_callback(pipe_conn->packet, rep_blob,
340
 
                                      named_pipe_handover_connection,
341
 
                                      pipe_conn);
342
 
        if (!NT_STATUS_IS_OK(status)) {
343
 
                DEBUG(0, ("packet_send_callback returned %s\n",
344
 
                          nt_errstr(status)));
345
 
                return status;
346
 
        }
347
 
 
348
 
        return NT_STATUS_OK;
 
143
        DEBUG(10, ("named pipe connection [%s] established\n",
 
144
                   conn->ops->name));
 
145
 
 
146
        talloc_free(tmp_ctx);
 
147
        return;
 
148
 
 
149
out:
 
150
        talloc_free(tmp_ctx);
 
151
        if (!reason) {
 
152
                reason = "Internal error";
 
153
        }
 
154
        stream_terminate_connection(conn, reason);
349
155
}
350
156
 
351
157
/*
353
159
*/
354
160
static void named_pipe_recv(struct stream_connection *conn, uint16_t flags)
355
161
{
356
 
        struct named_pipe_connection *pipe_conn = talloc_get_type(
357
 
                conn->private_data, struct named_pipe_connection);
358
 
 
359
 
        DEBUG(10,("named_pipe_recv\n"));
360
 
 
361
 
        packet_recv(pipe_conn->packet);
 
162
        stream_terminate_connection(conn, "named_pipe_recv: called");
362
163
}
363
164
 
364
165
/*
366
167
*/
367
168
static void named_pipe_send(struct stream_connection *conn, uint16_t flags)
368
169
{
369
 
        struct named_pipe_connection *pipe_conn = talloc_get_type(
370
 
                conn->private_data, struct named_pipe_connection);
371
 
 
372
 
        packet_queue_run(pipe_conn->packet);
373
 
}
374
 
 
375
 
/*
376
 
  handle socket recv errors
377
 
*/
378
 
static void named_pipe_recv_error(void *private_data, NTSTATUS status)
379
 
{
380
 
        struct named_pipe_connection *pipe_conn = talloc_get_type(
381
 
                private_data, struct named_pipe_connection);
382
 
 
383
 
        stream_terminate_connection(pipe_conn->connection, nt_errstr(status));
384
 
}
385
 
 
386
 
static NTSTATUS named_pipe_full_request(void *private_data, DATA_BLOB blob, size_t *size)
387
 
{
388
 
        if (blob.length < 8) {
389
 
                return STATUS_MORE_ENTRIES;
390
 
        }
391
 
 
392
 
        if (memcmp(NAMED_PIPE_AUTH_MAGIC, &blob.data[4], 4) != 0) {
393
 
                DEBUG(0,("named_pipe_full_request: wrong protocol\n"));
394
 
                *size = blob.length;
395
 
                /* the error will be handled in named_pipe_recv_auth_request */
396
 
                return NT_STATUS_OK;
397
 
        }
398
 
 
399
 
        *size = 4 + RIVAL(blob.data, 0);
400
 
        if (*size > blob.length) {
401
 
                return STATUS_MORE_ENTRIES;
402
 
        }
403
 
 
404
 
        return NT_STATUS_OK;
405
 
}
406
 
 
407
 
static void named_pipe_accept(struct stream_connection *conn)
408
 
{
409
 
        struct named_pipe_socket *pipe_sock = talloc_get_type(
410
 
                conn->private_data, struct named_pipe_socket);
411
 
        struct named_pipe_connection *pipe_conn;
412
 
 
413
 
        DEBUG(5,("named_pipe_accept\n"));
414
 
 
415
 
        pipe_conn = talloc_zero(conn, struct named_pipe_connection);
416
 
        if (!pipe_conn) {
417
 
                stream_terminate_connection(conn, "out of memory");
418
 
                return;
419
 
        }
420
 
 
421
 
        pipe_conn->packet = packet_init(pipe_conn);
422
 
        if (!pipe_conn->packet) {
423
 
                stream_terminate_connection(conn, "out of memory");
424
 
                return;
425
 
        }
426
 
        packet_set_private(pipe_conn->packet, pipe_conn);
427
 
        packet_set_socket(pipe_conn->packet, conn->socket);
428
 
        packet_set_callback(pipe_conn->packet, named_pipe_recv_auth_request);
429
 
        packet_set_full_request(pipe_conn->packet, named_pipe_full_request);
430
 
        packet_set_error_handler(pipe_conn->packet, named_pipe_recv_error);
431
 
        packet_set_event_context(pipe_conn->packet, conn->event.ctx);
432
 
        packet_set_fde(pipe_conn->packet, conn->event.fde);
433
 
        packet_set_serialise(pipe_conn->packet);
434
 
        packet_set_initial_read(pipe_conn->packet, 8);
435
 
 
436
 
        pipe_conn->pipe_sock = pipe_sock;
437
 
 
438
 
        pipe_conn->connection = conn;
439
 
        conn->private_data = pipe_conn;
 
170
        stream_terminate_connection(conn, "named_pipe_send: called");
440
171
}
441
172
 
442
173
static const struct stream_server_ops named_pipe_stream_ops = {
446
177
        .send_handler           = named_pipe_send,
447
178
};
448
179
 
449
 
NTSTATUS stream_setup_named_pipe(struct tevent_context *event_context,
450
 
                                 struct loadparm_context *lp_ctx,
451
 
                                 const struct model_ops *model_ops,
452
 
                                 const struct stream_server_ops *stream_ops,
453
 
                                 const char *pipe_name,
454
 
                                 void *private_data)
 
180
NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx,
 
181
                                  struct tevent_context *event_context,
 
182
                                  struct loadparm_context *lp_ctx,
 
183
                                  const struct model_ops *model_ops,
 
184
                                  const struct stream_server_ops *stream_ops,
 
185
                                  const char *pipe_name,
 
186
                                  void *private_data)
455
187
{
456
188
        char *dirname;
457
189
        struct named_pipe_socket *pipe_sock;
458
190
        NTSTATUS status = NT_STATUS_NO_MEMORY;;
459
191
 
460
 
        pipe_sock = talloc(event_context, struct named_pipe_socket);
 
192
        pipe_sock = talloc(mem_ctx, struct named_pipe_socket);
461
193
        if (pipe_sock == NULL) {
462
194
                goto fail;
463
195
        }
468
200
                goto fail;
469
201
        }
470
202
 
471
 
        dirname = talloc_asprintf(pipe_sock, "%s/np", lp_ncalrpc_dir(lp_ctx));
 
203
        if (!directory_create_or_exist(lpcfg_ncalrpc_dir(lp_ctx), geteuid(), 0755)) {
 
204
                status = map_nt_error_from_unix(errno);
 
205
                DEBUG(0,(__location__ ": Failed to create ncalrpc pipe directory '%s' - %s\n",
 
206
                         lpcfg_ncalrpc_dir(lp_ctx), nt_errstr(status)));
 
207
                goto fail;
 
208
        }
 
209
 
 
210
        dirname = talloc_asprintf(pipe_sock, "%s/np", lpcfg_ncalrpc_dir(lp_ctx));
472
211
        if (dirname == NULL) {
473
212
                goto fail;
474
213
        }
492
231
 
493
232
        talloc_free(dirname);
494
233
 
495
 
        pipe_sock->ops          = stream_ops;
496
 
        pipe_sock->private_data = talloc_reference(pipe_sock, private_data);
 
234
        pipe_sock->ops = stream_ops;
 
235
        pipe_sock->private_data = private_data;
497
236
 
498
 
        status = stream_setup_socket(event_context,
 
237
        status = stream_setup_socket(pipe_sock,
 
238
                                     event_context,
499
239
                                     lp_ctx,
500
240
                                     model_ops,
501
241
                                     &named_pipe_stream_ops,