summaryrefslogtreecommitdiff
path: root/kerberosV
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2003-04-12 23:20:09 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2003-04-12 23:20:09 +0000
commit8035f06849a068b72731292e08723fe99c213759 (patch)
tree77dbce33c1587713f03349a153dc4ca7249d9b33 /kerberosV
parentbf761442e550a4c08a17e58daa66180a7d65c354 (diff)
string cleaning; parts by me, then parts by hin, then more parts by me.
since this is not a very important part of the source tree, and since it does compile, i am dumping it in now.
Diffstat (limited to 'kerberosV')
-rw-r--r--kerberosV/src/appl/kf/kfd.c4
-rw-r--r--kerberosV/src/include/bits.c7
-rw-r--r--kerberosV/src/kdc/hpropd.c22
-rw-r--r--kerberosV/src/lib/asn1/der_copy.c4
-rw-r--r--kerberosV/src/lib/asn1/der_put.c2
-rw-r--r--kerberosV/src/lib/asn1/gen.c10
-rw-r--r--kerberosV/src/lib/com_err/com_err.c24
-rw-r--r--kerberosV/src/lib/com_err/parse.y4
-rw-r--r--kerberosV/src/lib/des/ecb_enc.c2
-rw-r--r--kerberosV/src/lib/kadm5/dump_log.c8
-rw-r--r--kerberosV/src/lib/krb5/aname_to_localname.c2
-rw-r--r--kerberosV/src/lib/krb5/krbhst.c807
-rw-r--r--kerberosV/src/lib/krb5/transited.c60
-rw-r--r--kerberosV/src/lib/krb5/warn.c6
-rw-r--r--kerberosV/src/lib/otp/otp_challenge.c2
-rw-r--r--kerberosV/src/lib/otp/otp_db.c4
-rw-r--r--kerberosV/src/lib/otp/otp_md.c18
-rw-r--r--kerberosV/src/lib/roken/getcap.c5
-rw-r--r--kerberosV/src/lib/roken/print_version.c4
-rw-r--r--kerberosV/src/lib/roken/resolve.c6
-rw-r--r--kerberosV/src/lib/sl/ss.c7
-rw-r--r--kerberosV/src/lib/vers/print_version.c4
22 files changed, 817 insertions, 195 deletions
diff --git a/kerberosV/src/appl/kf/kfd.c b/kerberosV/src/appl/kf/kfd.c
index d644c2566a7..dea7c5c3aa1 100644
--- a/kerberosV/src/appl/kf/kfd.c
+++ b/kerberosV/src/appl/kf/kfd.c
@@ -280,10 +280,10 @@ proto (int sock, const char *service)
(char *)(remotename.data),ccname);
out:
if (status) {
- strcpy(ret_string, "no");
+ strlcpy(ret_string, "no", sizeof ret_string);
syslog_and_cont("failed");
} else {
- strcpy(ret_string, "ok");
+ strlcpy(ret_string, "ok", sizeof ret_string);
}
krb5_data_free (&tk_file);
diff --git a/kerberosV/src/include/bits.c b/kerberosV/src/include/bits.c
index ee747c6cebf..06f0b23b93e 100644
--- a/kerberosV/src/include/bits.c
+++ b/kerberosV/src/include/bits.c
@@ -47,8 +47,8 @@ RCSID("$KTH: bits.c,v 1.18 2000/08/27 05:42:46 assar Exp $");
while(x){ x <<= 1; b++; if(x < zero) pre=""; } \
if(b >= len){ \
int tabs; \
- sprintf(tmp, "%sint%d_t" , pre, len); \
- sprintf(tmp2, "typedef %s %s;", #TYPE, tmp); \
+ snprintf(tmp, sizeof tmp, "%sint%d_t" , pre, len); \
+ snprintf(tmp2, sizeof tmp2, "typedef %s %s;", #TYPE, tmp); \
tabs = 5 - strlen(tmp2) / 8; \
fprintf(f, "%s", tmp2); \
while(tabs-- > 0) fprintf(f, "\t"); \
@@ -121,8 +121,7 @@ int main(int argc, char **argv)
} else {
char *p;
fn = argv[1];
- hb = malloc(strlen(fn) + 5);
- sprintf(hb, "__%s__", fn);
+ asprintf(&hb, "__%s__", fn);
for(p = hb; *p; p++){
if(!isalnum((unsigned char)*p))
*p = '_';
diff --git a/kerberosV/src/kdc/hpropd.c b/kerberosV/src/kdc/hpropd.c
index bc2d7d98235..3c4c3ae50c3 100644
--- a/kerberosV/src/kdc/hpropd.c
+++ b/kerberosV/src/kdc/hpropd.c
@@ -87,11 +87,11 @@ dump_krb4(krb5_context context, hdb_entry *ent, int fd)
if (ent->max_life) {
asprintf(&p, "%d", krb_time_to_life(0, *ent->max_life));
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
} else
- strcat(buf, "255");
- strcat(buf, " ");
+ strlcat(buf, "255", sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
i = 0;
while (i < ent->keys.len &&
@@ -107,15 +107,15 @@ dump_krb4(krb5_context context, hdb_entry *ent, int fd)
asprintf(&p, "%d ", *ent->keys.val[i].mkvno);
else
asprintf(&p, "%d ", 1);
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
asprintf(&p, "%d ", ent->kvno);
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
asprintf(&p, "%d ", 0); /* Attributes are always 0*/
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
{
@@ -123,15 +123,15 @@ dump_krb4(krb5_context context, hdb_entry *ent, int fd)
kdb_encrypt_key((des_cblock*)key, (des_cblock*)key,
&mkey4, msched4, DES_ENCRYPT);
asprintf(&p, "%x %x ", (int)htonl(*key), (int)htonl(*(key+1)));
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
}
if (ent->valid_end == NULL)
- strcat(buf, time2str(60*60*24*365*50)); /* no expiration */
+ strlcat(buf, time2str(60*60*24*365*50), sizeof(buf)); /* no expiration */
else
- strcat(buf, time2str(*ent->valid_end));
- strcat(buf, " ");
+ strlcat(buf, time2str(*ent->valid_end), sizeof(buf));
+ strlcat(buf, " ", sizeof(buf));
if (ent->modified_by == NULL)
modifier = &ent->created_by;
@@ -149,7 +149,7 @@ dump_krb4(krb5_context context, hdb_entry *ent, int fd)
asprintf(&p, "%s %s %s\n", time2str(modifier->time),
(strlen(name) != 0) ? name : "*",
(strlen(instance) != 0) ? instance : "*");
- strcat(buf, p);
+ strlcat(buf, p, sizeof(buf));
free(p);
ret = write(fd, buf, strlen(buf));
diff --git a/kerberosV/src/lib/asn1/der_copy.c b/kerberosV/src/lib/asn1/der_copy.c
index b6a61eaeca2..e00c3e89868 100644
--- a/kerberosV/src/lib/asn1/der_copy.c
+++ b/kerberosV/src/lib/asn1/der_copy.c
@@ -38,10 +38,8 @@ RCSID("$KTH: der_copy.c,v 1.8 1999/12/02 17:05:01 joda Exp $");
int
copy_general_string (const general_string *from, general_string *to)
{
- *to = malloc(strlen(*from) + 1);
- if(*to == NULL)
+ if ((*to = strdup(*from)) == NULL)
return ENOMEM;
- strcpy(*to, *from);
return 0;
}
diff --git a/kerberosV/src/lib/asn1/der_put.c b/kerberosV/src/lib/asn1/der_put.c
index 600e18ecbf2..a6f935d56dd 100644
--- a/kerberosV/src/lib/asn1/der_put.c
+++ b/kerberosV/src/lib/asn1/der_put.c
@@ -303,7 +303,7 @@ time2generalizedtime (time_t t, octet_string *s)
return ENOMEM;
s->length = 15;
tm = gmtime (&t);
- sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
+ snprintf (s->data, 16, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec);
return 0;
diff --git a/kerberosV/src/lib/asn1/gen.c b/kerberosV/src/lib/asn1/gen.c
index 1ea7240883c..9d7cb07bd20 100644
--- a/kerberosV/src/lib/asn1/gen.c
+++ b/kerberosV/src/lib/asn1/gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "gen_locl.h"
-RCSID("$KTH: gen.c,v 1.44 2000/06/19 15:17:52 joda Exp $");
+RCSID("$KTH: gen.c,v 1.45 2001/07/15 04:51:36 assar Exp $");
FILE *headerfile, *codefile, *logfile;
@@ -54,8 +54,8 @@ init_generate (const char *filename, const char *base)
{
orig_filename = filename;
if(base)
- strcpy(headerbase, base);
- sprintf(header, "%s.h", headerbase);
+ strlcpy(headerbase, base, sizeof(headerbase));
+ snprintf(header, sizeof(header), "%s.h", headerbase);
headerfile = fopen (header, "w");
if (headerfile == NULL)
err (1, "open %s", header);
@@ -142,10 +142,8 @@ define_asn1 (int level, Type *t)
break;
case TBitString: {
Member *m;
- Type i;
int tag = -1;
- i.type = TInteger;
space(level);
fprintf (headerfile, "BIT STRING {\n");
for (m = t->members; m && m->val != tag; m = m->next) {
diff --git a/kerberosV/src/lib/com_err/com_err.c b/kerberosV/src/lib/com_err/com_err.c
index 657c9887160..5e44fc043fe 100644
--- a/kerberosV/src/lib/com_err/com_err.c
+++ b/kerberosV/src/lib/com_err/com_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
-RCSID("$KTH: com_err.c,v 1.15 2000/04/04 22:04:55 assar Exp $");
+RCSID("$KTH: com_err.c,v 1.17 2001/05/11 20:02:34 assar Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -55,7 +55,7 @@ error_message (long code)
strncpy(msg, p, sizeof(msg) - 1);
msg[sizeof(msg) - 1] = 0;
} else
- sprintf(msg, "Unknown error %ld", code);
+ snprintf(msg, sizeof msg, "Unknown error %ld", code);
return msg;
}
@@ -68,6 +68,10 @@ init_error_table(const char **msgs, long base, int count)
static void
default_proc (const char *whoami, long code, const char *fmt, va_list args)
+ __attribute__((__format__(__printf__, 3, 0)));
+
+static void
+default_proc (const char *whoami, long code, const char *fmt, va_list args)
{
if (whoami)
fprintf(stderr, "%s: ", whoami);
@@ -149,3 +153,17 @@ error_table_name(int num)
*p = '\0';
return(buf);
}
+
+void
+add_to_error_table(struct et_list *new_table)
+{
+ struct et_list *et;
+
+ for (et = _et_list; et; et = et->next) {
+ if (et->table->base == new_table->table->base)
+ return;
+ }
+
+ new_table->next = _et_list;
+ _et_list = new_table;
+}
diff --git a/kerberosV/src/lib/com_err/parse.y b/kerberosV/src/lib/com_err/parse.y
index 379569c0884..78b50ff77f5 100644
--- a/kerberosV/src/lib/com_err/parse.y
+++ b/kerberosV/src/lib/com_err/parse.y
@@ -102,9 +102,7 @@ statement : INDEX NUMBER
}
| PREFIX STRING
{
- prefix = realloc(prefix, strlen($2) + 2);
- strcpy(prefix, $2);
- strcat(prefix, "_");
+ asprintf(&prefix, "%s_", $2);
free($2);
}
| PREFIX
diff --git a/kerberosV/src/lib/des/ecb_enc.c b/kerberosV/src/lib/des/ecb_enc.c
index 5fcaf192898..257182c85bc 100644
--- a/kerberosV/src/lib/des/ecb_enc.c
+++ b/kerberosV/src/lib/des/ecb_enc.c
@@ -96,7 +96,7 @@ char *des_options()
size="int";
else
size="long";
- sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
+ snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
}
return(buf);
}
diff --git a/kerberosV/src/lib/kadm5/dump_log.c b/kerberosV/src/lib/kadm5/dump_log.c
index ab1bc4f4f6b..72f7f20e08e 100644
--- a/kerberosV/src/lib/kadm5/dump_log.c
+++ b/kerberosV/src/lib/kadm5/dump_log.c
@@ -124,7 +124,7 @@ print_entry(kadm5_server_context *server_context,
}
if(mask & KADM5_PRINC_EXPIRE_TIME) {
if(ent.valid_end == NULL) {
- strcpy(t, "never");
+ strlcpy(t, "never", sizeof(t));
} else {
strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
localtime(ent.valid_end));
@@ -133,7 +133,7 @@ print_entry(kadm5_server_context *server_context,
}
if(mask & KADM5_PW_EXPIRATION) {
if(ent.pw_end == NULL) {
- strcpy(t, "never");
+ strlcpy(t, "never", sizeof(t));
} else {
strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
localtime(ent.pw_end));
@@ -149,14 +149,14 @@ print_entry(kadm5_server_context *server_context,
}
if(mask & KADM5_MAX_LIFE) {
if(ent.max_life == NULL)
- strcpy(t, "for ever");
+ strlcpy(t, "for ever", sizeof(t));
else
unparse_time(*ent.max_life, t, sizeof(t));
printf(" max life = %s\n", t);
}
if(mask & KADM5_MAX_RLIFE) {
if(ent.max_renew == NULL)
- strcpy(t, "for ever");
+ strlcpy(t, "for ever", sizeof(t));
else
unparse_time(*ent.max_renew, t, sizeof(t));
printf(" max rlife = %s\n", t);
diff --git a/kerberosV/src/lib/krb5/aname_to_localname.c b/kerberosV/src/lib/krb5/aname_to_localname.c
index a21430c10bc..290db36e488 100644
--- a/kerberosV/src/lib/krb5/aname_to_localname.c
+++ b/kerberosV/src/lib/krb5/aname_to_localname.c
@@ -71,6 +71,6 @@ krb5_aname_to_localname (krb5_context context,
len = strlen (res);
if (len >= lnsize)
return ERANGE;
- strcpy (lname, res);
+ strlcpy (lname, res, lnsize);
return 0;
}
diff --git a/kerberosV/src/lib/krb5/krbhst.c b/kerberosV/src/lib/krb5/krbhst.c
index a66595d46bb..4787a4768e5 100644
--- a/kerberosV/src/lib/krb5/krbhst.c
+++ b/kerberosV/src/lib/krb5/krbhst.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -34,136 +34,727 @@
#include "krb5_locl.h"
#include <resolve.h>
-RCSID("$KTH: krbhst.c,v 1.25 2001/01/19 04:30:54 assar Exp $");
-
-/*
- * assuming that `*res' contains `*count' strings, add a copy of `string'.
- */
+RCSID("$KTH: krbhst.c,v 1.40 2001/07/19 16:57:15 assar Exp $");
static int
-add_string(char ***res, int *count, const char *string)
+string_to_proto(const char *string)
{
- char **tmp = realloc(*res, (*count + 1) * sizeof(**res));
-
- if(tmp == NULL)
- return ENOMEM;
- *res = tmp;
- if(string) {
- tmp[*count] = strdup(string);
- if(tmp[*count] == NULL)
- return ENOMEM;
- } else
- tmp[*count] = NULL;
- (*count)++;
- return 0;
+ if(strcasecmp(string, "udp") == 0)
+ return KRB5_KRBHST_UDP;
+ else if(strcasecmp(string, "tcp") == 0)
+ return KRB5_KRBHST_TCP;
+ else if(strcasecmp(string, "http") == 0)
+ return KRB5_KRBHST_HTTP;
+ return -1;
}
/*
- * do a SRV lookup for `realm, proto, service' returning the result
- * in `res, count'
+ * set `res' and `count' to the result of looking up SRV RR in DNS for
+ * `proto', `proto', `realm' using `dns_type'.
+ * if `port' != 0, force that port number
*/
static krb5_error_code
-srv_find_realm(krb5_context context, char ***res, int *count,
- const char *realm, const char *proto, const char *service)
+srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
+ const char *realm, const char *dns_type,
+ const char *proto, const char *service, int port)
{
char domain[1024];
- char alt_domain[1024];
- krb5_error_code ret;
struct dns_reply *r;
struct resource_record *rr;
+ int num_srv;
+ int proto_num;
+ int def_port;
+
+ proto_num = string_to_proto(proto);
+ if(proto_num < 0) {
+ krb5_set_error_string(context, "unknown protocol `%s'", proto);
+ return EINVAL;
+ }
+
+ if(proto_num == KRB5_KRBHST_HTTP)
+ def_port = ntohs(krb5_getportbyname (context, "http", "tcp", 80));
+ else if(port == 0)
+ def_port = ntohs(krb5_getportbyname (context, service, proto, 88));
+ else
+ def_port = port;
snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
-
- r = dns_lookup(domain, "srv");
- if(r == NULL && context->srv_try_rfc2052) {
- snprintf(alt_domain, sizeof(alt_domain), "%s.%s.%s.",
- service, proto, realm);
- r = dns_lookup(alt_domain, "srv");
- }
- if(r == NULL && context->srv_try_txt)
- r = dns_lookup(domain, "txt");
- if(r == NULL && context->srv_try_rfc2052 && context->srv_try_txt)
- r = dns_lookup(alt_domain, "txt");
- if(r == NULL)
- return 0;
- for(rr = r->head; rr; rr = rr->next){
- if(rr->type == T_SRV){
- char buf[1024];
- char **tmp;
+ r = dns_lookup(domain, dns_type);
+ if(r == NULL) {
+ *res = NULL;
+ *count = 0;
+ return KRB5_KDC_UNREACH;
+ }
+
+ for(num_srv = 0, rr = r->head; rr; rr = rr->next)
+ if(rr->type == T_SRV)
+ num_srv++;
- tmp = realloc(*res, (*count + 1) * sizeof(**res));
- if (tmp == NULL)
+ *res = malloc(num_srv * sizeof(**res));
+ if(*res == NULL) {
+ dns_free_data(r);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+
+ dns_srv_order(r);
+
+ for(num_srv = 0, rr = r->head; rr; rr = rr->next)
+ if(rr->type == T_SRV) {
+ krb5_krbhst_info *hi;
+ size_t len;
+
+ len = strlen(rr->u.srv->target);
+ hi = calloc(1, sizeof(*hi) + len);
+ if(hi == NULL) {
+ dns_free_data(r);
+ while(--num_srv >= 0)
+ free((*res)[num_srv]);
+ free(*res);
return ENOMEM;
- *res = tmp;
- snprintf (buf, sizeof(buf),
- "%s/%s:%u",
- proto,
- rr->u.srv->target,
- rr->u.srv->port);
- ret = add_string(res, count, buf);
- if(ret)
- return ret;
- }else if(rr->type == T_TXT) {
- ret = add_string(res, count, rr->u.txt);
- if(ret)
- return ret;
+ }
+ (*res)[num_srv++] = hi;
+
+ hi->proto = proto_num;
+
+ hi->def_port = def_port;
+ if (port != 0)
+ hi->port = port;
+ else
+ hi->port = rr->u.srv->port;
+
+ strlcpy(hi->hostname, rr->u.srv->target, len);
}
- }
+
+ *count = num_srv;
+
dns_free_data(r);
return 0;
}
+
+struct krb5_krbhst_data {
+ char *realm;
+ unsigned int flags;
+ int def_port;
+ int port; /* hardwired port number if != 0 */
+#define KD_CONFIG 1
+#define KD_SRV_UDP 2
+#define KD_SRV_TCP 4
+#define KD_SRV_HTTP 8
+#define KD_FALLBACK 16
+#define KD_CONFIG_EXISTS 32
+
+ krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,
+ krb5_krbhst_info**);
+
+ unsigned int fallback_count;
+
+ struct krb5_krbhst_info *hosts, **index, **end;
+};
+
+static krb5_boolean
+krbhst_empty(const struct krb5_krbhst_data *kd)
+{
+ return kd->index == &kd->hosts;
+}
+
/*
- * lookup the servers for realm `realm', looking for the config string
- * `conf_string' in krb5.conf or for `serv_string' in SRV records.
- * return a malloc-ed list of servers in hostlist.
+ * parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port'
+ * and forcing it to `port' if port != 0
*/
+static struct krb5_krbhst_info*
+parse_hostspec(krb5_context context, const char *spec, int def_port, int port)
+{
+ const char *p = spec;
+ struct krb5_krbhst_info *hi;
+
+ hi = calloc(1, sizeof(*hi) + strlen(spec));
+ if(hi == NULL)
+ return NULL;
+
+ hi->proto = KRB5_KRBHST_UDP;
+
+ if(strncmp(p, "http://", 7) == 0){
+ hi->proto = KRB5_KRBHST_HTTP;
+ p += 7;
+ } else if(strncmp(p, "http/", 5) == 0) {
+ hi->proto = KRB5_KRBHST_HTTP;
+ p += 5;
+ def_port = ntohs(krb5_getportbyname (context, "http", "tcp", 80));
+ }else if(strncmp(p, "tcp/", 4) == 0){
+ hi->proto = KRB5_KRBHST_TCP;
+ p += 4;
+ } else if(strncmp(p, "udp/", 4) == 0) {
+ p += 4;
+ }
+
+ if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
+ free(hi);
+ return NULL;
+ }
+ /* get rid of trailing /, and convert to lower case */
+ hi->hostname[strcspn(hi->hostname, "/")] = '\0';
+ strlwr(hi->hostname);
+
+ hi->port = hi->def_port = def_port;
+ if(p != NULL) {
+ char *end;
+ hi->port = strtol(p, &end, 0);
+ if(end == p) {
+ free(hi);
+ return NULL;
+ }
+ }
+ if (port)
+ hi->port = port;
+ return hi;
+}
+
+static void
+free_krbhst_info(krb5_krbhst_info *hi)
+{
+ if (hi->ai != NULL)
+ freeaddrinfo(hi->ai);
+ free(hi);
+}
+
+static void
+append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)
+{
+ struct krb5_krbhst_info *h;
+
+ for(h = kd->hosts; h; h = h->next)
+ if(h->proto == host->proto &&
+ h->port == host->port &&
+ strcmp(h->hostname, host->hostname) == 0) {
+ free_krbhst_info(host);
+ return;
+ }
+ *kd->end = host;
+ kd->end = &host->next;
+}
+
static krb5_error_code
-get_krbhst (krb5_context context,
- const krb5_realm *realm,
- const char *conf_string,
- const char *serv_string,
- char ***hostlist)
-{
- char **res, **r;
- int count;
+append_host_string(krb5_context context, struct krb5_krbhst_data *kd,
+ const char *host, int def_port, int port)
+{
+ struct krb5_krbhst_info *hi;
+
+ hi = parse_hostspec(context, host, def_port, port);
+ if(hi == NULL)
+ return ENOMEM;
+
+ append_host_hostinfo(kd, hi);
+ return 0;
+}
+
+/*
+ * return a readable representation of `host' in `hostname, hostlen'
+ */
+
+krb5_error_code
+krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,
+ char *hostname, size_t hostlen)
+{
+ const char *proto = "";
+ char portstr[7] = "";
+ if(host->proto == KRB5_KRBHST_TCP)
+ proto = "tcp/";
+ else if(host->proto == KRB5_KRBHST_HTTP)
+ proto = "http://";
+ if(host->port != host->def_port)
+ snprintf(portstr, sizeof(portstr), ":%d", host->port);
+ snprintf(hostname, hostlen, "%s%s%s", proto, host->hostname, portstr);
+ return 0;
+}
+
+/*
+ * create a getaddrinfo `hints' based on `proto'
+ */
+
+static void
+make_hints(struct addrinfo *hints, int proto)
+{
+ memset(hints, 0, sizeof(*hints));
+ hints->ai_family = AF_UNSPEC;
+ switch(proto) {
+ case KRB5_KRBHST_UDP :
+ hints->ai_socktype = SOCK_DGRAM;
+ break;
+ case KRB5_KRBHST_HTTP :
+ case KRB5_KRBHST_TCP :
+ hints->ai_socktype = SOCK_STREAM;
+ break;
+ }
+}
+
+/*
+ * return an `struct addrinfo *' in `ai' corresponding to the information
+ * in `host'. free:ing is handled by krb5_krbhst_free.
+ */
+
+krb5_error_code
+krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
+ struct addrinfo **ai)
+{
+ struct addrinfo hints;
+ char portstr[NI_MAXSERV];
+ int ret;
+
+ if (host->ai == NULL) {
+ make_hints(&hints, host->proto);
+ snprintf (portstr, sizeof(portstr), "%d", host->port);
+ ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
+ if (ret)
+ return krb5_eai_to_heim_errno(ret, errno);
+ }
+ *ai = host->ai;
+ return 0;
+}
+
+static krb5_boolean
+get_next(struct krb5_krbhst_data *kd, krb5_krbhst_info **host)
+{
+ struct krb5_krbhst_info *hi = *kd->index;
+ if(hi != NULL) {
+ *host = hi;
+ kd->index = &(*kd->index)->next;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
+ const char *proto, const char *service)
+{
+ krb5_krbhst_info **res;
+ int count, i;
+
+ srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
+ kd->port);
+ for(i = 0; i < count; i++)
+ append_host_hostinfo(kd, res[i]);
+ free(res);
+}
+
+/*
+ * read the configuration for `conf_string', defaulting to kd->def_port and
+ * forcing it to `kd->port' if kd->port != 0
+ */
+
+static void
+config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
+ const char *conf_string)
+{
+ int i;
+
+ char **hostlist;
+ hostlist = krb5_config_get_strings(context, NULL,
+ "realms", kd->realm, conf_string, NULL);
+
+ if(hostlist == NULL)
+ return;
+ kd->flags |= KD_CONFIG_EXISTS;
+ for(i = 0; hostlist && hostlist[i] != NULL; i++)
+ append_host_string(context, kd, hostlist[i], kd->def_port, kd->port);
+
+ krb5_config_free_strings(hostlist);
+}
+
+/*
+ * as a fallback, look for `serv_string.kd->realm' (typically
+ * kerberos.REALM, kerberos-1.REALM, ...
+ * `port' is the default port for the service, and `proto' the
+ * protocol
+ */
+
+static krb5_error_code
+fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
+ const char *serv_string, int port, int proto)
+{
+ char *host;
+ int ret;
+ struct addrinfo *ai;
+ struct addrinfo hints;
+ char portstr[NI_MAXSERV];
+
+ if(kd->fallback_count == 0)
+ asprintf(&host, "%s.%s.", serv_string, kd->realm);
+ else
+ asprintf(&host, "%s-%d.%s.",
+ serv_string, kd->fallback_count, kd->realm);
+
+ if (host == NULL)
+ return ENOMEM;
+
+ make_hints(&hints, proto);
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ ret = getaddrinfo(host, portstr, &hints, &ai);
+ if (ret) {
+ /* no more hosts, so we're done here */
+ free(host);
+ kd->flags |= KD_FALLBACK;
+ } else {
+ struct krb5_krbhst_info *hi;
+ size_t hostlen = strlen(host);
+
+ hi = calloc(1, sizeof(*hi) + hostlen);
+ if(hi == NULL) {
+ free(host);
+ return ENOMEM;
+ }
+
+ hi->proto = proto;
+ hi->port = hi->def_port = port;
+ hi->ai = ai;
+ memmove(hi->hostname, host, hostlen - 1);
+ hi->hostname[hostlen - 1] = '\0';
+ free(host);
+ append_host_hostinfo(kd, hi);
+ kd->fallback_count++;
+ }
+ return 0;
+}
+
+static krb5_error_code
+kdc_get_next(krb5_context context,
+ struct krb5_krbhst_data *kd,
+ krb5_krbhst_info **host)
+{
krb5_error_code ret;
- res = krb5_config_get_strings(context, NULL,
- "realms", *realm, conf_string, NULL);
- for(r = res, count = 0; r && *r; r++, count++);
-
- if(count == 0 && context->srv_lookup) {
- char *s[] = { "udp", "tcp", "http" }, **q;
- for(q = s; q < s + sizeof(s) / sizeof(s[0]); q++) {
- ret = srv_find_realm(context, &res, &count, *realm, *q,
- serv_string);
- if(ret) {
- krb5_config_free_strings(res);
- return ret;
- }
+ if((kd->flags & KD_CONFIG) == 0) {
+ config_get_hosts(context, kd, "kdc");
+ kd->flags |= KD_CONFIG;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ if (kd->flags & KD_CONFIG_EXISTS)
+ return KRB5_KDC_UNREACH; /* XXX */
+
+ if(context->srv_lookup) {
+ if((kd->flags & KD_SRV_UDP) == 0) {
+ srv_get_hosts(context, kd, "udp", "kerberos");
+ kd->flags |= KD_SRV_UDP;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ if((kd->flags & KD_SRV_TCP) == 0) {
+ srv_get_hosts(context, kd, "tcp", "kerberos");
+ kd->flags |= KD_SRV_TCP;
+ if(get_next(kd, host))
+ return 0;
+ }
+ if((kd->flags & KD_SRV_HTTP) == 0) {
+ srv_get_hosts(context, kd, "http", "kerberos");
+ kd->flags |= KD_SRV_HTTP;
+ if(get_next(kd, host))
+ return 0;
}
}
- if(count == 0) {
- char buf[1024];
- snprintf(buf, sizeof(buf), "kerberos.%s", *realm);
- ret = add_string(&res, &count, buf);
- if(ret) {
- krb5_config_free_strings(res);
+ while((kd->flags & KD_FALLBACK) == 0) {
+ ret = fallback_get_hosts(context, kd, "kerberos",
+ kd->def_port, KRB5_KRBHST_UDP);
+ if(ret)
return ret;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ return KRB5_KDC_UNREACH; /* XXX */
+}
+
+static krb5_error_code
+admin_get_next(krb5_context context,
+ struct krb5_krbhst_data *kd,
+ krb5_krbhst_info **host)
+{
+ krb5_error_code ret;
+
+ if((kd->flags & KD_CONFIG) == 0) {
+ config_get_hosts(context, kd, "admin_server");
+ kd->flags |= KD_CONFIG;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ if (kd->flags & KD_CONFIG_EXISTS)
+ return KRB5_KDC_UNREACH; /* XXX */
+
+ if(context->srv_lookup) {
+ if((kd->flags & KD_SRV_TCP) == 0) {
+ srv_get_hosts(context, kd, "tcp", "kerberos-adm");
+ kd->flags |= KD_SRV_TCP;
+ if(get_next(kd, host))
+ return 0;
}
}
- add_string(&res, &count, NULL);
- *hostlist = res;
+
+ if (krbhst_empty(kd)
+ && (kd->flags & KD_FALLBACK) == 0) {
+ ret = fallback_get_hosts(context, kd, "kerberos",
+ kd->def_port, KRB5_KRBHST_UDP);
+ if(ret)
+ return ret;
+ kd->flags |= KD_FALLBACK;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ return KRB5_KDC_UNREACH; /* XXX */
+}
+
+static krb5_error_code
+kpasswd_get_next(krb5_context context,
+ struct krb5_krbhst_data *kd,
+ krb5_krbhst_info **host)
+{
+ if((kd->flags & KD_CONFIG) == 0) {
+ config_get_hosts(context, kd, "kpasswd_server");
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ if (kd->flags & KD_CONFIG_EXISTS)
+ return KRB5_KDC_UNREACH; /* XXX */
+
+ if(context->srv_lookup) {
+ if((kd->flags & KD_SRV_UDP) == 0) {
+ srv_get_hosts(context, kd, "udp", "kpasswd");
+ kd->flags |= KD_SRV_UDP;
+ if(get_next(kd, host))
+ return 0;
+ }
+ }
+
+ /* no matches -> try admin */
+
+ if (krbhst_empty(kd)) {
+ kd->flags = 0;
+ kd->port = kd->def_port;
+ kd->get_next = admin_get_next;
+ return (*kd->get_next)(context, kd, host);
+ }
+
+ return KRB5_KDC_UNREACH; /* XXX */
+}
+
+static krb5_error_code
+krb524_get_next(krb5_context context,
+ struct krb5_krbhst_data *kd,
+ krb5_krbhst_info **host)
+{
+ if((kd->flags & KD_CONFIG) == 0) {
+ config_get_hosts(context, kd, "krb524_server");
+ if(get_next(kd, host))
+ return 0;
+ kd->flags |= KD_CONFIG;
+ }
+
+ if (kd->flags & KD_CONFIG_EXISTS)
+ return KRB5_KDC_UNREACH; /* XXX */
+
+ if(context->srv_lookup) {
+ if((kd->flags & KD_SRV_UDP) == 0) {
+ srv_get_hosts(context, kd, "udp", "krb524");
+ kd->flags |= KD_SRV_UDP;
+ if(get_next(kd, host))
+ return 0;
+ }
+
+ if((kd->flags & KD_SRV_TCP) == 0) {
+ srv_get_hosts(context, kd, "tcp", "krb524");
+ kd->flags |= KD_SRV_TCP;
+ if(get_next(kd, host))
+ return 0;
+ }
+ }
+
+ /* no matches -> try kdc */
+
+ if (krbhst_empty(kd)) {
+ kd->flags = 0;
+ kd->port = kd->def_port;
+ kd->get_next = kdc_get_next;
+ return (*kd->get_next)(context, kd, host);
+ }
+
+ return KRB5_KDC_UNREACH; /* XXX */
+}
+
+static struct krb5_krbhst_data*
+common_init(krb5_context context,
+ const char *realm)
+{
+ struct krb5_krbhst_data *kd;
+
+ if((kd = calloc(1, sizeof(*kd))) == NULL)
+ return NULL;
+
+ if((kd->realm = strdup(realm)) == NULL) {
+ free(kd);
+ return NULL;
+ }
+
+ kd->end = kd->index = &kd->hosts;
+ return kd;
+}
+
+/*
+ * initialize `handle' to look for hosts of type `type' in realm `realm'
+ */
+
+krb5_error_code
+krb5_krbhst_init(krb5_context context,
+ const char *realm,
+ unsigned int type,
+ krb5_krbhst_handle *handle)
+{
+ struct krb5_krbhst_data *kd;
+ krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,
+ krb5_krbhst_info **);
+ int def_port;
+
+ switch(type) {
+ case KRB5_KRBHST_KDC:
+ get_next = kdc_get_next;
+ def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
+ break;
+ case KRB5_KRBHST_ADMIN:
+ get_next = admin_get_next;
+ def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
+ "tcp", 749));
+ break;
+ case KRB5_KRBHST_CHANGEPW:
+ get_next = kpasswd_get_next;
+ def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
+ KPASSWD_PORT));
+ break;
+ case KRB5_KRBHST_KRB524:
+ get_next = krb524_get_next;
+ def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
+ break;
+ default:
+ krb5_set_error_string(context, "unknown krbhst type (%u)", type);
+ return ENOTTY;
+ }
+ if((kd = common_init(context, realm)) == NULL)
+ return ENOMEM;
+ kd->get_next = get_next;
+ kd->def_port = def_port;
+ *handle = kd;
+ return 0;
+}
+
+/*
+ * return the next host information from `handle' in `host'
+ */
+
+krb5_error_code
+krb5_krbhst_next(krb5_context context,
+ krb5_krbhst_handle handle,
+ krb5_krbhst_info **host)
+{
+ if(get_next(handle, host))
+ return 0;
+
+ return (*handle->get_next)(context, handle, host);
+}
+
+/*
+ * return the next host information from `handle' as a host name
+ * in `hostname' (or length `hostlen)
+ */
+
+krb5_error_code
+krb5_krbhst_next_as_string(krb5_context context,
+ krb5_krbhst_handle handle,
+ char *hostname,
+ size_t hostlen)
+{
+ krb5_error_code ret;
+ krb5_krbhst_info *host;
+ ret = krb5_krbhst_next(context, handle, &host);
+ if(ret)
+ return ret;
+ return krb5_krbhst_format_string(context, host, hostname, hostlen);
+}
+
+
+void
+krb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle)
+{
+ handle->index = &handle->hosts;
+}
+
+void
+krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)
+{
+ krb5_krbhst_info *h, *next;
+
+ if (handle == NULL)
+ return;
+
+ for (h = handle->hosts; h != NULL; h = next) {
+ next = h->next;
+ free_krbhst_info(h);
+ }
+
+ free(handle->realm);
+ free(handle);
+}
+
+/* backwards compatibility ahead */
+
+static krb5_error_code
+gethostlist(krb5_context context, const char *realm,
+ unsigned int type, char ***hostlist)
+{
+ krb5_error_code ret;
+ int nhost = 0;
+ krb5_krbhst_handle handle;
+ char host[MAXHOSTNAMELEN];
+ krb5_krbhst_info *hostinfo;
+
+ ret = krb5_krbhst_init(context, realm, type, &handle);
+ if (ret)
+ return ret;
+
+ while(krb5_krbhst_next(context, handle, &hostinfo) == 0)
+ nhost++;
+ if(nhost == 0)
+ return KRB5_KDC_UNREACH;
+ *hostlist = calloc(nhost + 1, sizeof(**hostlist));
+ if(*hostlist == NULL) {
+ krb5_krbhst_free(context, handle);
+ return ENOMEM;
+ }
+
+ krb5_krbhst_reset(context, handle);
+ nhost = 0;
+ while(krb5_krbhst_next_as_string(context, handle,
+ host, sizeof(host)) == 0) {
+ if(((*hostlist)[nhost++] = strdup(host)) == NULL) {
+ krb5_free_krbhst(context, *hostlist);
+ krb5_krbhst_free(context, handle);
+ return ENOMEM;
+ }
+ }
+ (*hostlist)[nhost++] = NULL;
+ krb5_krbhst_free(context, handle);
return 0;
}
/*
- * set `hostlist' to a malloced list of kadmin servers.
+ * return an malloced list of kadmin-hosts for `realm' in `hostlist'
*/
krb5_error_code
@@ -171,12 +762,11 @@ krb5_get_krb_admin_hst (krb5_context context,
const krb5_realm *realm,
char ***hostlist)
{
- return get_krbhst (context, realm, "admin_server", "kerberos-adm",
- hostlist);
+ return gethostlist(context, *realm, KRB5_KRBHST_ADMIN, hostlist);
}
/*
- * set `hostlist' to a malloced list of changepw servers.
+ * return an malloced list of changepw-hosts for `realm' in `hostlist'
*/
krb5_error_code
@@ -184,19 +774,24 @@ krb5_get_krb_changepw_hst (krb5_context context,
const krb5_realm *realm,
char ***hostlist)
{
- krb5_error_code ret;
+ return gethostlist(context, *realm, KRB5_KRBHST_CHANGEPW, hostlist);
+}
- ret = get_krbhst (context, realm, "kpasswd_server", "kpasswd",
- hostlist);
- if (ret)
- return ret;
- ret = get_krbhst (context, realm, "admin_server", "kpasswd",
- hostlist);
- return ret;
+/*
+ * return an malloced list of 524-hosts for `realm' in `hostlist'
+ */
+
+krb5_error_code
+krb5_get_krb524hst (krb5_context context,
+ const krb5_realm *realm,
+ char ***hostlist)
+{
+ return gethostlist(context, *realm, KRB5_KRBHST_KRB524, hostlist);
}
+
/*
- * set `hostlist' to a malloced list of kerberos servers.
+ * return an malloced list of KDC's for `realm' in `hostlist'
*/
krb5_error_code
@@ -204,11 +799,11 @@ krb5_get_krbhst (krb5_context context,
const krb5_realm *realm,
char ***hostlist)
{
- return get_krbhst (context, realm, "kdc", "kerberos", hostlist);
+ return gethostlist(context, *realm, KRB5_KRBHST_KDC, hostlist);
}
/*
- * free all memory associated with `hostlist'
+ * free all the memory allocated in `hostlist'
*/
krb5_error_code
diff --git a/kerberosV/src/lib/krb5/transited.c b/kerberosV/src/lib/krb5/transited.c
index aa25e75404b..aae48a946c4 100644
--- a/kerberosV/src/lib/krb5/transited.c
+++ b/kerberosV/src/lib/krb5/transited.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$KTH: transited.c,v 1.7 2000/02/07 13:30:41 joda Exp $");
+RCSID("$KTH: transited.c,v 1.8 2001/05/14 06:14:52 assar Exp $");
/* this is an attempt at one of the most horrible `compression'
schemes that has ever been invented; it's so amazingly brain-dead
@@ -61,7 +61,8 @@ free_realms(struct tr_realm *r)
}
static int
-make_path(struct tr_realm *r, const char *from, const char *to)
+make_path(krb5_context context, struct tr_realm *r,
+ const char *from, const char *to)
{
const char *p;
struct tr_realm *path = r->next;
@@ -78,8 +79,10 @@ make_path(struct tr_realm *r, const char *from, const char *to)
p = from;
while(1){
p = strchr(p, '.');
- if(p == NULL)
+ if(p == NULL) {
+ krb5_clear_error_string (context);
return KRB5KDC_ERR_POLICY;
+ }
p++;
if(strcmp(p, to) == 0)
break;
@@ -89,6 +92,7 @@ make_path(struct tr_realm *r, const char *from, const char *to)
path->realm = strdup(p);
if(path->realm == NULL){
r->next = path; /* XXX */
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;;
}
}
@@ -106,21 +110,25 @@ make_path(struct tr_realm *r, const char *from, const char *to)
path->realm = malloc(p - from + 1);
if(path->realm == NULL){
r->next = path; /* XXX */
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
memcpy(path->realm, from, p - from);
path->realm[p - from] = '\0';
p--;
}
- }else
+ } else {
+ krb5_clear_error_string (context);
return KRB5KDC_ERR_POLICY;
+ }
r->next = path;
return 0;
}
static int
-make_paths(struct tr_realm *realms, const char *client_realm,
+make_paths(krb5_context context,
+ struct tr_realm *realms, const char *client_realm,
const char *server_realm)
{
struct tr_realm *r;
@@ -138,7 +146,7 @@ make_paths(struct tr_realm *realms, const char *client_realm,
next_realm = r->next->realm;
else
next_realm = server_realm;
- ret = make_path(r, prev_realm, next_realm);
+ ret = make_path(context, r, prev_realm, next_realm);
if(ret){
free_realms(realms);
return ret;
@@ -150,7 +158,8 @@ make_paths(struct tr_realm *realms, const char *client_realm,
}
static int
-expand_realms(struct tr_realm *realms, const char *client_realm)
+expand_realms(krb5_context context,
+ struct tr_realm *realms, const char *client_realm)
{
struct tr_realm *r;
const char *prev_realm = NULL;
@@ -162,21 +171,25 @@ expand_realms(struct tr_realm *realms, const char *client_realm)
tmp = realloc(r->realm, strlen(r->realm) + strlen(prev_realm) + 1);
if(tmp == NULL){
free_realms(realms);
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
r->realm = tmp;
- strcat(r->realm, prev_realm);
+ strlcat(r->realm, prev_realm,
+ strlen(r->realm) + strlen(prev_realm) + 1);
}else if(r->leading_slash && !r->leading_space && prev_realm){
/* yet another exception: if you use x500-names, the
leading realm doesn't have to be "quoted" with a space */
+ size_t len = strlen(r->realm) + strlen(prev_realm) + 1;
char *tmp;
- tmp = malloc(strlen(r->realm) + strlen(prev_realm) + 1);
+ tmp = malloc(len);
if(tmp == NULL){
free_realms(realms);
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
- strcpy(tmp, prev_realm);
- strcat(tmp, r->realm);
+ strlcpy(tmp, prev_realm, len);
+ strlcat(tmp, r->realm, len);
free(r->realm);
r->realm = tmp;
}
@@ -236,7 +249,8 @@ append_realm(struct tr_realm *head, struct tr_realm *r)
}
static int
-decode_realms(const char *tr, int length, struct tr_realm **realms)
+decode_realms(krb5_context context,
+ const char *tr, int length, struct tr_realm **realms)
{
struct tr_realm *r = NULL;
@@ -261,6 +275,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
r = make_realm(tmp);
if(r == NULL){
free_realms(*realms);
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
*realms = append_realm(*realms, r);
@@ -273,6 +288,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
r = make_realm(tmp);
if(r == NULL){
free_realms(*realms);
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
*realms = append_realm(*realms, r);
@@ -282,7 +298,8 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
krb5_error_code
-krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
+krb5_domain_x500_decode(krb5_context context,
+ krb5_data tr, char ***realms, int *num_realms,
const char *client_realm, const char *server_realm)
{
struct tr_realm *r = NULL;
@@ -290,16 +307,16 @@ krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
int ret;
/* split string in components */
- ret = decode_realms(tr.data, tr.length, &r);
+ ret = decode_realms(context, tr.data, tr.length, &r);
if(ret)
return ret;
/* apply prefix rule */
- ret = expand_realms(r, client_realm);
+ ret = expand_realms(context, r, client_realm);
if(ret)
return ret;
- ret = make_paths(r, client_realm, server_realm);
+ ret = make_paths(context, r, client_realm, server_realm);
if(ret)
return ret;
@@ -324,6 +341,7 @@ krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
R = realloc(*realms, (*num_realms + 1) * sizeof(**realms));
if(R == NULL) {
free(*realms);
+ krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
R[*num_realms] = r->realm;
@@ -353,10 +371,10 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
*s = '\0';
for(i = 0; i < num_realms; i++){
if(i && i < num_realms - 1)
- strcat(s, ",");
+ strlcat(s, ",", len+1);
if(realms[i][0] == '/')
- strcat(s, " ");
- strcat(s, realms[i]);
+ strlcat(s, " ", len+1);
+ strlcat(s, realms[i], len+1);
}
encoding->data = s;
encoding->length = strlen(s);
@@ -382,6 +400,8 @@ krb5_check_transited_realms(krb5_context context,
char **p;
for(p = bad_realms; *p; p++)
if(strcmp(*p, realms[i]) == 0) {
+ krb5_set_error_string (context, "no transit through realm %s",
+ *p);
ret = KRB5KRB_AP_ERR_ILL_CR_TKT;
if(bad_realm)
*bad_realm = i;
diff --git a/kerberosV/src/lib/krb5/warn.c b/kerberosV/src/lib/krb5/warn.c
index fe79d967020..df270f0928f 100644
--- a/kerberosV/src/lib/krb5/warn.c
+++ b/kerberosV/src/lib/krb5/warn.c
@@ -52,9 +52,9 @@ _warnerr(krb5_context context, int do_errtext,
args[0] = args[1] = NULL;
arg = args;
if(fmt){
- strcat(xfmt, "%s");
+ strlcat(xfmt, "%s", sizeof(xfmt));
if(do_errtext)
- strcat(xfmt, ": ");
+ strlcat(xfmt, ": ", sizeof(xfmt));
vasprintf(&msg, fmt, ap);
if(msg == NULL)
return ENOMEM;
@@ -63,7 +63,7 @@ _warnerr(krb5_context context, int do_errtext,
if(context && do_errtext){
const char *err_msg;
- strcat(xfmt, "%s");
+ strlcat(xfmt, "%s", sizeof(xfmt));
err_str = krb5_get_error_string(context);
if (err_str != NULL) {
diff --git a/kerberosV/src/lib/otp/otp_challenge.c b/kerberosV/src/lib/otp/otp_challenge.c
index 791fac494a6..99a998207e4 100644
--- a/kerberosV/src/lib/otp/otp_challenge.c
+++ b/kerberosV/src/lib/otp/otp_challenge.c
@@ -51,7 +51,7 @@ otp_challenge (OtpContext *ctx, char *user, char *str, size_t len)
ctx->err = "Out of memory";
return -1;
}
- strcpy(ctx->user, user);
+ strlcpy(ctx->user, user, strlen(user)+1);
dbm = otp_db_open ();
if (dbm == NULL) {
ctx->err = "Cannot open database";
diff --git a/kerberosV/src/lib/otp/otp_db.c b/kerberosV/src/lib/otp/otp_db.c
index 58b4eb2756f..0021ec5fcd0 100644
--- a/kerberosV/src/lib/otp/otp_db.c
+++ b/kerberosV/src/lib/otp/otp_db.c
@@ -195,7 +195,7 @@ otp_put (void *v, OtpContext *ctx)
if (rem < len)
return -1;
- strcpy (p, ctx->alg->name);
+ strlcpy (p, ctx->alg->name, rem);
p += len;
rem -= len;
@@ -220,7 +220,7 @@ otp_put (void *v, OtpContext *ctx)
len = strlen(ctx->seed) + 1;
if (rem < len)
return -1;
- strcpy (p, ctx->seed);
+ strlcpy (p, ctx->seed, rem);
p += len;
rem -= len;
dat.dptr = buf;
diff --git a/kerberosV/src/lib/otp/otp_md.c b/kerberosV/src/lib/otp/otp_md.c
index e68db51ab09..bbc14b69c20 100644
--- a/kerberosV/src/lib/otp/otp_md.c
+++ b/kerberosV/src/lib/otp/otp_md.c
@@ -33,24 +33,18 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
-RCSID("$KTH: otp_md.c,v 1.14 2001/01/29 05:55:18 assar Exp $");
+RCSID("$KTH: otp_md.c,v 1.15 2001/08/22 20:30:32 assar Exp $");
#endif
#include "otp_locl.h"
#include "otp_md.h"
-#ifdef HAVE_OPENSSL_MD4_H
+#ifdef HAVE_OPENSSL
#include <openssl/md4.h>
-#else
-#include <md4.h>
-#endif
-#ifdef HAVE_OPENSSL_MD5_H
#include <openssl/md5.h>
-#else
-#include <md5.h>
-#endif
-#ifdef HAVE_OPENSSL_SHA_H
#include <openssl/sha.h>
#else
+#include <md4.h>
+#include <md5.h>
#include <sha.h>
#endif
@@ -93,9 +87,9 @@ otp_md_init (OtpKey key,
p = malloc (len + 1);
if (p == NULL)
return -1;
- strcpy (p, seed);
+ strlcpy (p, seed, len+1);
strlwr (p);
- strcat (p, pwd);
+ strlcat (p, pwd, len+1);
(*init)(arg);
(*update)(arg, p, len);
(*final)(res, arg);
diff --git a/kerberosV/src/lib/roken/getcap.c b/kerberosV/src/lib/roken/getcap.c
index 75979452ef7..86f0e61a933 100644
--- a/kerberosV/src/lib/roken/getcap.c
+++ b/kerberosV/src/lib/roken/getcap.c
@@ -251,11 +251,12 @@ getent(char **cap, size_t *len, char **db_array, int fd,
* Check if we have a top record from cgetset().
*/
if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) {
- if ((record = malloc (topreclen + BFRAG)) == NULL) {
+ size_t len = topreclen + BFRAG;
+ if ((record = malloc (len)) == NULL) {
errno = ENOMEM;
return (-2);
}
- (void)strcpy(record, toprec); /* XXX: strcpy is safe */
+ (void)strlcpy(record, toprec, len);
db_p = db_array;
rp = record + topreclen + 1;
r_end = rp + BFRAG;
diff --git a/kerberosV/src/lib/roken/print_version.c b/kerberosV/src/lib/roken/print_version.c
index cfe69a295ce..d46ab992ba2 100644
--- a/kerberosV/src/lib/roken/print_version.c
+++ b/kerberosV/src/lib/roken/print_version.c
@@ -69,8 +69,8 @@ print_version(const char *progname)
msg[0] = '\0';
for(i = 0; i < num_args; i++) {
if(i > 0)
- strcat(msg, ", ");
- strcat(msg, arg[i]);
+ strlcat(msg, ", ", len+1);
+ strlcat(msg, arg[i], len+1);
}
}
fprintf(stderr, "%s (%s)\n", progname, msg);
diff --git a/kerberosV/src/lib/roken/resolve.c b/kerberosV/src/lib/roken/resolve.c
index 77ce5f5503d..229ddd6ca17 100644
--- a/kerberosV/src/lib/roken/resolve.c
+++ b/kerberosV/src/lib/roken/resolve.c
@@ -209,7 +209,7 @@ parse_reply(unsigned char *data, int len)
return NULL;
}
(*rr)->u.mx->preference = (p[0] << 8) | p[1];
- strcpy((*rr)->u.mx->domain, host);
+ strlcpy((*rr)->u.mx->domain, host, strlen(host));
break;
}
case T_SRV:{
@@ -228,7 +228,7 @@ parse_reply(unsigned char *data, int len)
(*rr)->u.srv->priority = (p[0] << 8) | p[1];
(*rr)->u.srv->weight = (p[2] << 8) | p[3];
(*rr)->u.srv->port = (p[4] << 8) | p[5];
- strcpy((*rr)->u.srv->target, host);
+ strlcpy((*rr)->u.srv->target, host, strlen(host));
break;
}
case T_TXT:{
@@ -286,7 +286,7 @@ parse_reply(unsigned char *data, int len)
(*rr)->u.sig->sig_len = sig_len;
memcpy ((*rr)->u.sig->sig_data, p + 18 + status, sig_len);
(*rr)->u.sig->signer = &(*rr)->u.sig->sig_data[sig_len];
- strcpy((*rr)->u.sig->signer, host);
+ strlcpy((*rr)->u.sig->signer, host, strlen(host));
break;
}
diff --git a/kerberosV/src/lib/sl/ss.c b/kerberosV/src/lib/sl/ss.c
index f7f8d259d8c..4f2918a20f5 100644
--- a/kerberosV/src/lib/sl/ss.c
+++ b/kerberosV/src/lib/sl/ss.c
@@ -137,12 +137,13 @@ ss_execute_line (int index, const char *line)
int
ss_listen (int index)
{
- char *prompt = malloc(strlen(subsystems[index].name) + 3);
+ size_t len = strlen(subsystems[index].name) + 3;
+ char *prompt = malloc(len);
if (prompt == NULL)
return ENOMEM;
- strcpy(prompt, subsystems[index].name);
- strcat(prompt, ": ");
+ strlcpy(prompt, subsystems[index].name, len);
+ strlcat(prompt, ": ", len);
sl_loop(subsystems[index].table, prompt);
free(prompt);
return 0;
diff --git a/kerberosV/src/lib/vers/print_version.c b/kerberosV/src/lib/vers/print_version.c
index 21b047820a7..e40cb9e138f 100644
--- a/kerberosV/src/lib/vers/print_version.c
+++ b/kerberosV/src/lib/vers/print_version.c
@@ -69,8 +69,8 @@ print_version(const char *progname)
msg[0] = '\0';
for(i = 0; i < num_args; i++) {
if(i > 0)
- strcat(msg, ", ");
- strcat(msg, arg[i]);
+ strlcat(msg, ", ", len+1);
+ strlcat(msg, arg[i], len+1);
}
}
fprintf(stderr, "%s (%s)\n", progname, msg);