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

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/roken/resolve.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:
48
48
 
49
49
#include <assert.h>
50
50
 
51
 
RCSID("$Id$");
52
 
 
53
51
#ifdef _AIX /* AIX have broken res_nsearch() in 5.1 (5.0 also ?) */
54
52
#undef HAVE_RES_NSEARCH
55
53
#endif
80
78
 
81
79
int _resolve_debug = 0;
82
80
 
83
 
int ROKEN_LIB_FUNCTION
 
81
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
84
82
rk_dns_string_to_type(const char *name)
85
83
{
86
84
    struct stot *p = stot;
90
88
    return -1;
91
89
}
92
90
 
93
 
const char * ROKEN_LIB_FUNCTION
 
91
ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL
94
92
rk_dns_type_to_string(int type)
95
93
{
96
94
    struct stot *p = stot;
100
98
    return NULL;
101
99
}
102
100
 
103
 
#if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
 
101
#if ((defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)) || defined(HAVE_WINDNS)
104
102
 
105
103
static void
106
104
dns_free_rr(struct rk_resource_record *rr)
112
110
    free(rr);
113
111
}
114
112
 
115
 
void ROKEN_LIB_FUNCTION
 
113
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
116
114
rk_dns_free_data(struct rk_dns_reply *r)
117
115
{
118
116
    struct rk_resource_record *rr;
126
124
    free (r);
127
125
}
128
126
 
 
127
#ifndef HAVE_WINDNS
 
128
 
129
129
static int
130
130
parse_record(const unsigned char *data, const unsigned char *end_data,
131
131
             const unsigned char **pp, struct rk_resource_record **ret_rr)
523
523
{
524
524
    struct rk_dns_reply *r;
525
525
    void *reply = NULL;
526
 
    int size;
527
 
    int len;
 
526
    int size, len;
528
527
#if defined(HAVE_DNS_SEARCH)
529
528
    struct sockaddr_storage from;
530
529
    uint32_t fromsize = sizeof(from);
542
541
        return NULL; /* is this the best we can do? */
543
542
#endif
544
543
 
545
 
    size = 0;
546
 
    len = 1000;
547
 
    do {
 
544
    len = 1500;
 
545
    while(1) {
548
546
        if (reply) {
549
547
            free(reply);
550
548
            reply = NULL;
551
549
        }
552
 
        if (size <= len)
553
 
            size = len;
554
550
        if (_resolve_debug) {
555
551
#if defined(HAVE_DNS_SEARCH)
556
552
            dns_set_debug(handle, 1);
558
554
            state.options |= RES_DEBUG;
559
555
#endif
560
556
            fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain,
561
 
                    rr_class, rk_dns_type_to_string(rr_type), size);
 
557
                    rr_class, rk_dns_type_to_string(rr_type), len);
562
558
        }
563
 
        reply = malloc(size);
 
559
        reply = malloc(len);
564
560
        if (reply == NULL) {
565
561
            resolve_free_handle(handle);
566
562
            return NULL;
567
563
        }
568
564
 
569
 
        len = resolve_search(handle, domain, rr_class, rr_type, reply, size);
 
565
        size = resolve_search(handle, domain, rr_class, rr_type, reply, len);
570
566
 
571
567
        if (_resolve_debug) {
572
568
            fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
573
 
                    domain, rr_class, rk_dns_type_to_string(rr_type), len);
 
569
                    domain, rr_class, rk_dns_type_to_string(rr_type), size);
574
570
        }
575
 
        if (len <= 0) {
 
571
        if (size > len) {
 
572
            /* resolver thinks it know better, go for it */
 
573
            len = size;
 
574
        } else if (size > 0) {
 
575
            /* got a good reply */
 
576
            break;
 
577
        } else if (size <= 0 && len < rk_DNS_MAX_PACKET_SIZE) {
 
578
            len *= 2;
 
579
            if (len > rk_DNS_MAX_PACKET_SIZE)
 
580
                len = rk_DNS_MAX_PACKET_SIZE;
 
581
        } else {
 
582
            /* the end, leave */
576
583
            resolve_free_handle(handle);
577
584
            free(reply);
578
585
            return NULL;
579
586
        }
580
 
    } while (size < len && len < rk_DNS_MAX_PACKET_SIZE);
581
 
    resolve_free_handle(handle);
 
587
    }
582
588
 
583
589
    len = min(len, size);
584
590
    r = parse_reply(reply, len);
586
592
    return r;
587
593
}
588
594
 
589
 
struct rk_dns_reply * ROKEN_LIB_FUNCTION
 
595
ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL
590
596
rk_dns_lookup(const char *domain, const char *type_name)
591
597
{
592
598
    int type;
601
607
    return dns_lookup_int(domain, rk_ns_c_in, type);
602
608
}
603
609
 
 
610
#endif  /* !HAVE_WINDNS */
 
611
 
604
612
static int
605
613
compare_srv(const void *a, const void *b)
606
614
{
611
619
    return ((*aa)->u.srv->priority - (*bb)->u.srv->priority);
612
620
}
613
621
 
614
 
#ifndef HAVE_RANDOM
615
 
#define random() rand()
616
 
#endif
617
 
 
618
622
/* try to rearrange the srv-records by the algorithm in RFC2782 */
619
 
void ROKEN_LIB_FUNCTION
 
623
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
620
624
rk_dns_srv_order(struct rk_dns_reply *r)
621
625
{
622
626
    struct rk_resource_record **srvs, **ss, **headp;
628
632
    char *oldstate;
629
633
#endif
630
634
 
 
635
    rk_random_init();
 
636
 
631
637
    for(rr = r->head; rr; rr = rr->next)
632
638
        if(rr->type == rk_ns_t_srv)
633
639
            num_srv++;
674
680
        /* ss is now the first record of this priority and ee is the
675
681
           first of the next */
676
682
        while(ss < ee) {
677
 
            rnd = random() % (sum + 1);
 
683
            rnd = rk_random() % (sum + 1);
678
684
            for(count = 0, tt = ss; ; tt++) {
679
685
                if(*tt == NULL)
680
686
                    continue;
704
710
    return;
705
711
}
706
712
 
 
713
#ifdef HAVE_WINDNS
 
714
 
 
715
#include <WinDNS.h>
 
716
 
 
717
static struct rk_resource_record *
 
718
parse_dns_record(PDNS_RECORD pRec)
 
719
{
 
720
    struct rk_resource_record * rr;
 
721
 
 
722
    if (pRec == NULL)
 
723
        return NULL;
 
724
 
 
725
    rr = calloc(1, sizeof(*rr));
 
726
 
 
727
    rr->domain = strdup(pRec->pName);
 
728
    rr->type = pRec->wType;
 
729
    rr->class = 0;
 
730
    rr->ttl = pRec->dwTtl;
 
731
    rr->size = 0;
 
732
 
 
733
    switch (rr->type) {
 
734
    case rk_ns_t_ns:
 
735
    case rk_ns_t_cname:
 
736
    case rk_ns_t_ptr:
 
737
        rr->u.txt = strdup(pRec->Data.NS.pNameHost);
 
738
        if(rr->u.txt == NULL) {
 
739
            dns_free_rr(rr);
 
740
            return NULL;
 
741
        }
 
742
        break;
 
743
 
 
744
    case rk_ns_t_mx:
 
745
    case rk_ns_t_afsdb:{
 
746
        size_t hostlen = strnlen(pRec->Data.MX.pNameExchange, DNS_MAX_NAME_LENGTH);
 
747
 
 
748
        rr->u.mx = (struct mx_record *)malloc(sizeof(struct mx_record) +
 
749
                                              hostlen);
 
750
        if (rr->u.mx == NULL) {
 
751
            dns_free_rr(rr);
 
752
            return NULL;
 
753
        }
 
754
 
 
755
        strcpy_s(rr->u.mx->domain, hostlen + 1, pRec->Data.MX.pNameExchange);
 
756
        rr->u.mx->preference = pRec->Data.MX.wPreference;
 
757
        break;
 
758
    }
 
759
 
 
760
    case rk_ns_t_srv:{
 
761
        size_t hostlen = strnlen(pRec->Data.SRV.pNameTarget, DNS_MAX_NAME_LENGTH);
 
762
 
 
763
        rr->u.srv =
 
764
            (struct srv_record*)malloc(sizeof(struct srv_record) +
 
765
                                       hostlen);
 
766
        if(rr->u.srv == NULL) {
 
767
            dns_free_rr(rr);
 
768
            return NULL;
 
769
        }
 
770
 
 
771
        rr->u.srv->priority = pRec->Data.SRV.wPriority;
 
772
        rr->u.srv->weight = pRec->Data.SRV.wWeight;
 
773
        rr->u.srv->port = pRec->Data.SRV.wPort;
 
774
        strcpy_s(rr->u.srv->target, hostlen + 1, pRec->Data.SRV.pNameTarget);
 
775
 
 
776
        break;
 
777
    }
 
778
 
 
779
    case rk_ns_t_txt:{
 
780
        size_t len;
 
781
 
 
782
        if (pRec->Data.TXT.dwStringCount == 0) {
 
783
            rr->u.txt = strdup("");
 
784
            break;
 
785
        }
 
786
 
 
787
        len = strnlen(pRec->Data.TXT.pStringArray[0], DNS_MAX_TEXT_STRING_LENGTH);
 
788
 
 
789
        rr->u.txt = (char *)malloc(len + 1);
 
790
        strcpy_s(rr->u.txt, len + 1, pRec->Data.TXT.pStringArray[0]);
 
791
 
 
792
        break;
 
793
    }
 
794
 
 
795
    case rk_ns_t_key : {
 
796
        size_t key_len;
 
797
 
 
798
        if (pRec->wDataLength < 4) {
 
799
            dns_free_rr(rr);
 
800
            return NULL;
 
801
        }
 
802
 
 
803
        key_len = pRec->wDataLength - 4;
 
804
        rr->u.key = malloc (sizeof(*rr->u.key) + key_len - 1);
 
805
        if (rr->u.key == NULL) {
 
806
            dns_free_rr(rr);
 
807
            return NULL;
 
808
        }
 
809
 
 
810
        rr->u.key->flags     = pRec->Data.KEY.wFlags;
 
811
        rr->u.key->protocol  = pRec->Data.KEY.chProtocol;
 
812
        rr->u.key->algorithm = pRec->Data.KEY.chAlgorithm;
 
813
        rr->u.key->key_len   = key_len;
 
814
        memcpy_s (rr->u.key->key_data, key_len,
 
815
                  pRec->Data.KEY.Key, key_len);
 
816
        break;
 
817
    }
 
818
 
 
819
    case rk_ns_t_sig : {
 
820
        size_t sig_len, hostlen;
 
821
 
 
822
        if(pRec->wDataLength <= 18) {
 
823
            dns_free_rr(rr);
 
824
            return NULL;
 
825
        }
 
826
 
 
827
        sig_len = pRec->wDataLength;
 
828
 
 
829
        hostlen = strnlen(pRec->Data.SIG.pNameSigner, DNS_MAX_NAME_LENGTH);
 
830
 
 
831
        rr->u.sig = malloc(sizeof(*rr->u.sig)
 
832
                              + hostlen + sig_len);
 
833
        if (rr->u.sig == NULL) {
 
834
            dns_free_rr(rr);
 
835
            return NULL;
 
836
        }
 
837
        rr->u.sig->type           = pRec->Data.SIG.wTypeCovered;
 
838
        rr->u.sig->algorithm      = pRec->Data.SIG.chAlgorithm;
 
839
        rr->u.sig->labels         = pRec->Data.SIG.chLabelCount;
 
840
        rr->u.sig->orig_ttl       = pRec->Data.SIG.dwOriginalTtl;
 
841
        rr->u.sig->sig_expiration = pRec->Data.SIG.dwExpiration;
 
842
        rr->u.sig->sig_inception  = pRec->Data.SIG.dwTimeSigned;
 
843
        rr->u.sig->key_tag        = pRec->Data.SIG.wKeyTag;
 
844
        rr->u.sig->sig_len        = sig_len;
 
845
        memcpy_s (rr->u.sig->sig_data, sig_len,
 
846
                  pRec->Data.SIG.Signature, sig_len);
 
847
        rr->u.sig->signer         = &rr->u.sig->sig_data[sig_len];
 
848
        strcpy_s(rr->u.sig->signer, hostlen + 1, pRec->Data.SIG.pNameSigner);
 
849
        break;
 
850
    }
 
851
 
 
852
#ifdef DNS_TYPE_DS
 
853
    case rk_ns_t_ds: {
 
854
        rr->u.ds = malloc (sizeof(*rr->u.ds) + pRec->Data.DS.wDigestLength - 1);
 
855
        if (rr->u.ds == NULL) {
 
856
            dns_free_rr(rr);
 
857
            return NULL;
 
858
        }
 
859
 
 
860
        rr->u.ds->key_tag     = pRec->Data.DS.wKeyTag;
 
861
        rr->u.ds->algorithm   = pRec->Data.DS.chAlgorithm;
 
862
        rr->u.ds->digest_type = pRec->Data.DS.chDigestType;
 
863
        rr->u.ds->digest_len  = pRec->Data.DS.wDigestLength;
 
864
        memcpy_s (rr->u.ds->digest_data, pRec->Data.DS.wDigestLength,
 
865
                  pRec->Data.DS.Digest, pRec->Data.DS.wDigestLength);
 
866
        break;
 
867
    }
 
868
#endif
 
869
 
 
870
    default:
 
871
        dns_free_rr(rr);
 
872
        return NULL;
 
873
    }
 
874
 
 
875
    rr->next = parse_dns_record(pRec->pNext);
 
876
    return rr;
 
877
}
 
878
 
 
879
ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL
 
880
rk_dns_lookup(const char *domain, const char *type_name)
 
881
{
 
882
    DNS_STATUS status;
 
883
    int type;
 
884
    PDNS_RECORD pRec = NULL;
 
885
    struct rk_dns_reply * r = NULL;
 
886
 
 
887
    __try {
 
888
 
 
889
        type = rk_dns_string_to_type(type_name);
 
890
        if(type == -1) {
 
891
            if(_resolve_debug)
 
892
                fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
 
893
                        type_name);
 
894
            return NULL;
 
895
        }
 
896
 
 
897
        status = DnsQuery_UTF8(domain, type, DNS_QUERY_STANDARD, NULL,
 
898
                               &pRec, NULL);
 
899
        if (status != ERROR_SUCCESS)
 
900
            return NULL;
 
901
 
 
902
        r = calloc(1, sizeof(*r));
 
903
        r->q.domain = strdup(domain);
 
904
        r->q.type = type;
 
905
        r->q.class = 0;
 
906
 
 
907
        r->head = parse_dns_record(pRec);
 
908
 
 
909
        if (r->head == NULL) {
 
910
            rk_dns_free_data(r);
 
911
            return NULL;
 
912
        } else {
 
913
            return r;
 
914
        }
 
915
 
 
916
    } __finally {
 
917
 
 
918
        if (pRec)
 
919
            DnsRecordListFree(pRec, DnsFreeRecordList);
 
920
 
 
921
    }
 
922
}
 
923
#endif  /* HAVE_WINDNS */
 
924
 
707
925
#else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
708
926
 
709
 
struct rk_dns_reply * ROKEN_LIB_FUNCTION
 
927
ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL
710
928
rk_dns_lookup(const char *domain, const char *type_name)
711
929
{
712
930
    return NULL;
713
931
}
714
932
 
715
 
void ROKEN_LIB_FUNCTION
 
933
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
716
934
rk_dns_free_data(struct rk_dns_reply *r)
717
935
{
718
936
}
719
937
 
720
 
void ROKEN_LIB_FUNCTION
 
938
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
721
939
rk_dns_srv_order(struct rk_dns_reply *r)
722
940
{
723
941
}