~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/smbd/close.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:
20
20
*/
21
21
 
22
22
#include "includes.h"
23
 
 
24
 
extern struct current_user current_user;
 
23
#include "system/filesys.h"
 
24
#include "printing.h"
 
25
#include "smbd/smbd.h"
 
26
#include "smbd/globals.h"
 
27
#include "fake_file.h"
 
28
#include "transfer_file.h"
 
29
#include "auth.h"
 
30
#include "messages.h"
25
31
 
26
32
/****************************************************************************
27
33
 Run a file if it is a magic script.
153
159
 If any deferred opens are waiting on this close, notify them.
154
160
****************************************************************************/
155
161
 
156
 
static void notify_deferred_opens(struct share_mode_lock *lck)
 
162
static void notify_deferred_opens(struct messaging_context *msg_ctx,
 
163
                                  struct share_mode_lock *lck)
157
164
{
158
165
        int i;
159
166
 
175
182
                         * the head of the queue and changing the wait time to
176
183
                         * zero.
177
184
                         */
178
 
                        schedule_deferred_open_smb_message(e->op_mid);
 
185
                        schedule_deferred_open_message_smb(e->op_mid);
179
186
                } else {
180
187
                        char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
181
188
 
182
189
                        share_mode_entry_to_message(msg, e);
183
190
 
184
 
                        messaging_send_buf(smbd_messaging_context(),
185
 
                                           e->pid, MSG_SMB_OPEN_RETRY,
 
191
                        messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
186
192
                                           (uint8 *)msg,
187
193
                                           MSG_SMB_SHARE_MODE_ENTRY_SIZE);
188
194
                }
273
279
        NTSTATUS status = NT_STATUS_OK;
274
280
        NTSTATUS tmp_status;
275
281
        struct file_id id;
 
282
        const struct security_unix_token *del_token = NULL;
276
283
 
277
284
        /* Ensure any pending write time updates are done. */
278
285
        if (fsp->update_write_time_event) {
326
333
                          fsp_str_dbg(fsp)));
327
334
        }
328
335
 
329
 
        if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
 
336
        if (fsp->initial_delete_on_close &&
 
337
                        !is_delete_on_close_set(lck, fsp->name_hash)) {
330
338
                bool became_user = False;
331
339
 
332
340
                /* Initial delete on close was set and no one else
333
341
                 * wrote a real delete on close. */
334
342
 
335
 
                if (current_user.vuid != fsp->vuid) {
 
343
                if (get_current_vuid(conn) != fsp->vuid) {
336
344
                        become_user(conn, fsp->vuid);
337
345
                        became_user = True;
338
346
                }
339
347
                fsp->delete_on_close = true;
340
 
                set_delete_on_close_lck(lck, True, &current_user.ut);
 
348
                set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
341
349
                if (became_user) {
342
350
                        unbecome_user();
343
351
                }
344
352
        }
345
353
 
346
 
        delete_file = lck->delete_on_close;
 
354
        delete_file = is_delete_on_close_set(lck, fsp->name_hash);
347
355
 
348
356
        if (delete_file) {
349
357
                int i;
350
 
                /* See if others still have the file open. If this is the
351
 
                 * case, then don't delete. If all opens are POSIX delete now. */
 
358
                /* See if others still have the file open via this pathname.
 
359
                   If this is the case, then don't delete. If all opens are
 
360
                   POSIX delete now. */
352
361
                for (i=0; i<lck->num_share_modes; i++) {
353
362
                        struct share_mode_entry *e = &lck->share_modes[i];
354
 
                        if (is_valid_share_mode_entry(e)) {
 
363
                        if (is_valid_share_mode_entry(e) &&
 
364
                                        e->name_hash == fsp->name_hash) {
355
365
                                if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
356
366
                                        continue;
357
367
                                }
362
372
        }
363
373
 
364
374
        /* Notify any deferred opens waiting on this close. */
365
 
        notify_deferred_opens(lck);
 
375
        notify_deferred_opens(conn->sconn->msg_ctx, lck);
366
376
        reply_to_oplock_break_requests(fsp);
367
377
 
368
378
        /*
370
380
         * reference to a file.
371
381
         */
372
382
 
373
 
        if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
374
 
            || !delete_file
375
 
            || (lck->delete_token == NULL)) {
 
383
        if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
 
384
                        !delete_file) {
376
385
                TALLOC_FREE(lck);
377
386
                return NT_STATUS_OK;
378
387
        }
389
398
         */
390
399
        fsp->update_write_time_on_close = false;
391
400
 
392
 
        if (!unix_token_equal(lck->delete_token, &current_user.ut)) {
 
401
        del_token = get_delete_on_close_token(lck, fsp->name_hash);
 
402
        SMB_ASSERT(del_token != NULL);
 
403
 
 
404
        if (!unix_token_equal(del_token, get_current_utok(conn))) {
393
405
                /* Become the user who requested the delete. */
394
406
 
395
407
                DEBUG(5,("close_remove_share_mode: file %s. "
396
408
                        "Change user to uid %u\n",
397
409
                        fsp_str_dbg(fsp),
398
 
                        (unsigned int)lck->delete_token->uid));
 
410
                        (unsigned int)del_token->uid));
399
411
 
400
412
                if (!push_sec_ctx()) {
401
413
                        smb_panic("close_remove_share_mode: file %s. failed to push "
402
414
                                  "sec_ctx.\n");
403
415
                }
404
416
 
405
 
                set_sec_ctx(lck->delete_token->uid,
406
 
                            lck->delete_token->gid,
407
 
                            lck->delete_token->ngroups,
408
 
                            lck->delete_token->groups,
 
417
                set_sec_ctx(del_token->uid,
 
418
                            del_token->gid,
 
419
                            del_token->ngroups,
 
420
                            del_token->groups,
409
421
                            NULL);
410
422
 
411
423
                changed_user = true;
471
483
                status = map_nt_error_from_unix(errno);
472
484
        }
473
485
 
474
 
        notify_fname(conn, NOTIFY_ACTION_REMOVED,
475
 
                     FILE_NOTIFY_CHANGE_FILE_NAME,
476
 
                     fsp->fsp_name->base_name);
477
 
 
478
486
        /* As we now have POSIX opens which can unlink
479
487
         * with other open files we may have taken
480
488
         * this code path with more than one share mode
483
491
         */
484
492
 
485
493
        fsp->delete_on_close = false;
486
 
        set_delete_on_close_lck(lck, False, NULL);
 
494
        set_delete_on_close_lck(fsp, lck, false, NULL);
487
495
 
488
496
 done:
489
497
 
493
501
        }
494
502
 
495
503
        TALLOC_FREE(lck);
 
504
 
 
505
        if (delete_file) {
 
506
                /*
 
507
                 * Do the notification after we released the share
 
508
                 * mode lock. Inside notify_fname we take out another
 
509
                 * tdb lock. With ctdb also accessing our databases,
 
510
                 * this can lead to deadlocks. Putting this notify
 
511
                 * after the TALLOC_FREE(lck) above we avoid locking
 
512
                 * two records simultaneously. Notifies are async and
 
513
                 * informational only, so calling the notify_fname
 
514
                 * without holding the share mode lock should not do
 
515
                 * any harm.
 
516
                 */
 
517
                notify_fname(conn, NOTIFY_ACTION_REMOVED,
 
518
                             FILE_NOTIFY_CHANGE_FILE_NAME,
 
519
                             fsp->fsp_name->base_name);
 
520
        }
 
521
 
496
522
        return status;
497
523
}
498
524
 
550
576
        }
551
577
 
552
578
        ft.mtime = fsp->close_write_time;
553
 
        status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
 
579
        /* We must use NULL for the fsp handle here, as smb_set_file_time()
 
580
           checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
 
581
           As this is a close based update, we are not directly changing the
 
582
           file attributes from a client call, but indirectly from a write. */
 
583
        status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
554
584
        if (!NT_STATUS_IS_OK(status)) {
 
585
                DEBUG(10,("update_write_time_on_close: smb_set_file_time "
 
586
                        "on file %s returned %s\n",
 
587
                        fsp_str_dbg(fsp),
 
588
                        nt_errstr(status)));
555
589
                return status;
556
590
        }
557
591
 
581
615
        NTSTATUS tmp;
582
616
        connection_struct *conn = fsp->conn;
583
617
 
584
 
        if (fsp->aio_write_behind) {
 
618
        if (close_type == ERROR_CLOSE) {
 
619
                cancel_aio_by_fsp(fsp);
 
620
        } else {
585
621
                /*
586
 
                 * If we're finishing write behind on a close we can get a write
 
622
                 * If we're finishing async io on a close we can get a write
587
623
                 * error here, we must remember this.
588
624
                 */
589
625
                int ret = wait_for_aio_completion(fsp);
591
627
                        status = ntstatus_keeperror(
592
628
                                status, map_nt_error_from_unix(ret));
593
629
                }
594
 
        } else {
595
 
                cancel_aio_by_fsp(fsp);
596
630
        }
597
 
 
 
631
 
598
632
        /*
599
633
         * If we're flushing on a close we can get a write
600
634
         * error here, we must remember this.
604
638
        status = ntstatus_keeperror(status, tmp);
605
639
 
606
640
        if (fsp->print_file) {
607
 
                print_fsp_end(fsp, close_type);
 
641
                /* FIXME: return spool errors */
 
642
                print_spool_end(fsp, close_type);
608
643
                file_free(req, fsp);
609
644
                return NT_STATUS_OK;
610
645
        }
624
659
                status = ntstatus_keeperror(status, tmp);
625
660
        }
626
661
 
627
 
        locking_close_file(smbd_messaging_context(), fsp);
 
662
        locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
628
663
 
629
664
        tmp = fd_close(fsp);
630
665
        status = ntstatus_keeperror(status, tmp);
651
686
        status = ntstatus_keeperror(status, tmp);
652
687
 
653
688
        DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
654
 
                conn->server_info->unix_name, fsp_str_dbg(fsp),
 
689
                conn->session_info->unix_name, fsp_str_dbg(fsp),
655
690
                conn->num_files_open - 1,
656
691
                nt_errstr(status) ));
657
692
 
927
962
        bool delete_dir = False;
928
963
        NTSTATUS status = NT_STATUS_OK;
929
964
        NTSTATUS status1 = NT_STATUS_OK;
 
965
        const struct security_unix_token *del_token = NULL;
930
966
 
931
967
        /*
932
968
         * NT can set delete_on_close of the last open
955
991
                 * directories we don't care if anyone else
956
992
                 * wrote a real delete on close. */
957
993
 
958
 
                if (current_user.vuid != fsp->vuid) {
 
994
                if (get_current_vuid(fsp->conn) != fsp->vuid) {
959
995
                        become_user(fsp->conn, fsp->vuid);
960
996
                        became_user = True;
961
997
                }
962
 
                send_stat_cache_delete_message(fsp->fsp_name->base_name);
963
 
                set_delete_on_close_lck(lck, True, &current_user.ut);
 
998
                send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
 
999
                                               fsp->fsp_name->base_name);
 
1000
                set_delete_on_close_lck(fsp, lck, true,
 
1001
                                get_current_utok(fsp->conn));
964
1002
                fsp->delete_on_close = true;
965
1003
                if (became_user) {
966
1004
                        unbecome_user();
967
1005
                }
968
1006
        }
969
1007
 
970
 
        delete_dir = lck->delete_on_close;
 
1008
        del_token = get_delete_on_close_token(lck, fsp->name_hash);
 
1009
        delete_dir = (del_token != NULL);
971
1010
 
972
1011
        if (delete_dir) {
973
1012
                int i;
975
1014
                 * case, then don't delete. If all opens are POSIX delete now. */
976
1015
                for (i=0; i<lck->num_share_modes; i++) {
977
1016
                        struct share_mode_entry *e = &lck->share_modes[i];
978
 
                        if (is_valid_share_mode_entry(e)) {
 
1017
                        if (is_valid_share_mode_entry(e) &&
 
1018
                                        e->name_hash == fsp->name_hash) {
979
1019
                                if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
980
1020
                                        continue;
981
1021
                                }
986
1026
        }
987
1027
 
988
1028
        if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
989
 
                                delete_dir &&
990
 
                                lck->delete_token) {
 
1029
                                delete_dir) {
991
1030
        
992
1031
                /* Become the user who requested the delete. */
993
1032
 
995
1034
                        smb_panic("close_directory: failed to push sec_ctx.\n");
996
1035
                }
997
1036
 
998
 
                set_sec_ctx(lck->delete_token->uid,
999
 
                                lck->delete_token->gid,
1000
 
                                lck->delete_token->ngroups,
1001
 
                                lck->delete_token->groups,
 
1037
                set_sec_ctx(del_token->uid,
 
1038
                                del_token->gid,
 
1039
                                del_token->ngroups,
 
1040
                                del_token->groups,
1002
1041
                                NULL);
1003
1042
 
1004
1043
                TALLOC_FREE(lck);
1034
1073
                          strerror(errno)));
1035
1074
        }
1036
1075
 
1037
 
        if (fsp->dptr) {
1038
 
                dptr_CloseDir(fsp->dptr);
1039
 
        }
1040
 
 
1041
1076
        /*
1042
1077
         * Do the code common to files and directories.
1043
1078
         */
1099
1134
                        struct server_id server_id,
1100
1135
                        DATA_BLOB *data)
1101
1136
{
 
1137
        struct smbd_server_connection *sconn;
1102
1138
        files_struct *fsp = NULL;
1103
1139
        struct share_mode_entry e;
1104
1140
 
 
1141
        sconn = msg_ctx_to_sconn(msg_ctx);
 
1142
        if (sconn == NULL) {
 
1143
                DEBUG(1, ("could not find sconn\n"));
 
1144
                return;
 
1145
        }
 
1146
 
1105
1147
        message_to_share_mode_entry(&e, (char *)data->data);
1106
1148
 
1107
1149
        if(DEBUGLVL(10)) {
1114
1156
                TALLOC_FREE(sm_str);
1115
1157
        }
1116
1158
 
1117
 
        fsp = file_find_dif(e.id, e.share_file_id);
 
1159
        fsp = file_find_dif(sconn, e.id, e.share_file_id);
1118
1160
        if (!fsp) {
1119
1161
                DEBUG(10,("msg_close_file: failed to find file.\n"));
1120
1162
                return;