Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libads/ldap.c

    r860 r988  
    2626#include "libads/sitename_cache.h"
    2727#include "libads/cldap.h"
    28 #include "libads/dns.h"
     28#include "../lib/addns/dnsquery.h"
    2929#include "../libds/common/flags.h"
    3030#include "smbldap.h"
    3131#include "../libcli/security/security.h"
     32#include "../librpc/gen_ndr/netlogon.h"
     33#include "lib/param/loadparm.h"
    3234
    3335#ifdef HAVE_LDAP
     
    6062}
    6163
    62  LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
     64 LDAP *ldap_open_with_timeout(const char *server,
     65                              struct sockaddr_storage *ss,
     66                              int port, unsigned int to)
    6367{
    6468        LDAP *ldp = NULL;
    65 
     69        int ldap_err;
     70        char *uri;
    6671
    6772        DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout "
    6873                   "%u seconds\n", server, port, to));
    6974
    70         /* Setup timeout */
    71         gotalarm = 0;
    72         CatchSignal(SIGALRM, gotalarm_sig);
    73         alarm(to);
    74         /* End setup timeout. */
    75 
     75        if (to) {
     76                /* Setup timeout */
     77                gotalarm = 0;
     78                CatchSignal(SIGALRM, gotalarm_sig);
     79                alarm(to);
     80                /* End setup timeout. */
     81        }
     82
     83        if ( strchr_m(server, ':') ) {
     84                /* IPv6 URI */
     85                uri = talloc_asprintf(talloc_tos(), "ldap://[%s]:%u", server, port);
     86        } else {
     87                /* IPv4 URI */
     88                uri = talloc_asprintf(talloc_tos(), "ldap://%s:%u", server, port);
     89        }
     90        if (uri == NULL) {
     91                return NULL;
     92        }
     93
     94#ifdef HAVE_LDAP_INITIALIZE
     95        ldap_err = ldap_initialize(&ldp, uri);
     96#else
    7697        ldp = ldap_open(server, port);
    77 
    78         if (ldp == NULL) {
    79                 DEBUG(2,("Could not open connection to LDAP server %s:%d: %s\n",
    80                          server, port, strerror(errno)));
     98        if (ldp != NULL) {
     99                ldap_err = LDAP_SUCCESS;
    81100        } else {
    82                 DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port));
    83         }
    84 
    85         /* Teardown timeout. */
    86         CatchSignal(SIGALRM, SIG_IGN);
    87         alarm(0);
     101                ldap_err = LDAP_OTHER;
     102        }
     103#endif
     104        if (ldap_err != LDAP_SUCCESS) {
     105                DEBUG(2,("Could not initialize connection for LDAP server '%s': %s\n",
     106                         uri, ldap_err2string(ldap_err)));
     107        } else {
     108                DEBUG(10, ("Initialized connection for LDAP server '%s'\n", uri));
     109        }
     110
     111        if (to) {
     112                /* Teardown timeout. */
     113                alarm(0);
     114                CatchSignal(SIGALRM, SIG_IGN);
     115        }
    88116
    89117        return ldp;
     
    101129                                    LDAPMessage **res )
    102130{
     131        int to = lp_ldap_timeout();
    103132        struct timeval timeout;
     133        struct timeval *timeout_ptr = NULL;
    104134        int result;
    105135
    106136        /* Setup timeout for the ldap_search_ext_s call - local and remote. */
    107         timeout.tv_sec = lp_ldap_timeout();
    108         timeout.tv_usec = 0;
    109 
    110         /* Setup alarm timeout.... Do we need both of these ? JRA. */
    111137        gotalarm = 0;
    112         CatchSignal(SIGALRM, gotalarm_sig);
    113         alarm(lp_ldap_timeout());
    114         /* End setup timeout. */
     138
     139        if (to) {
     140                timeout.tv_sec = to;
     141                timeout.tv_usec = 0;
     142                timeout_ptr = &timeout;
     143
     144                /* Setup alarm timeout. */
     145                CatchSignal(SIGALRM, gotalarm_sig);
     146                /* Make the alarm time one second beyond
     147                   the timout we're setting for the
     148                   remote search timeout, to allow that
     149                   to fire in preference. */
     150                alarm(to+1);
     151                /* End setup timeout. */
     152        }
     153
    115154
    116155        result = ldap_search_ext_s(ld, base, scope, filter, attrs,
    117                                    attrsonly, sctrls, cctrls, &timeout,
     156                                   attrsonly, sctrls, cctrls, timeout_ptr,
    118157                                   sizelimit, res);
    119158
    120         /* Teardown timeout. */
    121         CatchSignal(SIGALRM, SIG_IGN);
    122         alarm(0);
     159        if (to) {
     160                /* Teardown alarm timeout. */
     161                CatchSignal(SIGALRM, SIG_IGN);
     162                alarm(0);
     163        }
    123164
    124165        if (gotalarm != 0)
     
    195236  in the ads struct if successful
    196237 */
    197 static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
    198 {
    199         char *srv;
     238static bool ads_try_connect(ADS_STRUCT *ads, bool gc,
     239                            struct sockaddr_storage *ss)
     240{
    200241        struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
    201242        TALLOC_CTX *frame = talloc_stackframe();
    202243        bool ret = false;
    203 
    204         if (!server || !*server) {
     244        char addr[INET6_ADDRSTRLEN];
     245
     246        if (ss == NULL) {
    205247                TALLOC_FREE(frame);
    206248                return False;
    207249        }
    208250
    209         if (!is_ipaddress(server)) {
    210                 struct sockaddr_storage ss;
    211                 char addr[INET6_ADDRSTRLEN];
    212 
    213                 if (!resolve_name(server, &ss, 0x20, true)) {
    214                         DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
    215                                 server ));
    216                         TALLOC_FREE(frame);
    217                         return false;
    218                 }
    219                 print_sockaddr(addr, sizeof(addr), &ss);
    220                 srv = talloc_strdup(frame, addr);
    221         } else {
    222                 /* this copes with inet_ntoa brokenness */
    223                 srv = talloc_strdup(frame, server);
    224         }
    225 
    226         if (!srv) {
    227                 TALLOC_FREE(frame);
    228                 return false;
    229         }
     251        print_sockaddr(addr, sizeof(addr), ss);
    230252
    231253        DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
    232                 srv, ads->server.realm));
     254                addr, ads->server.realm));
    233255
    234256        ZERO_STRUCT( cldap_reply );
    235257
    236         if ( !ads_cldap_netlogon_5(frame, srv, ads->server.realm, &cldap_reply ) ) {
    237                 DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
     258        if ( !ads_cldap_netlogon_5(frame, ss, ads->server.realm, &cldap_reply ) ) {
     259                DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", addr));
    238260                ret = false;
    239261                goto out;
     
    244266        if ( !(cldap_reply.server_type & NBT_SERVER_LDAP) ) {
    245267                DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n",
    246                         srv));
     268                        addr));
    247269                ret = false;
    248270                goto out;
     
    261283        ads->config.ldap_server_name   = SMB_STRDUP(cldap_reply.pdc_dns_name);
    262284        ads->config.realm              = SMB_STRDUP(cldap_reply.dns_domain);
    263         strupper_m(ads->config.realm);
     285        if (!strupper_m(ads->config.realm)) {
     286                ret = false;
     287                goto out;
     288        }
     289
    264290        ads->config.bind_path          = ads_build_dn(ads->config.realm);
    265291        if (*cldap_reply.server_site) {
     
    274300
    275301        ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT;
    276         if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) {
    277                 DEBUG(1,("ads_try_connect: unable to convert %s "
    278                         "to an address\n",
    279                         srv));
    280                 ret = false;
    281                 goto out;
    282         }
     302        ads->ldap.ss = *ss;
    283303
    284304        /* Store our site name. */
     
    295315
    296316/**********************************************************************
     317 send a cldap ping to list of servers, one at a time, until one of
     318 them answers it's an ldap server. Record success in the ADS_STRUCT.
     319 Take note of and update negative connection cache.
     320**********************************************************************/
     321
     322static NTSTATUS cldap_ping_list(ADS_STRUCT *ads,const char *domain,
     323                                struct ip_service *ip_list, int count)
     324{
     325        int i;
     326        bool ok;
     327
     328        for (i = 0; i < count; i++) {
     329                char server[INET6_ADDRSTRLEN];
     330
     331                print_sockaddr(server, sizeof(server), &ip_list[i].ss);
     332
     333                if (!NT_STATUS_IS_OK(
     334                        check_negative_conn_cache(domain, server)))
     335                        continue;
     336
     337                ok = ads_try_connect(ads, false, &ip_list[i].ss);
     338                if (ok) {
     339                        return NT_STATUS_OK;
     340                }
     341
     342                /* keep track of failures */
     343                add_failed_connection_entry(domain, server,
     344                                            NT_STATUS_UNSUCCESSFUL);
     345        }
     346
     347        return NT_STATUS_NO_LOGON_SERVERS;
     348}
     349
     350/***************************************************************************
     351 resolve a name and perform an "ldap ping" using NetBIOS and related methods
     352****************************************************************************/
     353
     354static NTSTATUS resolve_and_ping_netbios(ADS_STRUCT *ads,
     355                                         const char *domain, const char *realm)
     356{
     357        int count, i;
     358        struct ip_service *ip_list;
     359        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     360
     361        DEBUG(6, ("resolve_and_ping_netbios: (cldap) looking for domain '%s'\n",
     362                  domain));
     363
     364        status = get_sorted_dc_list(domain, NULL, &ip_list, &count,
     365                                    false);
     366        if (!NT_STATUS_IS_OK(status)) {
     367                return status;
     368        }
     369
     370        /* remove servers which are known to be dead based on
     371           the corresponding DNS method */
     372        if (*realm) {
     373                for (i = 0; i < count; ++i) {
     374                        char server[INET6_ADDRSTRLEN];
     375
     376                        print_sockaddr(server, sizeof(server), &ip_list[i].ss);
     377
     378                        if(!NT_STATUS_IS_OK(
     379                                check_negative_conn_cache(realm, server))) {
     380                                /* Ensure we add the workgroup name for this
     381                                   IP address as negative too. */
     382                                add_failed_connection_entry(
     383                                    domain, server,
     384                                    NT_STATUS_UNSUCCESSFUL);
     385                        }
     386                }
     387        }
     388
     389        status = cldap_ping_list(ads, domain, ip_list, count);
     390
     391        SAFE_FREE(ip_list);
     392
     393        return status;
     394}
     395
     396
     397/**********************************************************************
     398 resolve a name and perform an "ldap ping" using DNS
     399**********************************************************************/
     400
     401static NTSTATUS resolve_and_ping_dns(ADS_STRUCT *ads, const char *sitename,
     402                                     const char *realm)
     403{
     404        int count;
     405        struct ip_service *ip_list;
     406        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     407
     408        DEBUG(6, ("resolve_and_ping_dns: (cldap) looking for realm '%s'\n",
     409                  realm));
     410
     411        status = get_sorted_dc_list(realm, sitename, &ip_list, &count,
     412                                    true);
     413        if (!NT_STATUS_IS_OK(status)) {
     414                return status;
     415        }
     416
     417        status = cldap_ping_list(ads, realm, ip_list, count);
     418
     419        SAFE_FREE(ip_list);
     420
     421        return status;
     422}
     423
     424/**********************************************************************
    297425 Try to find an AD dc using our internal name resolution routines
    298  Try the realm first and then then workgroup name if netbios is not 
     426 Try the realm first and then then workgroup name if netbios is not
    299427 disabled
    300428**********************************************************************/
     
    302430static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
    303431{
    304         const char *c_domain;
     432        const char *c_domain = "";
    305433        const char *c_realm;
    306         int count, i=0;
    307         struct ip_service *ip_list;
    308         const char *realm;
    309         const char *domain;
    310         bool got_realm = False;
    311434        bool use_own_domain = False;
    312         char *sitename;
     435        char *sitename = NULL;
    313436        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     437        bool ok = false;
    314438
    315439        /* if the realm and workgroup are both empty, assume they are ours */
     
    318442        c_realm = ads->server.realm;
    319443
    320         if ( !c_realm || !*c_realm ) {
     444        if (c_realm == NULL)
     445                c_realm = "";
     446
     447        if (!*c_realm) {
    321448                /* special case where no realm and no workgroup means our own */
    322449                if ( !ads->server.workgroup || !*ads->server.workgroup ) {
     
    326453        }
    327454
    328         if (c_realm && *c_realm)
    329                 got_realm = True;
    330 
    331         /* we need to try once with the realm name and fallback to the
    332            netbios domain name if we fail (if netbios has not been disabled */
    333 
    334         if ( !got_realm && !lp_disable_netbios() ) {
    335                 c_realm = ads->server.workgroup;
    336                 if (!c_realm || !*c_realm) {
    337                         if ( use_own_domain )
    338                                 c_realm = lp_workgroup();
    339                 }
    340         }
    341 
    342         if ( !c_realm || !*c_realm ) {
    343                 DEBUG(0,("ads_find_dc: no realm or workgroup!  Don't know what to do\n"));
     455        if (!lp_disable_netbios()) {
     456                if (use_own_domain) {
     457                        c_domain = lp_workgroup();
     458                } else {
     459                        c_domain = ads->server.workgroup;
     460                        if (!*c_realm && (!c_domain || !*c_domain)) {
     461                                c_domain = lp_workgroup();
     462                        }
     463                }
     464
     465                if (!c_domain) {
     466                        c_domain = "";
     467                }
     468        }
     469
     470        if (!*c_realm && !*c_domain) {
     471                DEBUG(0, ("ads_find_dc: no realm or workgroup!  Don't know "
     472                          "what to do\n"));
    344473                return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
    345474        }
    346 
    347         if ( use_own_domain ) {
    348                 c_domain = lp_workgroup();
    349         } else {
    350                 c_domain = ads->server.workgroup;
    351         }
    352 
    353         realm = c_realm;
    354         domain = c_domain;
    355475
    356476        /*
     
    362482                struct sockaddr_storage ip_out;
    363483
    364                 DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n",
    365                         (got_realm ? "realm" : "domain"), realm));
    366 
    367                 if (get_dc_name(domain, realm, srv_name, &ip_out)) {
     484                DEBUG(6, ("ads_find_dc: (ldap) looking for realm '%s'"
     485                          " and falling back to domain '%s'\n",
     486                          c_realm, c_domain));
     487
     488                ok = get_dc_name(c_domain, c_realm, srv_name, &ip_out);
     489                if (ok) {
    368490                        /*
    369491                         * we call ads_try_connect() to fill in the
    370492                         * ads->config details
    371493                         */
    372                         if (ads_try_connect(ads, srv_name, false)) {
     494                        ok = ads_try_connect(ads, false, &ip_out);
     495                        if (ok) {
    373496                                return NT_STATUS_OK;
    374497                        }
     
    378501        }
    379502
    380         sitename = sitename_fetch(realm);
    381 
    382  again:
    383 
    384         DEBUG(6,("ads_find_dc: (cldap) looking for %s '%s'\n",
    385                 (got_realm ? "realm" : "domain"), realm));
    386 
    387         status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm);
    388         if (!NT_STATUS_IS_OK(status)) {
    389                 /* fall back to netbios if we can */
    390                 if ( got_realm && !lp_disable_netbios() ) {
    391                         got_realm = False;
    392                         goto again;
    393                 }
    394 
    395                 SAFE_FREE(sitename);
    396                 return status;
    397         }
    398 
    399         /* if we fail this loop, then giveup since all the IP addresses returned were dead */
    400         for ( i=0; i<count; i++ ) {
    401                 char server[INET6_ADDRSTRLEN];
    402 
    403                 print_sockaddr(server, sizeof(server), &ip_list[i].ss);
    404 
    405                 if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
    406                         continue;
    407 
    408                 if (!got_realm) {
    409                         /* realm in this case is a workgroup name. We need
    410                            to ignore any IP addresses in the negative connection
    411                            cache that match ip addresses returned in the ad realm
    412                            case. It sucks that I have to reproduce the logic above... */
    413                         c_realm = ads->server.realm;
    414                         if ( !c_realm || !*c_realm ) {
    415                                 if ( !ads->server.workgroup || !*ads->server.workgroup ) {
    416                                         c_realm = lp_realm();
    417                                 }
     503        if (*c_realm) {
     504                sitename = sitename_fetch(talloc_tos(), c_realm);
     505                status = resolve_and_ping_dns(ads, sitename, c_realm);
     506
     507                if (NT_STATUS_IS_OK(status)) {
     508                        TALLOC_FREE(sitename);
     509                        return status;
     510                }
     511
     512                /* In case we failed to contact one of our closest DC on our
     513                 * site we
     514                 * need to try to find another DC, retry with a site-less SRV
     515                 * DNS query
     516                 * - Guenther */
     517
     518                if (sitename) {
     519                        DEBUG(3, ("ads_find_dc: failed to find a valid DC on "
     520                                  "our site (%s), Trying to find another DC "
     521                                  "for realm '%s' (domain '%s')\n",
     522                                  sitename, c_realm, c_domain));
     523                        namecache_delete(c_realm, 0x1C);
     524                        status =
     525                            resolve_and_ping_dns(ads, NULL, c_realm);
     526
     527                        if (NT_STATUS_IS_OK(status)) {
     528                                TALLOC_FREE(sitename);
     529                                return status;
    418530                        }
    419                         if (c_realm && *c_realm &&
    420                                         !NT_STATUS_IS_OK(check_negative_conn_cache(c_realm, server))) {
    421                                 /* Ensure we add the workgroup name for this
    422                                    IP address as negative too. */
    423                                 add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
    424                                 continue;
    425                         }
    426                 }
    427 
    428                 if ( ads_try_connect(ads, server, false) ) {
    429                         SAFE_FREE(ip_list);
    430                         SAFE_FREE(sitename);
    431                         return NT_STATUS_OK;
    432                 }
    433 
    434                 /* keep track of failures */
    435                 add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
    436         }
    437 
    438         SAFE_FREE(ip_list);
    439 
    440         /* In case we failed to contact one of our closest DC on our site we
    441          * need to try to find another DC, retry with a site-less SRV DNS query
    442          * - Guenther */
    443 
    444         if (sitename) {
    445                 DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), "
    446                                 "trying to find another DC\n", sitename));
    447                 SAFE_FREE(sitename);
    448                 namecache_delete(realm, 0x1C);
    449                 goto again;
    450         }
    451 
    452         return NT_STATUS_NO_LOGON_SERVERS;
    453 }
    454 
    455 /*********************************************************************
    456  *********************************************************************/
    457 
    458 static NTSTATUS ads_lookup_site(void)
    459 {
    460         ADS_STRUCT *ads = NULL;
    461         ADS_STATUS ads_status;
    462         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    463 
    464         ads = ads_init(lp_realm(), NULL, NULL);
    465         if (!ads) {
    466                 return NT_STATUS_NO_MEMORY;
    467         }
    468 
    469         /* The NO_BIND here will find a DC and set the client site
    470            but not establish the TCP connection */
    471 
    472         ads->auth.flags = ADS_AUTH_NO_BIND;
    473         ads_status = ads_connect(ads);
    474         if (!ADS_ERR_OK(ads_status)) {
    475                 DEBUG(4, ("ads_lookup_site: ads_connect to our realm failed! (%s)\n",
    476                           ads_errstr(ads_status)));
    477         }
    478         nt_status = ads_ntstatus(ads_status);
    479 
    480         if (ads) {
    481                 ads_destroy(&ads);
    482         }
    483 
    484         return nt_status;
    485 }
    486 
    487 /*********************************************************************
    488  *********************************************************************/
    489 
    490 static const char* host_dns_domain(const char *fqdn)
    491 {
    492         const char *p = fqdn;
    493 
    494         /* go to next char following '.' */
    495 
    496         if ((p = strchr_m(fqdn, '.')) != NULL) {
    497                 p++;
    498         }
    499 
    500         return p;
    501 }
    502 
    503 
    504 /**
    505  * Connect to the Global Catalog server
    506  * @param ads Pointer to an existing ADS_STRUCT
    507  * @return status of connection
    508  *
    509  * Simple wrapper around ads_connect() that fills in the
    510  * GC ldap server information
    511  **/
    512 
    513 ADS_STATUS ads_connect_gc(ADS_STRUCT *ads)
    514 {
    515         TALLOC_CTX *frame = talloc_stackframe();
    516         struct dns_rr_srv *gcs_list;
    517         int num_gcs;
    518         char *realm = ads->server.realm;
    519         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    520         ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
    521         int i;
    522         bool done = false;
    523         char *sitename = NULL;
    524 
    525         if (!realm)
    526                 realm = lp_realm();
    527 
    528         if ((sitename = sitename_fetch(realm)) == NULL) {
    529                 ads_lookup_site();
    530                 sitename = sitename_fetch(realm);
    531         }
    532 
    533         do {
    534                 /* We try once with a sitename and once without
    535                    (unless we don't have a sitename and then we're
    536                    done */
    537 
    538                 if (sitename == NULL)
    539                         done = true;
    540 
    541                 nt_status = ads_dns_query_gcs(frame, realm, sitename,
    542                                               &gcs_list, &num_gcs);
    543 
    544                 SAFE_FREE(sitename);
    545 
    546                 if (!NT_STATUS_IS_OK(nt_status)) {
    547                         ads_status = ADS_ERROR_NT(nt_status);
    548                         goto done;
    549                 }
    550 
    551                 /* Loop until we get a successful connection or have gone
    552                    through them all.  When connecting a GC server, make sure that
    553                    the realm is the server's DNS name and not the forest root */
    554 
    555                 for (i=0; i<num_gcs; i++) {
    556                         ads->server.gc = true;
    557                         ads->server.ldap_server = SMB_STRDUP(gcs_list[i].hostname);
    558                         ads->server.realm = SMB_STRDUP(host_dns_domain(ads->server.ldap_server));
    559                         ads_status = ads_connect(ads);
    560                         if (ADS_ERR_OK(ads_status)) {
    561                                 /* Reset the bind_dn to "".  A Global Catalog server
    562                                    may host  multiple domain trees in a forest.
    563                                    Windows 2003 GC server will accept "" as the search
    564                                    path to imply search all domain trees in the forest */
    565 
    566                                 SAFE_FREE(ads->config.bind_path);
    567                                 ads->config.bind_path = SMB_STRDUP("");
    568 
    569 
    570                                 goto done;
    571                         }
    572                         SAFE_FREE(ads->server.ldap_server);
    573                         SAFE_FREE(ads->server.realm);
    574                 }
    575 
    576                 TALLOC_FREE(gcs_list);
    577                 num_gcs = 0;
    578         } while (!done);
    579 
    580 done:
    581         SAFE_FREE(sitename);
    582         talloc_destroy(frame);
    583 
    584         return ads_status;
    585 }
    586 
    587 
     531                }
     532
     533                TALLOC_FREE(sitename);
     534        }
     535
     536        /* try netbios as fallback - if permitted,
     537           or if configuration specifically requests it */
     538        if (*c_domain) {
     539                if (*c_realm) {
     540                        DEBUG(3, ("ads_find_dc: falling back to netbios "
     541                                  "name resolution for domain '%s' (realm '%s')\n",
     542                                  c_domain, c_realm));
     543                }
     544
     545                status = resolve_and_ping_netbios(ads, c_domain, c_realm);
     546                if (NT_STATUS_IS_OK(status)) {
     547                        return status;
     548                }
     549        }
     550
     551        DEBUG(1, ("ads_find_dc: "
     552                  "name resolution for realm '%s' (domain '%s') failed: %s\n",
     553                  c_realm, c_domain, nt_errstr(status)));
     554        return status;
     555}
    588556/**
    589557 * Connect to the LDAP server
     
    611579        }
    612580
    613         if (ads->server.ldap_server)
    614         {
    615                 if (ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) {
     581        if (ads->server.ldap_server) {
     582                bool ok = false;
     583                struct sockaddr_storage ss;
     584
     585                ok = resolve_name(ads->server.ldap_server, &ss, 0x20, true);
     586                if (!ok) {
     587                        DEBUG(5,("ads_connect: unable to resolve name %s\n",
     588                                 ads->server.ldap_server));
     589                        status = ADS_ERROR_NT(NT_STATUS_NOT_FOUND);
     590                        goto out;
     591                }
     592                ok = ads_try_connect(ads, ads->server.gc, &ss);
     593                if (ok) {
    616594                        goto got_connection;
    617595                }
     
    644622                   and not servicePrincipalName; found by Guenther Deschner */
    645623
    646                 if (asprintf(&ads->auth.user_name, "%s$", global_myname() ) == -1) {
     624                if (asprintf(&ads->auth.user_name, "%s$", lp_netbios_name() ) == -1) {
    647625                        DEBUG(0,("ads_connect: asprintf fail.\n"));
    648626                        ads->auth.user_name = NULL;
     
    658636                ads->auth.kdc_server = SMB_STRDUP(addr);
    659637        }
    660 
    661 #if KRB5_DNS_HACK
    662         /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch
    663            to MIT kerberos to work (tridge) */
    664         {
    665                 char *env = NULL;
    666                 if (asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm) > 0) {
    667                         setenv(env, ads->auth.kdc_server, 1);
    668                         free(env);
    669                 }
    670         }
    671 #endif
    672638
    673639        /* If the caller() requested no LDAP bind, then we are done */
     
    686652        /* Otherwise setup the TCP LDAP session */
    687653
    688         ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
     654        ads->ldap.ld = ldap_open_with_timeout(addr,
     655                                              &ads->ldap.ss,
    689656                                              ads->ldap.port, lp_ldap_timeout());
    690657        if (ads->ldap.ld == NULL) {
     
    703670
    704671        if ( lp_ldap_ssl_ads() ) {
    705                 status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version));
     672                status = ADS_ERROR(smbldap_start_tls(ads->ldap.ld, version));
    706673                if (!ADS_ERR_OK(status)) {
    707674                        goto out;
     
    782749        if (!in_val) return NULL;
    783750
    784         value = TALLOC_ZERO_P(ctx, struct berval);
     751        value = talloc_zero(ctx, struct berval);
    785752        if (value == NULL)
    786753                return NULL;
     
    788755
    789756        value->bv_len = in_val->bv_len;
    790         value->bv_val = (char *)TALLOC_MEMDUP(ctx, in_val->bv_val,
     757        value->bv_val = (char *)talloc_memdup(ctx, in_val->bv_val,
    791758                                              in_val->bv_len);
    792759        return value;
     
    805772        for (i=0; in_vals[i]; i++)
    806773                ; /* count values */
    807         values = TALLOC_ZERO_ARRAY(ctx, struct berval *, i+1);
     774        values = talloc_zero_array(ctx, struct berval *, i+1);
    808775        if (!values) return NULL;
    809776
     
    826793        for (i=0; in_vals[i]; i++)
    827794                ; /* count values */
    828         values = TALLOC_ZERO_ARRAY(ctx, char *, i+1);
     795        values = talloc_zero_array(ctx, char *, i+1);
    829796        if (!values) return NULL;
    830797
     
    850817        for (i=0; in_vals[i]; i++)
    851818                ; /* count values */
    852         values = TALLOC_ZERO_ARRAY(ctx, char *, i+1);
     819        values = talloc_zero_array(ctx, char *, i+1);
    853820        if (!values) return NULL;
    854821
     
    938905        }
    939906        ber_flatten(cookie_be, &cookie_bv);
    940         PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
     907        PagedResults.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
    941908        PagedResults.ldctl_iscritical = (char) 1;
    942909        PagedResults.ldctl_value.bv_len = cookie_bv->bv_len;
    943910        PagedResults.ldctl_value.bv_val = cookie_bv->bv_val;
    944911
    945         NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID);
     912        NoReferrals.ldctl_oid = discard_const_p(char, ADS_NO_REFERRALS_OID);
    946913        NoReferrals.ldctl_iscritical = (char) 0;
    947914        NoReferrals.ldctl_value.bv_len = 0;
    948         NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, "");
     915        NoReferrals.ldctl_value.bv_val = discard_const_p(char, "");
    949916
    950917        if (external_control &&
     
    952919             strequal(external_control->control, ADS_SD_FLAGS_OID))) {
    953920
    954                 ExternalCtrl.ldctl_oid = CONST_DISCARD(char *, external_control->control);
     921                ExternalCtrl.ldctl_oid = discard_const_p(char, external_control->control);
    955922                ExternalCtrl.ldctl_iscritical = (char) external_control->critical;
    956923
     
    1013980                DEBUG(3,("ads_do_paged_search_args: ldap_search_with_timeout(%s) -> %s\n", expr,
    1014981                         ldap_err2string(rc)));
     982                if (rc == LDAP_OTHER) {
     983                        char *ldap_errmsg;
     984                        int ret;
     985
     986                        ret = ldap_parse_result(ads->ldap.ld,
     987                                                *res,
     988                                                NULL,
     989                                                NULL,
     990                                                &ldap_errmsg,
     991                                                NULL,
     992                                                NULL,
     993                                                0);
     994                        if (ret == LDAP_SUCCESS) {
     995                                DEBUG(3, ("ldap_search_with_timeout(%s) "
     996                                          "error: %s\n", expr, ldap_errmsg));
     997                                ldap_memfree(ldap_errmsg);
     998                        }
     999                }
    10151000                goto done;
    10161001        }
     
    10971082        while (cookie) {
    10981083                LDAPMessage *res2 = NULL;
    1099                 ADS_STATUS status2;
    11001084                LDAPMessage *msg, *next;
    11011085
    1102                 status2 = ads_do_paged_search_args(ads, bind_path, scope, expr,
     1086                status = ads_do_paged_search_args(ads, bind_path, scope, expr,
    11031087                                              attrs, args, &res2, &count, &cookie);
    1104 
    1105                 if (!ADS_ERR_OK(status2)) break;
     1088                if (!ADS_ERR_OK(status)) {
     1089                        /* Ensure we free all collected results */
     1090                        ads_msgfree(ads, *res);
     1091                        *res = NULL;
     1092                        break;
     1093                }
    11061094
    11071095                /* this relies on the way that ldap_add_result_entry() works internally. I hope
     
    11311119 ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path,
    11321120                                       int scope, const char *expr,
    1133                                        const char **attrs, uint32 sd_flags,
     1121                                       const char **attrs, uint32_t sd_flags,
    11341122                                       LDAPMessage **res)
    11351123{
     
    13571345        ADS_STATUS status;
    13581346        char *expr;
    1359         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
     1347        const char *attrs[] = {"*", "msDS-SupportedEncryptionTypes", "nTSecurityDescriptor", NULL};
    13601348
    13611349        *res = NULL;
     
    13831371        LDAPMod **mods;
    13841372
    1385         if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1)))
     1373        if ((mods = talloc_zero_array(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1)))
    13861374                /* -1 is safety to make sure we don't go over the end.
    13871375                   need to reset it to NULL before doing ldap modify */
     
    13991387                                  const void *_invals)
    14001388{
    1401         const void **invals = (const void **)_invals;
    14021389        int curmod;
    14031390        LDAPMod **modlist = (LDAPMod **) *mods;
     
    14051392        char **char_values = NULL;
    14061393
    1407         if (!invals) {
     1394        if (!_invals) {
    14081395                mod_op = LDAP_MOD_DELETE;
    14091396        } else {
    1410                 if (mod_op & LDAP_MOD_BVALUES)
    1411                         ber_values = ads_dup_values(ctx,
    1412                                                 (const struct berval **)invals);
    1413                 else
    1414                         char_values = ads_push_strvals(ctx,
    1415                                                   (const char **) invals);
     1397                if (mod_op & LDAP_MOD_BVALUES) {
     1398                        const struct berval **b;
     1399                        b = discard_const_p(const struct berval *, _invals);
     1400                        ber_values = ads_dup_values(ctx, b);
     1401                } else {
     1402                        const char **c;
     1403                        c = discard_const_p(const char *, _invals);
     1404                        char_values = ads_push_strvals(ctx, c);
     1405                }
    14161406        }
    14171407
     
    14201410             curmod++);
    14211411        if (modlist[curmod] == (LDAPMod *) -1) {
    1422                 if (!(modlist = TALLOC_REALLOC_ARRAY(ctx, modlist, LDAPMod *,
     1412                if (!(modlist = talloc_realloc(ctx, modlist, LDAPMod *,
    14231413                                curmod+ADS_MODLIST_ALLOC_SIZE+1)))
    14241414                        return ADS_ERROR(LDAP_NO_MEMORY);
     
    14291419        }
    14301420
    1431         if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod)))
     1421        if (!(modlist[curmod] = talloc_zero(ctx, LDAPMod)))
    14321422                return ADS_ERROR(LDAP_NO_MEMORY);
    14331423        modlist[curmod]->mod_type = talloc_strdup(ctx, name);
     
    15051495#endif
    15061496
     1497static void ads_print_error(int ret, LDAP *ld)
     1498{
     1499        if (ret != 0) {
     1500                char *ld_error = NULL;
     1501                ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &ld_error);
     1502                DEBUG(10,("AD LDAP failure %d (%s):\n%s\n", ret,
     1503                        ldap_err2string(ret), ld_error));
     1504                SAFE_FREE(ld_error);
     1505        }
     1506}
     1507
    15071508/**
    15081509 * Perform an ldap modify
     
    15221523        */
    15231524        LDAPControl PermitModify = {
    1524                 CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID),
     1525                discard_const_p(char, ADS_PERMIT_MODIFY_OID),
    15251526                {0, NULL},
    15261527                (char) 1};
     
    15401541        ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn,
    15411542                                (LDAPMod **) mods, controls, NULL);
     1543        ads_print_error(ret, ads->ldap.ld);
    15421544        TALLOC_FREE(utf8_dn);
    15431545        return ADS_ERROR(ret);
     
    15681570
    15691571        ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods);
     1572        ads_print_error(ret, ads->ldap.ld);
    15701573        TALLOC_FREE(utf8_dn);
    15711574        return ADS_ERROR(ret);
     
    15891592
    15901593        ret = ldap_delete_s(ads->ldap.ld, utf8_dn);
     1594        ads_print_error(ret, ads->ldap.ld);
    15911595        TALLOC_FREE(utf8_dn);
    15921596        return ADS_ERROR(ret);
     
    17401744 **/
    17411745
    1742 uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name)
     1746uint32_t ads_get_kvno(ADS_STRUCT *ads, const char *account_name)
    17431747{
    17441748        LDAPMessage *res = NULL;
    1745         uint32 kvno = (uint32)-1;      /* -1 indicates a failure */
     1749        uint32_t kvno = (uint32_t)-1;      /* -1 indicates a failure */
    17461750        char *filter;
    17471751        const char *attrs[] = {"msDS-KeyVersionNumber", NULL};
     
    18781882
    18791883/**
     1884 * @brief Search for an element in a string array.
     1885 *
     1886 * @param[in]  el_array  The string array to search.
     1887 *
     1888 * @param[in]  num_el    The number of elements in the string array.
     1889 *
     1890 * @param[in]  el        The string to search.
     1891 *
     1892 * @return               True if found, false if not.
     1893 */
     1894bool ads_element_in_array(const char **el_array, size_t num_el, const char *el)
     1895{
     1896        size_t i;
     1897
     1898        if (el_array == NULL || num_el == 0 || el == NULL) {
     1899                return false;
     1900        }
     1901
     1902        for (i = 0; i < num_el && el_array[i] != NULL; i++) {
     1903                int cmp;
     1904
     1905                cmp = strcasecmp_m(el_array[i], el);
     1906                if (cmp == 0) {
     1907                        return true;
     1908                }
     1909        }
     1910
     1911        return false;
     1912}
     1913
     1914/**
     1915 * @brief This gets the service principal names of an existing computer account.
     1916 *
     1917 * @param[in]  mem_ctx      The memory context to use to allocate the spn array.
     1918 *
     1919 * @param[in]  ads          The ADS context to use.
     1920 *
     1921 * @param[in]  machine_name The NetBIOS name of the computer, which is used to
     1922 *                          identify the computer account.
     1923 *
     1924 * @param[in]  spn_array    A pointer to store the array for SPNs.
     1925 *
     1926 * @param[in]  num_spns     The number of principals stored in the array.
     1927 *
     1928 * @return                  0 on success, or a ADS error if a failure occured.
     1929 */
     1930ADS_STATUS ads_get_service_principal_names(TALLOC_CTX *mem_ctx,
     1931                                           ADS_STRUCT *ads,
     1932                                           const char *machine_name,
     1933                                           char ***spn_array,
     1934                                           size_t *num_spns)
     1935{
     1936        ADS_STATUS status;
     1937        LDAPMessage *res = NULL;
     1938        int count;
     1939
     1940        status = ads_find_machine_acct(ads,
     1941                                       &res,
     1942                                       machine_name);
     1943        if (!ADS_ERR_OK(status)) {
     1944                DEBUG(1,("Host Account for %s not found... skipping operation.\n",
     1945                         machine_name));
     1946                return status;
     1947        }
     1948
     1949        count = ads_count_replies(ads, res);
     1950        if (count != 1) {
     1951                status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
     1952                goto done;
     1953        }
     1954
     1955        *spn_array = ads_pull_strings(ads,
     1956                                      mem_ctx,
     1957                                      res,
     1958                                      "servicePrincipalName",
     1959                                      num_spns);
     1960        if (*spn_array == NULL) {
     1961                DEBUG(1, ("Host account for %s does not have service principal "
     1962                          "names.\n",
     1963                          machine_name));
     1964                status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
     1965                goto done;
     1966        }
     1967
     1968done:
     1969        ads_msgfree(ads, res);
     1970
     1971        return status;
     1972}
     1973
     1974/**
    18801975 * This adds a service principal name to an existing computer account
    18811976 * (found by hostname) in AD.
     
    19212016                return ADS_ERROR(LDAP_NO_MEMORY);
    19222017        }
    1923         strlower_m(&psp1[strlen(spn) + 1]);
     2018        if (!strlower_m(&psp1[strlen(spn) + 1])) {
     2019                ret = ADS_ERROR(LDAP_NO_MEMORY);
     2020                goto out;
     2021        }
    19242022        servicePrincipalName[0] = psp1;
    19252023
     
    19342032                goto out;
    19352033        }
    1936         strlower_m(&psp2[strlen(spn) + 1]);
     2034        if (!strlower_m(&psp2[strlen(spn) + 1])) {
     2035                ret = ADS_ERROR(LDAP_NO_MEMORY);
     2036                goto out;
     2037        }
    19372038        servicePrincipalName[1] = psp2;
    19382039
     
    19772078**/
    19782079
    1979 ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name,
    1980                                    const char *org_unit)
     2080ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
     2081                                   const char *machine_name,
     2082                                   const char *org_unit,
     2083                                   uint32_t etype_list)
    19812084{
    19822085        ADS_STATUS ret;
     
    19892092                                     "user", "computer", NULL};
    19902093        LDAPMessage *res = NULL;
    1991         uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\
     2094        uint32_t acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\
    19922095                                UF_DONT_EXPIRE_PASSWD |\
    19932096                                UF_ACCOUNTDISABLE );
     2097        uint32_t func_level = 0;
     2098
     2099        ret = ads_domain_func_level(ads, &func_level);
     2100        if (!ADS_ERR_OK(ret)) {
     2101                return ret;
     2102        }
    19942103
    19952104        if (!(ctx = talloc_init("ads_add_machine_acct")))
     
    20262135        ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
    20272136        ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
     2137
     2138        if (func_level >= DS_DOMAIN_FUNCTION_2008) {
     2139                const char *etype_list_str;
     2140
     2141                etype_list_str = talloc_asprintf(ctx, "%d", (int)etype_list);
     2142                if (etype_list_str == NULL) {
     2143                        goto done;
     2144                }
     2145                ads_mod_str(ctx, &mods, "msDS-SupportedEncryptionTypes",
     2146                            etype_list_str);
     2147        }
    20282148
    20292149        ret = ads_gen_add(ads, new_dn, mods);
     
    21492269                struct dom_sid sid;
    21502270                fstring tmp;
    2151                 if (!sid_parse(values[i]->bv_val, values[i]->bv_len, &sid)) {
     2271                if (!sid_parse((const uint8_t *)values[i]->bv_val,
     2272                               values[i]->bv_len, &sid)) {
    21522273                        return;
    21532274                }
     
    21652286        NTSTATUS status;
    21662287
    2167         status = unmarshall_sec_desc(talloc_tos(), (uint8 *)values[0]->bv_val,
     2288        status = unmarshall_sec_desc(talloc_tos(), (uint8_t *)values[0]->bv_val,
    21682289                                     values[0]->bv_len, &psd);
    21692290        if (!NT_STATUS_IS_OK(status)) {
     
    22242345
    22252346        for (i=0; handlers[i].name; i++) {
    2226                 if (StrCaseCmp(handlers[i].name, field) == 0) {
     2347                if (strcasecmp_m(handlers[i].name, field) == 0) {
    22272348                        if (!values) /* first time, indicate string or not */
    22282349                                return handlers[i].string;
     
    22842405                                                    (LDAPMessage *)msg,b)) {
    22852406                        struct berval **ber_vals;
    2286                         char **str_vals, **utf8_vals;
     2407                        char **str_vals;
     2408                        char **utf8_vals;
    22872409                        char *field;
    22882410                        bool string;
     
    22992421
    23002422                        if (string) {
     2423                                const char **p;
     2424
    23012425                                utf8_vals = ldap_get_values(ads->ldap.ld,
    23022426                                                 (LDAPMessage *)msg, field);
    2303                                 str_vals = ads_pull_strvals(ctx,
    2304                                                   (const char **) utf8_vals);
     2427                                p = discard_const_p(const char *, utf8_vals);
     2428                                str_vals = ads_pull_strvals(ctx, p);
    23052429                                fn(ads, field, (void **) str_vals, data_area);
    23062430                                ldap_value_free(utf8_vals);
     
    24292553        *num_values = ldap_count_values(values);
    24302554
    2431         ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1);
     2555        ret = talloc_array(mem_ctx, char *, *num_values + 1);
    24322556        if (!ret) {
    24332557                ldap_value_free(values);
     
    25422666        }
    25432667
    2544         strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *,
     2668        strings = talloc_realloc(mem_ctx, current_strings, char *,
    25452669                                 *num_strings + num_new_strings);
    25462670
     
    25782702
    25792703/**
    2580  * pull a single uint32 from a ADS result
     2704 * pull a single uint32_t from a ADS result
    25812705 * @param ads connection to ads server
    25822706 * @param msg Results of search
     
    25862710*/
    25872711 bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field,
    2588                       uint32 *v)
     2712                      uint32_t *v)
    25892713{
    25902714        char **values;
     
    26652789
    26662790        if (i) {
    2667                 (*sids) = TALLOC_ARRAY(mem_ctx, struct dom_sid, i);
     2791                (*sids) = talloc_array(mem_ctx, struct dom_sid, i);
    26682792                if (!(*sids)) {
    26692793                        ldap_value_free_len(values);
     
    26762800        count = 0;
    26772801        for (i=0; values[i]; i++) {
    2678                 ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]);
     2802                ret = sid_parse((const uint8_t *)values[i]->bv_val,
     2803                                values[i]->bv_len, &(*sids)[count]);
    26792804                if (ret) {
    26802805                        DEBUG(10, ("pulling SID: %s\n",
     
    27112836                NTSTATUS status;
    27122837                status = unmarshall_sec_desc(mem_ctx,
    2713                                              (uint8 *)values[0]->bv_val,
     2838                                             (uint8_t *)values[0]->bv_val,
    27142839                                             values[0]->bv_len, sd);
    27152840                if (!NT_STATUS_IS_OK(status)) {
     
    27612886 * @return status of search
    27622887 **/
    2763 ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn)
     2888ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32_t *usn)
    27642889{
    27652890        const char *attrs[] = {"highestCommittedUSN", NULL};
     
    28532978        if (ads->config.current_time != 0) {
    28542979                ads->auth.time_offset = ads->config.current_time - time(NULL);
    2855                 DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset));
     2980                DEBUG(4,("KDC time offset is %d seconds\n", ads->auth.time_offset));
    28562981        }
    28572982
     
    28732998********************************************************************/
    28742999
    2875 ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val)
     3000ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32_t *val)
    28763001{
    28773002        const char *attrs[] = {"domainFunctionality", NULL};
     
    31433268        for (msg = ads_first_entry(ads, res); msg;
    31443269             msg = ads_next_entry(ads, msg)) {
    3145 
     3270                const char **p = discard_const_p(const char *, *ous);
    31463271                char *dn = NULL;
    31473272
     
    31523277                }
    31533278
    3154                 if (!add_string_to_array(mem_ctx, dn,
    3155                                          (const char ***)ous,
    3156                                          (int *)num_ous)) {
     3279                if (!add_string_to_array(mem_ctx, dn, &p, num_ous)) {
    31573280                        TALLOC_FREE(dn);
    31583281                        ads_msgfree(ads, res);
     
    31613284
    31623285                TALLOC_FREE(dn);
     3286                *ous = discard_const_p(char *, p);
    31633287        }
    31643288
     
    32423366                }
    32433367
    3244                 if (!sid_parse(buf, buf_len, sid)) {
     3368                if (!sid_parse((const uint8_t *)buf, buf_len, sid)) {
    32453369                        DEBUG(10,("failed to parse sid\n"));
    32463370                        return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
     
    32543378
    32553379        return ADS_ERROR_NT(NT_STATUS_OK);
    3256 }
    3257 
    3258 /**
    3259  * pull an array of struct dom_sids from a ADS result
    3260  * @param ads connection to ads server
    3261  * @param mem_ctx TALLOC_CTX for allocating sid array
    3262  * @param msg Results of search
    3263  * @param field Attribute to retrieve
    3264  * @param flags string type of extended_dn
    3265  * @param sids pointer to sid array to allocate
    3266  * @return the count of SIDs pulled
    3267  **/
    3268  int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads,
    3269                                    TALLOC_CTX *mem_ctx,
    3270                                    LDAPMessage *msg,
    3271                                    const char *field,
    3272                                    enum ads_extended_dn_flags flags,
    3273                                    struct dom_sid **sids)
    3274 {
    3275         int i;
    3276         ADS_STATUS rc;
    3277         size_t dn_count, ret_count = 0;
    3278         char **dn_strings;
    3279 
    3280         if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field,
    3281                                            &dn_count)) == NULL) {
    3282                 return 0;
    3283         }
    3284 
    3285         (*sids) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, dn_count + 1);
    3286         if (!(*sids)) {
    3287                 TALLOC_FREE(dn_strings);
    3288                 return 0;
    3289         }
    3290 
    3291         for (i=0; i<dn_count; i++) {
    3292                 rc = ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i],
    3293                                                   flags, &(*sids)[i]);
    3294                 if (!ADS_ERR_OK(rc)) {
    3295                         if (NT_STATUS_EQUAL(ads_ntstatus(rc),
    3296                             NT_STATUS_NOT_FOUND)) {
    3297                                 continue;
    3298                         }
    3299                         else {
    3300                                 TALLOC_FREE(*sids);
    3301                                 TALLOC_FREE(dn_strings);
    3302                                 return 0;
    3303                         }
    3304                 }
    3305                 ret_count++;
    3306         }
    3307 
    3308         TALLOC_FREE(dn_strings);
    3309 
    3310         return ret_count;
    33113380}
    33123381
     
    33213390        char *name = NULL;
    33223391
    3323         status = ads_find_machine_acct(ads, &res, global_myname());
     3392        status = ads_find_machine_acct(ads, &res, lp_netbios_name());
    33243393        if (!ADS_ERR_OK(status)) {
    33253394                DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
    3326                         global_myname()));
     3395                        lp_netbios_name()));
    33273396                goto out;
    33283397        }
     
    33563425        if (!ADS_ERR_OK(status)) {
    33573426                DEBUG(0,("ads_get_upn: Failed to find account for %s\n",
    3358                         global_myname()));
     3427                        lp_netbios_name()));
    33593428                goto out;
    33603429        }
     
    33853454        char *name = NULL;
    33863455
    3387         status = ads_find_machine_acct(ads, &res, global_myname());
     3456        status = ads_find_machine_acct(ads, &res, lp_netbios_name());
    33883457        if (!ADS_ERR_OK(status)) {
    33893458                DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
    3390                         global_myname()));
     3459                        lp_netbios_name()));
    33913460                goto out;
    33923461        }
     
    34203489 **/
    34213490ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
    3422                         uint32 account_type, const char *org_unit)
     3491                        uint32_t account_type, const char *org_unit)
    34233492{
    34243493        ADS_STATUS status;
     
    34813550        pldap_control[0] = &ldap_control;
    34823551        memset(&ldap_control, 0, sizeof(LDAPControl));
    3483         ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID;
     3552        ldap_control.ldctl_oid = discard_const_p(char, LDAP_SERVER_TREE_DELETE_OID);
    34843553
    34853554        /* hostname must be lowercase */
    34863555        host = SMB_STRDUP(hostname);
    3487         strlower_m(host);
     3556        if (!strlower_m(host)) {
     3557                SAFE_FREE(host);
     3558                return ADS_ERROR_SYSTEM(EINVAL);
     3559        }
    34883560
    34893561        status = ads_find_machine_acct(ads, &res, host);
     
    36133685        struct dom_sid tmp_user_sid;
    36143686        struct dom_sid tmp_primary_group_sid;
    3615         uint32 pgid;
     3687        uint32_t pgid;
    36163688        const char *attrs[] = {
    36173689                "objectSid",
     
    36953767 * @param mem_ctx TALLOC_CTX for allocating sid array
    36963768 * @param samaccountname to search
    3697  * @param uac_ret uint32 pointer userAccountControl attribute value
     3769 * @param uac_ret uint32_t pointer userAccountControl attribute value
    36983770 * @param dn_ret pointer to dn
    36993771 * @return status of token query
     
    37023774                               TALLOC_CTX *mem_ctx,
    37033775                               const char *samaccountname,
    3704                                uint32 *uac_ret,
     3776                               uint32_t *uac_ret,
    37053777                               const char **dn_ret)
    37063778{
     
    37103782        LDAPMessage *res = NULL;
    37113783        char *dn = NULL;
    3712         uint32 uac = 0;
     3784        uint32_t uac = 0;
    37133785
    37143786        filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))",
     
    38683940        char *ou_string;
    38693941
    3870         exploded_dn = ldap_explode_dn(*account_ou, 0);
    3871         if (exploded_dn) {
    3872                 ldap_value_free(exploded_dn);
    3873                 return ADS_SUCCESS;
     3942        if (account_ou == NULL) {
     3943                return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
     3944        }
     3945
     3946        if (*account_ou != NULL) {
     3947                exploded_dn = ldap_explode_dn(*account_ou, 0);
     3948                if (exploded_dn) {
     3949                        ldap_value_free(exploded_dn);
     3950                        return ADS_SUCCESS;
     3951                }
    38743952        }
    38753953
Note: See TracChangeset for help on using the changeset viewer.