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

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/krb5/krbhst.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:
86
86
    snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
87
87
 
88
88
    r = rk_dns_lookup(domain, dns_type);
89
 
    if(r == NULL)
 
89
    if(r == NULL) {
 
90
        _krb5_debug(context, 0,
 
91
                    "DNS lookup failed domain: %s", domain);
90
92
        return KRB5_KDC_UNREACH;
 
93
    }
91
94
 
92
95
    for(num_srv = 0, rr = r->head; rr; rr = rr->next)
93
96
        if(rr->type == rk_ns_t_srv)
176
179
    return KRB5_KRBHST_UDP;
177
180
}
178
181
 
 
182
/*
 
183
 *
 
184
 */
 
185
 
 
186
const char *
 
187
_krb5_krbhst_get_realm(krb5_krbhst_handle handle)
 
188
{
 
189
    return handle->realm;
 
190
}
179
191
 
180
192
/*
181
193
 * parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port'
186
198
parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,
187
199
               const char *spec, int def_port, int port)
188
200
{
189
 
    const char *p = spec;
 
201
    const char *p = spec, *q;
190
202
    struct krb5_krbhst_info *hi;
191
203
 
192
204
    hi = calloc(1, sizeof(*hi) + strlen(spec));
209
221
        p += 4;
210
222
    }
211
223
 
212
 
    if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
 
224
    if (p[0] == '[' && (q = strchr(p, ']')) != NULL) {
 
225
        /* if address looks like [foo:bar] or [foo:bar]: its a ipv6
 
226
           adress, strip of [] */
 
227
        memcpy(hi->hostname, &p[1], q - p - 1);
 
228
        hi->hostname[q - p - 1] = '\0';
 
229
        p = q + 1;
 
230
        /* get trailing : */
 
231
        if (p[0] == ':')
 
232
            p++;
 
233
    } else if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
 
234
        /* copy everything before : */
213
235
        free(hi);
214
236
        return NULL;
215
237
    }
218
240
    strlwr(hi->hostname);
219
241
 
220
242
    hi->port = hi->def_port = def_port;
221
 
    if(p != NULL) {
 
243
    if(p != NULL && p[0]) {
222
244
        char *end;
223
245
        hi->port = strtol(p, &end, 0);
224
246
        if(end == p) {
298
320
 * return a readable representation of `host' in `hostname, hostlen'
299
321
 */
300
322
 
301
 
krb5_error_code KRB5_LIB_FUNCTION
 
323
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
302
324
krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,
303
325
                          char *hostname, size_t hostlen)
304
326
{
334
356
    }
335
357
}
336
358
 
337
 
/*
338
 
 * return an `struct addrinfo *' in `ai' corresponding to the information
339
 
 * in `host'.  free:ing is handled by krb5_krbhst_free.
 
359
/**
 
360
 * Return an `struct addrinfo *' for a KDC host.
 
361
 *
 
362
 * Returns an the struct addrinfo in in that corresponds to the
 
363
 * information in `host'.  free:ing is handled by krb5_krbhst_free, so
 
364
 * the returned ai must not be released.
 
365
 *
 
366
 * @ingroup krb5
340
367
 */
341
368
 
342
 
krb5_error_code KRB5_LIB_FUNCTION
 
369
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
343
370
krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
344
371
                         struct addrinfo **ai)
345
372
{
346
 
    struct addrinfo hints;
347
 
    char portstr[NI_MAXSERV];
348
 
    int ret;
 
373
    int ret = 0;
349
374
 
350
375
    if (host->ai == NULL) {
 
376
        struct addrinfo hints;
 
377
        char portstr[NI_MAXSERV];
 
378
        char *hostname = host->hostname;
 
379
 
 
380
        snprintf (portstr, sizeof(portstr), "%d", host->port);
351
381
        make_hints(&hints, host->proto);
352
 
        snprintf (portstr, sizeof(portstr), "%d", host->port);
 
382
 
 
383
        /**
 
384
         * First try this as an IP address, this allows us to add a
 
385
         * dot at the end to stop using the search domains.
 
386
         */
 
387
 
 
388
        hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
 
389
 
353
390
        ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
354
 
        if (ret)
355
 
            return krb5_eai_to_heim_errno(ret, errno);
 
391
        if (ret == 0)
 
392
            goto out;
 
393
 
 
394
        /**
 
395
         * If the hostname contains a dot, assumes it's a FQDN and
 
396
         * don't use search domains since that might be painfully slow
 
397
         * when machine is disconnected from that network.
 
398
         */
 
399
 
 
400
        hints.ai_flags &= ~(AI_NUMERICHOST);
 
401
 
 
402
        if (strchr(hostname, '.') && hostname[strlen(hostname) - 1] != '.') {
 
403
            ret = asprintf(&hostname, "%s.", host->hostname);
 
404
            if (ret < 0 || hostname == NULL)
 
405
                return ENOMEM;
 
406
        }
 
407
 
 
408
        ret = getaddrinfo(hostname, portstr, &hints, &host->ai);
 
409
        if (hostname != host->hostname)
 
410
            free(hostname);
 
411
        if (ret) {
 
412
            ret = krb5_eai_to_heim_errno(ret, errno);
 
413
            goto out;
 
414
        }
356
415
    }
 
416
 out:
357
417
    *ai = host->ai;
358
 
    return 0;
 
418
    return ret;
359
419
}
360
420
 
361
421
static krb5_boolean
374
434
srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
375
435
              const char *proto, const char *service)
376
436
{
 
437
    krb5_error_code ret;
377
438
    krb5_krbhst_info **res;
378
439
    int count, i;
379
440
 
380
 
    if (srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
381
 
                       kd->port))
 
441
    ret = srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
 
442
                         kd->port);
 
443
    _krb5_debug(context, 2, "searching DNS for realm %s %s.%s -> %d",
 
444
                kd->realm, proto, service, ret);
 
445
    if (ret)
382
446
        return;
383
447
    for(i = 0; i < count; i++)
384
448
        append_host_hostinfo(kd, res[i]);
395
459
                 const char *conf_string)
396
460
{
397
461
    int i;
398
 
        
399
462
    char **hostlist;
400
463
    hostlist = krb5_config_get_strings(context, NULL,
401
464
                                       "realms", kd->realm, conf_string, NULL);
402
465
 
 
466
    _krb5_debug(context, 2, "configuration file for realm %s%s found",
 
467
                kd->realm, hostlist ? "" : " not");
 
468
 
403
469
    if(hostlist == NULL)
404
470
        return;
405
471
    kd->flags |= KD_CONFIG_EXISTS;
420
486
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
421
487
                   const char *serv_string, int port, int proto)
422
488
{
423
 
    char *host;
 
489
    char *host = NULL;
424
490
    int ret;
425
491
    struct addrinfo *ai;
426
492
    struct addrinfo hints;
427
493
    char portstr[NI_MAXSERV];
428
494
 
 
495
    _krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)",
 
496
                kd->fallback_count, kd->realm, serv_string);
 
497
 
429
498
    /*
430
499
     * Don't try forever in case the DNS server keep returning us
431
500
     * entries (like wildcard entries or the .nu TLD)
436
505
    }
437
506
 
438
507
    if(kd->fallback_count == 0)
439
 
        asprintf(&host, "%s.%s.", serv_string, kd->realm);
 
508
        ret = asprintf(&host, "%s.%s.", serv_string, kd->realm);
440
509
    else
441
 
        asprintf(&host, "%s-%d.%s.",
442
 
                 serv_string, kd->fallback_count, kd->realm);   
 
510
        ret = asprintf(&host, "%s-%d.%s.",
 
511
                       serv_string, kd->fallback_count, kd->realm);     
443
512
 
444
 
    if (host == NULL)
 
513
    if (ret < 0 || host == NULL)
445
514
        return ENOMEM;
446
515
 
447
516
    make_hints(&hints, proto);
545
614
                                   N_("Locate plugin failed to lookup realm %s: %d", ""),
546
615
                                   kd->realm, ret);
547
616
            break;
548
 
        } else if (ret == 0)
 
617
        } else if (ret == 0) {
 
618
            _krb5_debug(context, 2, "plugin found result for realm %s", kd->realm);
549
619
            kd->flags |= KD_CONFIG_EXISTS;
 
620
        }
550
621
 
551
622
    }
552
623
    _krb5_plugin_free(list);
577
648
            return 0;
578
649
    }
579
650
 
580
 
    if (kd->flags & KD_CONFIG_EXISTS)
581
 
        return KRB5_KDC_UNREACH; /* XXX */
 
651
    if (kd->flags & KD_CONFIG_EXISTS) {
 
652
        _krb5_debug(context, 1,
 
653
                    "Configuration exists for realm %s, wont go to DNS",
 
654
                    kd->realm);
 
655
        return KRB5_KDC_UNREACH;
 
656
    }
582
657
 
583
658
    if(context->srv_lookup) {
584
659
        if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) {
612
687
            return 0;
613
688
    }
614
689
 
 
690
    _krb5_debug(context, 0, "No KDC entries found for %s", kd->realm);
 
691
 
615
692
    return KRB5_KDC_UNREACH; /* XXX */
616
693
}
617
694
 
636
713
            return 0;
637
714
    }
638
715
 
639
 
    if (kd->flags & KD_CONFIG_EXISTS)
640
 
        return KRB5_KDC_UNREACH; /* XXX */
 
716
    if (kd->flags & KD_CONFIG_EXISTS) {
 
717
        _krb5_debug(context, 1,
 
718
                    "Configuration exists for realm %s, wont go to DNS",
 
719
                    kd->realm);
 
720
        return KRB5_KDC_UNREACH;
 
721
    }
641
722
 
642
723
    if(context->srv_lookup) {
643
724
        if((kd->flags & KD_SRV_TCP) == 0) {
660
741
            return 0;
661
742
    }
662
743
 
 
744
    _krb5_debug(context, 0, "No admin entries found for realm %s", kd->realm);
 
745
 
663
746
    return KRB5_KDC_UNREACH;    /* XXX */
664
747
}
665
748
 
684
767
            return 0;
685
768
    }
686
769
 
687
 
    if (kd->flags & KD_CONFIG_EXISTS)
688
 
        return KRB5_KDC_UNREACH; /* XXX */
 
770
    if (kd->flags & KD_CONFIG_EXISTS) {
 
771
        _krb5_debug(context, 1,
 
772
                    "Configuration exists for realm %s, wont go to DNS",
 
773
                    kd->realm);
 
774
        return KRB5_KDC_UNREACH;
 
775
    }
689
776
 
690
777
    if(context->srv_lookup) {
691
778
        if((kd->flags & KD_SRV_UDP) == 0) {
714
801
        return ret;
715
802
    }
716
803
 
717
 
    return KRB5_KDC_UNREACH; /* XXX */
 
804
    _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm);
 
805
 
 
806
    return KRB5_KDC_UNREACH;
718
807
}
719
808
 
720
809
static krb5_error_code
736
825
        kd->flags |= KD_CONFIG;
737
826
    }
738
827
 
739
 
    if (kd->flags & KD_CONFIG_EXISTS)
740
 
        return KRB5_KDC_UNREACH; /* XXX */
 
828
    if (kd->flags & KD_CONFIG_EXISTS) {
 
829
        _krb5_debug(context, 1,
 
830
                    "Configuration exists for realm %s, wont go to DNS",
 
831
                    kd->realm);
 
832
        return KRB5_KDC_UNREACH;
 
833
    }
741
834
 
742
835
    if(context->srv_lookup) {
743
836
        if((kd->flags & KD_SRV_UDP) == 0) {
764
857
        return (*kd->get_next)(context, kd, host);
765
858
    }
766
859
 
767
 
    return KRB5_KDC_UNREACH; /* XXX */
 
860
    _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm);
 
861
 
 
862
    return KRB5_KDC_UNREACH;
768
863
}
769
864
 
770
865
static struct krb5_krbhst_data*
771
866
common_init(krb5_context context,
 
867
            const char *service,
772
868
            const char *realm,
773
869
            int flags)
774
870
{
782
878
        return NULL;
783
879
    }
784
880
 
 
881
    _krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x",
 
882
                service, realm, flags);
 
883
 
785
884
    /* For 'realms' without a . do not even think of going to DNS */
786
885
    if (!strchr(realm, '.'))
787
886
        kd->flags |= KD_CONFIG_EXISTS;
796
895
 * initialize `handle' to look for hosts of type `type' in realm `realm'
797
896
 */
798
897
 
799
 
krb5_error_code KRB5_LIB_FUNCTION
 
898
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
800
899
krb5_krbhst_init(krb5_context context,
801
900
                 const char *realm,
802
901
                 unsigned int type,
805
904
    return krb5_krbhst_init_flags(context, realm, type, 0, handle);
806
905
}
807
906
 
808
 
krb5_error_code KRB5_LIB_FUNCTION
 
907
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
809
908
krb5_krbhst_init_flags(krb5_context context,
810
909
                       const char *realm,
811
910
                       unsigned int type,
816
915
    krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,
817
916
                            krb5_krbhst_info **);
818
917
    int def_port;
 
918
    const char *service;
819
919
 
820
920
    switch(type) {
821
921
    case KRB5_KRBHST_KDC:
822
922
        next = kdc_get_next;
823
923
        def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
 
924
        service = "kdc";
824
925
        break;
825
926
    case KRB5_KRBHST_ADMIN:
826
927
        next = admin_get_next;
827
928
        def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
828
929
                                             "tcp", 749));
 
930
        service = "admin";
829
931
        break;
830
932
    case KRB5_KRBHST_CHANGEPW:
831
933
        next = kpasswd_get_next;
832
934
        def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
833
935
                                             KPASSWD_PORT));
 
936
        service = "change_password";
834
937
        break;
835
938
    case KRB5_KRBHST_KRB524:
836
939
        next = krb524_get_next;
837
940
        def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
 
941
        service = "524";
838
942
        break;
839
943
    default:
840
944
        krb5_set_error_message(context, ENOTTY,
841
945
                               N_("unknown krbhst type (%u)", ""), type);
842
946
        return ENOTTY;
843
947
    }
844
 
    if((kd = common_init(context, realm, flags)) == NULL)
 
948
    if((kd = common_init(context, service, realm, flags)) == NULL)
845
949
        return ENOMEM;
846
950
    kd->get_next = next;
847
951
    kd->def_port = def_port;
853
957
 * return the next host information from `handle' in `host'
854
958
 */
855
959
 
856
 
krb5_error_code KRB5_LIB_FUNCTION
 
960
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
857
961
krb5_krbhst_next(krb5_context context,
858
962
                 krb5_krbhst_handle handle,
859
963
                 krb5_krbhst_info **host)
869
973
 * in `hostname' (or length `hostlen)
870
974
 */
871
975
 
872
 
krb5_error_code KRB5_LIB_FUNCTION
 
976
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
873
977
krb5_krbhst_next_as_string(krb5_context context,
874
978
                           krb5_krbhst_handle handle,
875
979
                           char *hostname,
884
988
}
885
989
 
886
990
 
887
 
void KRB5_LIB_FUNCTION
 
991
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
888
992
krb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle)
889
993
{
890
994
    handle->index = &handle->hosts;
891
995
}
892
996
 
893
 
void KRB5_LIB_FUNCTION
 
997
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
894
998
krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)
895
999
{
896
1000
    krb5_krbhst_info *h, *next;
955
1059
 * return an malloced list of kadmin-hosts for `realm' in `hostlist'
956
1060
 */
957
1061
 
958
 
krb5_error_code KRB5_LIB_FUNCTION
 
1062
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
959
1063
krb5_get_krb_admin_hst (krb5_context context,
960
1064
                        const krb5_realm *realm,
961
1065
                        char ***hostlist)
967
1071
 * return an malloced list of changepw-hosts for `realm' in `hostlist'
968
1072
 */
969
1073
 
970
 
krb5_error_code KRB5_LIB_FUNCTION
 
1074
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
971
1075
krb5_get_krb_changepw_hst (krb5_context context,
972
1076
                           const krb5_realm *realm,
973
1077
                           char ***hostlist)
979
1083
 * return an malloced list of 524-hosts for `realm' in `hostlist'
980
1084
 */
981
1085
 
982
 
krb5_error_code KRB5_LIB_FUNCTION
 
1086
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
983
1087
krb5_get_krb524hst (krb5_context context,
984
1088
                    const krb5_realm *realm,
985
1089
                    char ***hostlist)
992
1096
 * return an malloced list of KDC's for `realm' in `hostlist'
993
1097
 */
994
1098
 
995
 
krb5_error_code KRB5_LIB_FUNCTION
 
1099
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
996
1100
krb5_get_krbhst (krb5_context context,
997
1101
                 const krb5_realm *realm,
998
1102
                 char ***hostlist)
1004
1108
 * free all the memory allocated in `hostlist'
1005
1109
 */
1006
1110
 
1007
 
krb5_error_code KRB5_LIB_FUNCTION
 
1111
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1008
1112
krb5_free_krbhst (krb5_context context,
1009
1113
                  char **hostlist)
1010
1114
{