diff options
author | Bjorn Sandell <biorn@cvs.openbsd.org> | 2006-10-06 07:09:11 +0000 |
---|---|---|
committer | Bjorn Sandell <biorn@cvs.openbsd.org> | 2006-10-06 07:09:11 +0000 |
commit | 59320a567993df86c2a916ba46a3e498a1dc7ddc (patch) | |
tree | 6ddcdcef51aa1db57a995f8daced0a2111d46e5e /kerberosV | |
parent | 2b7f5f9782552858d18e8cb2db17c4f83fce8287 (diff) |
Coverity fixes backported from the heimdal cvs.
ok beck@, No problem deraadt@
Diffstat (limited to 'kerberosV')
-rw-r--r-- | kerberosV/src/kadmin/random_password.c | 23 | ||||
-rw-r--r-- | kerberosV/src/kdc/524.c | 28 | ||||
-rw-r--r-- | kerberosV/src/kdc/hprop.c | 4 | ||||
-rw-r--r-- | kerberosV/src/kdc/mit_dump.c | 11 | ||||
-rw-r--r-- | kerberosV/src/kdc/string2key.c | 11 | ||||
-rw-r--r-- | kerberosV/src/kpasswd/kpasswdd.c | 5 | ||||
-rw-r--r-- | kerberosV/src/lib/asn1/hash.c | 19 | ||||
-rw-r--r-- | kerberosV/src/lib/kadm5/init_c.c | 168 | ||||
-rw-r--r-- | kerberosV/src/lib/kadm5/log.c | 227 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/addr_families.c | 9 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/build_auth.c | 263 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/crypto.c | 4 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/keytab_any.c | 31 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/keytab_file.c | 326 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/keytab_krb4.c | 240 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/log.c | 2 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/mk_req_ext.c | 57 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/principal.c | 266 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/rd_req.c | 4 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/store.c | 412 | ||||
-rw-r--r-- | kerberosV/src/lib/krb5/transited.c | 4 |
21 files changed, 1522 insertions, 592 deletions
diff --git a/kerberosV/src/kadmin/random_password.c b/kerberosV/src/kadmin/random_password.c index e836f54c432..3f9c6033d7d 100644 --- a/kerberosV/src/kadmin/random_password.c +++ b/kerberosV/src/kadmin/random_password.c @@ -33,7 +33,7 @@ #include "kadmin_locl.h" -RCSID("$KTH: random_password.c,v 1.3 1999/12/02 17:04:58 joda Exp $"); +RCSID("$KTH: random_password.c,v 1.4 2001/02/15 04:20:53 assar Exp $"); /* This file defines some a function that generates a random password, that can be used when creating a large amount of principals (such @@ -57,9 +57,9 @@ random_password(char *pw, size_t len) { #ifdef OTP_STYLE { - des_cblock newkey; + OtpKey newkey; - des_new_random_key(&newkey); + krb5_generate_random_block(&newkey, sizeof(newkey)); otp_print_stddict (newkey, pw, len); strlwr(pw); } @@ -80,11 +80,11 @@ random_password(char *pw, size_t len) #ifndef OTP_STYLE /* return a random value in range 0-127 */ static int -RND(des_cblock *key, int *left) +RND(unsigned char *key, int keylen, int *left) { if(*left == 0){ - des_new_random_key(key); - *left = 8; + krb5_generate_random_block(key, keylen); + *left = keylen; } (*left)--; return ((unsigned char*)key)[*left]; @@ -120,7 +120,7 @@ generate_password(char **pw, int num_classes, ...) } *classes; va_list ap; int len, i; - des_cblock rbuf; /* random buffer */ + unsigned char rbuf[8]; /* random buffer */ int rleft = 0; classes = malloc(num_classes * sizeof(*classes)); @@ -134,15 +134,18 @@ generate_password(char **pw, int num_classes, ...) } va_end(ap); *pw = malloc(len + 1); - if(*pw == NULL) + if(*pw == NULL) { + free(classes); return; + } for(i = 0; i < len; i++) { int j; - int x = RND(&rbuf, &rleft) % (len - i); + int x = RND(rbuf, sizeof(rbuf), &rleft) % (len - i); int t = 0; for(j = 0; j < num_classes; j++) { if(x < t + classes[j].freq) { - (*pw)[i] = classes[j].str[RND(&rbuf, &rleft) % classes[j].len]; + (*pw)[i] = classes[j].str[RND(rbuf, sizeof(rbuf), &rleft) + % classes[j].len]; classes[j].freq--; break; } diff --git a/kerberosV/src/kdc/524.c b/kerberosV/src/kdc/524.c index 74b7d25f417..d62f932e37f 100644 --- a/kerberosV/src/kdc/524.c +++ b/kerberosV/src/kdc/524.c @@ -348,19 +348,21 @@ out: /* make reply */ memset(buf, 0, sizeof(buf)); sp = krb5_storage_from_mem(buf, sizeof(buf)); - krb5_store_int32(sp, ret); - if(ret == 0){ - krb5_store_int32(sp, kvno); - krb5_store_data(sp, ticket.cipher); - /* Aargh! This is coded as a KTEXT_ST. */ - krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR); - krb5_store_int32(sp, 0); /* mbz */ - free_EncryptedData(&ticket); - } - ret = krb5_storage_to_data(sp, reply); - reply->length = krb5_storage_seek(sp, 0, SEEK_CUR); - krb5_storage_free(sp); - + if (sp) { + krb5_store_int32(sp, ret); + if(ret == 0){ + krb5_store_int32(sp, kvno); + krb5_store_data(sp, ticket.cipher); + /* Aargh! This is coded as a KTEXT_ST. */ + krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR); + krb5_store_int32(sp, 0); /* mbz */ + free_EncryptedData(&ticket); + } + ret = krb5_storage_to_data(sp, reply); + reply->length = krb5_storage_seek(sp, 0, SEEK_CUR); + krb5_storage_free(sp); + } else + krb5_data_zero(reply); if(spn) free(spn); if(server) diff --git a/kerberosV/src/kdc/hprop.c b/kerberosV/src/kdc/hprop.c index bd48a5ae98b..1ddc85e116f 100644 --- a/kerberosV/src/kdc/hprop.c +++ b/kerberosV/src/kdc/hprop.c @@ -749,7 +749,7 @@ main(int argc, char **argv) HDB *db = NULL; int optind = 0; - int type = 0; + int type; if(getarg(args, num_args, argc, argv, &optind)) usage(1); @@ -788,8 +788,6 @@ main(int argc, char **argv) "only one of `--encrypt' and `--decrypt' is meaningful"); if(source_type != NULL) { - if(type != 0) - krb5_errx(context, 1, "more than one database type specified"); type = parse_source_type(source_type); if(type == 0) krb5_errx(context, 1, "unknown source type `%s'", source_type); diff --git a/kerberosV/src/kdc/mit_dump.c b/kerberosV/src/kdc/mit_dump.c index f2670c3c732..623333aeaf0 100644 --- a/kerberosV/src/kdc/mit_dump.c +++ b/kerberosV/src/kdc/mit_dump.c @@ -33,7 +33,7 @@ #include "hprop.h" -RCSID("$KTH: mit_dump.c,v 1.3 2000/08/09 09:57:37 joda Exp $"); +RCSID("$KTH: mit_dump.c,v 1.5 2005/06/02 09:55:43 lha Exp $"); /* can have any number of princ stanzas. @@ -310,14 +310,14 @@ mit_prop_dump(void *arg, const char *file) tl_type = getint(&p); /* data type */ tl_length = getint(&p); /* data length */ -#define KRB5_TL_LAST_PWD_CHANGE 1 -#define KRB5_TL_MOD_PRINC 2 +#define mit_KRB5_TL_LAST_PWD_CHANGE 1 +#define mit_KRB5_TL_MOD_PRINC 2 switch(tl_type) { - case KRB5_TL_MOD_PRINC: + case mit_KRB5_TL_MOD_PRINC: buf = malloc(tl_length); getdata(&p, buf, tl_length); /* data itself */ val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); - ret = krb5_parse_name(pd->context, buf + 4, &princ); + ret = krb5_parse_name(pd->context, (char *)buf + 4, &princ); free(buf); ALLOC(ent.modified_by); ent.modified_by->time = val; @@ -366,5 +366,6 @@ mit_prop_dump(void *arg, const char *file) q = nexttoken(&p); /* extra data */ v5_prop(pd->context, NULL, &ent, arg); } + fclose(f); return 0; } diff --git a/kerberosV/src/kdc/string2key.c b/kerberosV/src/kdc/string2key.c index 077b1525918..ecd0d8e9020 100644 --- a/kerberosV/src/kdc/string2key.c +++ b/kerberosV/src/kdc/string2key.c @@ -74,17 +74,24 @@ tokey(krb5_context context, krb5_salt salt, const char *label) { + krb5_error_code ret; int i; krb5_keyblock key; char *e; - krb5_string_to_key_salt(context, enctype, password, salt, &key); - krb5_enctype_to_string(context, enctype, &e); + + ret = krb5_string_to_key_salt(context, enctype, password, salt, &key); + if (ret) + krb5_err(context, 1, ret, "krb5_string_to_key_salt"); + ret = krb5_enctype_to_string(context, enctype, &e); + if (ret) + krb5_err(context, 1, ret, "krb5_enctype_to_string"); printf(label, e); printf(": "); for(i = 0; i < key.keyvalue.length; i++) printf("%02x", ((unsigned char*)key.keyvalue.data)[i]); printf("\n"); krb5_free_keyblock_contents(context, &key); + free(e); } int diff --git a/kerberosV/src/kpasswd/kpasswdd.c b/kerberosV/src/kpasswd/kpasswdd.c index 9b8c7c40925..deb28e7bcc1 100644 --- a/kerberosV/src/kpasswd/kpasswdd.c +++ b/kerberosV/src/kpasswd/kpasswdd.c @@ -687,6 +687,11 @@ doit (krb5_keytab keytab, int port) buf, ret); } } + + for (i = 0; i < n; ++i) + close(sockets[i]); + free(sockets); + krb5_free_addresses (context, &addrs); krb5_free_host_realm (context, realms); krb5_free_context (context); diff --git a/kerberosV/src/lib/asn1/hash.c b/kerberosV/src/lib/asn1/hash.c index b63baa5e964..9e29a7e9fcc 100644 --- a/kerberosV/src/lib/asn1/hash.c +++ b/kerberosV/src/lib/asn1/hash.c @@ -37,7 +37,7 @@ #include "gen_locl.h" -RCSID("$KTH: hash.c,v 1.8 1999/12/02 17:05:02 joda Exp $"); +RCSID("$KTH: hash.c,v 1.9 2005/01/08 22:55:26 lha Exp $"); static Hashentry *_search(Hashtab * htab, /* The hash table */ void *ptr); /* And key */ @@ -53,17 +53,16 @@ hashtabnew(int sz, assert(sz > 0); htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *)); + if (htab == NULL) + return NULL; + for (i = 0; i < sz; ++i) htab->tab[i] = NULL; - if (htab == NULL) { - return NULL; - } else { - htab->cmp = cmp; - htab->hash = hash; - htab->sz = sz; - return htab; - } + htab->cmp = cmp; + htab->hash = hash; + htab->sz = sz; + return htab; } /* Intern search function */ @@ -183,7 +182,7 @@ hashcaseadd(const char *s) assert(s); for (i = 0; *s; ++s) - i += toupper(*s); + i += toupper((unsigned char)*s); return i; } diff --git a/kerberosV/src/lib/kadm5/init_c.c b/kerberosV/src/lib/kadm5/init_c.c index 9de500ee18c..8b519a1dcef 100644 --- a/kerberosV/src/lib/kadm5/init_c.c +++ b/kerberosV/src/lib/kadm5/init_c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ #include <netinet/in.h> #include <netdb.h> -RCSID("$KTH: init_c.c,v 1.40 2000/12/31 08:00:23 assar Exp $"); +RCSID("$KTH: init_c.c,v 1.51 2005/05/13 10:57:13 lha Exp $"); static void set_funcs(kadm5_client_context *c) @@ -72,24 +72,37 @@ _kadm5_c_init_context(kadm5_client_context **ctx, krb5_add_et_list (context, initialize_kadm5_error_table_r); set_funcs(*ctx); (*ctx)->context = context; - if(params->mask & KADM5_CONFIG_REALM) + if(params->mask & KADM5_CONFIG_REALM) { + ret = 0; (*ctx)->realm = strdup(params->realm); - else - krb5_get_default_realm((*ctx)->context, &(*ctx)->realm); + if ((*ctx)->realm == NULL) + ret = ENOMEM; + } else + ret = krb5_get_default_realm((*ctx)->context, &(*ctx)->realm); + if (ret) { + free(*ctx); + return ret; + } if(params->mask & KADM5_CONFIG_ADMIN_SERVER) (*ctx)->admin_server = strdup(params->admin_server); else { char **hostlist; ret = krb5_get_krb_admin_hst (context, &(*ctx)->realm, &hostlist); - if (ret) + if (ret) { + free((*ctx)->realm); + free(*ctx); return ret; + } (*ctx)->admin_server = strdup(*hostlist); krb5_free_krbhst (context, hostlist); } - if ((*ctx)->admin_server == NULL) + if ((*ctx)->admin_server == NULL) { + free((*ctx)->realm); + free(*ctx); return ENOMEM; + } colon = strchr ((*ctx)->admin_server, ':'); if (colon != NULL) *colon++ = '\0'; @@ -141,12 +154,21 @@ get_new_cache(krb5_context context, { krb5_error_code ret; krb5_creds cred; - krb5_get_init_creds_opt opt; + krb5_get_init_creds_opt *opt; krb5_ccache id; - krb5_get_init_creds_opt_init (&opt); - krb5_get_init_creds_opt_set_forwardable (&opt, FALSE); - krb5_get_init_creds_opt_set_proxiable (&opt, FALSE); + ret = krb5_get_init_creds_opt_alloc (context, &opt); + if (ret) + return ret; + + krb5_get_init_creds_opt_set_default_flags(context, "kadmin", + krb5_principal_get_realm(context, + client), + opt); + + + krb5_get_init_creds_opt_set_forwardable (opt, FALSE); + krb5_get_init_creds_opt_set_proxiable (opt, FALSE); if(password == NULL && prompter == NULL) { krb5_keytab kt; @@ -154,15 +176,17 @@ get_new_cache(krb5_context context, ret = krb5_kt_default(context, &kt); else ret = krb5_kt_resolve(context, keytab, &kt); - if(ret) + if(ret) { + krb5_get_init_creds_opt_free(opt); return ret; + } ret = krb5_get_init_creds_keytab (context, &cred, client, kt, 0, server_name, - &opt); + opt); krb5_kt_close(context, kt); } else { ret = krb5_get_init_creds_password (context, @@ -173,8 +197,9 @@ get_new_cache(krb5_context context, NULL, 0, server_name, - &opt); + opt); } + krb5_get_init_creds_opt_free(opt); switch(ret){ case 0: break; @@ -194,20 +219,20 @@ get_new_cache(krb5_context context, ret = krb5_cc_store_cred (context, id, &cred); if (ret) return ret; - krb5_free_creds_contents (context, &cred); + krb5_free_cred_contents (context, &cred); *ret_cache = id; return 0; } -static krb5_error_code -get_cred_cache(krb5_context context, - const char *client_name, - const char *server_name, - const char *password, - krb5_prompter_fct prompter, - const char *keytab, - krb5_ccache ccache, - krb5_ccache *ret_cache) +krb5_error_code +_kadm5_c_get_cred_cache(krb5_context context, + const char *client_name, + const char *server_name, + const char *password, + krb5_prompter_fct prompter, + const char *keytab, + krb5_ccache ccache, + krb5_ccache *ret_cache) { krb5_error_code ret; krb5_ccache id = NULL; @@ -233,12 +258,47 @@ get_cred_cache(krb5_context context, if(ret) { krb5_cc_close(context, id); id = NULL; + } else { + const char *name, *inst; + krb5_principal tmp; + name = krb5_principal_get_comp_string(context, + default_client, 0); + inst = krb5_principal_get_comp_string(context, + default_client, 1); + if(inst == NULL || strcmp(inst, "admin") != 0) { + ret = krb5_make_principal(context, &tmp, NULL, + name, "admin", NULL); + if(ret != 0) { + krb5_free_principal(context, default_client); + if (client) + krb5_free_principal(context, client); + krb5_cc_close(context, id); + return ret; + } + krb5_free_principal(context, default_client); + default_client = tmp; + krb5_cc_close(context, id); + id = NULL; + } } } - - if(client == NULL) + + if (client != NULL) { + /* A client was specified by the caller. */ + if (default_client != NULL) { + krb5_free_principal(context, default_client); + default_client = NULL; + } + } + else if (default_client != NULL) + /* No client was specified by the caller, but we have a + * client from the default credentials cache. + */ client = default_client; - if(client == NULL) { + else { + /* No client was specified by the caller and we cannot determine + * the client from a credentials cache. + */ const char *user; user = get_default_username (); @@ -249,19 +309,19 @@ get_cred_cache(krb5_context context, NULL, user, "admin", NULL); if(ret) return ret; - } - if(client != default_client) { - krb5_free_principal(context, default_client); - default_client = NULL; if (id != NULL) { krb5_cc_close(context, id); id = NULL; } } - } else if(ccache != NULL) + } else if(ccache != NULL) { id = ccache; - + ret = krb5_cc_get_principal(context, id, &client); + if(ret) + return ret; + } + if(id && (default_client == NULL || krb5_principal_compare(context, client, default_client))) { ret = get_kadm_ticket(context, id, client, server_name); @@ -277,7 +337,7 @@ get_cred_cache(krb5_context context, return -1; } /* get creds via AS request */ - if(id) + if(id && (id != ccache)) krb5_cc_close(context, id); if (client != default_client) krb5_free_principal(context, default_client); @@ -300,6 +360,7 @@ kadm_connect(kadm5_client_context *ctx) int error; char portstr[NI_MAXSERV]; char *hostname, *slash; + char *service_name; krb5_context context = ctx->context; memset (&hints, 0, sizeof(hints)); @@ -333,16 +394,31 @@ kadm_connect(kadm5_client_context *ctx) krb5_warnx (context, "failed to contact %s", hostname); return KADM5_FAILURE; } - ret = get_cred_cache(context, ctx->client_name, ctx->service_name, - NULL, ctx->prompter, ctx->keytab, - ctx->ccache, &cc); + ret = _kadm5_c_get_cred_cache(context, + ctx->client_name, + ctx->service_name, + NULL, ctx->prompter, ctx->keytab, + ctx->ccache, &cc); if(ret) { freeaddrinfo (ai); close(s); return ret; } - ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server); + + if (ctx->realm) + asprintf(&service_name, "%s@%s", KADM5_ADMIN_SERVICE, ctx->realm); + else + asprintf(&service_name, "%s", KADM5_ADMIN_SERVICE); + + if (service_name == NULL) { + freeaddrinfo (ai); + close(s); + return ENOMEM; + } + + ret = krb5_parse_name(context, service_name, &server); + free(service_name); if(ret) { freeaddrinfo (ai); if(ctx->ccache == NULL) @@ -358,7 +434,13 @@ kadm_connect(kadm5_client_context *ctx) NULL, NULL, cc, NULL, NULL, NULL); if(ret == 0) { krb5_data params; - ret = _kadm5_marshal_params(context, ctx->realm_params, ¶ms); + kadm5_config_params p; + memset(&p, 0, sizeof(p)); + if(ctx->realm) { + p.mask |= KADM5_CONFIG_REALM; + p.realm = ctx->realm; + } + ret = _kadm5_marshal_params(context, &p, ¶ms); ret = krb5_write_priv_message(context, ctx->ac, &s, ¶ms); krb5_data_free(¶ms); @@ -436,8 +518,10 @@ kadm5_c_init_with_context(krb5_context context, return ret; if(password != NULL && *password != '\0') { - ret = get_cred_cache(context, client_name, service_name, - password, prompter, keytab, ccache, &cc); + ret = _kadm5_c_get_cred_cache(context, + client_name, + service_name, + password, prompter, keytab, ccache, &cc); if(ret) return ret; /* XXX */ ccache = cc; @@ -455,7 +539,7 @@ kadm5_c_init_with_context(krb5_context context, ctx->prompter = prompter; ctx->keytab = keytab; ctx->ccache = ccache; - ctx->realm_params = realm_params; + /* maybe we should copy the params here */ ctx->sock = -1; *server_handle = ctx; diff --git a/kerberosV/src/lib/kadm5/log.c b/kerberosV/src/lib/kadm5/log.c index 5ca040ab82c..24a517e8946 100644 --- a/kerberosV/src/lib/kadm5/log.c +++ b/kerberosV/src/lib/kadm5/log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kadm5_locl.h" -RCSID("$KTH: log.c,v 1.18 2000/07/24 04:32:17 assar Exp $"); +RCSID("$KTH: log.c,v 1.21 2003/09/19 00:24:05 lha Exp $"); /* * A log record consists of: @@ -64,7 +64,7 @@ kadm5_log_get_version_fd (int fd, return 0; } sp = krb5_storage_from_fd (fd); - sp->seek(sp, -4, SEEK_CUR); + krb5_storage_seek(sp, -4, SEEK_CUR); krb5_ret_int32 (sp, &old_version); *ver = old_version; krb5_storage_free(sp); @@ -237,7 +237,7 @@ kadm5_log_create (kadm5_server_context *context, return ret; } krb5_store_int32 (sp, value.length); - sp->store(sp, value.data, value.length); + krb5_storage_write(sp, value.data, value.length); krb5_store_int32 (sp, value.length); krb5_data_free (&value); ret = kadm5_log_postamble (log_context, sp); @@ -268,13 +268,15 @@ kadm5_log_replay_create (kadm5_server_context *context, krb5_data data; hdb_entry ent; - krb5_data_alloc (&data, len); - sp->fetch (sp, data.data, len); + ret = krb5_data_alloc (&data, len); + if (ret) + return ret; + krb5_storage_read (sp, data.data, len); ret = hdb_value2entry (context->context, &data, &ent); krb5_data_free(&data); if (ret) return ret; - ret = context->db->store(context->context, context->db, 0, &ent); + ret = context->db->hdb_store(context->context, context->db, 0, &ent); hdb_free_entry (context->context, &ent); return ret; } @@ -294,33 +296,36 @@ kadm5_log_delete (kadm5_server_context *context, kadm5_log_context *log_context = &context->log_context; sp = krb5_storage_emem(); + if (sp == NULL) + return ENOMEM; ret = kadm5_log_preamble (context, sp, kadm_delete); - if (ret) { - krb5_storage_free(sp); - return ret; - } - krb5_store_int32 (sp, 0); - off = sp->seek (sp, 0, SEEK_CUR); - krb5_store_principal (sp, princ); - len = sp->seek (sp, 0, SEEK_CUR) - off; - sp->seek(sp, -(len + 4), SEEK_CUR); - krb5_store_int32 (sp, len); - sp->seek(sp, len, SEEK_CUR); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto out; + ret = krb5_store_int32 (sp, 0); + if (ret) + goto out; + off = krb5_storage_seek (sp, 0, SEEK_CUR); + ret = krb5_store_principal (sp, princ); + if (ret) + goto out; + len = krb5_storage_seek (sp, 0, SEEK_CUR) - off; + krb5_storage_seek(sp, -(len + 4), SEEK_CUR); + ret = krb5_store_int32 (sp, len); + if (ret) + goto out; + krb5_storage_seek(sp, len, SEEK_CUR); + ret = krb5_store_int32 (sp, len); + if (ret) + goto out; ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto out; ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; + goto out; ret = kadm5_log_end (context); +out: + krb5_storage_free (sp); return ret; } @@ -339,7 +344,7 @@ kadm5_log_replay_delete (kadm5_server_context *context, krb5_ret_principal (sp, &ent.principal); - ret = context->db->remove(context->context, context->db, &ent); + ret = context->db->hdb_remove(context->context, context->db, &ent); krb5_free_principal (context->context, ent.principal); return ret; } @@ -360,43 +365,53 @@ kadm5_log_rename (kadm5_server_context *context, krb5_data value; kadm5_log_context *log_context = &context->log_context; + krb5_data_zero(&value); + sp = krb5_storage_emem(); ret = hdb_entry2value (context->context, ent, &value); - if (ret) { - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_preamble (context, sp, kadm_rename); - if (ret) { - krb5_storage_free(sp); - krb5_data_free (&value); - return ret; - } - krb5_store_int32 (sp, 0); - off = sp->seek (sp, 0, SEEK_CUR); - krb5_store_principal (sp, source); - sp->store(sp, value.data, value.length); - krb5_data_free (&value); - len = sp->seek (sp, 0, SEEK_CUR) - off; + if (ret) + goto failed; + + ret = krb5_store_int32 (sp, 0); + if (ret) + goto failed; + off = krb5_storage_seek (sp, 0, SEEK_CUR); + ret = krb5_store_principal (sp, source); + if (ret) + goto failed; + + krb5_storage_write(sp, value.data, value.length); + len = krb5_storage_seek (sp, 0, SEEK_CUR) - off; + + krb5_storage_seek(sp, -(len + 4), SEEK_CUR); + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; + + krb5_storage_seek(sp, len, SEEK_CUR); + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; - sp->seek(sp, -(len + 4), SEEK_CUR); - krb5_store_int32 (sp, len); - sp->seek(sp, len, SEEK_CUR); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; - ret = kadm5_log_end (context); + goto failed; + krb5_storage_free (sp); + krb5_data_free (&value); + + return kadm5_log_end (context); + +failed: + krb5_data_free(&value); + krb5_storage_free(sp); return ret; } @@ -417,26 +432,31 @@ kadm5_log_replay_rename (kadm5_server_context *context, off_t off; size_t princ_len, data_len; - off = sp->seek(sp, 0, SEEK_CUR); + off = krb5_storage_seek(sp, 0, SEEK_CUR); krb5_ret_principal (sp, &source); - princ_len = sp->seek(sp, 0, SEEK_CUR) - off; + princ_len = krb5_storage_seek(sp, 0, SEEK_CUR) - off; data_len = len - princ_len; - krb5_data_alloc (&value, data_len); - sp->fetch (sp, value.data, data_len); + ret = krb5_data_alloc (&value, data_len); + if (ret) { + krb5_free_principal (context->context, source); + return ret; + } + krb5_storage_read (sp, value.data, data_len); ret = hdb_value2entry (context->context, &value, &target_ent); krb5_data_free(&value); if (ret) { krb5_free_principal (context->context, source); return ret; } - ret = context->db->store (context->context, context->db, 0, &target_ent); + ret = context->db->hdb_store (context->context, context->db, + 0, &target_ent); hdb_free_entry (context->context, &target_ent); if (ret) { krb5_free_principal (context->context, source); return ret; } source_ent.principal = source; - ret = context->db->remove (context->context, context->db, &source_ent); + ret = context->db->hdb_remove (context->context, context->db, &source_ent); krb5_free_principal (context->context, source); return ret; } @@ -457,38 +477,41 @@ kadm5_log_modify (kadm5_server_context *context, u_int32_t len; kadm5_log_context *log_context = &context->log_context; + krb5_data_zero(&value); + sp = krb5_storage_emem(); ret = hdb_entry2value (context->context, ent, &value); - if (ret) { - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + ret = kadm5_log_preamble (context, sp, kadm_modify); - if (ret) { - krb5_data_free (&value); - krb5_storage_free(sp); - return ret; - } + if (ret) + goto failed; + len = value.length + 4; - krb5_store_int32 (sp, len); - krb5_store_int32 (sp, mask); - sp->store(sp, value.data, value.length); - krb5_data_free (&value); - krb5_store_int32 (sp, len); - if (ret) { - krb5_storage_free (sp); - return ret; - } + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; + ret = krb5_store_int32 (sp, mask); + if (ret) + goto failed; + krb5_storage_write (sp, value.data, value.length); + + ret = krb5_store_int32 (sp, len); + if (ret) + goto failed; ret = kadm5_log_postamble (log_context, sp); - if (ret) { - krb5_storage_free (sp); - return ret; - } + if (ret) + goto failed; ret = kadm5_log_flush (log_context, sp); - krb5_storage_free (sp); if (ret) - return ret; - ret = kadm5_log_end (context); + goto failed; + krb5_data_free(&value); + krb5_storage_free (sp); + return kadm5_log_end (context); +failed: + krb5_data_free(&value); + krb5_storage_free(sp); return ret; } @@ -509,16 +532,18 @@ kadm5_log_replay_modify (kadm5_server_context *context, krb5_ret_int32 (sp, &mask); len -= 4; - krb5_data_alloc (&value, len); - sp->fetch (sp, value.data, len); + ret = krb5_data_alloc (&value, len); + if (ret) + return ret; + krb5_storage_read (sp, value.data, len); ret = hdb_value2entry (context->context, &value, &log_ent); krb5_data_free(&value); if (ret) return ret; ent.principal = log_ent.principal; log_ent.principal = NULL; - ret = context->db->fetch(context->context, context->db, - HDB_F_DECRYPT, &ent); + ret = context->db->hdb_fetch(context->context, context->db, + HDB_F_DECRYPT, &ent); if (ret) return ret; if (mask & KADM5_PRINC_EXPIRE_TIME) { @@ -610,8 +635,8 @@ kadm5_log_replay_modify (kadm5_server_context *context, copy_Key(&log_ent.keys.val[i], &ent.keys.val[i]); } - ret = context->db->store(context->context, context->db, - HDB_F_REPLACE, &ent); + ret = context->db->hdb_store(context->context, context->db, + HDB_F_REPLACE, &ent); hdb_free_entry (context->context, &ent); hdb_free_entry (context->context, &log_ent); return ret; @@ -689,7 +714,7 @@ kadm5_log_foreach (kadm5_server_context *context, krb5_ret_int32 (sp, &op); krb5_ret_int32 (sp, &len); (*func)(context, ver, timestamp, op, len, sp); - sp->seek(sp, 8, SEEK_CUR); + krb5_storage_seek(sp, 8, SEEK_CUR); } return 0; } @@ -704,7 +729,7 @@ kadm5_log_goto_end (int fd) krb5_storage *sp; sp = krb5_storage_from_fd (fd); - sp->seek(sp, 0, SEEK_END); + krb5_storage_seek(sp, 0, SEEK_END); return sp; } @@ -722,13 +747,13 @@ kadm5_log_previous (krb5_storage *sp, off_t off; int32_t tmp; - sp->seek(sp, -8, SEEK_CUR); + krb5_storage_seek(sp, -8, SEEK_CUR); krb5_ret_int32 (sp, &tmp); *len = tmp; krb5_ret_int32 (sp, &tmp); *ver = tmp; off = 24 + *len; - sp->seek(sp, -off, SEEK_CUR); + krb5_storage_seek(sp, -off, SEEK_CUR); krb5_ret_int32 (sp, &tmp); assert(tmp == *ver); krb5_ret_int32 (sp, &tmp); diff --git a/kerberosV/src/lib/krb5/addr_families.c b/kerberosV/src/lib/krb5/addr_families.c index 22ccc63af4f..8daeb6a911a 100644 --- a/kerberosV/src/lib/krb5/addr_families.c +++ b/kerberosV/src/lib/krb5/addr_families.c @@ -928,11 +928,18 @@ krb5_parse_address(krb5_context context, int error; int save_errno; + addresses->len = 0; + addresses->val = NULL; + for(i = 0; i < num_addrs; i++) { if(at[i].parse_addr) { krb5_address addr; if((*at[i].parse_addr)(context, string, &addr) == 0) { ALLOC_SEQ(addresses, 1); + if (addresses->val == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } addresses->val[0] = addr; return 0; } @@ -1045,6 +1052,8 @@ krb5_free_addresses(krb5_context context, for(i = 0; i < addresses->len; i++) krb5_free_address(context, &addresses->val[i]); free(addresses->val); + addresses->len = 0; + addresses->val = NULL; return 0; } diff --git a/kerberosV/src/lib/krb5/build_auth.c b/kerberosV/src/lib/krb5/build_auth.c index dd30de45cf7..a5571c01957 100644 --- a/kerberosV/src/lib/krb5/build_auth.c +++ b/kerberosV/src/lib/krb5/build_auth.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,9 +33,73 @@ #include <krb5_locl.h> -RCSID("$KTH: build_auth.c,v 1.34 2000/11/15 06:58:51 assar Exp $"); +RCSID("$KTH: build_auth.c,v 1.42 2005/01/05 02:34:53 lukeh Exp $"); -krb5_error_code +static krb5_error_code +make_etypelist(krb5_context context, + krb5_authdata **auth_data) +{ + EtypeList etypes; + krb5_error_code ret; + krb5_authdata ad; + u_char *buf; + size_t len; + size_t buf_size; + + ret = krb5_init_etype(context, &etypes.len, &etypes.val, NULL); + if (ret) + return ret; + + ASN1_MALLOC_ENCODE(EtypeList, buf, buf_size, &etypes, &len, ret); + if (ret) { + free_EtypeList(&etypes); + return ret; + } + if(buf_size != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + free_EtypeList(&etypes); + + ALLOC_SEQ(&ad, 1); + if (ad.val == NULL) { + free(buf); + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + ad.val[0].ad_type = KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION; + ad.val[0].ad_data.length = len; + ad.val[0].ad_data.data = buf; + + ASN1_MALLOC_ENCODE(AD_IF_RELEVANT, buf, buf_size, &ad, &len, ret); + if (ret) { + free_AuthorizationData(&ad); + return ret; + } + if(buf_size != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + free_AuthorizationData(&ad); + + ALLOC(*auth_data, 1); + if (*auth_data == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + ALLOC_SEQ(*auth_data, 1); + if ((*auth_data)->val == NULL) { + free(buf); + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + (*auth_data)->val[0].ad_type = KRB5_AUTHDATA_IF_RELEVANT; + (*auth_data)->val[0].ad_data.length = len; + (*auth_data)->val[0].ad_data.data = buf; + + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION krb5_build_authenticator (krb5_context context, krb5_auth_context auth_context, krb5_enctype enctype, @@ -45,115 +109,94 @@ krb5_build_authenticator (krb5_context context, krb5_data *result, krb5_key_usage usage) { - Authenticator *auth; - u_char *buf = NULL; - size_t buf_size; - size_t len; - krb5_error_code ret; - krb5_crypto crypto; - - auth = malloc(sizeof(*auth)); - if (auth == NULL) - return ENOMEM; - - memset (auth, 0, sizeof(*auth)); - auth->authenticator_vno = 5; - copy_Realm(&cred->client->realm, &auth->crealm); - copy_PrincipalName(&cred->client->name, &auth->cname); - - { - int32_t sec, usec; - - krb5_us_timeofday (context, &sec, &usec); - auth->ctime = sec; - auth->cusec = usec; - } - ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth->subkey); - if(ret) - goto fail; - - if(auth->subkey == NULL) { - krb5_generate_subkey (context, &cred->session, &auth->subkey); - ret = krb5_auth_con_setlocalsubkey(context, auth_context, auth->subkey); - if(ret) - goto fail; - } - - if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { - krb5_generate_seq_number (context, - &cred->session, - &auth_context->local_seqnumber); - ALLOC(auth->seq_number, 1); - *auth->seq_number = auth_context->local_seqnumber; - } else - auth->seq_number = NULL; - auth->authorization_data = NULL; - auth->cksum = cksum; - - /* XXX - Copy more to auth_context? */ - - if (auth_context) { + Authenticator *auth; + u_char *buf = NULL; + size_t buf_size; + size_t len; + krb5_error_code ret; + krb5_crypto crypto; + + auth = calloc(1, sizeof(*auth)); + if (auth == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + auth->authenticator_vno = 5; + copy_Realm(&cred->client->realm, &auth->crealm); + copy_PrincipalName(&cred->client->name, &auth->cname); + + krb5_us_timeofday (context, &auth->ctime, &auth->cusec); + + ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth->subkey); + if(ret) + goto fail; + + if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { + if(auth_context->local_seqnumber == 0) + krb5_generate_seq_number (context, + &cred->session, + &auth_context->local_seqnumber); + ALLOC(auth->seq_number, 1); + if(auth->seq_number == NULL) { + ret = ENOMEM; + goto fail; + } + *auth->seq_number = auth_context->local_seqnumber; + } else + auth->seq_number = NULL; + auth->authorization_data = NULL; + auth->cksum = cksum; + + if (cksum != NULL && cksum->cksumtype == CKSUMTYPE_GSSAPI) { + /* + * This is not GSS-API specific, we only enable it for + * GSS for now + */ + ret = make_etypelist(context, &auth->authorization_data); + if (ret) + goto fail; + } + + /* XXX - Copy more to auth_context? */ + auth_context->authenticator->ctime = auth->ctime; auth_context->authenticator->cusec = auth->cusec; - } - - buf_size = 1024; - buf = malloc (buf_size); - if (buf == NULL) { - ret = ENOMEM; - goto fail; - } - - do { - ret = krb5_encode_Authenticator (context, - buf + buf_size - 1, - buf_size, - auth, &len); - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc (buf, buf_size); - if (tmp == NULL) { - ret = ENOMEM; - goto fail; - } - buf = tmp; - } else { - goto fail; - } - } - } while(ret == ASN1_OVERFLOW); - - ret = krb5_crypto_init(context, &cred->session, enctype, &crypto); - if (ret) - goto fail; - ret = krb5_encrypt (context, - crypto, - usage /* KRB5_KU_AP_REQ_AUTH */, - buf + buf_size - len, - len, - result); - krb5_crypto_destroy(context, crypto); - - if (ret) - goto fail; - - free (buf); - - if (auth_result) - *auth_result = auth; - else { - /* Don't free the `cksum', it's allocated by the caller */ - auth->cksum = NULL; + + ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, auth, &len, ret); + if (ret) + goto fail; + if(buf_size != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + + ret = krb5_crypto_init(context, &cred->session, enctype, &crypto); + if (ret) + goto fail; + ret = krb5_encrypt (context, + crypto, + usage /* KRB5_KU_AP_REQ_AUTH */, + buf + buf_size - len, + len, + result); + krb5_crypto_destroy(context, crypto); + + if (ret) + goto fail; + + free (buf); + + if (auth_result) + *auth_result = auth; + else { + /* Don't free the `cksum', it's allocated by the caller */ + auth->cksum = NULL; + free_Authenticator (auth); + free (auth); + } + return ret; + fail: free_Authenticator (auth); free (auth); - } - return ret; -fail: - free_Authenticator (auth); - free (auth); - free (buf); - return ret; + free (buf); + return ret; } diff --git a/kerberosV/src/lib/krb5/crypto.c b/kerberosV/src/lib/krb5/crypto.c index ad584732827..dab6aa79956 100644 --- a/kerberosV/src/lib/krb5/crypto.c +++ b/kerberosV/src/lib/krb5/crypto.c @@ -4176,7 +4176,7 @@ krb5_string_to_key_derived(krb5_context context, struct encryption_type *et = _find_enctype(etype); krb5_error_code ret; struct key_data kd; - size_t keylen = et->keytype->bits / 8; + size_t keylen; u_char *tmp; if(et == NULL) { @@ -4184,6 +4184,8 @@ krb5_string_to_key_derived(krb5_context context, etype); return KRB5_PROG_ETYPE_NOSUPP; } + keylen = et->keytype->bits / 8; + ALLOC(kd.key, 1); if(kd.key == NULL) { krb5_set_error_string (context, "malloc: out of memory"); diff --git a/kerberosV/src/lib/krb5/keytab_any.c b/kerberosV/src/lib/krb5/keytab_any.c index f7512d5327f..f627ab6ca15 100644 --- a/kerberosV/src/lib/krb5/keytab_any.c +++ b/kerberosV/src/lib/krb5/keytab_any.c @@ -162,23 +162,22 @@ any_next_entry (krb5_context context, ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor); if (ret == 0) return 0; - else if (ret == KRB5_KT_END) { - ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor); - if (ret2) - return ret2; - while ((ed->a = ed->a->next) != NULL) { - ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); - if (ret2 == 0) - break; - } - if (ed->a == NULL) { - krb5_clear_error_string (context); - return KRB5_KT_END; - } - } else + else if (ret != KRB5_KT_END) return ret; - } while (ret == KRB5_KT_END); - return ret; + + ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor); + if (ret2) + return ret2; + while ((ed->a = ed->a->next) != NULL) { + ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); + if (ret2 == 0) + break; + } + if (ed->a == NULL) { + krb5_clear_error_string (context); + return KRB5_KT_END; + } + } while (1); } static krb5_error_code diff --git a/kerberosV/src/lib/krb5/keytab_file.c b/kerberosV/src/lib/krb5/keytab_file.c index 0af6e17254c..b491523ea8b 100644 --- a/kerberosV/src/lib/krb5/keytab_file.c +++ b/kerberosV/src/lib/krb5/keytab_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,20 +33,25 @@ #include "krb5_locl.h" -RCSID("$KTH: keytab_file.c,v 1.6 2000/01/02 00:20:22 assar Exp $"); +RCSID("$KTH: keytab_file.c,v 1.18 2005/05/31 21:50:43 lha Exp $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 #define KRB5_KT_VNO KRB5_KT_VNO_2 +#define KRB5_KT_FL_JAVA 1 + + /* file operations -------------------------------------------- */ struct fkt_data { char *filename; + int flags; }; static krb5_error_code -krb5_kt_ret_data(krb5_storage *sp, +krb5_kt_ret_data(krb5_context context, + krb5_storage *sp, krb5_data *data) { int ret; @@ -56,17 +61,20 @@ krb5_kt_ret_data(krb5_storage *sp, return ret; data->length = size; data->data = malloc(size); - if (data->data == NULL) + if (data->data == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; - ret = sp->fetch(sp, data->data, size); + } + ret = krb5_storage_read(sp, data->data, size); if(ret != size) return (ret < 0)? errno : KRB5_KT_END; return 0; } static krb5_error_code -krb5_kt_ret_string(krb5_storage *sp, - general_string *data) +krb5_kt_ret_string(krb5_context context, + krb5_storage *sp, + heim_general_string *data) { int ret; int16_t size; @@ -74,9 +82,11 @@ krb5_kt_ret_string(krb5_storage *sp, if(ret) return ret; *data = malloc(size + 1); - if (*data == NULL) + if (*data == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; - ret = sp->fetch(sp, *data, size); + } + ret = krb5_storage_read(sp, *data, size); (*data)[size] = '\0'; if(ret != size) return (ret < 0)? errno : KRB5_KT_END; @@ -84,14 +94,15 @@ krb5_kt_ret_string(krb5_storage *sp, } static krb5_error_code -krb5_kt_store_data(krb5_storage *sp, +krb5_kt_store_data(krb5_context context, + krb5_storage *sp, krb5_data data) { int ret; ret = krb5_store_int16(sp, data.length); if(ret < 0) return ret; - ret = sp->store(sp, data.data, data.length); + ret = krb5_storage_write(sp, data.data, data.length); if(ret != data.length){ if(ret < 0) return errno; @@ -102,14 +113,14 @@ krb5_kt_store_data(krb5_storage *sp, static krb5_error_code krb5_kt_store_string(krb5_storage *sp, - general_string data) + heim_general_string data) { int ret; size_t len = strlen(data); ret = krb5_store_int16(sp, len); if(ret < 0) return ret; - ret = sp->store(sp, data, len); + ret = krb5_storage_write(sp, data, len); if(ret != len){ if(ret < 0) return errno; @@ -119,7 +130,7 @@ krb5_kt_store_string(krb5_storage *sp, } static krb5_error_code -krb5_kt_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) +krb5_kt_ret_keyblock(krb5_context context, krb5_storage *sp, krb5_keyblock *p) { int ret; int16_t tmp; @@ -127,51 +138,68 @@ krb5_kt_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) ret = krb5_ret_int16(sp, &tmp); /* keytype + etype */ if(ret) return ret; p->keytype = tmp; - ret = krb5_kt_ret_data(sp, &p->keyvalue); + ret = krb5_kt_ret_data(context, sp, &p->keyvalue); return ret; } static krb5_error_code -krb5_kt_store_keyblock(krb5_storage *sp, +krb5_kt_store_keyblock(krb5_context context, + krb5_storage *sp, krb5_keyblock *p) { int ret; ret = krb5_store_int16(sp, p->keytype); /* keytype + etype */ if(ret) return ret; - ret = krb5_kt_store_data(sp, p->keyvalue); + ret = krb5_kt_store_data(context, sp, p->keyvalue); return ret; } static krb5_error_code -krb5_kt_ret_principal(krb5_storage *sp, +krb5_kt_ret_principal(krb5_context context, + krb5_storage *sp, krb5_principal *princ) { int i; int ret; krb5_principal p; - int16_t tmp; + int16_t len; ALLOC(p, 1); - if(p == NULL) + if(p == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } - ret = krb5_ret_int16(sp, &tmp); + ret = krb5_ret_int16(sp, &len); + if(ret) { + krb5_set_error_string(context, + "Failed decoding length of keytab principal"); + goto out; + } + if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) + len--; + if (len < 0) { + krb5_set_error_string(context, + "Keytab principal contains invalid length"); + ret = KRB5_KT_END; + goto out; + } + ret = krb5_kt_ret_string(context, sp, &p->realm); if(ret) - return ret; - if (sp->flags & KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS) - tmp--; - p->name.name_string.len = tmp; - ret = krb5_kt_ret_string(sp, &p->realm); - if(ret) return ret; - p->name.name_string.val = calloc(p->name.name_string.len, - sizeof(*p->name.name_string.val)); - if(p->name.name_string.val == NULL) - return ENOMEM; + goto out; + p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val)); + if(p->name.name_string.val == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); + ret = ENOMEM; + goto out; + } + p->name.name_string.len = len; for(i = 0; i < p->name.name_string.len; i++){ - ret = krb5_kt_ret_string(sp, p->name.name_string.val + i); - if(ret) return ret; + ret = krb5_kt_ret_string(context, sp, p->name.name_string.val + i); + if(ret) + goto out; } if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) p->name.name_type = KRB5_NT_UNKNOWN; @@ -180,14 +208,18 @@ krb5_kt_ret_principal(krb5_storage *sp, ret = krb5_ret_int32(sp, &tmp32); p->name.name_type = tmp32; if (ret) - return ret; + goto out; } *princ = p; return 0; +out: + krb5_free_principal(context, p); + return ret; } static krb5_error_code -krb5_kt_store_principal(krb5_storage *sp, +krb5_kt_store_principal(krb5_context context, + krb5_storage *sp, krb5_principal p) { int i; @@ -202,7 +234,8 @@ krb5_kt_store_principal(krb5_storage *sp, if(ret) return ret; for(i = 0; i < p->name.name_string.len; i++){ ret = krb5_kt_store_string(sp, p->name.name_string.val[i]); - if(ret) return ret; + if(ret) + return ret; } if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) { ret = krb5_store_int32(sp, p->name.name_type); @@ -217,19 +250,37 @@ static krb5_error_code fkt_resolve(krb5_context context, const char *name, krb5_keytab id) { struct fkt_data *d; + d = malloc(sizeof(*d)); - if(d == NULL) + if(d == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } d->filename = strdup(name); if(d->filename == NULL) { free(d); + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } + d->flags = 0; id->data = d; return 0; } static krb5_error_code +fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id) +{ + krb5_error_code ret; + + ret = fkt_resolve(context, name, id); + if (ret == 0) { + struct fkt_data *d = id->data; + d->flags |= KRB5_KT_FL_JAVA; + } + return ret; +} + +static krb5_error_code fkt_close(krb5_context context, krb5_keytab id) { struct fkt_data *d = id->data; @@ -263,8 +314,8 @@ storage_set_flags(krb5_context context, krb5_storage *sp, int vno) case KRB5_KT_VNO_2: break; default: - krb5_abortx(context, - "storage_set_flags called with bad vno (%x)", vno); + krb5_warnx(context, + "storage_set_flags called with bad vno (%d)", vno); } krb5_storage_set_flags(sp, flags); } @@ -273,6 +324,7 @@ static krb5_error_code fkt_start_seq_get_int(krb5_context context, krb5_keytab id, int flags, + int exclusive, krb5_kt_cursor *c) { int8_t pvno, tag; @@ -280,24 +332,40 @@ fkt_start_seq_get_int(krb5_context context, struct fkt_data *d = id->data; c->fd = open (d->filename, flags); - if (c->fd < 0) - return errno; + if (c->fd < 0) { + ret = errno; + krb5_set_error_string(context, "%s: %s", d->filename, + strerror(ret)); + return ret; + } + ret = _krb5_xlock(context, c->fd, exclusive, d->filename); + if (ret) { + close(c->fd); + return ret; + } c->sp = krb5_storage_from_fd(c->fd); + krb5_storage_set_eof_code(c->sp, KRB5_KT_END); ret = krb5_ret_int8(c->sp, &pvno); if(ret) { krb5_storage_free(c->sp); + _krb5_xunlock(context, c->fd); close(c->fd); + krb5_clear_error_string(context); return ret; } if(pvno != 5) { krb5_storage_free(c->sp); + _krb5_xunlock(context, c->fd); close(c->fd); + krb5_clear_error_string (context); return KRB5_KEYTAB_BADVNO; } ret = krb5_ret_int8(c->sp, &tag); if (ret) { krb5_storage_free(c->sp); + _krb5_xunlock(context, c->fd); close(c->fd); + krb5_clear_error_string(context); return ret; } id->version = tag; @@ -310,7 +378,7 @@ fkt_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *c) { - return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY, c); + return fkt_start_seq_get_int(context, id, O_RDONLY | O_BINARY, 0, c); } static krb5_error_code @@ -325,18 +393,18 @@ fkt_next_entry_int(krb5_context context, int ret; int8_t tmp8; int32_t tmp32; - off_t pos; + off_t pos, curpos; - pos = cursor->sp->seek(cursor->sp, 0, SEEK_CUR); + pos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR); loop: ret = krb5_ret_int32(cursor->sp, &len); if (ret) return ret; if(len < 0) { - pos = cursor->sp->seek(cursor->sp, -len, SEEK_CUR); + pos = krb5_storage_seek(cursor->sp, -len, SEEK_CUR); goto loop; } - ret = krb5_kt_ret_principal (cursor->sp, &entry->principal); + ret = krb5_kt_ret_principal (context, cursor->sp, &entry->principal); if (ret) goto out; ret = krb5_ret_int32(cursor->sp, &tmp32); @@ -347,13 +415,23 @@ loop: if (ret) goto out; entry->vno = tmp8; - ret = krb5_kt_ret_keyblock (cursor->sp, &entry->keyblock); + ret = krb5_kt_ret_keyblock (context, cursor->sp, &entry->keyblock); if (ret) goto out; + /* there might be a 32 bit kvno here + * if it's zero, assume that the 8bit one was right, + * otherwise trust the new value */ + curpos = krb5_storage_seek(cursor->sp, 0, SEEK_CUR); + if(len + 4 + pos - curpos == 4) { + ret = krb5_ret_int32(cursor->sp, &tmp32); + if (ret == 0 && tmp32 != 0) { + entry->vno = tmp32; + } + } if(start) *start = pos; if(end) *end = *start + 4 + len; out: - cursor->sp->seek(cursor->sp, pos + 4 + len, SEEK_SET); + krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET); return ret; } @@ -372,11 +450,26 @@ fkt_end_seq_get(krb5_context context, krb5_kt_cursor *cursor) { krb5_storage_free(cursor->sp); + _krb5_xunlock(context, cursor->fd); close(cursor->fd); return 0; } static krb5_error_code +fkt_setup_keytab(krb5_context context, + krb5_keytab id, + krb5_storage *sp) +{ + krb5_error_code ret; + ret = krb5_store_int8(sp, 5); + if(ret) + return ret; + if(id->version == 0) + id->version = KRB5_KT_VNO; + return krb5_store_int8 (sp, id->version); +} + +static krb5_error_code fkt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) @@ -390,47 +483,61 @@ fkt_add_entry(krb5_context context, fd = open (d->filename, O_RDWR | O_BINARY); if (fd < 0) { - fd = open (d->filename, O_RDWR | O_CREAT | O_BINARY, 0600); - if (fd < 0) - return errno; - sp = krb5_storage_from_fd(fd); - ret = krb5_store_int8(sp, 5); - if(ret) { - krb5_storage_free(sp); - close(fd); + fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); + if (fd < 0) { + ret = errno; + krb5_set_error_string(context, "open(%s): %s", d->filename, + strerror(ret)); return ret; } - if(id->version == 0) - id->version = KRB5_KT_VNO; - ret = krb5_store_int8 (sp, id->version); + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { - krb5_storage_free(sp); close(fd); return ret; } - storage_set_flags(context, sp, id->version); - } else { - int8_t pvno, tag; sp = krb5_storage_from_fd(fd); - ret = krb5_ret_int8(sp, &pvno); + krb5_storage_set_eof_code(sp, KRB5_KT_END); + ret = fkt_setup_keytab(context, id, sp); if(ret) { - krb5_storage_free(sp); - close(fd); - return ret; - } - if(pvno != 5) { - krb5_storage_free(sp); - close(fd); - return KRB5_KEYTAB_BADVNO; + goto out; } - ret = krb5_ret_int8 (sp, &tag); + storage_set_flags(context, sp, id->version); + } else { + int8_t pvno, tag; + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { - krb5_storage_free(sp); close(fd); return ret; } - id->version = tag; - storage_set_flags(context, sp, id->version); + sp = krb5_storage_from_fd(fd); + krb5_storage_set_eof_code(sp, KRB5_KT_END); + ret = krb5_ret_int8(sp, &pvno); + if(ret) { + /* we probably have a zero byte file, so try to set it up + properly */ + ret = fkt_setup_keytab(context, id, sp); + if(ret) { + krb5_set_error_string(context, "%s: keytab is corrupted: %s", + d->filename, strerror(ret)); + goto out; + } + storage_set_flags(context, sp, id->version); + } else { + if(pvno != 5) { + ret = KRB5_KEYTAB_BADVNO; + krb5_set_error_string(context, "%s: %s", + d->filename, strerror(ret)); + goto out; + } + ret = krb5_ret_int8 (sp, &tag); + if (ret) { + krb5_set_error_string(context, "%s: reading tag: %s", + d->filename, strerror(ret)); + goto out; + } + id->version = tag; + storage_set_flags(context, sp, id->version); + } } { @@ -438,9 +545,10 @@ fkt_add_entry(krb5_context context, emem = krb5_storage_emem(); if(emem == NULL) { ret = ENOMEM; + krb5_set_error_string (context, "malloc: out of memory"); goto out; } - ret = krb5_kt_store_principal(emem, entry->principal); + ret = krb5_kt_store_principal(context, emem, entry->principal); if(ret) { krb5_storage_free(emem); goto out; @@ -450,16 +558,24 @@ fkt_add_entry(krb5_context context, krb5_storage_free(emem); goto out; } - ret = krb5_store_int8 (emem, entry->vno); + ret = krb5_store_int8 (emem, entry->vno % 256); if(ret) { krb5_storage_free(emem); goto out; } - ret = krb5_kt_store_keyblock (emem, &entry->keyblock); + ret = krb5_kt_store_keyblock (context, emem, &entry->keyblock); if(ret) { krb5_storage_free(emem); goto out; } + if ((d->flags & KRB5_KT_FL_JAVA) == 0) { + ret = krb5_store_int32 (emem, entry->vno); + if (ret) { + krb5_storage_free(emem); + goto out; + } + } + ret = krb5_storage_to_data(emem, &keytab); krb5_storage_free(emem); if(ret) @@ -468,26 +584,27 @@ fkt_add_entry(krb5_context context, while(1) { ret = krb5_ret_int32(sp, &len); - if(ret == KRB5_CC_END) { + if(ret == KRB5_KT_END) { len = keytab.length; break; } if(len < 0) { len = -len; if(len >= keytab.length) { - sp->seek(sp, -4, SEEK_CUR); + krb5_storage_seek(sp, -4, SEEK_CUR); break; } } - sp->seek(sp, len, SEEK_CUR); + krb5_storage_seek(sp, len, SEEK_CUR); } ret = krb5_store_int32(sp, len); - if(sp->store(sp, keytab.data, keytab.length) < 0) + if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) ret = errno; memset(keytab.data, 0, keytab.length); krb5_data_free(&keytab); - out: + out: krb5_storage_free(sp); + _krb5_xunlock(context, fd); close(fd); return ret; } @@ -501,8 +618,11 @@ fkt_remove_entry(krb5_context context, krb5_kt_cursor cursor; off_t pos_start, pos_end; int found = 0; + krb5_error_code ret; - fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY, &cursor); + ret = fkt_start_seq_get_int(context, id, O_RDWR | O_BINARY, 1, &cursor); + if(ret != 0) + goto out; /* return other error here? */ while(fkt_next_entry_int(context, id, &e, &cursor, &pos_start, &pos_end) == 0) { if(krb5_kt_compare(context, &e, entry->principal, @@ -510,19 +630,23 @@ fkt_remove_entry(krb5_context context, int32_t len; unsigned char buf[128]; found = 1; - cursor.sp->seek(cursor.sp, pos_start, SEEK_SET); + krb5_storage_seek(cursor.sp, pos_start, SEEK_SET); len = pos_end - pos_start - 4; krb5_store_int32(cursor.sp, -len); memset(buf, 0, sizeof(buf)); while(len > 0) { - cursor.sp->store(cursor.sp, buf, min(len, sizeof(buf))); + krb5_storage_write(cursor.sp, buf, min(len, sizeof(buf))); len -= min(len, sizeof(buf)); } } + krb5_kt_free_entry(context, &e); } krb5_kt_end_seq_get(context, id, &cursor); - if (!found) + out: + if (!found) { + krb5_clear_error_string (context); return KRB5_KT_NOTFOUND; + } return 0; } @@ -538,3 +662,29 @@ const krb5_kt_ops krb5_fkt_ops = { fkt_add_entry, fkt_remove_entry }; + +const krb5_kt_ops krb5_wrfkt_ops = { + "WRFILE", + fkt_resolve, + fkt_get_name, + fkt_close, + NULL, /* get */ + fkt_start_seq_get, + fkt_next_entry, + fkt_end_seq_get, + fkt_add_entry, + fkt_remove_entry +}; + +const krb5_kt_ops krb5_javakt_ops = { + "JAVA14", + fkt_resolve_java14, + fkt_get_name, + fkt_close, + NULL, /* get */ + fkt_start_seq_get, + fkt_next_entry, + fkt_end_seq_get, + fkt_add_entry, + fkt_remove_entry +}; diff --git a/kerberosV/src/lib/krb5/keytab_krb4.c b/kerberosV/src/lib/krb5/keytab_krb4.c index 76d6f777826..5efeb8826af 100644 --- a/kerberosV/src/lib/krb5/keytab_krb4.c +++ b/kerberosV/src/lib/krb5/keytab_krb4.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$KTH: keytab_krb4.c,v 1.6 2000/12/15 17:10:40 joda Exp $"); +RCSID("$KTH: keytab_krb4.c,v 1.13 2005/05/19 04:13:18 lha Exp $"); struct krb4_kt_data { char *filename; @@ -45,11 +45,14 @@ krb4_kt_resolve(krb5_context context, const char *name, krb5_keytab id) struct krb4_kt_data *d; d = malloc (sizeof(*d)); - if (d == NULL) + if (d == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } d->filename = strdup (name); if (d->filename == NULL) { free(d); + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } id->data = d; @@ -84,6 +87,31 @@ struct krb4_cursor_extra_data { int num; }; +static int +open_flock(const char *filename, int flags, int mode) +{ + int lock_mode; + int tries = 0; + int fd = open(filename, flags, mode); + if(fd < 0) + return fd; + if((flags & O_ACCMODE) == O_RDONLY) + lock_mode = LOCK_SH | LOCK_NB; + else + lock_mode = LOCK_EX | LOCK_NB; + while(flock(fd, lock_mode) < 0) { + if(++tries < 5) { + sleep(1); + } else { + close(fd); + return -1; + } + } + return fd; +} + + + static krb5_error_code krb4_kt_start_seq_get_int (krb5_context context, krb5_keytab id, @@ -92,19 +120,31 @@ krb4_kt_start_seq_get_int (krb5_context context, { struct krb4_kt_data *d = id->data; struct krb4_cursor_extra_data *ed; + int ret; ed = malloc (sizeof(*ed)); - if (ed == NULL) + if (ed == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } ed->entry.principal = NULL; ed->num = -1; c->data = ed; - c->fd = open (d->filename, flags); + c->fd = open_flock (d->filename, flags, 0); if (c->fd < 0) { + ret = errno; free (ed); - return errno; + krb5_set_error_string(context, "open(%s): %s", d->filename, + strerror(ret)); + return ret; } c->sp = krb5_storage_from_fd(c->fd); + if(c->sp == NULL) { + close(c->fd); + free(ed); + return ENOMEM; + } + krb5_storage_set_eof_code(c->sp, KRB5_KT_END); return 0; } @@ -122,10 +162,10 @@ read_v4_entry (krb5_context context, krb5_kt_cursor *c, struct krb4_cursor_extra_data *ed) { + unsigned char des_key[8]; krb5_error_code ret; char *service, *instance, *realm; int8_t kvno; - des_cblock key; ret = krb5_ret_stringz(c->sp, &service); if (ret) @@ -153,7 +193,7 @@ read_v4_entry (krb5_context context, krb5_free_principal (context, ed->entry.principal); return ret; } - ret = c->sp->fetch(c->sp, key, 8); + ret = krb5_storage_read(c->sp, des_key, sizeof(des_key)); if (ret < 0) { krb5_free_principal(context, ed->entry.principal); return ret; @@ -164,7 +204,7 @@ read_v4_entry (krb5_context context, } ed->entry.vno = kvno; ret = krb5_data_copy (&ed->entry.keyblock.keyvalue, - key, 8); + des_key, sizeof(des_key)); if (ret) return ret; ed->entry.timestamp = time(NULL); @@ -219,47 +259,168 @@ krb4_kt_end_seq_get (krb5_context context, } static krb5_error_code -krb4_kt_add_entry (krb5_context context, - krb5_keytab id, - krb5_keytab_entry *entry) +krb4_store_keytab_entry(krb5_context context, + krb5_keytab_entry *entry, + krb5_storage *sp) { - struct krb4_kt_data *d = id->data; krb5_error_code ret; - int fd; #define ANAME_SZ 40 #define INST_SZ 40 #define REALM_SZ 40 char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; - int8_t kvno; + ret = krb5_524_conv_principal (context, entry->principal, + service, instance, realm); + if (ret) + return ret; + if (entry->keyblock.keyvalue.length == 8 + && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) { + ret = krb5_store_stringz(sp, service); + ret = krb5_store_stringz(sp, instance); + ret = krb5_store_stringz(sp, realm); + ret = krb5_store_int8(sp, entry->vno); + ret = krb5_storage_write(sp, entry->keyblock.keyvalue.data, 8); + } + return 0; +} + +static krb5_error_code +krb4_kt_add_entry (krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry) +{ + struct krb4_kt_data *d = id->data; + krb5_storage *sp; + krb5_error_code ret; + int fd; - fd = open (d->filename, O_WRONLY | O_APPEND | O_BINARY); + fd = open_flock (d->filename, O_WRONLY | O_APPEND | O_BINARY, 0); if (fd < 0) { - fd = open (d->filename, + fd = open_flock (d->filename, O_WRONLY | O_APPEND | O_BINARY | O_CREAT, 0600); - if (fd < 0) - return errno; + if (fd < 0) { + ret = errno; + krb5_set_error_string(context, "open(%s): %s", d->filename, + strerror(ret)); + return ret; + } } - ret = krb5_524_conv_principal (context, entry->principal, - service, instance, realm); + sp = krb5_storage_from_fd(fd); + if(sp == NULL) { + close(fd); + return ENOMEM; + } + krb5_storage_set_eof_code(sp, KRB5_KT_END); + ret = krb4_store_keytab_entry(context, entry, sp); + krb5_storage_free(sp); + if(close (fd) < 0) + return errno; + return ret; +} + +static krb5_error_code +krb4_kt_remove_entry(krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry) +{ + struct krb4_kt_data *d = id->data; + krb5_error_code ret; + krb5_keytab_entry e; + krb5_kt_cursor cursor; + krb5_storage *sp; + int remove_flag = 0; + + sp = krb5_storage_emem(); + if (sp == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + ret = krb5_kt_start_seq_get(context, id, &cursor); if (ret) { - close (fd); + krb5_storage_free(sp); return ret; + } + while(krb5_kt_next_entry(context, id, &e, &cursor) == 0) { + if(!krb5_kt_compare(context, &e, entry->principal, + entry->vno, entry->keyblock.keytype)) { + ret = krb4_store_keytab_entry(context, &e, sp); + if(ret) { + krb5_kt_free_entry(context, &e); + krb5_storage_free(sp); + return ret; + } + } else + remove_flag = 1; + krb5_kt_free_entry(context, &e); } - if (entry->keyblock.keyvalue.length == 8 - && entry->keyblock.keytype == ETYPE_DES_CBC_MD5) { - write(fd, service, strlen(service)+1); - write(fd, instance, strlen(instance)+1); - write(fd, realm, strlen(realm)+1); - kvno = entry->vno; - write(fd, &kvno, sizeof(kvno)); - write(fd, entry->keyblock.keyvalue.data, 8); + krb5_kt_end_seq_get(context, id, &cursor); + if(remove_flag) { + int fd; + unsigned char buf[1024]; + ssize_t n; + krb5_data data; + struct stat st; + + krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + + fd = open_flock (d->filename, O_RDWR | O_BINARY, 0); + if(fd < 0) { + memset(data.data, 0, data.length); + krb5_data_free(&data); + if(errno == EACCES || errno == EROFS) + return KRB5_KT_NOWRITE; + return errno; + } + + if(write(fd, data.data, data.length) != data.length) { + memset(data.data, 0, data.length); + krb5_data_free(&data); + close(fd); + krb5_set_error_string(context, "failed writing to \"%s\"", d->filename); + return errno; + } + memset(data.data, 0, data.length); + if(fstat(fd, &st) < 0) { + krb5_data_free(&data); + close(fd); + krb5_set_error_string(context, "failed getting size of \"%s\"", d->filename); + return errno; + } + st.st_size -= data.length; + memset(buf, 0, sizeof(buf)); + while(st.st_size > 0) { + n = min(st.st_size, sizeof(buf)); + n = write(fd, buf, n); + if(n <= 0) { + krb5_data_free(&data); + close(fd); + krb5_set_error_string(context, "failed writing to \"%s\"", d->filename); + return errno; + + } + st.st_size -= n; + } + if(ftruncate(fd, data.length) < 0) { + krb5_data_free(&data); + close(fd); + krb5_set_error_string(context, "failed truncating \"%s\"", d->filename); + return errno; + } + krb5_data_free(&data); + if(close(fd) < 0) { + krb5_set_error_string(context, "error closing \"%s\"", d->filename); + return errno; + } + return 0; + } else { + krb5_storage_free(sp); + return KRB5_KT_NOTFOUND; } - close (fd); - return 0; } + const krb5_kt_ops krb4_fkt_ops = { "krb4", krb4_kt_resolve, @@ -270,5 +431,18 @@ const krb5_kt_ops krb4_fkt_ops = { krb4_kt_next_entry, krb4_kt_end_seq_get, krb4_kt_add_entry, /* add_entry */ - NULL /* remove_entry */ + krb4_kt_remove_entry /* remove_entry */ +}; + +const krb5_kt_ops krb5_srvtab_fkt_ops = { + "SRVTAB", + krb4_kt_resolve, + krb4_kt_get_name, + krb4_kt_close, + NULL, /* get */ + krb4_kt_start_seq_get, + krb4_kt_next_entry, + krb4_kt_end_seq_get, + krb4_kt_add_entry, /* add_entry */ + krb4_kt_remove_entry /* remove_entry */ }; diff --git a/kerberosV/src/lib/krb5/log.c b/kerberosV/src/lib/krb5/log.c index 67f21e95933..2ab8af9bc2c 100644 --- a/kerberosV/src/lib/krb5/log.c +++ b/kerberosV/src/lib/krb5/log.c @@ -301,6 +301,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) ret = errno; krb5_set_error_string (context, "open(%s): %s", fn, strerror(ret)); + free(fn); return ret; } file = fdopen(i, "a"); @@ -309,6 +310,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) close(i); krb5_set_error_string (context, "fdopen(%s): %s", fn, strerror(ret)); + free(fn); return ret; } keep_open = 1; diff --git a/kerberosV/src/lib/krb5/mk_req_ext.c b/kerberosV/src/lib/krb5/mk_req_ext.c index 18faf1d7f57..3ad4bbf0437 100644 --- a/kerberosV/src/lib/krb5/mk_req_ext.c +++ b/kerberosV/src/lib/krb5/mk_req_ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,17 +33,17 @@ #include <krb5_locl.h> -RCSID("$KTH: mk_req_ext.c,v 1.24 2000/11/15 07:01:26 assar Exp $"); +RCSID("$KTH: mk_req_ext.c,v 1.30 2005/01/05 06:31:01 lukeh Exp $"); krb5_error_code -krb5_mk_req_internal(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - krb5_data *in_data, - krb5_creds *in_creds, - krb5_data *outbuf, - krb5_key_usage checksum_usage, - krb5_key_usage encrypt_usage) +_krb5_mk_req_internal(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + krb5_data *in_data, + krb5_creds *in_creds, + krb5_data *outbuf, + krb5_key_usage checksum_usage, + krb5_key_usage encrypt_usage) { krb5_error_code ret; krb5_data authenticator; @@ -62,6 +62,12 @@ krb5_mk_req_internal(krb5_context context, if(ret) return ret; + if(ac->local_subkey == NULL && (ap_req_options & AP_OPTS_USE_SUBKEY)) { + ret = krb5_auth_con_generatelocalsubkey(context, ac, &in_creds->session); + if(ret) + goto out; + } + #if 0 { /* This is somewhat bogus since we're possibly overwriting a @@ -87,7 +93,9 @@ krb5_mk_req_internal(krb5_context context, #endif krb5_free_keyblock(context, ac->keyblock); - krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock); + ret = krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock); + if (ret) + goto out; /* it's unclear what type of checksum we can use. try the best one, except: * a) if it's configured differently for the current realm, or @@ -99,29 +107,43 @@ krb5_mk_req_internal(krb5_context context, /* this is to make DCE secd (and older MIT kdcs?) happy */ ret = krb5_create_checksum(context, NULL, + 0, CKSUMTYPE_RSA_MD4, in_data->data, in_data->length, &c); + } else if(ac->keyblock->keytype == ETYPE_ARCFOUR_HMAC_MD5 || + ac->keyblock->keytype == ETYPE_ARCFOUR_HMAC_MD5_56) { + /* this is to make MS kdc happy */ + ret = krb5_create_checksum(context, + NULL, + 0, + CKSUMTYPE_RSA_MD5, + in_data->data, + in_data->length, + &c); } else { krb5_crypto crypto; ret = krb5_crypto_init(context, ac->keyblock, 0, &crypto); if (ret) - return ret; + goto out; ret = krb5_create_checksum(context, crypto, checksum_usage, + 0, in_data->data, in_data->length, &c); - - krb5_crypto_destroy(context, crypto); + krb5_crypto_destroy(context, crypto); } c_opt = &c; } else { c_opt = NULL; } + + if (ret) + goto out; ret = krb5_build_authenticator (context, ac, @@ -134,16 +156,17 @@ krb5_mk_req_internal(krb5_context context, if (c_opt) free_Checksum (c_opt); if (ret) - return ret; + goto out; ret = krb5_build_ap_req (context, ac->keyblock->keytype, in_creds, ap_req_options, authenticator, outbuf); +out: if(auth_context == NULL) krb5_auth_con_free(context, ac); return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, @@ -151,7 +174,7 @@ krb5_mk_req_extended(krb5_context context, krb5_creds *in_creds, krb5_data *outbuf) { - return krb5_mk_req_internal (context, + return _krb5_mk_req_internal (context, auth_context, ap_req_options, in_data, diff --git a/kerberosV/src/lib/krb5/principal.c b/kerberosV/src/lib/krb5/principal.c index 6145a7b912c..e5e7cccb972 100644 --- a/kerberosV/src/lib/krb5/principal.c +++ b/kerberosV/src/lib/krb5/principal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -41,7 +41,7 @@ #include <fnmatch.h> #include "resolve.h" -RCSID("$KTH: principal.c,v 1.73 2000/10/16 03:42:14 assar Exp $"); +RCSID("$KTH: principal.c,v 1.88 2004/12/29 01:54:54 lha Exp $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -49,7 +49,7 @@ RCSID("$KTH: principal.c,v 1.73 2000/10/16 03:42:14 assar Exp $"); #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)]) #define princ_realm(P) ((P)->realm) -void +void KRB5_LIB_FUNCTION krb5_free_principal(krb5_context context, krb5_principal p) { @@ -59,17 +59,49 @@ krb5_free_principal(krb5_context context, } } -krb5_error_code +void KRB5_LIB_FUNCTION +krb5_principal_set_type(krb5_context context, + krb5_principal principal, + int type) +{ + princ_type(principal) = type; +} + +int KRB5_LIB_FUNCTION +krb5_principal_get_type(krb5_context context, + krb5_principal principal) +{ + return princ_type(principal); +} + +const char* KRB5_LIB_FUNCTION +krb5_principal_get_realm(krb5_context context, + krb5_principal principal) +{ + return princ_realm(principal); +} + +const char* KRB5_LIB_FUNCTION +krb5_principal_get_comp_string(krb5_context context, + krb5_principal principal, + unsigned int component) +{ + if(component >= princ_num_comp(principal)) + return NULL; + return princ_ncomp(principal, component); +} + +krb5_error_code KRB5_LIB_FUNCTION krb5_parse_name(krb5_context context, const char *name, krb5_principal *principal) { krb5_error_code ret; - general_string *comp; - general_string realm; + heim_general_string *comp; + heim_general_string realm = NULL; int ncomp; - char *p; + const char *p; char *q; char *s; char *start; @@ -80,22 +112,28 @@ krb5_parse_name(krb5_context context, /* count number of component */ ncomp = 1; - for(p = (char*)name; *p; p++){ + for(p = name; *p; p++){ if(*p=='\\'){ - if(!p[1]) + if(!p[1]) { + krb5_set_error_string (context, + "trailing \\ in principal name"); return KRB5_PARSE_MALFORMED; + } p++; } else if(*p == '/') ncomp++; } comp = calloc(ncomp, sizeof(*comp)); - if (comp == NULL) + if (comp == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } n = 0; - start = q = p = s = strdup(name); + p = start = q = s = strdup(name); if (start == NULL) { free (comp); + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } while(*p){ @@ -110,13 +148,22 @@ krb5_parse_name(krb5_context context, c = '\b'; else if(c == '0') c = '\0'; + else if(c == '\0') { + krb5_set_error_string (context, + "trailing \\ in principal name"); + ret = KRB5_PARSE_MALFORMED; + goto exit; + } }else if(c == '/' || c == '@'){ if(got_realm){ + krb5_set_error_string (context, + "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; goto exit; }else{ comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } @@ -130,6 +177,8 @@ krb5_parse_name(krb5_context context, continue; } if(got_realm && (c == ':' || c == '/' || c == '\0')) { + krb5_set_error_string (context, + "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; goto exit; } @@ -138,6 +187,7 @@ krb5_parse_name(krb5_context context, if(got_realm){ realm = malloc(q - start + 1); if (realm == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } @@ -150,6 +200,7 @@ krb5_parse_name(krb5_context context, comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } @@ -159,6 +210,7 @@ krb5_parse_name(krb5_context context, } *principal = malloc(sizeof(**principal)); if (*principal == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } @@ -173,6 +225,7 @@ exit: free(comp[--n]); } free(comp); + free(realm); free(s); return ret; } @@ -235,7 +288,7 @@ unparse_name_fixed(krb5_context context, return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_fixed(krb5_context context, krb5_const_principal principal, char *name, @@ -244,7 +297,7 @@ krb5_unparse_name_fixed(krb5_context context, return unparse_name_fixed(context, principal, name, len, FALSE); } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_fixed_short(krb5_context context, krb5_const_principal principal, char *name, @@ -277,16 +330,21 @@ unparse_name(krb5_context context, len += 2*plen; len++; } + len++; *name = malloc(len); - if(len != 0 && *name == NULL) + if(*name == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } ret = unparse_name_fixed(context, principal, *name, len, short_flag); - if(ret) + if(ret) { free(*name); + *name = NULL; + } return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name(krb5_context context, krb5_const_principal principal, char **name) @@ -294,7 +352,7 @@ krb5_unparse_name(krb5_context context, return unparse_name(context, principal, name, FALSE); } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_short(krb5_context context, krb5_const_principal principal, char **name) @@ -304,7 +362,7 @@ krb5_unparse_name_short(krb5_context context, #if 0 /* not implemented */ -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, char **name, @@ -323,7 +381,7 @@ krb5_princ_realm(krb5_context context, } -void +void KRB5_LIB_FUNCTION krb5_princ_set_realm(krb5_context context, krb5_principal principal, krb5_realm *realm) @@ -332,7 +390,7 @@ krb5_princ_set_realm(krb5_context context, } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal(krb5_context context, krb5_principal *principal, int rlen, @@ -352,16 +410,20 @@ append_component(krb5_context context, krb5_principal p, const char *comp, size_t comp_len) { - general_string *tmp; + heim_general_string *tmp; size_t len = princ_num_comp(p); tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp)); - if(tmp == NULL) + if(tmp == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } princ_comp(p) = tmp; princ_ncomp(p, len) = malloc(comp_len + 1); - if (princ_ncomp(p, len) == NULL) + if (princ_ncomp(p, len) == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } memcpy (princ_ncomp(p, len), comp, comp_len); princ_ncomp(p, len)[comp_len] = '\0'; princ_num_comp(p)++; @@ -406,13 +468,16 @@ build_principal(krb5_context context, krb5_principal p; p = calloc(1, sizeof(*p)); - if (p == NULL) + if (p == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } princ_type(p) = KRB5_NT_PRINCIPAL; princ_realm(p) = strdup(realm); if(p->realm == NULL){ free(p); + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } @@ -421,7 +486,7 @@ build_principal(krb5_context context, return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_make_principal(krb5_context context, krb5_principal *principal, krb5_const_realm realm, @@ -444,7 +509,7 @@ krb5_make_principal(krb5_context context, return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal_va(krb5_context context, krb5_principal *principal, int rlen, @@ -454,7 +519,7 @@ krb5_build_principal_va(krb5_context context, return build_principal(context, principal, rlen, realm, va_princ, ap); } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal_va_ext(krb5_context context, krb5_principal *principal, int rlen, @@ -465,7 +530,7 @@ krb5_build_principal_va_ext(krb5_context context, } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal_ext(krb5_context context, krb5_principal *principal, int rlen, @@ -481,16 +546,21 @@ krb5_build_principal_ext(krb5_context context, } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc) { krb5_principal p = malloc(sizeof(*p)); - if (p == NULL) + if (p == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; - if(copy_Principal(inprinc, p)) + } + if(copy_Principal(inprinc, p)) { + free(p); + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; + } *outprinc = p; return 0; } @@ -499,7 +569,7 @@ krb5_copy_principal(krb5_context context, * return TRUE iff princ1 == princ2 (without considering the realm) */ -krb5_boolean +krb5_boolean KRB5_LIB_FUNCTION krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) @@ -518,7 +588,7 @@ krb5_principal_compare_any_realm(krb5_context context, * return TRUE iff princ1 == princ2 */ -krb5_boolean +krb5_boolean KRB5_LIB_FUNCTION krb5_principal_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) @@ -532,7 +602,7 @@ krb5_principal_compare(krb5_context context, * return TRUE iff realm(princ1) == realm(princ2) */ -krb5_boolean +krb5_boolean KRB5_LIB_FUNCTION krb5_realm_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) @@ -544,7 +614,7 @@ krb5_realm_compare(krb5_context context, * return TRUE iff princ matches pattern */ -krb5_boolean +krb5_boolean KRB5_LIB_FUNCTION krb5_principal_match(krb5_context context, krb5_const_principal princ, krb5_const_principal pattern) @@ -562,7 +632,7 @@ krb5_principal_match(krb5_context context, } -struct v4_name_convert { +static struct v4_name_convert { const char *from; const char *to; } default_v4_name_convert[] = { @@ -571,6 +641,7 @@ struct v4_name_convert { { "pop", "pop" }, { "imap", "imap" }, { "rcmd", "host" }, + { "smtp", "smtp" }, { NULL, NULL } }; @@ -624,7 +695,7 @@ get_name_conversion(krb5_context context, const char *realm, const char *name) * if `func', use that function for validating the conversion */ -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_425_conv_principal_ext(krb5_context context, const char *name, const char *instance, @@ -637,6 +708,7 @@ krb5_425_conv_principal_ext(krb5_context context, krb5_error_code ret; krb5_principal pr; char host[MAXHOSTNAMELEN]; + char local_hostname[MAXHOSTNAMELEN]; /* do the following: if the name is found in the `v4_name_convert:host' part, is is assumed to be a `host' type @@ -667,48 +739,89 @@ krb5_425_conv_principal_ext(krb5_context context, } krb5_free_principal(context, pr); *princ = NULL; + krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; } if(resolve){ - const char *inst = NULL; + krb5_boolean passed = FALSE; + char *inst = NULL; #ifdef USE_RESOLVER struct dns_reply *r; - r = dns_lookup(instance, "a"); - if(r && r->head && r->head->type == T_A) - inst = r->head->domain; -#else - struct hostent *hp = roken_gethostbyname(instance); - if(hp) - inst = hp->h_name; -#endif - if(inst) { - char *low_inst = strdup(inst); - if (low_inst == NULL) { -#ifdef USE_RESOLVER + r = dns_lookup(instance, "aaaa"); + if (r && r->head && r->head->type == T_AAAA) { + inst = strdup(r->head->domain); + dns_free_data(r); + passed = TRUE; + } else { + r = dns_lookup(instance, "a"); + if(r && r->head && r->head->type == T_A) { + inst = strdup(r->head->domain); dns_free_data(r); + passed = TRUE; + } + } +#else + struct addrinfo hints, *ai; + int ret; + + memset (&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + ret = getaddrinfo(instance, NULL, &hints, &ai); + if (ret == 0) { + const struct addrinfo *a; + for (a = ai; a != NULL; a = a->ai_next) { + if (a->ai_canonname != NULL) { + inst = strdup (a->ai_canonname); + passed = TRUE; + break; + } + } + freeaddrinfo (ai); + } #endif + if (passed) { + if (inst == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } - ret = krb5_make_principal(context, &pr, realm, name, low_inst, + strlwr(inst); + ret = krb5_make_principal(context, &pr, realm, name, inst, NULL); - free (low_inst); + free (inst); if(ret == 0) { if(func == NULL || (*func)(context, pr)){ *princ = pr; -#ifdef USE_RESOLVER - dns_free_data(r); -#endif return 0; } krb5_free_principal(context, pr); } } -#ifdef USE_RESOLVER - if(r) - dns_free_data(r); -#endif } + if(func != NULL) { + snprintf(host, sizeof(host), "%s.%s", instance, realm); + strlwr(host); + ret = krb5_make_principal(context, &pr, realm, name, host, NULL); + if((*func)(context, pr)){ + *princ = pr; + return 0; + } + krb5_free_principal(context, pr); + } + + /* + * if the instance is the first component of the local hostname, + * the converted host should be the long hostname. + */ + + if (func == NULL && + gethostname (local_hostname, sizeof(local_hostname)) == 0 && + strncmp(instance, local_hostname, strlen(instance)) == 0 && + local_hostname[strlen(instance)] == '.') { + strlcpy(host, local_hostname, sizeof(host)); + goto local_host; + } + { char **domains, **d; domains = krb5_config_get_strings(context, NULL, "realms", realm, @@ -725,24 +838,27 @@ krb5_425_conv_principal_ext(krb5_context context, } krb5_config_free_strings(domains); } - + p = krb5_config_get_string(context, NULL, "realms", realm, "default_domain", NULL); if(p == NULL){ /* this should be an error, just faking a name is not good */ + krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; } if (*p == '.') ++p; snprintf(host, sizeof(host), "%s.%s", instance, p); +local_host: ret = krb5_make_principal(context, &pr, realm, name, host, NULL); if(func == NULL || (*func)(context, pr)){ *princ = pr; return 0; } krb5_free_principal(context, pr); + krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; no_host: p = krb5_config_get_string(context, NULL, @@ -768,10 +884,11 @@ no_host: return 0; } krb5_free_principal(context, pr); + krb5_clear_error_string (context); return HEIM_ERR_V4_PRINC_NO_CONV; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_425_conv_principal(krb5_context context, const char *name, const char *instance, @@ -864,7 +981,7 @@ name_convert(krb5_context context, const char *name, const char *realm, * three parameters. They have to be 40 bytes each (ANAME_SZ). */ -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_524_conv_principal(krb5_context context, const krb5_principal principal, char *name, @@ -888,6 +1005,9 @@ krb5_524_conv_principal(krb5_context context, i = principal->name.name_string.val[1]; break; default: + krb5_set_error_string (context, + "cannot convert a %d component principal", + principal->name.name_string.len); return KRB5_PARSE_MALFORMED; } @@ -910,12 +1030,21 @@ krb5_524_conv_principal(krb5_context context, i = tmpinst; } - if (strlcpy (name, n, aname_sz) >= aname_sz) + if (strlcpy (name, n, aname_sz) >= aname_sz) { + krb5_set_error_string (context, + "too long name component to convert"); return KRB5_PARSE_MALFORMED; - if (strlcpy (instance, i, aname_sz) >= aname_sz) + } + if (strlcpy (instance, i, aname_sz) >= aname_sz) { + krb5_set_error_string (context, + "too long instance component to convert"); return KRB5_PARSE_MALFORMED; - if (strlcpy (realm, r, aname_sz) >= aname_sz) + } + if (strlcpy (realm, r, aname_sz) >= aname_sz) { + krb5_set_error_string (context, + "too long realm component to convert"); return KRB5_PARSE_MALFORMED; + } return 0; } @@ -923,7 +1052,7 @@ krb5_524_conv_principal(krb5_context context, * Create a principal in `ret_princ' for the service `sname' running * on host `hostname'. */ -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_sname_to_principal (krb5_context context, const char *hostname, const char *sname, @@ -934,8 +1063,11 @@ krb5_sname_to_principal (krb5_context context, char localhost[MAXHOSTNAMELEN]; char **realms, *host = NULL; - if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) + if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) { + krb5_set_error_string (context, "unsupported name type %d", + type); return KRB5_SNAME_UNSUPP_NAMETYPE; + } if(hostname == NULL) { gethostname(localhost, sizeof(localhost)); hostname = localhost; diff --git a/kerberosV/src/lib/krb5/rd_req.c b/kerberosV/src/lib/krb5/rd_req.c index 1ff1ab920bb..b37d41314cc 100644 --- a/kerberosV/src/lib/krb5/rd_req.c +++ b/kerberosV/src/lib/krb5/rd_req.c @@ -271,8 +271,10 @@ krb5_verify_authenticator_checksum(krb5_context context, &authenticator); if(ret) return ret; - if(authenticator->cksum == NULL) + if(authenticator->cksum == NULL) { + krb5_free_authenticator(context, &authenticator); return -17; + } ret = krb5_auth_con_getkey(context, ac, &key); if(ret) { krb5_free_authenticator(context, &authenticator); diff --git a/kerberosV/src/lib/krb5/store.c b/kerberosV/src/lib/krb5/store.c index cf2aadc95d8..b9b2ad8f2dc 100644 --- a/kerberosV/src/lib/krb5/store.c +++ b/kerberosV/src/lib/krb5/store.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,28 +32,72 @@ */ #include "krb5_locl.h" +#include "store-int.h" -RCSID("$KTH: store.c,v 1.34 2000/04/11 00:46:09 assar Exp $"); +RCSID("$KTH: store.c,v 1.49 2005/06/01 10:40:05 lha Exp $"); -void +#define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) +#define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) +#define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE) +#define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \ + krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER)) + +void KRB5_LIB_FUNCTION krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags) { sp->flags |= flags; } -void +void KRB5_LIB_FUNCTION krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags) { sp->flags &= ~flags; } -krb5_boolean +krb5_boolean KRB5_LIB_FUNCTION krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags) { return (sp->flags & flags) == flags; } -ssize_t +void KRB5_LIB_FUNCTION +krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder) +{ + sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK; + sp->flags |= byteorder; +} + +krb5_flags KRB5_LIB_FUNCTION +krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder) +{ + return sp->flags & KRB5_STORAGE_BYTEORDER_MASK; +} + +off_t KRB5_LIB_FUNCTION +krb5_storage_seek(krb5_storage *sp, off_t offset, int whence) +{ + return (*sp->seek)(sp, offset, whence); +} + +krb5_ssize_t KRB5_LIB_FUNCTION +krb5_storage_read(krb5_storage *sp, void *buf, size_t len) +{ + return sp->fetch(sp, buf, len); +} + +krb5_ssize_t KRB5_LIB_FUNCTION +krb5_storage_write(krb5_storage *sp, const void *buf, size_t len) +{ + return sp->store(sp, buf, len); +} + +void KRB5_LIB_FUNCTION +krb5_storage_set_eof_code(krb5_storage *sp, int code) +{ + sp->eof_code = code; +} + +krb5_ssize_t KRB5_LIB_FUNCTION _krb5_put_int(void *buffer, unsigned long value, size_t size) { unsigned char *p = buffer; @@ -65,7 +109,7 @@ _krb5_put_int(void *buffer, unsigned long value, size_t size) return size; } -ssize_t +krb5_ssize_t KRB5_LIB_FUNCTION _krb5_get_int(void *buffer, unsigned long *value, size_t size) { unsigned char *p = buffer; @@ -77,7 +121,7 @@ _krb5_get_int(void *buffer, unsigned long *value, size_t size) return size; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_storage_free(krb5_storage *sp) { if(sp->free) @@ -87,7 +131,7 @@ krb5_storage_free(krb5_storage *sp) return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_storage_to_data(krb5_storage *sp, krb5_data *data) { off_t pos; @@ -115,21 +159,25 @@ krb5_store_int(krb5_storage *sp, size_t len) { int ret; - unsigned char v[4]; + unsigned char v[16]; + if(len > sizeof(v)) + return EINVAL; _krb5_put_int(v, value, len); ret = sp->store(sp, v, len); if (ret != len) - return (ret<0)?errno:KRB5_CC_END; + return (ret<0)?errno:sp->eof_code; return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_int32(krb5_storage *sp, int32_t value) { - if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER)) + if(BYTEORDER_IS_HOST(sp)) value = htonl(value); + else if(BYTEORDER_IS_LE(sp)) + value = bswap32(value); return krb5_store_int(sp, value, 4); } @@ -143,34 +191,38 @@ krb5_ret_int(krb5_storage *sp, unsigned long w; ret = sp->fetch(sp, v, len); if(ret != len) - return (ret<0)?errno:KRB5_CC_END; + return (ret<0)?errno:sp->eof_code; _krb5_get_int(v, &w, len); *value = w; return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int32(krb5_storage *sp, int32_t *value) { krb5_error_code ret = krb5_ret_int(sp, value, 4); if(ret) return ret; - if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER)) - *value = ntohl(*value); + if(BYTEORDER_IS_HOST(sp)) + *value = htonl(*value); + else if(BYTEORDER_IS_LE(sp)) + *value = bswap32(*value); return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_int16(krb5_storage *sp, int16_t value) { - if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER)) + if(BYTEORDER_IS_HOST(sp)) value = htons(value); + else if(BYTEORDER_IS_LE(sp)) + value = bswap16(value); return krb5_store_int(sp, value, 2); } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int16(krb5_storage *sp, int16_t *value) { @@ -180,12 +232,14 @@ krb5_ret_int16(krb5_storage *sp, if(ret) return ret; *value = v; - if(krb5_storage_is_flags(sp, KRB5_STORAGE_HOST_BYTEORDER)) - *value = ntohs(*value); + if(BYTEORDER_IS_HOST(sp)) + *value = htons(*value); + else if(BYTEORDER_IS_LE(sp)) + *value = bswap16(*value); return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_int8(krb5_storage *sp, int8_t value) { @@ -193,11 +247,11 @@ krb5_store_int8(krb5_storage *sp, ret = sp->store(sp, &value, sizeof(value)); if (ret != sizeof(value)) - return (ret<0)?errno:KRB5_CC_END; + return (ret<0)?errno:sp->eof_code; return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_int8(krb5_storage *sp, int8_t *value) { @@ -205,11 +259,11 @@ krb5_ret_int8(krb5_storage *sp, ret = sp->fetch(sp, value, sizeof(*value)); if (ret != sizeof(*value)) - return (ret<0)?errno:KRB5_CC_END; + return (ret<0)?errno:sp->eof_code; return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_data(krb5_storage *sp, krb5_data data) { @@ -221,12 +275,12 @@ krb5_store_data(krb5_storage *sp, if(ret != data.length){ if(ret < 0) return errno; - return KRB5_CC_END; + return sp->eof_code; } return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_data(krb5_storage *sp, krb5_data *data) { @@ -242,12 +296,12 @@ krb5_ret_data(krb5_storage *sp, if (size) { ret = sp->fetch(sp, data->data, size); if(ret != size) - return (ret < 0)? errno : KRB5_CC_END; + return (ret < 0)? errno : sp->eof_code; } return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_string(krb5_storage *sp, const char *s) { krb5_data data; @@ -256,7 +310,7 @@ krb5_store_string(krb5_storage *sp, const char *s) return krb5_store_data(sp, data); } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_string(krb5_storage *sp, char **string) { @@ -274,7 +328,7 @@ krb5_ret_string(krb5_storage *sp, return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_stringz(krb5_storage *sp, const char *s) { size_t len = strlen(s) + 1; @@ -285,12 +339,12 @@ krb5_store_stringz(krb5_storage *sp, const char *s) if(ret < 0) return ret; else - return KRB5_CC_END; + return sp->eof_code; } return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_stringz(krb5_storage *sp, char **string) { @@ -316,7 +370,7 @@ krb5_ret_stringz(krb5_storage *sp, if(ret != 1){ free(s); if(ret == 0) - return KRB5_CC_END; + return sp->eof_code; return ret; } *string = s; @@ -324,7 +378,7 @@ krb5_ret_stringz(krb5_storage *sp, } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_principal(krb5_storage *sp, krb5_principal p) { @@ -350,7 +404,7 @@ krb5_store_principal(krb5_storage *sp, return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_principal(krb5_storage *sp, krb5_principal *princ) { @@ -366,7 +420,7 @@ krb5_ret_principal(krb5_storage *sp, if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) type = KRB5_NT_UNKNOWN; - else if((ret = krb5_ret_int32(sp, &type))){ + else if((ret = krb5_ret_int32(sp, &type))){ free(p); return ret; } @@ -376,24 +430,37 @@ krb5_ret_principal(krb5_storage *sp, } if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) ncomp--; + if (ncomp < 0) { + free(p); + return EINVAL; + } p->name.name_type = type; p->name.name_string.len = ncomp; ret = krb5_ret_string(sp, &p->realm); - if(ret) return ret; + if(ret) { + free(p); + return ret; + } p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val)); - if(p->name.name_string.val == NULL){ + if(p->name.name_string.val == NULL && ncomp != 0){ free(p->realm); return ENOMEM; } for(i = 0; i < ncomp; i++){ ret = krb5_ret_string(sp, &p->name.name_string.val[i]); - if(ret) return ret; /* XXX */ + if(ret) { + while (i >= 0) + free(p->name.name_string.val[i--]); + free(p->realm); + free(p); + return ret; + } } *princ = p; return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p) { int ret; @@ -411,7 +478,7 @@ krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) { int ret; @@ -430,7 +497,7 @@ krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_times(krb5_storage *sp, krb5_times times) { int ret; @@ -444,7 +511,7 @@ krb5_store_times(krb5_storage *sp, krb5_times times) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_times(krb5_storage *sp, krb5_times *times) { int ret; @@ -463,7 +530,7 @@ krb5_ret_times(krb5_storage *sp, krb5_times *times) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_address(krb5_storage *sp, krb5_address p) { int ret; @@ -473,7 +540,7 @@ krb5_store_address(krb5_storage *sp, krb5_address p) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_address(krb5_storage *sp, krb5_address *adr) { int16_t t; @@ -485,7 +552,7 @@ krb5_ret_address(krb5_storage *sp, krb5_address *adr) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_addrs(krb5_storage *sp, krb5_addresses p) { int i; @@ -499,7 +566,7 @@ krb5_store_addrs(krb5_storage *sp, krb5_addresses p) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) { int i; @@ -510,6 +577,8 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) if(ret) return ret; adr->len = tmp; ALLOC(adr->val, adr->len); + if (adr->val == NULL && adr->len != 0) + return ENOMEM; for(i = 0; i < adr->len; i++){ ret = krb5_ret_address(sp, &adr->val[i]); if(ret) break; @@ -517,7 +586,7 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) { krb5_error_code ret; @@ -533,7 +602,7 @@ krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) return 0; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) { krb5_error_code ret; @@ -543,6 +612,8 @@ krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) ret = krb5_ret_int32(sp, &tmp); if(ret) return ret; ALLOC_SEQ(auth, tmp); + if (auth->val == NULL && tmp != 0) + return ENOMEM; for(i = 0; i < tmp; i++){ ret = krb5_ret_int16(sp, &tmp2); if(ret) break; @@ -553,50 +624,65 @@ krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) return ret; } +static int32_t +bitswap32(int32_t b) +{ + int32_t r = 0; + int i; + for (i = 0; i < 32; i++) { + r = r << 1 | (b & 1); + b = b >> 1; + } + return r; +} + + /* - * store `creds' on `sp' returning error or zero + * */ -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_store_creds(krb5_storage *sp, krb5_creds *creds) { int ret; ret = krb5_store_principal(sp, creds->client); - if (ret) + if(ret) return ret; ret = krb5_store_principal(sp, creds->server); - if (ret) + if(ret) return ret; ret = krb5_store_keyblock(sp, creds->session); - if (ret) + if(ret) return ret; ret = krb5_store_times(sp, creds->times); - if (ret) + if(ret) return ret; - ret = krb5_store_int8(sp, 0); /* this is probably the - enc-tkt-in-skey bit from KDCOptions */ - if (ret) + ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ + if(ret) return ret; - ret = krb5_store_int32(sp, creds->flags.i); - if (ret) + + if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER)) + ret = krb5_store_int32(sp, creds->flags.i); + else + ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); + if(ret) return ret; + ret = krb5_store_addrs(sp, creds->addresses); - if (ret) + if(ret) return ret; ret = krb5_store_authdata(sp, creds->authdata); - if (ret) + if(ret) return ret; ret = krb5_store_data(sp, creds->ticket); - if (ret) + if(ret) return ret; ret = krb5_store_data(sp, creds->second_ticket); - if (ret) - return ret; - return 0; + return ret; } -krb5_error_code +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) { krb5_error_code ret; @@ -616,6 +702,22 @@ krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) if(ret) goto cleanup; ret = krb5_ret_int32 (sp, &dummy32); if(ret) goto cleanup; + /* + * Runtime detect the what is the higher bits of the bitfield. If + * any of the higher bits are set in the input data, its either a + * new ticket flag (and this code need to be removed), or its a + * MIT cache (or new Heimdal cache), lets change it to our current + * format. + */ + { + u_int32_t mask = 0xffff0000; + creds->flags.i = 0; + creds->flags.b.anonymous = 1; + if (creds->flags.i & mask) + mask = ~mask; + if (dummy32 & mask) + dummy32 = bitswap32(dummy32); + } creds->flags.i = dummy32; ret = krb5_ret_addrs (sp, &creds->addresses); if(ret) goto cleanup; @@ -625,10 +727,176 @@ krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) if(ret) goto cleanup; ret = krb5_ret_data (sp, &creds->second_ticket); cleanup: + if(ret) { +#if 0 + krb5_free_cred_contents(context, creds); /* XXX */ +#endif + } + return ret; +} + +#define SC_CLIENT_PRINCIPAL 0x0001 +#define SC_SERVER_PRINCIPAL 0x0002 +#define SC_SESSION_KEY 0x0004 +#define SC_TICKET 0x0008 +#define SC_SECOND_TICKET 0x0010 +#define SC_AUTHDATA 0x0020 +#define SC_ADDRESSES 0x0040 + +/* + * + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_store_creds_tag(krb5_storage *sp, + krb5_creds *creds) +{ + int ret; + int32_t header = 0; + + if (creds->client) + header |= SC_CLIENT_PRINCIPAL; + if (creds->server) + header |= SC_SERVER_PRINCIPAL; + if (creds->session.keyvalue.data) + header |= SC_SESSION_KEY; + if (creds->ticket.data) + header |= SC_TICKET; + if (creds->second_ticket.length) + header |= SC_SECOND_TICKET; + if (creds->authdata.len) + header |= SC_AUTHDATA; + if (creds->addresses.len) + header |= SC_ADDRESSES; + + ret = krb5_store_int32(sp, header); + + if (creds->client) { + ret = krb5_store_principal(sp, creds->client); + if(ret) + return ret; + } + + if (creds->server) { + ret = krb5_store_principal(sp, creds->server); + if(ret) + return ret; + } + + if (creds->session.keyvalue.data) { + ret = krb5_store_keyblock(sp, creds->session); + if(ret) + return ret; + } + + ret = krb5_store_times(sp, creds->times); + if(ret) + return ret; + ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ if(ret) + return ret; + + ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); + if(ret) + return ret; + + if (creds->addresses.len) { + ret = krb5_store_addrs(sp, creds->addresses); + if(ret) + return ret; + } + + if (creds->authdata.len) { + ret = krb5_store_authdata(sp, creds->authdata); + if(ret) + return ret; + } + + if (creds->ticket.data) { + ret = krb5_store_data(sp, creds->ticket); + if(ret) + return ret; + } + + if (creds->second_ticket.data) { + ret = krb5_store_data(sp, creds->second_ticket); + if (ret) + return ret; + } + + return ret; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_ret_creds_tag(krb5_storage *sp, + krb5_creds *creds) +{ + krb5_error_code ret; + int8_t dummy8; + int32_t dummy32, header; + + memset(creds, 0, sizeof(*creds)); + + ret = krb5_ret_int32 (sp, &header); + if (ret) goto cleanup; + + if (header & SC_CLIENT_PRINCIPAL) { + ret = krb5_ret_principal (sp, &creds->client); + if(ret) goto cleanup; + } + if (header & SC_SERVER_PRINCIPAL) { + ret = krb5_ret_principal (sp, &creds->server); + if(ret) goto cleanup; + } + if (header & SC_SESSION_KEY) { + ret = krb5_ret_keyblock (sp, &creds->session); + if(ret) goto cleanup; + } + ret = krb5_ret_times (sp, &creds->times); + if(ret) goto cleanup; + ret = krb5_ret_int8 (sp, &dummy8); + if(ret) goto cleanup; + ret = krb5_ret_int32 (sp, &dummy32); + if(ret) goto cleanup; + /* + * Runtime detect the what is the higher bits of the bitfield. If + * any of the higher bits are set in the input data, its either a + * new ticket flag (and this code need to be removed), or its a + * MIT cache (or new Heimdal cache), lets change it to our current + * format. + */ + { + u_int32_t mask = 0xffff0000; + creds->flags.i = 0; + creds->flags.b.anonymous = 1; + if (creds->flags.i & mask) + mask = ~mask; + if (dummy32 & mask) + dummy32 = bitswap32(dummy32); + } + creds->flags.i = dummy32; + if (header & SC_ADDRESSES) { + ret = krb5_ret_addrs (sp, &creds->addresses); + if(ret) goto cleanup; + } + if (header & SC_AUTHDATA) { + ret = krb5_ret_authdata (sp, &creds->authdata); + if(ret) goto cleanup; + } + if (header & SC_TICKET) { + ret = krb5_ret_data (sp, &creds->ticket); + if(ret) goto cleanup; + } + if (header & SC_SECOND_TICKET) { + ret = krb5_ret_data (sp, &creds->second_ticket); + if(ret) goto cleanup; + } + +cleanup: + if(ret) { #if 0 - krb5_free_creds_contents(context, creds) /* XXX */ + krb5_free_cred_contents(context, creds); /* XXX */ #endif - ; + } return ret; } diff --git a/kerberosV/src/lib/krb5/transited.c b/kerberosV/src/lib/krb5/transited.c index 4635a7d71d2..b617625b331 100644 --- a/kerberosV/src/lib/krb5/transited.c +++ b/kerberosV/src/lib/krb5/transited.c @@ -100,8 +100,10 @@ make_path(krb5_context context, struct tr_realm *r, p = from + strlen(from); while(1){ while(p >= from && *p != '/') p--; - if(p == from) + if(p == from) { + r->next = path; /* XXX */ return KRB5KDC_ERR_POLICY; + } if(strncmp(to, from, p - from) == 0) break; tmp = calloc(1, sizeof(*tmp)); |