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/kerberos.c

    r860 r988  
    2727#include "../librpc/gen_ndr/ndr_misc.h"
    2828#include "libads/kerberos_proto.h"
     29#include "libads/cldap.h"
    2930#include "secrets.h"
     31#include "../lib/tsocket/tsocket.h"
    3032
    3133#ifdef HAVE_KRB5
    32 
    33 #define DEFAULT_KRB5_PORT 88
    3434
    3535#define LIBADS_CCACHE_NAME "MEMORY:libads"
     
    4848{
    4949        if (num_prompts == 0) return 0;
    50 
     50#if HAVE_KRB5_PROMPT_TYPE
     51
     52        /*
     53         * only heimdal has a prompt type and we need to deal with it here to
     54         * avoid loops.
     55         *
     56         * removing the prompter completely is not an option as at least these
     57         * versions would crash: heimdal-1.0.2 and heimdal-1.1. Later heimdal
     58         * version have looping detection and return with a proper error code.
     59         */
     60
     61        if ((num_prompts == 2) &&
     62            (prompts[0].type == KRB5_PROMPT_TYPE_NEW_PASSWORD) &&
     63            (prompts[1].type == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN)) {
     64                /*
     65                 * We don't want to change passwords here. We're
     66                 * called from heimal when the KDC returns
     67                 * KRB5KDC_ERR_KEY_EXPIRED, but at this point we don't
     68                 * have the chance to ask the user for a new
     69                 * password. If we return 0 (i.e. success), we will be
     70                 * spinning in the endless for-loop in
     71                 * change_password() in
     72                 * source4/heimdal/lib/krb5/init_creds_pw.c:526ff
     73                 */
     74                return KRB5KDC_ERR_KEY_EXPIRED;
     75        }
     76#endif /* HAVE_KRB5_PROMPT_TYPE */
    5177        memset(prompts[0].reply->data, '\0', prompts[0].reply->length);
    5278        if (prompts[0].reply->length > 0) {
     
    218244#endif
    219245        if (add_netbios_addr) {
    220                 if ((code = smb_krb5_gen_netbios_krb5_address(&addr))) {
     246                if ((code = smb_krb5_gen_netbios_krb5_address(&addr,
     247                                                        lp_netbios_name()))) {
    221248                        goto out;
    222249                }
     
    224251        }
    225252
    226         if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password),
    227                                                  kerb_prompter, CONST_DISCARD(char *,password),
     253        if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, discard_const_p(char,password),
     254                                                 kerb_prompter, discard_const_p(char, password),
    228255                                                 0, NULL, opt))) {
    229256                goto out;
     
    353380        fstring salt;
    354381
    355         fstr_sprintf( salt, "host/%s.%s@", global_myname(), lp_realm() );
    356         strlower_m( salt );
     382        fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
     383        (void)strlower_m( salt );
    357384        fstrcat( salt, lp_realm() );
    358385
     
    406433************************************************************************/
    407434
     435static
    408436char* kerberos_secrets_fetch_des_salt( void )
    409437{
     
    412440        if ( (key = des_salt_key()) == NULL ) {
    413441                DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
    414                 return False;
     442                return NULL;
    415443        }
    416444
     
    420448
    421449        return salt;
    422 }
    423 
    424 /************************************************************************
    425  Routine to get the default realm from the kerberos credentials cache.
    426  Caller must free if the return value is not NULL.
    427 ************************************************************************/
    428 
    429 char *kerberos_get_default_realm_from_ccache( void )
    430 {
    431         char *realm = NULL;
    432         krb5_context ctx = NULL;
    433         krb5_ccache cc = NULL;
    434         krb5_principal princ = NULL;
    435 
    436         initialize_krb5_error_table();
    437         if (krb5_init_context(&ctx)) {
    438                 return NULL;
    439         }
    440 
    441         DEBUG(5,("kerberos_get_default_realm_from_ccache: "
    442                 "Trying to read krb5 cache: %s\n",
    443                 krb5_cc_default_name(ctx)));
    444         if (krb5_cc_default(ctx, &cc)) {
    445                 DEBUG(0,("kerberos_get_default_realm_from_ccache: "
    446                         "failed to read default cache\n"));
    447                 goto out;
    448         }
    449         if (krb5_cc_get_principal(ctx, cc, &princ)) {
    450                 DEBUG(0,("kerberos_get_default_realm_from_ccache: "
    451                         "failed to get default principal\n"));
    452                 goto out;
    453         }
    454 
    455 #if defined(HAVE_KRB5_PRINCIPAL_GET_REALM)
    456         realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ));
    457 #elif defined(HAVE_KRB5_PRINC_REALM)
    458         {
    459                 krb5_data *realm_data = krb5_princ_realm(ctx, princ);
    460                 realm = SMB_STRNDUP(realm_data->data, realm_data->length);
    461         }
    462 #endif
    463 
    464   out:
    465 
    466         if (ctx) {
    467                 if (princ) {
    468                         krb5_free_principal(ctx, princ);
    469                 }
    470                 if (cc) {
    471                         krb5_cc_close(ctx, cc);
    472                 }
    473                 krb5_free_context(ctx);
    474         }
    475 
    476         return realm;
    477 }
    478 
    479 /************************************************************************
    480  Routine to get the realm from a given DNS name. Returns malloc'ed memory.
    481  Caller must free() if the return value is not NULL.
    482 ************************************************************************/
    483 
    484 char *kerberos_get_realm_from_hostname(const char *hostname)
    485 {
    486 #if defined(HAVE_KRB5_GET_HOST_REALM) && defined(HAVE_KRB5_FREE_HOST_REALM)
    487 #if defined(HAVE_KRB5_REALM_TYPE)
    488         /* Heimdal. */
    489         krb5_realm *realm_list = NULL;
    490 #else
    491         /* MIT */
    492         char **realm_list = NULL;
    493 #endif
    494         char *realm = NULL;
    495         krb5_error_code kerr;
    496         krb5_context ctx = NULL;
    497 
    498         initialize_krb5_error_table();
    499         if (krb5_init_context(&ctx)) {
    500                 return NULL;
    501         }
    502 
    503         kerr = krb5_get_host_realm(ctx, hostname, &realm_list);
    504         if (kerr != 0) {
    505                 DEBUG(3,("kerberos_get_realm_from_hostname %s: "
    506                         "failed %s\n",
    507                         hostname ? hostname : "(NULL)",
    508                         error_message(kerr) ));
    509                 goto out;
    510         }
    511 
    512         if (realm_list && realm_list[0]) {
    513                 realm = SMB_STRDUP(realm_list[0]);
    514         }
    515 
    516   out:
    517 
    518         if (ctx) {
    519                 if (realm_list) {
    520                         krb5_free_host_realm(ctx, realm_list);
    521                         realm_list = NULL;
    522                 }
    523                 krb5_free_context(ctx);
    524                 ctx = NULL;
    525         }
    526         return realm;
    527 #else
    528         return NULL;
    529 #endif
    530450}
    531451
     
    537457 ************************************************************************/
    538458
     459static
    539460krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
    540461                                                        krb5_principal host_princ,
     
    567488
    568489        return ret_princ;
     490}
     491
     492int create_kerberos_key_from_string(krb5_context context,
     493                                        krb5_principal host_princ,
     494                                        krb5_data *password,
     495                                        krb5_keyblock *key,
     496                                        krb5_enctype enctype,
     497                                        bool no_salt)
     498{
     499        krb5_principal salt_princ = NULL;
     500        int ret;
     501        /*
     502         * Check if we've determined that the KDC is salting keys for this
     503         * principal/enctype in a non-obvious way.  If it is, try to match
     504         * its behavior.
     505         */
     506        if (no_salt) {
     507                KRB5_KEY_DATA(key) = (KRB5_KEY_DATA_CAST *)SMB_MALLOC(password->length);
     508                if (!KRB5_KEY_DATA(key)) {
     509                        return ENOMEM;
     510                }
     511                memcpy(KRB5_KEY_DATA(key), password->data, password->length);
     512                KRB5_KEY_LENGTH(key) = password->length;
     513                KRB5_KEY_TYPE(key) = enctype;
     514                return 0;
     515        }
     516        salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype);
     517        ret = smb_krb5_create_key_from_string(context,
     518                                              salt_princ ? salt_princ : host_princ,
     519                                              NULL,
     520                                              password,
     521                                              enctype,
     522                                              key);
     523        if (salt_princ) {
     524                krb5_free_principal(context, salt_princ);
     525        }
     526        return ret;
    569527}
    570528
     
    664622************************************************************************/
    665623
    666 static char *print_kdc_line(char *mem_ctx,
    667                         const char *prev_line,
    668                         const struct sockaddr_storage *pss,
    669                         const char *kdc_name)
    670 {
    671         char *kdc_str = NULL;
    672 
    673         if (pss->ss_family == AF_INET) {
    674                 kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
    675                                         prev_line,
    676                                         print_canonical_sockaddr(mem_ctx, pss));
    677         } else {
    678                 char addr[INET6_ADDRSTRLEN];
    679                 uint16_t port = get_sockaddr_port(pss);
    680 
    681                 DEBUG(10,("print_kdc_line: IPv6 case for kdc_name: %s, port: %d\n",
    682                         kdc_name, port));
    683 
    684                 if (port != 0 && port != DEFAULT_KRB5_PORT) {
    685                         /* Currently for IPv6 we can't specify a non-default
    686                            krb5 port with an address, as this requires a ':'.
    687                            Resolve to a name. */
    688                         char hostname[MAX_DNS_NAME_LENGTH];
    689                         int ret = sys_getnameinfo((const struct sockaddr *)pss,
    690                                         sizeof(*pss),
    691                                         hostname, sizeof(hostname),
    692                                         NULL, 0,
    693                                         NI_NAMEREQD);
    694                         if (ret) {
    695                                 DEBUG(0,("print_kdc_line: can't resolve name "
    696                                         "for kdc with non-default port %s. "
    697                                         "Error %s\n.",
    698                                         print_canonical_sockaddr(mem_ctx, pss),
    699                                         gai_strerror(ret)));
    700                                 return NULL;
    701                         }
    702                         /* Success, use host:port */
    703                         kdc_str = talloc_asprintf(mem_ctx,
    704                                         "%s\tkdc = %s:%u\n",
    705                                         prev_line,
    706                                         hostname,
    707                                         (unsigned int)port);
    708                 } else {
    709 
    710                         /* no krb5 lib currently supports "kdc = ipv6 address"
    711                          * at all, so just fill in just the kdc_name if we have
    712                          * it and let the krb5 lib figure out the appropriate
    713                          * ipv6 address - gd */
    714 
    715                         if (kdc_name) {
    716                                 kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
    717                                                 prev_line, kdc_name);
    718                         } else {
    719                                 kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
    720                                                 prev_line,
    721                                                 print_sockaddr(addr,
    722                                                         sizeof(addr),
    723                                                         pss));
    724                         }
    725                 }
    726         }
    727         return kdc_str;
    728 }
    729 
    730624/************************************************************************
    731625 Create a string list of available kdc's, possibly searching by sitename.
     
    736630************************************************************************/
    737631
     632static void add_sockaddr_unique(struct sockaddr_storage *addrs, int *num_addrs,
     633                                const struct sockaddr_storage *addr)
     634{
     635        int i;
     636
     637        for (i=0; i<*num_addrs; i++) {
     638                if (sockaddr_equal((const struct sockaddr *)&addrs[i],
     639                                   (const struct sockaddr *)addr)) {
     640                        return;
     641                }
     642        }
     643        addrs[i] = *addr;
     644        *num_addrs += 1;
     645}
     646
     647/* print_canonical_sockaddr prints an ipv6 addr in the form of
     648* [ipv6.addr]. This string, when put in a generated krb5.conf file is not
     649* always properly dealt with by some older krb5 libraries. Adding the hard-coded
     650* portnumber workarounds the issue. - gd */
     651
     652static char *print_canonical_sockaddr_with_port(TALLOC_CTX *mem_ctx,
     653                                                const struct sockaddr_storage *pss)
     654{
     655        char *str = NULL;
     656
     657        str = print_canonical_sockaddr(mem_ctx, pss);
     658        if (str == NULL) {
     659                return NULL;
     660        }
     661
     662        if (pss->ss_family != AF_INET6) {
     663                return str;
     664        }
     665
     666#if defined(HAVE_IPV6)
     667        str = talloc_asprintf_append(str, ":88");
     668#endif
     669        return str;
     670}
     671
    738672static char *get_kdc_ip_string(char *mem_ctx,
    739673                const char *realm,
    740674                const char *sitename,
    741                 struct sockaddr_storage *pss,
    742                 const char *kdc_name)
    743 {
     675                const struct sockaddr_storage *pss)
     676{
     677        TALLOC_CTX *frame = talloc_stackframe();
    744678        int i;
    745679        struct ip_service *ip_srv_site = NULL;
     
    747681        int count_site = 0;
    748682        int count_nonsite;
    749         char *kdc_str = print_kdc_line(mem_ctx, "", pss, kdc_name);
     683        int num_dcs;
     684        struct sockaddr_storage *dc_addrs;
     685        struct tsocket_address **dc_addrs2 = NULL;
     686        const struct tsocket_address * const *dc_addrs3 = NULL;
     687        char *result = NULL;
     688        struct netlogon_samlogon_response **responses = NULL;
     689        NTSTATUS status;
     690        char *kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n", "",
     691                                        print_canonical_sockaddr_with_port(mem_ctx, pss));
    750692
    751693        if (kdc_str == NULL) {
     694                TALLOC_FREE(frame);
    752695                return NULL;
    753696        }
     
    759702
    760703        if (sitename) {
    761 
    762704                get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
    763 
    764                 for (i = 0; i < count_site; i++) {
    765                         if (sockaddr_equal((struct sockaddr *)&ip_srv_site[i].ss,
    766                                                    (struct sockaddr *)pss)) {
    767                                 continue;
    768                         }
    769                         /* Append to the string - inefficient
    770                          * but not done often. */
    771                         kdc_str = print_kdc_line(mem_ctx,
    772                                                 kdc_str,
    773                                                 &ip_srv_site[i].ss,
    774                                                 NULL);
    775                         if (!kdc_str) {
    776                                 SAFE_FREE(ip_srv_site);
    777                                 return NULL;
    778                         }
    779                 }
     705                DEBUG(10, ("got %d addresses from site %s search\n", count_site,
     706                           sitename));
    780707        }
    781708
     
    783710
    784711        get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite);
     712        DEBUG(10, ("got %d addresses from site-less search\n", count_nonsite));
     713
     714        dc_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
     715                                count_site + count_nonsite);
     716        if (dc_addrs == NULL) {
     717                goto out;
     718        }
     719
     720        num_dcs = 0;
     721
     722        for (i = 0; i < count_site; i++) {
     723                if (!sockaddr_equal(
     724                        (const struct sockaddr *)pss,
     725                        (const struct sockaddr *)&ip_srv_site[i].ss)) {
     726                        add_sockaddr_unique(dc_addrs, &num_dcs,
     727                                            &ip_srv_site[i].ss);
     728                }
     729        }
    785730
    786731        for (i = 0; i < count_nonsite; i++) {
    787                 int j;
    788 
    789                 if (sockaddr_equal((struct sockaddr *)&ip_srv_nonsite[i].ss, (struct sockaddr *)pss)) {
     732                if (!sockaddr_equal(
     733                        (const struct sockaddr *)pss,
     734                        (const struct sockaddr *)&ip_srv_nonsite[i].ss)) {
     735                        add_sockaddr_unique(dc_addrs, &num_dcs,
     736                                            &ip_srv_nonsite[i].ss);
     737                }
     738        }
     739
     740        dc_addrs2 = talloc_zero_array(talloc_tos(),
     741                                      struct tsocket_address *,
     742                                      num_dcs);
     743
     744        DEBUG(10, ("%d additional KDCs to test\n", num_dcs));
     745        if (num_dcs == 0) {
     746                goto out;
     747        }
     748        if (dc_addrs2 == NULL) {
     749                goto out;
     750        }
     751
     752        for (i=0; i<num_dcs; i++) {
     753                char addr[INET6_ADDRSTRLEN];
     754                int ret;
     755
     756                print_sockaddr(addr, sizeof(addr), &dc_addrs[i]);
     757
     758                ret = tsocket_address_inet_from_strings(dc_addrs2, "ip",
     759                                                        addr, LDAP_PORT,
     760                                                        &dc_addrs2[i]);
     761                if (ret != 0) {
     762                        status = map_nt_error_from_unix(errno);
     763                        DEBUG(2,("Failed to create tsocket_address for %s - %s\n",
     764                                 addr, nt_errstr(status)));
     765                        goto out;
     766                }
     767        }
     768
     769        dc_addrs3 = (const struct tsocket_address * const *)dc_addrs2;
     770
     771        status = cldap_multi_netlogon(talloc_tos(),
     772                        dc_addrs3, num_dcs,
     773                        realm, lp_netbios_name(),
     774                        NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX,
     775                        MIN(num_dcs, 3), timeval_current_ofs(3, 0), &responses);
     776        TALLOC_FREE(dc_addrs2);
     777        dc_addrs3 = NULL;
     778
     779        if (!NT_STATUS_IS_OK(status)) {
     780                DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: "
     781                          "%s\n", nt_errstr(status)));
     782                goto out;
     783        }
     784
     785        for (i=0; i<num_dcs; i++) {
     786                char *new_kdc_str;
     787
     788                if (responses[i] == NULL) {
    790789                        continue;
    791790                }
    792791
    793                 /* Ensure this isn't an IP already seen (YUK! this is n*n....) */
    794                 for (j = 0; j < count_site; j++) {
    795                         if (sockaddr_equal((struct sockaddr *)&ip_srv_nonsite[i].ss,
    796                                                 (struct sockaddr *)&ip_srv_site[j].ss)) {
    797                                 break;
    798                         }
    799                         /* As the lists are sorted we can break early if nonsite > site. */
    800                         if (ip_service_compare(&ip_srv_nonsite[i], &ip_srv_site[j]) > 0) {
    801                                 break;
    802                         }
    803                 }
    804                 if (j != i) {
    805                         continue;
    806                 }
    807 
    808792                /* Append to the string - inefficient but not done often. */
    809                 kdc_str = print_kdc_line(mem_ctx,
    810                                 kdc_str,
    811                                 &ip_srv_nonsite[i].ss,
    812                                 NULL);
    813                 if (!kdc_str) {
    814                         SAFE_FREE(ip_srv_site);
    815                         SAFE_FREE(ip_srv_nonsite);
    816                         return NULL;
    817                 }
    818         }
    819 
    820 
     793                new_kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n",
     794                                              kdc_str,
     795                                              print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
     796                if (new_kdc_str == NULL) {
     797                        goto out;
     798                }
     799                TALLOC_FREE(kdc_str);
     800                kdc_str = new_kdc_str;
     801        }
     802
     803out:
     804        DEBUG(10, ("get_kdc_ip_string: Returning %s\n", kdc_str));
     805
     806        result = kdc_str;
    821807        SAFE_FREE(ip_srv_site);
    822808        SAFE_FREE(ip_srv_nonsite);
    823 
    824         DEBUG(10,("get_kdc_ip_string: Returning %s\n",
    825                 kdc_str ));
    826 
    827         return kdc_str;
     809        TALLOC_FREE(frame);
     810        return result;
    828811}
    829812
     
    838821                                                const char *domain,
    839822                                                const char *sitename,
    840                                                 struct sockaddr_storage *pss,
    841                                                 const char *kdc_name)
     823                                                const struct sockaddr_storage *pss)
    842824{
    843825        char *dname;
     
    852834        bool result = false;
    853835        char *aes_enctypes = NULL;
     836        mode_t mask;
    854837
    855838        if (!lp_create_krb5_conf()) {
     
    863846        }
    864847
    865         if (domain == NULL || pss == NULL || kdc_name == NULL) {
     848        if (domain == NULL || pss == NULL) {
    866849                return false;
    867850        }
     
    892875
    893876        realm_upper = talloc_strdup(fname, realm);
    894         strupper_m(realm_upper);
    895 
    896         kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss, kdc_name);
     877        if (!strupper_m(realm_upper)) {
     878                goto done;
     879        }
     880
     881        kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss);
    897882        if (!kdc_ip_string) {
    898883                goto done;
     
    921906                                        "\tdefault_tgs_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
    922907                                        "\tdefault_tkt_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
    923                                         "\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
     908                                        "\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
     909                                        "\tdns_lookup_realm = false\n\n"
    924910                                        "[realms]\n\t%s = {\n"
    925                                         "\t%s\t}\n",
     911                                        "%s\t}\n",
    926912                                        realm_upper, aes_enctypes, aes_enctypes, aes_enctypes,
    927913                                        realm_upper, kdc_ip_string);
     
    933919        flen = strlen(file_contents);
    934920
     921        mask = umask(S_IRWXO | S_IRWXG);
    935922        fd = mkstemp(tmpname);
     923        umask(mask);
    936924        if (fd == -1) {
    937925                DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed,"
     
    989977
    990978        if (strequal(realm, lp_realm())) {
    991                 char linkpath[PATH_MAX+1];
    992                 int lret;
    993 
    994                 lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1);
    995                 if (lret != -1) {
    996                         linkpath[lret] = '\0';
    997                 }
    998 
    999                 if (lret != -1 || strcmp(linkpath, fname) == 0) {
    1000                         /* Symlink already exists. */
    1001                         goto done;
     979                SMB_STRUCT_STAT sbuf;
     980
     981                if (sys_lstat(SYSTEM_KRB5_CONF_PATH, &sbuf, false) == 0) {
     982                        if (S_ISLNK(sbuf.st_ex_mode) && sbuf.st_ex_size) {
     983                                int lret;
     984                                size_t alloc_size = sbuf.st_ex_size + 1;
     985                                char *linkpath = talloc_array(talloc_tos(), char,
     986                                                alloc_size);
     987                                if (!linkpath) {
     988                                        goto done;
     989                                }
     990                                lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath,
     991                                                alloc_size - 1);
     992                                if (lret == -1) {
     993                                        TALLOC_FREE(linkpath);
     994                                        goto done;
     995                                }
     996                                linkpath[lret] = '\0';
     997
     998                                if (strcmp(linkpath, fname) == 0) {
     999                                        /* Symlink already exists. */
     1000                                        TALLOC_FREE(linkpath);
     1001                                        goto done;
     1002                                }
     1003                                TALLOC_FREE(linkpath);
     1004                        }
    10021005                }
    10031006
    10041007                /* Try and replace with a symlink. */
    10051008                if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) {
    1006                         const char *newpath = SYSTEM_KRB5_CONF_PATH ## ".saved";
     1009                        const char *newpath = SYSTEM_KRB5_CONF_PATH ".saved";
    10071010                        if (errno != EEXIST) {
    10081011                                DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink "
Note: See TracChangeset for help on using the changeset viewer.