~veger/ubuntu/precise/samba/fix-for-902339

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/krb5/fcache.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:
3
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
4
 * All rights reserved.
5
5
 *
 
6
 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
 
7
 *
6
8
 * Redistribution and use in source and binary forms, with or without
7
9
 * modification, are permitted provided that the following conditions
8
10
 * are met:
56
58
 
57
59
#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
58
60
 
59
 
static const char*
 
61
static const char* KRB5_CALLCONV
60
62
fcc_get_name(krb5_context context,
61
63
             krb5_ccache id)
62
64
{
95
97
                               N_("timed out locking cache file %s", "file"),
96
98
                               filename);
97
99
        break;
98
 
    default:
 
100
    default: {
 
101
        char buf[128];
 
102
        rk_strerror_r(ret, buf, sizeof(buf));
99
103
        krb5_set_error_message(context, ret,
100
104
                               N_("error locking cache file %s: %s",
101
 
                                  "file, error"),
102
 
                               filename, strerror(ret));
 
105
                                  "file, error"), filename, buf);
103
106
        break;
104
107
    }
 
108
    }
105
109
    return ret;
106
110
}
107
111
 
127
131
    case EINVAL: /* filesystem doesn't support locking, let the user have it */
128
132
        ret = 0;
129
133
        break;
130
 
    default:
 
134
    default: {
 
135
        char buf[128];
 
136
        rk_strerror_r(ret, buf, sizeof(buf));
131
137
        krb5_set_error_message(context, ret,
132
 
                               N_("Failed to unlock file: %s", ""),
133
 
                               strerror(ret));
 
138
                               N_("Failed to unlock file: %s", ""), buf);
134
139
        break;
135
140
    }
 
141
    }
136
142
    return ret;
137
143
}
138
144
 
161
167
}
162
168
 
163
169
 
164
 
static krb5_error_code
 
170
static krb5_error_code KRB5_CALLCONV
165
171
fcc_lock(krb5_context context, krb5_ccache id,
166
172
         int fd, krb5_boolean exclusive)
167
173
{
168
174
    return _krb5_xlock(context, fd, exclusive, fcc_get_name(context, id));
169
175
}
170
176
 
171
 
static krb5_error_code
 
177
static krb5_error_code KRB5_CALLCONV
172
178
fcc_unlock(krb5_context context, int fd)
173
179
{
174
180
    return _krb5_xunlock(context, fd);
175
181
}
176
182
 
177
 
static krb5_error_code
 
183
static krb5_error_code KRB5_CALLCONV
178
184
fcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
179
185
{
180
186
    krb5_fcache *f;
220
226
            return errno;
221
227
        pos -= tmp;
222
228
    }
 
229
#ifdef _MSC_VER
 
230
    _commit (fd);
 
231
#else
223
232
    fsync (fd);
 
233
#endif
224
234
    return 0;
225
235
}
226
236
 
294
304
    return ret;
295
305
}
296
306
 
297
 
static krb5_error_code
 
307
static krb5_error_code KRB5_CALLCONV
298
308
fcc_gen_new(krb5_context context, krb5_ccache *id)
299
309
{
 
310
    char *file = NULL, *exp_file = NULL;
 
311
    krb5_error_code ret;
300
312
    krb5_fcache *f;
301
313
    int fd;
302
 
    char *file;
303
314
 
304
315
    f = malloc(sizeof(*f));
305
316
    if(f == NULL) {
307
318
                               N_("malloc: out of memory", ""));
308
319
        return KRB5_CC_NOMEM;
309
320
    }
310
 
    asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
311
 
    if(file == NULL) {
 
321
    ret = asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
 
322
    if(ret < 0 || file == NULL) {
312
323
        free(f);
313
324
        krb5_set_error_message(context, KRB5_CC_NOMEM,
314
325
                               N_("malloc: out of memory", ""));
315
326
        return KRB5_CC_NOMEM;
316
327
    }
317
 
    fd = mkstemp(file);
 
328
    ret = _krb5_expand_path_tokens(context, file, &exp_file);
 
329
    free(file);
 
330
    if (ret)
 
331
        return ret;
 
332
 
 
333
    file = exp_file;
 
334
 
 
335
    fd = mkstemp(exp_file);
318
336
    if(fd < 0) {
319
337
        int ret = errno;
320
 
        krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), file);
 
338
        krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), exp_file);
321
339
        free(f);
322
 
        free(file);
 
340
        free(exp_file);
323
341
        return ret;
324
342
    }
325
343
    close(fd);
326
 
    f->filename = file;
 
344
    f->filename = exp_file;
327
345
    f->version = 0;
328
346
    (*id)->data.data = f;
329
347
    (*id)->data.length = sizeof(*f);
355
373
    krb5_storage_set_flags(sp, flags);
356
374
}
357
375
 
358
 
static krb5_error_code
 
376
static krb5_error_code KRB5_CALLCONV
359
377
fcc_open(krb5_context context,
360
378
         krb5_ccache id,
361
379
         int *fd_ret,
369
387
    int fd;
370
388
    fd = open(filename, flags, mode);
371
389
    if(fd < 0) {
 
390
        char buf[128];
372
391
        ret = errno;
 
392
        rk_strerror_r(ret, buf, sizeof(buf));
373
393
        krb5_set_error_message(context, ret, N_("open(%s): %s", "file, error"),
374
 
                               filename, strerror(ret));
 
394
                               filename, buf);
375
395
        return ret;
376
396
    }
377
397
    rk_cloexec(fd);
384
404
    return 0;
385
405
}
386
406
 
387
 
static krb5_error_code
 
407
static krb5_error_code KRB5_CALLCONV
388
408
fcc_initialize(krb5_context context,
389
409
               krb5_ccache id,
390
410
               krb5_principal primary_principal)
431
451
    fcc_unlock(context, fd);
432
452
    if (close(fd) < 0)
433
453
        if (ret == 0) {
 
454
            char buf[128];
434
455
            ret = errno;
 
456
            rk_strerror_r(ret, buf, sizeof(buf));
435
457
            krb5_set_error_message (context, ret, N_("close %s: %s", ""),
436
 
                                    FILENAME(id), strerror(ret));
 
458
                                    FILENAME(id), buf);
437
459
        }
438
460
    return ret;
439
461
}
440
462
 
441
 
static krb5_error_code
 
463
static krb5_error_code KRB5_CALLCONV
442
464
fcc_close(krb5_context context,
443
465
          krb5_ccache id)
444
466
{
447
469
    return 0;
448
470
}
449
471
 
450
 
static krb5_error_code
 
472
static krb5_error_code KRB5_CALLCONV
451
473
fcc_destroy(krb5_context context,
452
474
            krb5_ccache id)
453
475
{
455
477
    return 0;
456
478
}
457
479
 
458
 
static krb5_error_code
 
480
static krb5_error_code KRB5_CALLCONV
459
481
fcc_store_cred(krb5_context context,
460
482
               krb5_ccache id,
461
483
               krb5_creds *creds)
485
507
    fcc_unlock(context, fd);
486
508
    if (close(fd) < 0) {
487
509
        if (ret == 0) {
 
510
            char buf[128];
 
511
            rk_strerror_r(ret, buf, sizeof(buf));
488
512
            ret = errno;
489
513
            krb5_set_error_message (context, ret, N_("close %s: %s", ""),
490
 
                                    FILENAME(id), strerror(ret));
 
514
                                    FILENAME(id), buf);
491
515
        }
492
516
    }
493
517
    return ret;
497
521
init_fcc (krb5_context context,
498
522
          krb5_ccache id,
499
523
          krb5_storage **ret_sp,
500
 
          int *ret_fd)
 
524
          int *ret_fd,
 
525
          krb5_deltat *kdc_offset)
501
526
{
502
527
    int fd;
503
528
    int8_t pvno, tag;
504
529
    krb5_storage *sp;
505
530
    krb5_error_code ret;
506
531
 
 
532
    if (kdc_offset)
 
533
        *kdc_offset = 0;
 
534
 
507
535
    ret = fcc_open(context, id, &fd, O_RDONLY | O_BINARY | O_CLOEXEC, 0);
508
536
    if(ret)
509
537
        return ret;
579
607
                goto out;
580
608
            }
581
609
            switch (dtag) {
582
 
            case FCC_TAG_DELTATIME :
583
 
                ret = krb5_ret_int32 (sp, &context->kdc_sec_offset);
 
610
            case FCC_TAG_DELTATIME : {
 
611
                int32_t offset;
 
612
 
 
613
                ret = krb5_ret_int32 (sp, &offset);
 
614
                ret |= krb5_ret_int32 (sp, &context->kdc_usec_offset);
584
615
                if(ret) {
585
616
                    ret = KRB5_CC_FORMAT;
586
617
                    krb5_set_error_message(context, ret,
589
620
                                           FILENAME(id));
590
621
                    goto out;
591
622
                }
592
 
                ret = krb5_ret_int32 (sp, &context->kdc_usec_offset);
593
 
                if(ret) {
594
 
                    ret = KRB5_CC_FORMAT;
595
 
                    krb5_set_error_message(context, ret,
596
 
                                           N_("Error reading kdc_usec in "
597
 
                                              "cache file: %s", ""),
598
 
                                           FILENAME(id));
599
 
                    goto out;
600
 
                }
 
623
                context->kdc_sec_offset = offset;
 
624
                if (kdc_offset)
 
625
                    *kdc_offset = offset;
601
626
                break;
 
627
            }
602
628
            default :
603
629
                for (i = 0; i < data_len; ++i) {
604
630
                    ret = krb5_ret_int8 (sp, &dummy);
641
667
    return ret;
642
668
}
643
669
 
644
 
static krb5_error_code
 
670
static krb5_error_code KRB5_CALLCONV
645
671
fcc_get_principal(krb5_context context,
646
672
                  krb5_ccache id,
647
673
                  krb5_principal *principal)
650
676
    int fd;
651
677
    krb5_storage *sp;
652
678
 
653
 
    ret = init_fcc (context, id, &sp, &fd);
 
679
    ret = init_fcc (context, id, &sp, &fd, NULL);
654
680
    if (ret)
655
681
        return ret;
656
682
    ret = krb5_ret_principal(sp, principal);
662
688
    return ret;
663
689
}
664
690
 
665
 
static krb5_error_code
 
691
static krb5_error_code KRB5_CALLCONV
666
692
fcc_end_get (krb5_context context,
667
693
             krb5_ccache id,
668
694
             krb5_cc_cursor *cursor);
669
695
 
670
 
static krb5_error_code
 
696
static krb5_error_code KRB5_CALLCONV
671
697
fcc_get_first (krb5_context context,
672
698
               krb5_ccache id,
673
699
               krb5_cc_cursor *cursor)
683
709
    memset(*cursor, 0, sizeof(struct fcc_cursor));
684
710
 
685
711
    ret = init_fcc (context, id, &FCC_CURSOR(*cursor)->sp,
686
 
                    &FCC_CURSOR(*cursor)->fd);
 
712
                    &FCC_CURSOR(*cursor)->fd, NULL);
687
713
    if (ret) {
688
714
        free(*cursor);
689
715
        *cursor = NULL;
700
726
    return 0;
701
727
}
702
728
 
703
 
static krb5_error_code
 
729
static krb5_error_code KRB5_CALLCONV
704
730
fcc_get_next (krb5_context context,
705
731
              krb5_ccache id,
706
732
              krb5_cc_cursor *cursor,
718
744
    return ret;
719
745
}
720
746
 
721
 
static krb5_error_code
 
747
static krb5_error_code KRB5_CALLCONV
722
748
fcc_end_get (krb5_context context,
723
749
             krb5_ccache id,
724
750
             krb5_cc_cursor *cursor)
730
756
    return 0;
731
757
}
732
758
 
733
 
static krb5_error_code
 
759
static krb5_error_code KRB5_CALLCONV
734
760
fcc_remove_cred(krb5_context context,
735
761
                 krb5_ccache id,
736
762
                 krb5_flags which,
738
764
{
739
765
    krb5_error_code ret;
740
766
    krb5_ccache copy, newfile;
741
 
    char *newname;
 
767
    char *newname = NULL;
742
768
    int fd;
743
769
 
744
770
    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &copy);
757
783
        return ret;
758
784
    }
759
785
 
760
 
    asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id));
761
 
    if (newname == NULL) {
 
786
    ret = asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id));
 
787
    if (ret < 0 || newname == NULL) {
762
788
        krb5_cc_destroy(context, copy);
763
 
        return ret;
 
789
        return ENOMEM;
764
790
    }
765
791
 
766
792
    fd = mkstemp(&newname[5]);
787
813
        return ret;
788
814
    }
789
815
 
790
 
    ret = rename(&newname[5], FILENAME(id));
 
816
    ret = rk_rename(&newname[5], FILENAME(id));
791
817
    if (ret)
792
818
        ret = errno;
793
819
    free(newname);
796
822
    return ret;
797
823
}
798
824
 
799
 
static krb5_error_code
 
825
static krb5_error_code KRB5_CALLCONV
800
826
fcc_set_flags(krb5_context context,
801
827
              krb5_ccache id,
802
828
              krb5_flags flags)
804
830
    return 0; /* XXX */
805
831
}
806
832
 
807
 
static int
 
833
static int KRB5_CALLCONV
808
834
fcc_get_version(krb5_context context,
809
835
                krb5_ccache id)
810
836
{
815
841
    int first;
816
842
};
817
843
 
818
 
static krb5_error_code
 
844
static krb5_error_code KRB5_CALLCONV
819
845
fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
820
846
{
821
847
    struct fcache_iter *iter;
830
856
    return 0;
831
857
}
832
858
 
833
 
static krb5_error_code
 
859
static krb5_error_code KRB5_CALLCONV
834
860
fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
835
861
{
836
862
    struct fcache_iter *iter = cursor;
853
879
            return ret;
854
880
        fn = expandedfn;
855
881
    }
 
882
    /* check if file exists, don't return a non existant "next" */
 
883
    if (strncasecmp(fn, "FILE:", 5) == 0) {
 
884
        struct stat sb;
 
885
        ret = stat(fn + 5, &sb);
 
886
        if (ret) {
 
887
            ret = KRB5_CC_END;
 
888
            goto out;
 
889
        }
 
890
    }
856
891
    ret = krb5_cc_resolve(context, fn, id);
 
892
 out:
857
893
    if (expandedfn)
858
894
        free(expandedfn);
859
895
 
860
896
    return ret;
861
897
}
862
898
 
863
 
static krb5_error_code
 
899
static krb5_error_code KRB5_CALLCONV
864
900
fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
865
901
{
866
902
    struct fcache_iter *iter = cursor;
868
904
    return 0;
869
905
}
870
906
 
871
 
static krb5_error_code
 
907
static krb5_error_code KRB5_CALLCONV
872
908
fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
873
909
{
874
910
    krb5_error_code ret = 0;
875
911
 
876
 
    ret = rename(FILENAME(from), FILENAME(to));
 
912
    ret = rk_rename(FILENAME(from), FILENAME(to));
 
913
 
877
914
    if (ret && errno != EXDEV) {
 
915
        char buf[128];
878
916
        ret = errno;
 
917
        rk_strerror_r(ret, buf, sizeof(buf));
879
918
        krb5_set_error_message(context, ret,
880
919
                               N_("Rename of file from %s "
881
920
                                  "to %s failed: %s", ""),
882
 
                               FILENAME(from), FILENAME(to),
883
 
                               strerror(ret));
 
921
                               FILENAME(from), FILENAME(to), buf);
884
922
        return ret;
885
923
    } else if (ret && errno == EXDEV) {
886
924
        /* make a copy and delete the orignal */
936
974
    {
937
975
        krb5_storage *sp;
938
976
        int fd;
939
 
        ret = init_fcc (context, to, &sp, &fd);
940
 
        if (sp)
941
 
            krb5_storage_free(sp);
942
 
        fcc_unlock(context, fd);
943
 
        close(fd);
 
977
        if ((ret = init_fcc (context, to, &sp, &fd, NULL)) == 0) {
 
978
            if (sp)
 
979
                krb5_storage_free(sp);
 
980
            fcc_unlock(context, fd);
 
981
            close(fd);
 
982
        }
944
983
    }
945
984
 
946
 
    fcc_destroy(context, from);
 
985
    fcc_close(context, from);
947
986
 
948
987
    return ret;
949
988
}
950
989
 
951
 
static krb5_error_code
 
990
static krb5_error_code KRB5_CALLCONV
952
991
fcc_get_default_name(krb5_context context, char **str)
953
992
{
954
993
    return _krb5_expand_default_cc_name(context,
956
995
                                        str);
957
996
}
958
997
 
959
 
static krb5_error_code
 
998
static krb5_error_code KRB5_CALLCONV
960
999
fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
961
1000
{
962
1001
    krb5_error_code ret;
977
1016
    return 0;
978
1017
}
979
1018
 
 
1019
static krb5_error_code KRB5_CALLCONV
 
1020
fcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
 
1021
{
 
1022
    return 0;
 
1023
}
 
1024
 
 
1025
static krb5_error_code KRB5_CALLCONV
 
1026
fcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset)
 
1027
{
 
1028
    krb5_error_code ret;
 
1029
    krb5_storage *sp = NULL;
 
1030
    int fd;
 
1031
    ret = init_fcc(context, id, &sp, &fd, kdc_offset);
 
1032
    if (sp)
 
1033
        krb5_storage_free(sp);
 
1034
    fcc_unlock(context, fd);
 
1035
    close(fd);
 
1036
 
 
1037
    return ret;
 
1038
}
 
1039
 
 
1040
 
980
1041
/**
981
1042
 * Variable containing the FILE based credential cache implemention.
982
1043
 *
1007
1068
    fcc_move,
1008
1069
    fcc_get_default_name,
1009
1070
    NULL,
1010
 
    fcc_lastchange
 
1071
    fcc_lastchange,
 
1072
    fcc_set_kdc_offset,
 
1073
    fcc_get_kdc_offset
1011
1074
};