Ignore:
Timestamp:
Jan 15, 2010, 8:23:30 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update Samba 3.3 to 3.3.10 (source)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.3.x/source/client/cifs.upcall.c

    r206 r370  
    22* CIFS user-space helper.
    33* Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
     4* Copyright (C) Jeff Layton (jlayton@redhat.com) 2009
    45*
    56* Used by /sbin/request-key for handling
     
    2627
    2728#include "includes.h"
     29#include "smb_krb5.h"
    2830#include <keyutils.h>
     31#include <getopt.h>
    2932
    3033#include "cifs_spnego.h"
    3134
    32 const char *CIFSSPNEGO_VERSION = "1.2";
     35#define CIFS_DEFAULT_KRB5_DIR           "/tmp"
     36#define CIFS_DEFAULT_KRB5_PREFIX        "krb5cc_"
     37
     38#define MAX_CCNAME_LEN                  PATH_MAX + 5
     39
     40const char *CIFSSPNEGO_VERSION = "1.3";
    3341static const char *prog = "cifs.upcall";
    34 typedef enum _secType {
     42typedef enum _sectype {
    3543        NONE = 0,
    3644        KRB5,
    3745        MS_KRB5
    38 } secType_t;
     46} sectype_t;
     47
     48/* does the ccache have a valid TGT? */
     49static time_t
     50get_tgt_time(const char *ccname) {
     51        krb5_context context;
     52        krb5_ccache ccache;
     53        krb5_cc_cursor cur;
     54        krb5_creds creds;
     55        krb5_principal principal;
     56        time_t credtime = 0;
     57        char *realm = NULL;
     58
     59        if (krb5_init_context(&context)) {
     60                syslog(LOG_DEBUG, "%s: unable to init krb5 context", __func__);
     61                return 0;
     62        }
     63
     64        if (krb5_cc_resolve(context, ccname, &ccache)) {
     65                syslog(LOG_DEBUG, "%s: unable to resolve krb5 cache", __func__);
     66                goto err_cache;
     67        }
     68
     69        if (krb5_cc_set_flags(context, ccache, 0)) {
     70                syslog(LOG_DEBUG, "%s: unable to set flags", __func__);
     71                goto err_cache;
     72        }
     73
     74        if (krb5_cc_get_principal(context, ccache, &principal)) {
     75                syslog(LOG_DEBUG, "%s: unable to get principal", __func__);
     76                goto err_princ;
     77        }
     78
     79        if (krb5_cc_start_seq_get(context, ccache, &cur)) {
     80                syslog(LOG_DEBUG, "%s: unable to seq start", __func__);
     81                goto err_ccstart;
     82        }
     83
     84        if ((realm = smb_krb5_principal_get_realm(context, principal)) == NULL) {
     85                syslog(LOG_DEBUG, "%s: unable to get realm", __func__);
     86                goto err_ccstart;
     87        }
     88
     89        while (!credtime && !krb5_cc_next_cred(context, ccache, &cur, &creds)) {
     90                char *name;
     91                if (smb_krb5_unparse_name(context, creds.server, &name)) {
     92                        syslog(LOG_DEBUG, "%s: unable to unparse name", __func__);
     93                        goto err_endseq;
     94                }
     95                if (krb5_realm_compare(context, creds.server, principal) &&
     96                    strnequal(name, KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE) &&
     97                    strnequal(name+KRB5_TGS_NAME_SIZE+1, realm, strlen(realm)) &&
     98                    creds.times.endtime > time(NULL))
     99                        credtime = creds.times.endtime;
     100                krb5_free_cred_contents(context, &creds);
     101                SAFE_FREE(name);
     102        }
     103err_endseq:
     104        krb5_cc_end_seq_get(context, ccache, &cur);
     105err_ccstart:
     106        krb5_free_principal(context, principal);
     107err_princ:
     108#if defined(KRB5_TC_OPENCLOSE)
     109        krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
     110#endif
     111        krb5_cc_close(context, ccache);
     112err_cache:
     113        krb5_free_context(context);
     114        return credtime;
     115}
     116
     117static int
     118krb5cc_filter(const struct dirent *dirent)
     119{
     120        if (strstr(dirent->d_name, CIFS_DEFAULT_KRB5_PREFIX))
     121                return 1;
     122        else
     123                return 0;
     124}
     125
     126/* search for a credcache that looks like a likely candidate */
     127static char *
     128find_krb5_cc(const char *dirname, uid_t uid)
     129{
     130        struct dirent **namelist;
     131        struct stat sbuf;
     132        char ccname[MAX_CCNAME_LEN], *credpath, *best_cache = NULL;
     133        int i, n;
     134        time_t cred_time, best_time = 0;
     135
     136        n = scandir(dirname, &namelist, krb5cc_filter, NULL);
     137        if (n < 0) {
     138                syslog(LOG_DEBUG, "%s: scandir error on directory '%s': %s",
     139                                  __func__, dirname, strerror(errno));
     140                return NULL;
     141        }
     142
     143        for (i = 0; i < n; i++) {
     144                snprintf(ccname, sizeof(ccname), "FILE:%s/%s", dirname,
     145                         namelist[i]->d_name);
     146                credpath = ccname + 5;
     147                syslog(LOG_DEBUG, "%s: considering %s", __func__, credpath);
     148
     149                if (lstat(credpath, &sbuf)) {
     150                        syslog(LOG_DEBUG, "%s: stat error on '%s': %s",
     151                                          __func__, credpath, strerror(errno));
     152                        free(namelist[i]);
     153                        continue;
     154                }
     155                if (sbuf.st_uid != uid) {
     156                        syslog(LOG_DEBUG, "%s: %s is owned by %u, not %u",
     157                                        __func__, credpath, sbuf.st_uid, uid);
     158                        free(namelist[i]);
     159                        continue;
     160                }
     161                if (!S_ISREG(sbuf.st_mode)) {
     162                        syslog(LOG_DEBUG, "%s: %s is not a regular file",
     163                                        __func__, credpath);
     164                        free(namelist[i]);
     165                        continue;
     166                }
     167                if (!(cred_time = get_tgt_time(ccname))) {
     168                        syslog(LOG_DEBUG, "%s: %s is not a valid credcache.",
     169                                        __func__, ccname);
     170                        free(namelist[i]);
     171                        continue;
     172                }
     173
     174                if (cred_time <= best_time) {
     175                        syslog(LOG_DEBUG, "%s: %s expires sooner than current "
     176                                          "best.", __func__, ccname);
     177                        free(namelist[i]);
     178                        continue;
     179                }
     180
     181                syslog(LOG_DEBUG, "%s: %s is valid ccache", __func__, ccname);
     182                free(best_cache);
     183                best_cache = SMB_STRNDUP(ccname, MAX_CCNAME_LEN);
     184                best_time = cred_time;
     185                free(namelist[i]);
     186        }
     187        free(namelist);
     188
     189        return best_cache;
     190}
    39191
    40192/*
     
    57209 *
    58210 * ret: 0 - success, others - failure
    59 */
     211 */
    60212static int
    61 handle_krb5_mech(const char *oid, const char *principal,
    62                      DATA_BLOB * secblob, DATA_BLOB * sess_key)
     213handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob,
     214                 DATA_BLOB *sess_key, const char *ccname)
    63215{
    64216        int retval;
    65217        DATA_BLOB tkt, tkt_wrapped;
    66218
     219        syslog(LOG_DEBUG, "%s: getting service ticket for %s", __func__,
     220                          principal);
     221
    67222        /* get a kerberos ticket for the service and extract the session key */
    68         retval = cli_krb5_get_ticket(principal, 0,
    69                                      &tkt, sess_key, 0, NULL, NULL);
    70 
    71         if (retval)
     223        retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname,
     224                                     NULL);
     225
     226        if (retval) {
     227                syslog(LOG_DEBUG, "%s: failed to obtain service ticket (%d)",
     228                                  __func__, retval);
    72229                return retval;
     230        }
     231
     232        syslog(LOG_DEBUG, "%s: obtained service ticket", __func__);
    73233
    74234        /* wrap that up in a nice GSS-API wrapping */
     
    83243}
    84244
    85 #define DKD_HAVE_HOSTNAME       1
    86 #define DKD_HAVE_VERSION        2
    87 #define DKD_HAVE_SEC            4
    88 #define DKD_HAVE_IPV4           8
    89 #define DKD_HAVE_IPV6           16
    90 #define DKD_HAVE_UID            32
     245#define DKD_HAVE_HOSTNAME       0x1
     246#define DKD_HAVE_VERSION        0x2
     247#define DKD_HAVE_SEC            0x4
     248#define DKD_HAVE_IP             0x8
     249#define DKD_HAVE_UID            0x10
     250#define DKD_HAVE_PID            0x20
    91251#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
    92252
    93 static int
    94 decode_key_description(const char *desc, int *ver, secType_t * sec,
    95                            char **hostname, uid_t * uid)
    96 {
     253struct decoded_args {
     254        int             ver;
     255        char            *hostname;
     256        char            *ip;
     257        uid_t           uid;
     258        pid_t           pid;
     259        sectype_t       sec;
     260};
     261
     262static unsigned int
     263decode_key_description(const char *desc, struct decoded_args *arg)
     264{
     265        int len;
    97266        int retval = 0;
    98267        char *pos;
     
    102271                pos = index(tkn, ';');
    103272                if (strncmp(tkn, "host=", 5) == 0) {
    104                         int len;
    105 
    106                         if (pos == NULL) {
     273
     274                        if (pos == NULL)
    107275                                len = strlen(tkn);
     276                        else
     277                                len = pos - tkn;
     278
     279                        len -= 4;
     280                        SAFE_FREE(arg->hostname);
     281                        arg->hostname = SMB_XMALLOC_ARRAY(char, len);
     282                        strlcpy(arg->hostname, tkn + 5, len);
     283                        retval |= DKD_HAVE_HOSTNAME;
     284                } else if (!strncmp(tkn, "ip4=", 4) ||
     285                           !strncmp(tkn, "ip6=", 4)) {
     286                        if (pos == NULL)
     287                                len = strlen(tkn);
     288                        else
     289                                len = pos - tkn;
     290
     291                        len -= 3;
     292                        SAFE_FREE(arg->ip);
     293                        arg->ip = SMB_XMALLOC_ARRAY(char, len);
     294                        strlcpy(arg->ip, tkn + 4, len);
     295                        retval |= DKD_HAVE_IP;
     296                } else if (strncmp(tkn, "pid=", 4) == 0) {
     297                        errno = 0;
     298                        arg->pid = strtol(tkn + 4, NULL, 0);
     299                        if (errno != 0) {
     300                                syslog(LOG_ERR, "Invalid pid format: %s",
     301                                       strerror(errno));
     302                                return 1;
    108303                        } else {
    109                                 len = pos - tkn;
     304                                retval |= DKD_HAVE_PID;
    110305                        }
    111                         len -= 4;
    112                         SAFE_FREE(*hostname);
    113                         *hostname = SMB_XMALLOC_ARRAY(char, len);
    114                         strlcpy(*hostname, tkn + 5, len);
    115                         retval |= DKD_HAVE_HOSTNAME;
    116                 } else if (strncmp(tkn, "ipv4=", 5) == 0) {
    117                         /* BB: do we need it if we have hostname already? */
    118                 } else if (strncmp(tkn, "ipv6=", 5) == 0) {
    119                         /* BB: do we need it if we have hostname already? */
    120306                } else if (strncmp(tkn, "sec=", 4) == 0) {
    121307                        if (strncmp(tkn + 4, "krb5", 4) == 0) {
    122308                                retval |= DKD_HAVE_SEC;
    123                                 *sec = KRB5;
     309                                arg->sec = KRB5;
    124310                        } else if (strncmp(tkn + 4, "mskrb5", 6) == 0) {
    125311                                retval |= DKD_HAVE_SEC;
    126                                 *sec = MS_KRB5;
     312                                arg->sec = MS_KRB5;
    127313                        }
    128314                } else if (strncmp(tkn, "uid=", 4) == 0) {
    129315                        errno = 0;
    130                         *uid = strtol(tkn + 4, NULL, 16);
     316                        arg->uid = strtol(tkn + 4, NULL, 16);
    131317                        if (errno != 0) {
    132                                 syslog(LOG_WARNING, "Invalid uid format: %s",
     318                                syslog(LOG_ERR, "Invalid uid format: %s",
    133319                                       strerror(errno));
    134320                                return 1;
     
    138324                } else if (strncmp(tkn, "ver=", 4) == 0) {      /* if version */
    139325                        errno = 0;
    140                         *ver = strtol(tkn + 4, NULL, 16);
     326                        arg->ver = strtol(tkn + 4, NULL, 16);
    141327                        if (errno != 0) {
    142                                 syslog(LOG_WARNING,
    143                                        "Invalid version format: %s",
     328                                syslog(LOG_ERR, "Invalid version format: %s",
    144329                                       strerror(errno));
    145330                                return 1;
     
    167352                keyend = index(keyend+1, ';');
    168353                if (!keyend) {
    169                         syslog(LOG_WARNING, "invalid key description: %s",
     354                        syslog(LOG_ERR, "invalid key description: %s",
    170355                                        key_descr);
    171356                        return 1;
     
    177362        c = getaddrinfo(keyend, NULL, NULL, &addr);
    178363        if (c) {
    179                 syslog(LOG_WARNING, "unable to resolve hostname: %s [%s]",
     364                syslog(LOG_ERR, "unable to resolve hostname: %s [%s]",
    180365                                keyend, gai_strerror(c));
    181366                return 1;
     
    183368
    184369        /* conver ip to string form */
    185         if (addr->ai_family == AF_INET) {
     370        if (addr->ai_family == AF_INET)
    186371                p = &(((struct sockaddr_in *)addr->ai_addr)->sin_addr);
    187         } else {
     372        else
    188373                p = &(((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr);
    189         }
     374
    190375        if (!inet_ntop(addr->ai_family, p, ip, sizeof(ip))) {
    191                 syslog(LOG_WARNING, "%s: inet_ntop: %s",
    192                                 __FUNCTION__, strerror(errno));
     376                syslog(LOG_ERR, "%s: inet_ntop: %s", __func__, strerror(errno));
    193377                freeaddrinfo(addr);
    194378                return 1;
     
    198382        c = keyctl_instantiate(key, ip, strlen(ip)+1, 0);
    199383        if (c == -1) {
    200                 syslog(LOG_WARNING, "%s: keyctl_instantiate: %s",
    201                                 __FUNCTION__, strerror(errno));
     384                syslog(LOG_ERR, "%s: keyctl_instantiate: %s", __func__,
     385                                strerror(errno));
    202386                freeaddrinfo(addr);
    203387                return 1;
     
    208392}
    209393
     394/*
     395 * Older kernels sent IPv6 addresses without colons. Well, at least
     396 * they're fixed-length strings. Convert these addresses to have colon
     397 * delimiters to make getaddrinfo happy.
     398 */
     399static void
     400convert_inet6_addr(const char *from, char *to)
     401{
     402        int i = 1;
     403
     404        while (*from) {
     405                *to++ = *from++;
     406                if (!(i++ % 4) && *from)
     407                        *to++ = ':';
     408        }
     409        *to = 0;
     410}
     411
     412static int
     413ip_to_fqdn(const char *addrstr, char *host, size_t hostlen)
     414{
     415        int rc;
     416        struct addrinfo hints = { .ai_flags = AI_NUMERICHOST };
     417        struct addrinfo *res;
     418        const char *ipaddr = addrstr;
     419        char converted[INET6_ADDRSTRLEN + 1];
     420
     421        if ((strlen(ipaddr) > INET_ADDRSTRLEN) && !strchr(ipaddr, ':')) {
     422                convert_inet6_addr(ipaddr, converted);
     423                ipaddr = converted;
     424        }
     425
     426        rc = getaddrinfo(ipaddr, NULL, &hints, &res);
     427        if (rc) {
     428                syslog(LOG_DEBUG, "%s: failed to resolve %s to "
     429                        "ipaddr: %s", __func__, ipaddr,
     430                rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
     431                return rc;
     432        }
     433
     434        rc = getnameinfo(res->ai_addr, res->ai_addrlen, host, hostlen,
     435                         NULL, 0, NI_NAMEREQD);
     436        freeaddrinfo(res);
     437        if (rc) {
     438                syslog(LOG_DEBUG, "%s: failed to resolve %s to fqdn: %s",
     439                        __func__, ipaddr,
     440                        rc == EAI_SYSTEM ? strerror(errno) : gai_strerror(rc));
     441                return rc;
     442        }
     443
     444        syslog(LOG_DEBUG, "%s: resolved %s to %s", __func__, ipaddr, host);
     445        return 0;
     446}
     447
    210448static void
    211449usage(void)
    212450{
    213         syslog(LOG_WARNING, "Usage: %s [-c] [-v] key_serial", prog);
    214         fprintf(stderr, "Usage: %s [-c] [-v] key_serial\n", prog);
    215 }
     451        syslog(LOG_INFO, "Usage: %s [-t] [-v] key_serial", prog);
     452        fprintf(stderr, "Usage: %s [-t] [-v] key_serial\n", prog);
     453}
     454
     455const struct option long_options[] = {
     456        { "trust-dns",  0, NULL, 't' },
     457        { "version",    0, NULL, 'v' },
     458        { NULL,         0, NULL, 0 }
     459};
    216460
    217461int main(const int argc, char *const argv[])
     
    220464        DATA_BLOB secblob = data_blob_null;
    221465        DATA_BLOB sess_key = data_blob_null;
    222         secType_t sectype = NONE;
    223466        key_serial_t key = 0;
    224467        size_t datalen;
     468        unsigned int have;
    225469        long rc = 1;
    226         uid_t uid = 0;
    227         int kernel_upcall_version = 0;
    228         int c, use_cifs_service_prefix = 0;
    229         char *buf, *hostname = NULL;
     470        int c, try_dns = 0;
     471        char *buf, *princ = NULL, *ccname = NULL;
     472        char hostbuf[NI_MAXHOST], *host;
     473        struct decoded_args arg = { };
    230474        const char *oid;
    231475
     476        hostbuf[0] = '\0';
     477
    232478        openlog(prog, 0, LOG_DAEMON);
    233479
    234         while ((c = getopt(argc, argv, "cv")) != -1) {
     480        while ((c = getopt_long(argc, argv, "ctv", long_options, NULL)) != -1) {
    235481                switch (c) {
    236                 case 'c':{
    237                         use_cifs_service_prefix = 1;
    238                         break;
    239                         }
    240                 case 'v':{
     482                case 'c':
     483                        /* legacy option -- skip it */
     484                        break;
     485                case 't':
     486                        try_dns++;
     487                        break;
     488                case 'v':
    241489                        printf("version: %s\n", CIFSSPNEGO_VERSION);
    242490                        goto out;
    243                         }
    244                 default:{
    245                         syslog(LOG_WARNING, "unknown option: %c", c);
     491                default:
     492                        syslog(LOG_ERR, "unknown option: %c", c);
    246493                        goto out;
    247                         }
    248494                }
    249495        }
     
    260506        if (errno != 0) {
    261507                key = 0;
    262                 syslog(LOG_WARNING, "Invalid key format: %s", strerror(errno));
     508                syslog(LOG_ERR, "Invalid key format: %s", strerror(errno));
    263509                goto out;
    264510        }
     
    266512        rc = keyctl_describe_alloc(key, &buf);
    267513        if (rc == -1) {
    268                 syslog(LOG_WARNING, "keyctl_describe_alloc failed: %s",
     514                syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
    269515                       strerror(errno));
    270516                rc = 1;
    271517                goto out;
    272518        }
     519
     520        syslog(LOG_DEBUG, "key description: %s", buf);
    273521
    274522        if ((strncmp(buf, "cifs.resolver", sizeof("cifs.resolver")-1) == 0) ||
     
    278526        }
    279527
    280         rc = decode_key_description(buf, &kernel_upcall_version, &sectype,
    281                                     &hostname, &uid);
    282         if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
    283                 syslog(LOG_WARNING,
    284                        "unable to get from description necessary params");
     528        have = decode_key_description(buf, &arg);
     529        SAFE_FREE(buf);
     530        if ((have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
     531                syslog(LOG_ERR, "unable to get necessary params from key "
     532                                "description (0x%x)", have);
    285533                rc = 1;
    286                 SAFE_FREE(buf);
    287                 goto out;
    288         }
    289         SAFE_FREE(buf);
    290 
    291         if (kernel_upcall_version > CIFS_SPNEGO_UPCALL_VERSION) {
    292                 syslog(LOG_WARNING,
    293                        "incompatible kernel upcall version: 0x%x",
    294                        kernel_upcall_version);
     534                goto out;
     535        }
     536
     537        if (arg.ver > CIFS_SPNEGO_UPCALL_VERSION) {
     538                syslog(LOG_ERR, "incompatible kernel upcall version: 0x%x",
     539                                arg.ver);
    295540                rc = 1;
    296541                goto out;
    297542        }
    298543
    299         if (rc & DKD_HAVE_UID) {
    300                 rc = setuid(uid);
     544        if (have & DKD_HAVE_UID) {
     545                rc = setuid(arg.uid);
    301546                if (rc == -1) {
    302                         syslog(LOG_WARNING, "setuid: %s", strerror(errno));
     547                        syslog(LOG_ERR, "setuid: %s", strerror(errno));
    303548                        goto out;
    304549                }
    305         }
    306 
    307         /* BB: someday upcall SPNEGO blob could be checked here to decide
    308          * what mech to use */
     550
     551                ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, arg.uid);
     552        }
     553
     554        host = arg.hostname;
    309555
    310556        // do mech specific authorization
    311         switch (sectype) {
     557        switch (arg.sec) {
    312558        case MS_KRB5:
    313         case KRB5:{
    314                         char *princ;
    315                         size_t len;
    316 
    317                         /* for "cifs/" service name + terminating 0 */
    318                         len = strlen(hostname) + 5 + 1;
    319                         princ = SMB_XMALLOC_ARRAY(char, len);
    320                         if (!princ) {
    321                                 rc = 1;
    322                                 break;
    323                         }
    324                         if (use_cifs_service_prefix) {
    325                                 strlcpy(princ, "cifs/", len);
    326                         } else {
    327                                 strlcpy(princ, "host/", len);
    328                         }
    329                         strlcpy(princ + 5, hostname, len - 5);
    330 
    331                         if (sectype == MS_KRB5)
    332                                 oid = OID_KERBEROS5_OLD;
    333                         else
    334                                 oid = OID_KERBEROS5;
    335 
    336                         rc = handle_krb5_mech(oid, princ, &secblob, &sess_key);
    337                         SAFE_FREE(princ);
    338                         break;
    339                 }
    340         default:{
    341                         syslog(LOG_WARNING, "sectype: %d is not implemented",
    342                                sectype);
    343                         rc = 1;
    344                         break;
    345                 }
    346         }
    347 
    348         if (rc) {
    349                 goto out;
    350         }
     559        case KRB5:
     560retry_new_hostname:
     561                /* for "cifs/" service name + terminating 0 */
     562                datalen = strlen(host) + 5 + 1;
     563                princ = SMB_XMALLOC_ARRAY(char, datalen);
     564                if (!princ) {
     565                        rc = -ENOMEM;
     566                        break;
     567                }
     568
     569                if (arg.sec == MS_KRB5)
     570                        oid = OID_KERBEROS5_OLD;
     571                else
     572                        oid = OID_KERBEROS5;
     573
     574                /*
     575                 * try getting a cifs/ principal first and then fall back to
     576                 * getting a host/ principal if that doesn't work.
     577                 */
     578                strlcpy(princ, "cifs/", datalen);
     579                strlcpy(princ + 5, host, datalen - 5);
     580                rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, ccname);
     581                if (!rc)
     582                        break;
     583
     584                memcpy(princ, "host/", 5);
     585                rc = handle_krb5_mech(oid, princ, &secblob, &sess_key, ccname);
     586                if (!rc)
     587                        break;
     588
     589                if (!try_dns || !(have & DKD_HAVE_IP))
     590                        break;
     591
     592                rc = ip_to_fqdn(arg.ip, hostbuf, sizeof(hostbuf));
     593                if (rc)
     594                        break;
     595
     596                SAFE_FREE(princ);
     597                try_dns = 0;
     598                host = hostbuf;
     599                goto retry_new_hostname;
     600        default:
     601                syslog(LOG_ERR, "sectype: %d is not implemented", arg.sec);
     602                rc = 1;
     603                break;
     604        }
     605
     606        SAFE_FREE(princ);
     607
     608        if (rc)
     609                goto out;
    351610
    352611        /* pack SecurityBLob and SessionKey into downcall packet */
     
    358617                goto out;
    359618        }
    360         keydata->version = kernel_upcall_version;
     619        keydata->version = arg.ver;
    361620        keydata->flags = 0;
    362621        keydata->sesskey_len = sess_key.length;
     
    369628        rc = keyctl_instantiate(key, keydata, datalen, 0);
    370629        if (rc == -1) {
    371                 syslog(LOG_WARNING, "keyctl_instantiate: %s", strerror(errno));
     630                syslog(LOG_ERR, "keyctl_instantiate: %s", strerror(errno));
    372631                goto out;
    373632        }
     
    386645        data_blob_free(&secblob);
    387646        data_blob_free(&sess_key);
    388         SAFE_FREE(hostname);
     647        SAFE_FREE(ccname);
     648        SAFE_FREE(arg.hostname);
     649        SAFE_FREE(arg.ip);
    389650        SAFE_FREE(keydata);
    390651        return rc;
Note: See TracChangeset for help on using the changeset viewer.