Ignore:
Timestamp:
May 29, 2008, 12:22:03 PM (17 years ago)
Author:
Paul Smedley
Message:

Update trunk to 3.2.0rc1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/samba/source/libsmb/dsgetdcname.c

    r133 r136  
    3232        const char *hostname;
    3333};
     34
     35static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx,
     36                                              uint32_t flags,
     37                                              struct sockaddr_storage *ss,
     38                                              uint32_t nt_version,
     39                                              union nbt_cldap_netlogon *r,
     40                                              struct netr_DsRGetDCNameInfo **info);
    3441
    3542/****************************************************************
     
    149156static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
    150157                                        const char *domain_name,
    151                                         struct netr_DsRGetDCNameInfo *info)
     158                                        const DATA_BLOB *blob)
    152159{
    153160        time_t expire_time;
    154161        char *key;
    155162        bool ret = false;
    156         DATA_BLOB blob;
    157         enum ndr_err_code ndr_err;
    158163
    159164        if (!gencache_init()) {
     
    168173        expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
    169174
    170         ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info,
    171                        (ndr_push_flags_fn_t)ndr_push_netr_DsRGetDCNameInfo);
     175        if (gencache_lock_entry(key) != 0) {
     176                return NT_STATUS_LOCK_NOT_GRANTED;
     177        }
     178
     179        ret = gencache_set_data_blob(key, blob, expire_time);
     180
     181        gencache_unlock_entry(key);
     182
     183        return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
     184}
     185
     186/****************************************************************
     187****************************************************************/
     188
     189#define SET_STRING(x) \
     190        talloc_strdup(mem_ctx, x); \
     191        NT_STATUS_HAVE_NO_MEMORY(x);
     192
     193static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx,
     194                                             uint32_t flags,
     195                                             struct sockaddr_storage *ss,
     196                                             uint32_t nt_version,
     197                                             union nbt_cldap_netlogon *r,
     198                                             struct nbt_cldap_netlogon_29 *p)
     199{
     200        char addr[INET6_ADDRSTRLEN];
     201
     202        ZERO_STRUCTP(p);
     203
     204        print_sockaddr(addr, sizeof(addr), ss);
     205
     206        /* FIXME */
     207        p->dc_sock_addr_size = 0x10; /* the w32 winsock addr size */
     208        p->dc_sock_addr.sa_family = 2; /* AF_INET */
     209        p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr);
     210
     211        switch (nt_version & 0x0000001f) {
     212                case 0:
     213                        return NT_STATUS_INVALID_PARAMETER;
     214                case 1:
     215                case 16:
     216                case 17:
     217                        p->pdc_name     = SET_STRING(r->logon1.pdc_name);
     218                        p->domain       = SET_STRING(r->logon1.domain_name);
     219
     220                        if (flags & DS_PDC_REQUIRED) {
     221                                p->server_type = NBT_SERVER_WRITABLE |
     222                                                 NBT_SERVER_PDC;
     223                        }
     224                        break;
     225                case 2:
     226                case 3:
     227                case 18:
     228                case 19:
     229                        p->pdc_name     = SET_STRING(r->logon3.pdc_name);
     230                        p->domain       = SET_STRING(r->logon3.domain_name);
     231                        p->pdc_dns_name = SET_STRING(r->logon3.pdc_dns_name);
     232                        p->dns_domain   = SET_STRING(r->logon3.dns_domain);
     233                        p->server_type  = r->logon3.server_type;
     234                        p->forest       = SET_STRING(r->logon3.forest);
     235                        p->domain_uuid  = r->logon3.domain_uuid;
     236
     237                        break;
     238                case 4:
     239                case 5:
     240                case 6:
     241                case 7:
     242                        p->pdc_name     = SET_STRING(r->logon5.pdc_name);
     243                        p->domain       = SET_STRING(r->logon5.domain);
     244                        p->pdc_dns_name = SET_STRING(r->logon5.pdc_dns_name);
     245                        p->dns_domain   = SET_STRING(r->logon5.dns_domain);
     246                        p->server_type  = r->logon5.server_type;
     247                        p->forest       = SET_STRING(r->logon5.forest);
     248                        p->domain_uuid  = r->logon5.domain_uuid;
     249                        p->server_site  = SET_STRING(r->logon5.server_site);
     250                        p->client_site  = SET_STRING(r->logon5.client_site);
     251
     252                        break;
     253                case 8:
     254                case 9:
     255                case 10:
     256                case 11:
     257                case 12:
     258                case 13:
     259                case 14:
     260                case 15:
     261                        p->pdc_name     = SET_STRING(r->logon13.pdc_name);
     262                        p->domain       = SET_STRING(r->logon13.domain);
     263                        p->pdc_dns_name = SET_STRING(r->logon13.pdc_dns_name);
     264                        p->dns_domain   = SET_STRING(r->logon13.dns_domain);
     265                        p->server_type  = r->logon13.server_type;
     266                        p->forest       = SET_STRING(r->logon13.forest);
     267                        p->domain_uuid  = r->logon13.domain_uuid;
     268                        p->server_site  = SET_STRING(r->logon13.server_site);
     269                        p->client_site  = SET_STRING(r->logon13.client_site);
     270
     271                        break;
     272                case 20:
     273                case 21:
     274                case 22:
     275                case 23:
     276                case 24:
     277                case 25:
     278                case 26:
     279                case 27:
     280                case 28:
     281                        p->pdc_name     = SET_STRING(r->logon15.pdc_name);
     282                        p->domain       = SET_STRING(r->logon15.domain);
     283                        p->pdc_dns_name = SET_STRING(r->logon15.pdc_dns_name);
     284                        p->dns_domain   = SET_STRING(r->logon15.dns_domain);
     285                        p->server_type  = r->logon15.server_type;
     286                        p->forest       = SET_STRING(r->logon15.forest);
     287                        p->domain_uuid  = r->logon15.domain_uuid;
     288                        p->server_site  = SET_STRING(r->logon15.server_site);
     289                        p->client_site  = SET_STRING(r->logon15.client_site);
     290
     291                        break;
     292                case 29:
     293                case 30:
     294                case 31:
     295                        p->pdc_name     = SET_STRING(r->logon29.pdc_name);
     296                        p->domain       = SET_STRING(r->logon29.domain);
     297                        p->pdc_dns_name = SET_STRING(r->logon29.pdc_dns_name);
     298                        p->dns_domain   = SET_STRING(r->logon29.dns_domain);
     299                        p->server_type  = r->logon29.server_type;
     300                        p->forest       = SET_STRING(r->logon29.forest);
     301                        p->domain_uuid  = r->logon29.domain_uuid;
     302                        p->server_site  = SET_STRING(r->logon29.server_site);
     303                        p->client_site  = SET_STRING(r->logon29.client_site);
     304                        p->next_closest_site = SET_STRING(r->logon29.next_closest_site);
     305
     306                        break;
     307                default:
     308                        return NT_STATUS_INVALID_PARAMETER;
     309        }
     310
     311        return NT_STATUS_OK;
     312}
     313
     314/****************************************************************
     315****************************************************************/
     316
     317static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx,
     318                                  uint32_t flags,
     319                                  struct sockaddr_storage *ss,
     320                                  uint32_t nt_version,
     321                                  union nbt_cldap_netlogon *r)
     322{
     323        DATA_BLOB blob;
     324        enum ndr_err_code ndr_err;
     325        NTSTATUS status;
     326        struct nbt_cldap_netlogon_29 logon29;
     327
     328        status = map_logon29_from_cldap_reply(mem_ctx, flags, ss,
     329                                              nt_version, r, &logon29);
     330        if (!NT_STATUS_IS_OK(status)) {
     331                return status;
     332        }
     333
     334        ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29,
     335                       (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29);
    172336        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    173337                return ndr_map_error2ntstatus(ndr_err);
    174338        }
    175339
    176         if (gencache_lock_entry(key) != 0) {
    177                 data_blob_free(&blob);
    178                 return NT_STATUS_LOCK_NOT_GRANTED;
    179         }
    180 
    181         ret = gencache_set_data_blob(key, &blob, expire_time);
     340        if (logon29.domain) {
     341                status = dsgetdcname_cache_store(mem_ctx, logon29.domain, &blob);
     342                if (!NT_STATUS_IS_OK(status)) {
     343                        goto done;
     344                }
     345                if (logon29.client_site) {
     346                        sitename_store(logon29.domain, logon29.client_site);
     347                }
     348        }
     349        if (logon29.dns_domain) {
     350                status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob);
     351                if (!NT_STATUS_IS_OK(status)) {
     352                        goto done;
     353                }
     354                if (logon29.client_site) {
     355                        sitename_store(logon29.dns_domain, logon29.client_site);
     356                }
     357        }
     358
     359 done:
    182360        data_blob_free(&blob);
    183361
    184         gencache_unlock_entry(key);
    185 
    186         return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
     362        return status;
    187363}
    188364
     
    191367
    192368static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx,
     369                                          struct messaging_context *msg_ctx,
    193370                                          const char *domain_name,
    194371                                          struct GUID *domain_guid,
     
    197374                                          struct netr_DsRGetDCNameInfo *info)
    198375{
    199         struct nbt_cldap_netlogon_5 r;
    200 
    201         /* check if matching entry is older then 15 minutes, if yes, send
    202          * CLDAP/MAILSLOT ping again and store the cached data */
    203 
    204         ZERO_STRUCT(r);
    205 
    206         if (ads_cldap_netlogon(mem_ctx, info->dc_unc,
    207                                info->domain_name, &r)) {
    208 
    209                 dsgetdcname_cache_delete(mem_ctx, domain_name);
    210 
    211                 return dsgetdcname_cache_store(mem_ctx,
    212                                                info->domain_name,
    213                                                info);
    214         }
    215 
    216         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     376        struct netr_DsRGetDCNameInfo *dc_info;
     377
     378        return dsgetdcname(mem_ctx,
     379                           msg_ctx,
     380                           domain_name,
     381                           domain_guid,
     382                           site_name,
     383                           flags | DS_FORCE_REDISCOVERY,
     384                           &dc_info);
     385}
     386
     387/****************************************************************
     388****************************************************************/
     389
     390static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r,
     391                                             uint32_t nt_version)
     392{
     393        switch (nt_version & 0x0000001f) {
     394                case 0:
     395                case 1:
     396                case 16:
     397                case 17:
     398                        return 0;
     399                case 2:
     400                case 3:
     401                case 18:
     402                case 19:
     403                        return r->logon3.server_type;
     404                case 4:
     405                case 5:
     406                case 6:
     407                case 7:
     408                        return r->logon5.server_type;
     409                case 8:
     410                case 9:
     411                case 10:
     412                case 11:
     413                case 12:
     414                case 13:
     415                case 14:
     416                case 15:
     417                        return r->logon13.server_type;
     418                case 20:
     419                case 21:
     420                case 22:
     421                case 23:
     422                case 24:
     423                case 25:
     424                case 26:
     425                case 27:
     426                case 28:
     427                        return r->logon15.server_type;
     428                case 29:
     429                case 30:
     430                case 31:
     431                        return r->logon29.server_type;
     432                default:
     433                        return 0;
     434        }
    217435}
    218436
     
    225443                                             uint32_t req_flags)
    226444{
     445        if (ret_flags == 0) {
     446                return true;
     447        }
     448
    227449        if (req_flags & DS_PDC_REQUIRED)
    228450                RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC);
     
    265487        enum ndr_err_code ndr_err;
    266488        struct netr_DsRGetDCNameInfo *info;
     489        union nbt_cldap_netlogon p;
     490        struct nbt_cldap_netlogon_29 r;
     491        NTSTATUS status;
    267492
    268493        if (!gencache_init()) {
     
    284509        }
    285510
    286         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, info,
    287                       (ndr_pull_flags_fn_t)ndr_pull_netr_DsRGetDCNameInfo);
     511        ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
     512                      (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29);
    288513
    289514        data_blob_free(&blob);
     
    293518        }
    294519
     520        p.logon29 = r;
     521
     522        status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL,
     523                                               29,
     524                                               &p, &info);
     525        if (!NT_STATUS_IS_OK(status)) {
     526                return status;
     527        }
     528
    295529        if (DEBUGLEVEL >= 10) {
    296530                NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info);
     
    317551
    318552static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx,
     553                                   struct messaging_context *msg_ctx,
    319554                                   const char *domain_name,
    320555                                   struct GUID *domain_guid,
     
    339574
    340575        if (expired) {
    341                 status = dsgetdcname_cache_refresh(mem_ctx, domain_name,
     576                status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
     577                                                   domain_name,
    342578                                                   domain_guid, flags,
    343579                                                   site_name, *info);
     
    353589****************************************************************/
    354590
    355 static bool check_allowed_required_flags(uint32_t flags)
     591static bool check_allowed_required_flags(uint32_t flags,
     592                                         const char *site_name)
    356593{
    357594        uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME);
     
    363600
    364601        debug_dsdcinfo_flags(10, flags);
     602
     603        if ((flags & DS_TRY_NEXTCLOSEST_SITE) && site_name) {
     604                return false;
     605        }
    365606
    366607        if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) {
     
    466707        struct ip_service_name *dclist = NULL;
    467708        int count = 0;
    468 
    469         if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) &&
    470             (!(flags & DS_KDC_REQUIRED)) &&
    471             (!(flags & DS_GC_SERVER_REQUIRED)) &&
    472             (!(flags & DS_PDC_REQUIRED))) {
    473                 DEBUG(1,("discover_dc_dns: invalid flags\n"));
    474                 return NT_STATUS_INVALID_PARAMETER;
    475         }
    476709
    477710        if (flags & DS_PDC_REQUIRED) {
     
    491724                                                domain_guid, &dcs, &numdcs);
    492725        } else {
    493                 /* FIXME: ? */
    494                 DEBUG(1,("discover_dc_dns: not enough input\n"));
    495                 status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
     726                status = ads_dns_query_dcs(mem_ctx, domain_name, site_name,
     727                                           &dcs, &numdcs);
    496728        }
    497729
     
    527759                r->port = dcs[count].port;
    528760                r->hostname = dcs[count].hostname;
    529 
    530                 if (!(flags & DS_IP_REQUIRED)) {
    531                         count++;
    532                         continue;
    533                 }
    534761
    535762                /* If we don't have an IP list for a name, lookup it up */
     
    602829
    603830        if (dc_address) {
    604                 info->dc_address = talloc_strdup(mem_ctx, dc_address);
     831                if (!(dc_address[0] == '\\' && dc_address[1] == '\\')) {
     832                        info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s",
     833                                                           dc_address);
     834                } else {
     835                        info->dc_address = talloc_strdup(mem_ctx, dc_address);
     836                }
    605837                NT_STATUS_HAVE_NO_MEMORY(info->dc_address);
    606838        }
     
    617849        }
    618850
    619         if (forest_name) {
     851        if (forest_name && *forest_name) {
    620852                info->forest_name = talloc_strdup(mem_ctx, forest_name);
    621853                NT_STATUS_HAVE_NO_MEMORY(info->forest_name);
     854                flags |= DS_DNS_FOREST;
    622855        }
    623856
     
    638871
    639872        return NT_STATUS_OK;
     873}
     874
     875/****************************************************************
     876****************************************************************/
     877
     878static void map_dc_and_domain_names(uint32_t flags,
     879                                    const char *dc_name,
     880                                    const char *domain_name,
     881                                    const char *dns_dc_name,
     882                                    const char *dns_domain_name,
     883                                    uint32_t *dc_flags,
     884                                    const char **hostname_p,
     885                                    const char **domain_p)
     886{
     887        switch (flags & 0xf0000000) {
     888                case DS_RETURN_FLAT_NAME:
     889                        if (dc_name && domain_name &&
     890                            *dc_name && *domain_name) {
     891                                *hostname_p = dc_name;
     892                                *domain_p = domain_name;
     893                                break;
     894                        }
     895                case DS_RETURN_DNS_NAME:
     896                default:
     897                        if (dns_dc_name && dns_domain_name &&
     898                            *dns_dc_name && *dns_domain_name) {
     899                                *hostname_p = dns_dc_name;
     900                                *domain_p = dns_domain_name;
     901                                *dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER;
     902                                break;
     903                        }
     904                        if (dc_name && domain_name &&
     905                            *dc_name && *domain_name) {
     906                                *hostname_p = dc_name;
     907                                *domain_p = domain_name;
     908                                break;
     909                        }
     910        }
     911}
     912
     913/****************************************************************
     914****************************************************************/
     915
     916static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx,
     917                                              uint32_t flags,
     918                                              struct sockaddr_storage *ss,
     919                                              uint32_t nt_version,
     920                                              union nbt_cldap_netlogon *r,
     921                                              struct netr_DsRGetDCNameInfo **info)
     922{
     923        const char *dc_hostname, *dc_domain_name;
     924        const char *dc_address = NULL;
     925        const char *dc_forest = NULL;
     926        uint32_t dc_address_type = 0;
     927        uint32_t dc_flags = 0;
     928        struct GUID *dc_domain_guid = NULL;
     929        const char *dc_server_site = NULL;
     930        const char *dc_client_site = NULL;
     931
     932        char addr[INET6_ADDRSTRLEN];
     933
     934        if (ss) {
     935                print_sockaddr(addr, sizeof(addr), ss);
     936                dc_address = addr;
     937                dc_address_type = DS_ADDRESS_TYPE_INET;
     938        }
     939
     940        switch (nt_version & 0x0000001f) {
     941                case 0:
     942                case 1:
     943                case 16:
     944                case 17:
     945                        if (!ss) {
     946                                dc_address      = r->logon1.pdc_name;
     947                                dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
     948                        }
     949
     950                        map_dc_and_domain_names(flags,
     951                                                r->logon1.pdc_name,
     952                                                r->logon1.domain_name,
     953                                                NULL,
     954                                                NULL,
     955                                                &dc_flags,
     956                                                &dc_hostname,
     957                                                &dc_domain_name);
     958
     959                        if (flags & DS_PDC_REQUIRED) {
     960                                dc_flags = NBT_SERVER_WRITABLE | NBT_SERVER_PDC;
     961                        }
     962                        break;
     963                case 2:
     964                case 3:
     965                case 18:
     966                case 19:
     967                        if (!ss) {
     968                                dc_address      = r->logon3.pdc_ip;
     969                                dc_address_type = DS_ADDRESS_TYPE_INET;
     970                        }
     971
     972                        map_dc_and_domain_names(flags,
     973                                                r->logon3.pdc_name,
     974                                                r->logon3.domain_name,
     975                                                r->logon3.pdc_dns_name,
     976                                                r->logon3.dns_domain,
     977                                                &dc_flags,
     978                                                &dc_hostname,
     979                                                &dc_domain_name);
     980
     981                        dc_flags        |= r->logon3.server_type;
     982                        dc_forest       = r->logon3.forest;
     983                        dc_domain_guid  = &r->logon3.domain_uuid;
     984
     985                        break;
     986                case 4:
     987                case 5:
     988                case 6:
     989                case 7:
     990                        if (!ss) {
     991                                dc_address      = r->logon5.pdc_name;
     992                                dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
     993                        }
     994
     995                        map_dc_and_domain_names(flags,
     996                                                r->logon5.pdc_name,
     997                                                r->logon5.domain,
     998                                                r->logon5.pdc_dns_name,
     999                                                r->logon5.dns_domain,
     1000                                                &dc_flags,
     1001                                                &dc_hostname,
     1002                                                &dc_domain_name);
     1003
     1004                        dc_flags        |= r->logon5.server_type;
     1005                        dc_forest       = r->logon5.forest;
     1006                        dc_domain_guid  = &r->logon5.domain_uuid;
     1007                        dc_server_site  = r->logon5.server_site;
     1008                        dc_client_site  = r->logon5.client_site;
     1009
     1010                        break;
     1011                case 8:
     1012                case 9:
     1013                case 10:
     1014                case 11:
     1015                case 12:
     1016                case 13:
     1017                case 14:
     1018                case 15:
     1019                        if (!ss) {
     1020                                dc_address      = r->logon13.dc_sock_addr.pdc_ip;
     1021                                dc_address_type = DS_ADDRESS_TYPE_INET;
     1022                        }
     1023
     1024                        map_dc_and_domain_names(flags,
     1025                                                r->logon13.pdc_name,
     1026                                                r->logon13.domain,
     1027                                                r->logon13.pdc_dns_name,
     1028                                                r->logon13.dns_domain,
     1029                                                &dc_flags,
     1030                                                &dc_hostname,
     1031                                                &dc_domain_name);
     1032
     1033                        dc_flags        |= r->logon13.server_type;
     1034                        dc_forest       = r->logon13.forest;
     1035                        dc_domain_guid  = &r->logon13.domain_uuid;
     1036                        dc_server_site  = r->logon13.server_site;
     1037                        dc_client_site  = r->logon13.client_site;
     1038
     1039                        break;
     1040                case 20:
     1041                case 21:
     1042                case 22:
     1043                case 23:
     1044                case 24:
     1045                case 25:
     1046                case 26:
     1047                case 27:
     1048                case 28:
     1049                        if (!ss) {
     1050                                dc_address      = r->logon15.pdc_name;
     1051                                dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
     1052                        }
     1053
     1054                        map_dc_and_domain_names(flags,
     1055                                                r->logon15.pdc_name,
     1056                                                r->logon15.domain,
     1057                                                r->logon15.pdc_dns_name,
     1058                                                r->logon15.dns_domain,
     1059                                                &dc_flags,
     1060                                                &dc_hostname,
     1061                                                &dc_domain_name);
     1062
     1063                        dc_flags        |= r->logon15.server_type;
     1064                        dc_forest       = r->logon15.forest;
     1065                        dc_domain_guid  = &r->logon15.domain_uuid;
     1066                        dc_server_site  = r->logon15.server_site;
     1067                        dc_client_site  = r->logon15.client_site;
     1068
     1069                        break;
     1070                case 29:
     1071                case 30:
     1072                case 31:
     1073                        if (!ss) {
     1074                                dc_address      = r->logon29.dc_sock_addr.pdc_ip;
     1075                                dc_address_type = DS_ADDRESS_TYPE_INET;
     1076                        }
     1077
     1078                        map_dc_and_domain_names(flags,
     1079                                                r->logon29.pdc_name,
     1080                                                r->logon29.domain,
     1081                                                r->logon29.pdc_dns_name,
     1082                                                r->logon29.dns_domain,
     1083                                                &dc_flags,
     1084                                                &dc_hostname,
     1085                                                &dc_domain_name);
     1086
     1087                        dc_flags        |= r->logon29.server_type;
     1088                        dc_forest       = r->logon29.forest;
     1089                        dc_domain_guid  = &r->logon29.domain_uuid;
     1090                        dc_server_site  = r->logon29.server_site;
     1091                        dc_client_site  = r->logon29.client_site;
     1092
     1093                        break;
     1094                default:
     1095                        return NT_STATUS_INVALID_PARAMETER;
     1096        }
     1097
     1098        return make_domain_controller_info(mem_ctx,
     1099                                           dc_hostname,
     1100                                           dc_address,
     1101                                           dc_address_type,
     1102                                           dc_domain_guid,
     1103                                           dc_domain_name,
     1104                                           dc_forest,
     1105                                           dc_flags,
     1106                                           dc_server_site,
     1107                                           dc_client_site,
     1108                                           info);
     1109}
     1110
     1111/****************************************************************
     1112****************************************************************/
     1113
     1114static uint32_t map_ds_flags_to_nt_version(uint32_t flags)
     1115{
     1116        uint32_t nt_version = 0;
     1117
     1118        if (flags & DS_PDC_REQUIRED) {
     1119                nt_version |= NETLOGON_VERSION_PDC;
     1120        }
     1121
     1122        if (flags & DS_GC_SERVER_REQUIRED) {
     1123                nt_version |= NETLOGON_VERSION_GC;
     1124        }
     1125
     1126        if (flags & DS_TRY_NEXTCLOSEST_SITE) {
     1127                nt_version |= NETLOGON_VERSION_WITH_CLOSEST_SITE;
     1128        }
     1129
     1130        if (flags & DS_IP_REQUIRED) {
     1131                nt_version |= NETLOGON_VERSION_IP;
     1132        }
     1133
     1134        return nt_version;
    6401135}
    6411136
     
    6521147        int i = 0;
    6531148        bool valid_dc = false;
    654         struct nbt_cldap_netlogon_5 r;
    655         const char *dc_hostname, *dc_domain_name;
    656         const char *dc_address;
    657         uint32_t dc_address_type;
    658         uint32_t dc_flags;
     1149        union nbt_cldap_netlogon *r = NULL;
     1150        uint32_t nt_version = NETLOGON_VERSION_5 |
     1151                              NETLOGON_VERSION_5EX;
     1152        uint32_t ret_flags = 0;
     1153        NTSTATUS status;
     1154
     1155        nt_version |= map_ds_flags_to_nt_version(flags);
    6591156
    6601157        for (i=0; i<num_dcs; i++) {
    6611158
    662                 ZERO_STRUCT(r);
    663 
    6641159                DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname));
    6651160
    666                 if ((ads_cldap_netlogon(mem_ctx, dclist[i].hostname,
    667                                         domain_name, &r)) &&
    668                     (check_cldap_reply_required_flags(r.server_type, flags))) {
    669                         valid_dc = true;
    670                         break;
     1161                if (ads_cldap_netlogon(mem_ctx, dclist[i].hostname,
     1162                                        domain_name,
     1163                                        &nt_version,
     1164                                        &r))
     1165                {
     1166                        ret_flags = get_cldap_reply_server_flags(r, nt_version);
     1167
     1168                        if (check_cldap_reply_required_flags(ret_flags, flags)) {
     1169                                valid_dc = true;
     1170                                break;
     1171                        }
    6711172                }
    6721173
     
    6781179        }
    6791180
    680         dc_flags = r.server_type;
    681 
    682         if (flags & DS_RETURN_FLAT_NAME) {
    683                 if (!strlen(r.pdc_name) || !strlen(r.domain)) {
    684                         return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    685                 }
    686                 dc_hostname = r.pdc_name;
    687                 dc_domain_name = r.domain;
    688         } else if (flags & DS_RETURN_DNS_NAME) {
    689                 if (!strlen(r.pdc_dns_name) || !strlen(r.dns_domain)) {
    690                         return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    691                 }
    692                 dc_hostname = r.pdc_dns_name;
    693                 dc_domain_name = r.dns_domain;
    694                 dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER;
    695         } else {
    696                 /* FIXME */
    697                 dc_hostname = r.pdc_dns_name;
    698                 dc_domain_name = r.dns_domain;
    699                 dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER;
    700         }
    701 
    702         if (flags & DS_IP_REQUIRED) {
    703                 char addr[INET6_ADDRSTRLEN];
    704                 print_sockaddr(addr, sizeof(addr), &dclist[i].ss);
    705                 dc_address = talloc_asprintf(mem_ctx, "\\\\%s",
    706                                                 addr);
    707                 dc_address_type = DS_ADDRESS_TYPE_INET;
    708         } else {
    709                 dc_address = talloc_asprintf(mem_ctx, "\\\\%s",
    710                                              r.pdc_name);
    711                 dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
    712         }
    713         NT_STATUS_HAVE_NO_MEMORY(dc_address);
    714 
    715         if (r.forest) {
    716                 dc_flags |= DS_DNS_FOREST;
    717         }
    718 
    719         return make_domain_controller_info(mem_ctx,
    720                                            dc_hostname,
    721                                            dc_address,
    722                                            dc_address_type,
    723                                            &r.domain_uuid,
    724                                            dc_domain_name,
    725                                            r.forest,
    726                                            dc_flags,
    727                                            r.server_site,
    728                                            r.client_site,
    729                                            info);
    730 
     1181        status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
     1182                                               nt_version, r, info);
     1183        if (NT_STATUS_IS_OK(status)) {
     1184                return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
     1185                                         nt_version, r);
     1186        }
     1187
     1188        return status;
    7311189}
    7321190
     
    7621220
    7631221static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
     1222                                   struct messaging_context *msg_ctx,
    7641223                                   const char *domain_name,
    7651224                                   uint32_t flags,
     
    7711230        struct ip_service ip_list;
    7721231        enum nbt_name_type name_type = NBT_NAME_LOGON;
    773 
     1232        NTSTATUS status;
    7741233        int i;
    775         const char *dc_hostname, *dc_domain_name;
    776         const char *dc_address;
    777         uint32_t dc_address_type;
    778         uint32_t dc_flags = 0;
    7791234        const char *dc_name = NULL;
    7801235        fstring tmp_dc_name;
    781         struct messaging_context *msg_ctx = msg_context(mem_ctx);
     1236        union nbt_cldap_netlogon *r = NULL;
     1237        bool store_cache = false;
     1238        uint32_t nt_version = NETLOGON_VERSION_1 |
     1239                              NETLOGON_VERSION_5 |
     1240                              NETLOGON_VERSION_5EX_WITH_IP;
     1241
     1242        if (!msg_ctx) {
     1243                msg_ctx = msg_context(mem_ctx);
     1244        }
    7821245
    7831246        if (flags & DS_PDC_REQUIRED) {
    7841247                name_type = NBT_NAME_PDC;
    7851248        }
     1249
     1250        nt_version |= map_ds_flags_to_nt_version(flags);
    7861251
    7871252        DEBUG(10,("process_dc_netbios\n"));
     
    7971262
    7981263                if (send_getdc_request(mem_ctx, msg_ctx,
    799                                        &dclist[i].ss, domain_name, NULL))
     1264                                       &dclist[i].ss, domain_name,
     1265                                       NULL, nt_version))
    8001266                {
    8011267                        int k;
    802                         smb_msleep(100);
     1268                        smb_msleep(300);
    8031269                        for (k=0; k<5; k++) {
    8041270                                if (receive_getdc_response(mem_ctx,
    8051271                                                           &dclist[i].ss,
    8061272                                                           domain_name,
    807                                                            &dc_name)) {
     1273                                                           &nt_version,
     1274                                                           &dc_name,
     1275                                                           &r)) {
     1276                                        store_cache = true;
    8081277                                        namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list);
    809                                         dc_hostname = dc_name;
    810                                         dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name);
    811                                         NT_STATUS_HAVE_NO_MEMORY(dc_domain_name);
    8121278                                        goto make_reply;
    8131279                                }
    814                                 smb_msleep(500);
     1280                                smb_msleep(1500);
    8151281                        }
    8161282                }
     
    8221288                                     tmp_dc_name))
    8231289                {
    824                         dc_hostname = tmp_dc_name;
    825                         dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name);
    826                         namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list);
     1290                        struct nbt_cldap_netlogon_1 logon1;
     1291
     1292                        r = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon);
     1293                        NT_STATUS_HAVE_NO_MEMORY(r);
     1294
     1295                        ZERO_STRUCT(logon1);
     1296
     1297                        nt_version = NETLOGON_VERSION_1;
     1298
     1299                        logon1.nt_version = nt_version;
     1300                        logon1.pdc_name = tmp_dc_name;
     1301                        logon1.domain_name = talloc_strdup_upper(mem_ctx, domain_name);
     1302                        NT_STATUS_HAVE_NO_MEMORY(logon1.domain_name);
     1303
     1304                        r->logon1 = logon1;
     1305
     1306                        namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);
     1307
    8271308                        goto make_reply;
    8281309                }
     
    8331314 make_reply:
    8341315
    835         if (flags & DS_IP_REQUIRED) {
    836                 char addr[INET6_ADDRSTRLEN];
    837                 print_sockaddr(addr, sizeof(addr), &dclist[i].ss);
    838                 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr);
    839                 dc_address_type = DS_ADDRESS_TYPE_INET;
    840         } else {
    841                 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", dc_hostname);
    842                 dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
    843         }
    844 
    845         if (flags & DS_PDC_REQUIRED) {
    846                 dc_flags |= NBT_SERVER_PDC | NBT_SERVER_WRITABLE;
    847         }
    848 
    849         return make_domain_controller_info(mem_ctx,
    850                                            dc_hostname,
    851                                            dc_address,
    852                                            dc_address_type,
    853                                            NULL,
    854                                            dc_domain_name,
    855                                            NULL,
    856                                            dc_flags,
    857                                            NULL,
    858                                            NULL,
    859                                            info);
     1316        status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
     1317                                               nt_version, r, info);
     1318        if (NT_STATUS_IS_OK(status) && store_cache) {
     1319                return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
     1320                                         nt_version, r);
     1321        }
     1322
     1323        return status;
    8601324}
    8611325
     
    8641328
    8651329static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx,
     1330                                       struct messaging_context *msg_ctx,
    8661331                                       const char *domain_name,
    8671332                                       struct GUID *domain_guid,
     
    8821347                NT_STATUS_NOT_OK_RETURN(status);
    8831348
    884                 return process_dc_netbios(mem_ctx, domain_name, flags,
     1349                return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags,
    8851350                                          dclist, num_dcs, info);
    8861351        }
     
    9121377        NT_STATUS_NOT_OK_RETURN(status);
    9131378
    914         return process_dc_netbios(mem_ctx, domain_name, flags, dclist,
     1379        return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags, dclist,
    9151380                                  num_dcs, info);
    9161381}
     
    9231388
    9241389NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
     1390                     struct messaging_context *msg_ctx,
    9251391                     const char *domain_name,
    9261392                     struct GUID *domain_guid,
     
    9311397        NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    9321398        struct netr_DsRGetDCNameInfo *myinfo = NULL;
     1399        char *query_site = NULL;
    9331400
    9341401        DEBUG(10,("dsgetdcname: domain_name: %s, "
     
    9401407        *info = NULL;
    9411408
    942         if (!check_allowed_required_flags(flags)) {
     1409        if (!check_allowed_required_flags(flags, site_name)) {
    9431410                DEBUG(0,("invalid flags specified\n"));
    9441411                return NT_STATUS_INVALID_PARAMETER;
    9451412        }
    9461413
     1414        if (!site_name) {
     1415                query_site = sitename_fetch(domain_name);
     1416        } else {
     1417                query_site = SMB_STRDUP(site_name);
     1418        }
     1419
    9471420        if (flags & DS_FORCE_REDISCOVERY) {
    9481421                goto rediscover;
    9491422        }
    9501423
    951         status = dsgetdcname_cached(mem_ctx, domain_name, domain_guid,
    952                                     flags, site_name, &myinfo);
     1424        status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid,
     1425                                    flags, query_site, &myinfo);
    9531426        if (NT_STATUS_IS_OK(status)) {
    9541427                *info = myinfo;
    955                 return status;
     1428                goto done;
    9561429        }
    9571430
    9581431        if (flags & DS_BACKGROUND_ONLY) {
    959                 return status;
     1432                goto done;
    9601433        }
    9611434
    9621435 rediscover:
    963         status = dsgetdcname_rediscover(mem_ctx, domain_name,
    964                                         domain_guid, flags, site_name,
     1436        status = dsgetdcname_rediscover(mem_ctx, msg_ctx, domain_name,
     1437                                        domain_guid, flags, query_site,
    9651438                                        &myinfo);
    9661439
    9671440        if (NT_STATUS_IS_OK(status)) {
    968                 dsgetdcname_cache_store(mem_ctx, domain_name, myinfo);
    9691441                *info = myinfo;
    9701442        }
    9711443
     1444 done:
     1445        SAFE_FREE(query_site);
     1446
    9721447        return status;
    9731448}
Note: See TracChangeset for help on using the changeset viewer.