~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source4/smb_server/smb/sesssetup.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
*/
24
24
 
25
25
#include "includes.h"
 
26
#include <tevent.h>
26
27
#include "version.h"
27
28
#include "auth/gensec/gensec.h"
28
29
#include "auth/auth.h"
29
30
#include "smb_server/smb_server.h"
30
31
#include "smbd/service_stream.h"
31
32
#include "param/param.h"
 
33
#include "../lib/tsocket/tsocket.h"
 
34
#include "lib/stream/packet.h"
 
35
 
 
36
struct sesssetup_context {
 
37
        struct auth_context *auth_context;
 
38
        struct smbsrv_request *req;
 
39
};
32
40
 
33
41
/*
34
42
  setup the OS, Lanman and domain portions of a session setup reply
39
47
        (*os) = talloc_asprintf(req, "Unix");
40
48
        (*lanman) = talloc_asprintf(req, "Samba %s", SAMBA_VERSION_STRING);
41
49
        (*domain) = talloc_asprintf(req, "%s", 
42
 
                                    lp_workgroup(req->smb_conn->lp_ctx));
 
50
                                    lpcfg_workgroup(req->smb_conn->lp_ctx));
43
51
}
44
52
 
45
53
static void smbsrv_sesssetup_backend_send(struct smbsrv_request *req,
54
62
        smbsrv_reply_sesssetup_send(req, sess, status);
55
63
}
56
64
 
57
 
static void sesssetup_old_send(struct auth_check_password_request *areq,
58
 
                               void *private_data)
 
65
static void sesssetup_old_send(struct tevent_req *subreq)
59
66
{
60
 
        struct smbsrv_request *req = talloc_get_type(private_data, struct smbsrv_request);
 
67
        struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
 
68
        struct smbsrv_request *req = state->req;
 
69
 
61
70
        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
62
 
        struct auth_serversupplied_info *server_info = NULL;
 
71
        struct auth_user_info_dc *user_info_dc = NULL;
63
72
        struct auth_session_info *session_info;
64
73
        struct smbsrv_session *smb_sess;
65
74
        NTSTATUS status;
 
75
        uint32_t flags;
66
76
 
67
 
        status = auth_check_password_recv(areq, req, &server_info);
 
77
        status = auth_check_password_recv(subreq, req, &user_info_dc);
 
78
        TALLOC_FREE(subreq);
68
79
        if (!NT_STATUS_IS_OK(status)) goto failed;
69
80
 
70
 
        /* This references server_info into session_info */
71
 
        status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, req->smb_conn->lp_ctx, 
72
 
                                            server_info, &session_info);
 
81
        flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
 
82
        if (user_info_dc->info->authenticated) {
 
83
                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
 
84
        }
 
85
        /* This references user_info_dc into session_info */
 
86
        status = req->smb_conn->negotiate.auth_context->generate_session_info(req,
 
87
                                                                              req->smb_conn->negotiate.auth_context,
 
88
                                                                              user_info_dc, flags, &session_info);
73
89
        if (!NT_STATUS_IS_OK(status)) goto failed;
74
90
 
75
91
        /* allocate a new session */
90
106
        sess->old.out.vuid = smb_sess->vuid;
91
107
 
92
108
failed:
93
 
        status = auth_nt_status_squash(status);
 
109
        status = nt_status_squash(status);
94
110
        smbsrv_sesssetup_backend_send(req, sess, status);
95
111
}
96
112
 
100
116
static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
101
117
{
102
118
        struct auth_usersupplied_info *user_info = NULL;
103
 
        struct socket_address *remote_address;
 
119
        struct tsocket_address *remote_address;
104
120
        const char *remote_machine = NULL;
 
121
        struct tevent_req *subreq;
 
122
        struct sesssetup_context *state;
105
123
 
106
124
        sess->old.out.vuid = 0;
107
125
        sess->old.out.action = 0;
119
137
                remote_machine = req->smb_conn->negotiate.calling_name->name;
120
138
        }
121
139
        
122
 
        remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req);
 
140
        remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
123
141
        if (!remote_address) goto nomem;
124
142
 
125
143
        if (!remote_machine) {
126
 
                remote_machine = remote_address->addr;
 
144
                remote_machine = tsocket_address_inet_addr_string(remote_address, req);
 
145
                if (!remote_machine) goto nomem;
127
146
        }
128
147
 
129
 
        user_info = talloc(req, struct auth_usersupplied_info);
 
148
        user_info = talloc_zero(req, struct auth_usersupplied_info);
130
149
        if (!user_info) goto nomem;
131
150
        
132
151
        user_info->mapped_state = false;
142
161
        user_info->password.response.lanman.data = talloc_steal(user_info, sess->old.in.password.data);
143
162
        user_info->password.response.nt = data_blob(NULL, 0);
144
163
 
145
 
        auth_check_password_send(req->smb_conn->negotiate.auth_context, user_info,
146
 
                                 sesssetup_old_send, req);
 
164
        state = talloc(req, struct sesssetup_context);
 
165
        if (!state) goto nomem;
 
166
 
 
167
        if (req->smb_conn->negotiate.auth_context) {
 
168
                state->auth_context = req->smb_conn->negotiate.auth_context;
 
169
        } else {
 
170
                /* TODO: should we use just "anonymous" here? */
 
171
                NTSTATUS status = auth_context_create(state,
 
172
                                                      req->smb_conn->connection->event.ctx,
 
173
                                                      req->smb_conn->connection->msg_ctx,
 
174
                                                      req->smb_conn->lp_ctx,
 
175
                                                      &state->auth_context);
 
176
                if (!NT_STATUS_IS_OK(status)) {
 
177
                        smbsrv_sesssetup_backend_send(req, sess, status);
 
178
                        return;
 
179
                }
 
180
        }
 
181
 
 
182
        state->req = req;
 
183
 
 
184
        subreq = auth_check_password_send(state,
 
185
                                          req->smb_conn->connection->event.ctx,
 
186
                                          req->smb_conn->negotiate.auth_context,
 
187
                                          user_info);
 
188
        if (!subreq) goto nomem;
 
189
        tevent_req_set_callback(subreq, sesssetup_old_send, state);
147
190
        return;
148
191
 
149
192
nomem:
150
193
        smbsrv_sesssetup_backend_send(req, sess, NT_STATUS_NO_MEMORY);
151
194
}
152
195
 
153
 
static void sesssetup_nt1_send(struct auth_check_password_request *areq,
154
 
                               void *private_data)
 
196
static void sesssetup_nt1_send(struct tevent_req *subreq)
155
197
{
156
 
        struct smbsrv_request *req = talloc_get_type(private_data, struct smbsrv_request);
 
198
        struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
 
199
        struct smbsrv_request *req = state->req;
157
200
        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
158
 
        struct auth_serversupplied_info *server_info = NULL;
 
201
        struct auth_user_info_dc *user_info_dc = NULL;
159
202
        struct auth_session_info *session_info;
160
203
        struct smbsrv_session *smb_sess;
 
204
 
 
205
        uint32_t flags;
161
206
        NTSTATUS status;
162
207
 
163
 
        status = auth_check_password_recv(areq, req, &server_info);
 
208
        status = auth_check_password_recv(subreq, req, &user_info_dc);
 
209
        TALLOC_FREE(subreq);
164
210
        if (!NT_STATUS_IS_OK(status)) goto failed;
165
211
 
166
 
        /* This references server_info into session_info */
167
 
        status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, 
168
 
                                            req->smb_conn->lp_ctx, 
169
 
                                            server_info, &session_info);
 
212
        flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
 
213
        if (user_info_dc->info->authenticated) {
 
214
                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
 
215
        }
 
216
        /* This references user_info_dc into session_info */
 
217
        status = state->auth_context->generate_session_info(req,
 
218
                                                            state->auth_context,
 
219
                                                            user_info_dc,
 
220
                                                            flags,
 
221
                                                            &session_info);
170
222
        if (!NT_STATUS_IS_OK(status)) goto failed;
171
223
 
172
224
        /* allocate a new session */
194
246
done:
195
247
        status = NT_STATUS_OK;
196
248
failed:
197
 
        status = auth_nt_status_squash(status);
 
249
        status = nt_status_squash(status);
198
250
        smbsrv_sesssetup_backend_send(req, sess, status);
199
251
}
200
252
 
204
256
static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
205
257
{
206
258
        NTSTATUS status;
207
 
        struct auth_context *auth_context;
208
259
        struct auth_usersupplied_info *user_info = NULL;
209
 
        struct socket_address *remote_address;
 
260
        struct tsocket_address *remote_address;
210
261
        const char *remote_machine = NULL;
211
 
        
 
262
        struct tevent_req *subreq;
 
263
        struct sesssetup_context *state;
 
264
 
212
265
        sess->nt1.out.vuid = 0;
213
266
        sess->nt1.out.action = 0;
214
267
 
222
275
                req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
223
276
        }
224
277
 
 
278
        state = talloc(req, struct sesssetup_context);
 
279
        if (!state) goto nomem;
 
280
 
 
281
        state->req = req;
 
282
 
225
283
        if (req->smb_conn->negotiate.oid) {
226
284
                if (sess->nt1.in.user && *sess->nt1.in.user) {
227
285
                        /* We can't accept a normal login, because we
231
289
                }
232
290
 
233
291
                /* TODO: should we use just "anonymous" here? */
234
 
                status = auth_context_create(req, 
 
292
                status = auth_context_create(state,
235
293
                                             req->smb_conn->connection->event.ctx,
236
294
                                             req->smb_conn->connection->msg_ctx,
237
295
                                             req->smb_conn->lp_ctx,
238
 
                                             &auth_context);
 
296
                                             &state->auth_context);
239
297
                if (!NT_STATUS_IS_OK(status)) goto failed;
 
298
        } else if (req->smb_conn->negotiate.auth_context) {
 
299
                state->auth_context = req->smb_conn->negotiate.auth_context;
240
300
        } else {
241
 
                auth_context = req->smb_conn->negotiate.auth_context;
 
301
                /* TODO: should we use just "anonymous" here? */
 
302
                status = auth_context_create(state,
 
303
                                             req->smb_conn->connection->event.ctx,
 
304
                                             req->smb_conn->connection->msg_ctx,
 
305
                                             req->smb_conn->lp_ctx,
 
306
                                             &state->auth_context);
 
307
                if (!NT_STATUS_IS_OK(status)) goto failed;
242
308
        }
243
309
 
244
310
        if (req->smb_conn->negotiate.calling_name) {
245
311
                remote_machine = req->smb_conn->negotiate.calling_name->name;
246
312
        }
247
313
 
248
 
        remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req);
 
314
        remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
249
315
        if (!remote_address) goto nomem;
250
316
 
251
317
        if (!remote_machine) {
252
 
                remote_machine = remote_address->addr;
 
318
                remote_machine = tsocket_address_inet_addr_string(remote_address, req);
 
319
                if (!remote_machine) goto nomem;
253
320
        }
254
321
 
255
 
        user_info = talloc(req, struct auth_usersupplied_info);
 
322
        user_info = talloc_zero(req, struct auth_usersupplied_info);
256
323
        if (!user_info) goto nomem;
257
324
 
258
325
        user_info->mapped_state = false;
269
336
        user_info->password.response.nt = sess->nt1.in.password2;
270
337
        user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);
271
338
 
272
 
        auth_check_password_send(auth_context, user_info,
273
 
                                 sesssetup_nt1_send, req);
 
339
        subreq = auth_check_password_send(state,
 
340
                                          req->smb_conn->connection->event.ctx,
 
341
                                          state->auth_context,
 
342
                                          user_info);
 
343
        if (!subreq) goto nomem;
 
344
        tevent_req_set_callback(subreq, sesssetup_nt1_send, state);
 
345
 
274
346
        return;
275
347
 
276
348
nomem:
277
349
        status = NT_STATUS_NO_MEMORY;
278
350
failed:
279
 
        status = auth_nt_status_squash(status);
 
351
        status = nt_status_squash(status);
280
352
        smbsrv_sesssetup_backend_send(req, sess, status);
281
353
}
282
354
 
286
358
        struct smbsrv_session *smb_sess;
287
359
};
288
360
 
289
 
static void sesssetup_spnego_send(struct gensec_update_request *greq, void *private_data)
 
361
static void sesssetup_spnego_send(struct tevent_req *subreq)
290
362
{
291
 
        struct sesssetup_spnego_state *s = talloc_get_type(private_data,
 
363
        struct sesssetup_spnego_state *s = tevent_req_callback_data(subreq,
292
364
                                           struct sesssetup_spnego_state);
293
365
        struct smbsrv_request *req = s->req;
294
366
        union smb_sesssetup *sess = s->sess;
298
370
        NTSTATUS skey_status;
299
371
        DATA_BLOB session_key;
300
372
 
301
 
        status = gensec_update_recv(greq, req, &sess->spnego.out.secblob);
 
373
        status = gensec_update_recv(subreq, req, &sess->spnego.out.secblob);
 
374
        packet_recv_enable(req->smb_conn->packet);
 
375
        TALLOC_FREE(subreq);
302
376
        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
303
377
                goto done;
304
378
        } else if (!NT_STATUS_IS_OK(status)) {
323
397
done:
324
398
        sess->spnego.out.vuid = smb_sess->vuid;
325
399
failed:
326
 
        status = auth_nt_status_squash(status);
 
400
        status = nt_status_squash(status);
327
401
        smbsrv_sesssetup_backend_send(req, sess, status);
328
402
        if (!NT_STATUS_IS_OK(status) && 
329
403
            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
340
414
        struct smbsrv_session *smb_sess = NULL;
341
415
        struct sesssetup_spnego_state *s = NULL;
342
416
        uint16_t vuid;
 
417
        struct tevent_req *subreq;
343
418
 
344
419
        sess->spnego.out.vuid = 0;
345
420
        sess->spnego.out.action = 0;
407
482
        s->sess         = sess;
408
483
        s->smb_sess     = smb_sess;
409
484
 
410
 
        gensec_update_send(smb_sess->gensec_ctx, sess->spnego.in.secblob,
411
 
                           sesssetup_spnego_send, s);
 
485
        subreq = gensec_update_send(s,
 
486
                                    req->smb_conn->connection->event.ctx,
 
487
                                    smb_sess->gensec_ctx,
 
488
                                    sess->spnego.in.secblob);
 
489
        if (!subreq) {
 
490
                goto nomem;
 
491
        }
 
492
        /* disable receipt of more packets on this socket until we've
 
493
           finished with the session setup. This avoids a problem with
 
494
           crashes if we get EOF on the socket while processing a session
 
495
           setup */
 
496
        packet_recv_disable(req->smb_conn->packet);
 
497
        tevent_req_set_callback(subreq, sesssetup_spnego_send, s);
 
498
 
412
499
        return;
413
500
 
414
501
nomem:
415
502
        status = NT_STATUS_NO_MEMORY;
416
503
failed:
417
504
        talloc_free(smb_sess);
418
 
        status = auth_nt_status_squash(status);
 
505
        status = nt_status_squash(status);
419
506
        smbsrv_sesssetup_backend_send(req, sess, status);
420
507
}
421
508