summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-03-27 11:55:22 +1100
committerAndrew Bartlett <abartlet@samba.org>2010-03-27 11:55:22 +1100
commit533024be44861c8d2c8ba3232738c7d2dbbe2e4f (patch)
tree048c8bd52b50604e950d7976115ebaf42a0802ed /source4/heimdal/lib
parent679854384252e698b8f8c09d31eb15ed043c919b (diff)
downloadsamba-533024be44861c8d2c8ba3232738c7d2dbbe2e4f.tar.gz
samba-533024be44861c8d2c8ba3232738c7d2dbbe2e4f.tar.bz2
samba-533024be44861c8d2c8ba3232738c7d2dbbe2e4f.zip
s4:heimdal: import lorikeet-heimdal-201003262338 (commit f4e0dc17709829235f057e0e100d34802d3929ff)
Diffstat (limited to 'source4/heimdal/lib')
-rw-r--r--source4/heimdal/lib/asn1/krb5.asn15
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h10
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_name.c25
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c57
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c15
-rw-r--r--source4/heimdal/lib/hcrypto/hmac.c4
-rw-r--r--source4/heimdal/lib/hcrypto/rand-unix.c12
-rw-r--r--source4/heimdal/lib/hcrypto/rand.c19
-rw-r--r--source4/heimdal/lib/hcrypto/randi.h1
-rw-r--r--source4/heimdal/lib/hdb/hdb.h2
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c107
-rw-r--r--source4/heimdal/lib/hx509/crypto.c2
-rw-r--r--source4/heimdal/lib/hx509/sel-lex.l4
-rw-r--r--source4/heimdal/lib/krb5/constants.c1
-rw-r--r--source4/heimdal/lib/krb5/context.c36
-rw-r--r--source4/heimdal/lib/krb5/crypto.c54
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c4
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c12
-rw-r--r--source4/heimdal/lib/krb5/principal.c14
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c2
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c2
-rw-r--r--source4/heimdal/lib/krb5/ticket.c12
-rw-r--r--source4/heimdal/lib/roken/resolve.c36
-rw-r--r--source4/heimdal/lib/roken/roken.h.in16
-rw-r--r--source4/heimdal/lib/roken/socket.c21
-rw-r--r--source4/heimdal/lib/roken/strerror_r.c14
29 files changed, 365 insertions, 134 deletions
diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1
index ed663fcf5f..b9a566de7b 100644
--- a/source4/heimdal/lib/asn1/krb5.asn1
+++ b/source4/heimdal/lib/asn1/krb5.asn1
@@ -190,8 +190,9 @@ AUTHDATA-TYPE ::= INTEGER {
KRB5-AUTHDATA-OSF-DCE-PKI-CERTID(66),
KRB5-AUTHDATA-WIN2K-PAC(128),
KRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129), -- Authenticator only
- KRB5-AUTHDATA-SIGNTICKET-OLD(-17),
- KRB5-AUTHDATA-SIGNTICKET(142)
+ KRB5-AUTHDATA-SIGNTICKET-OLDER(-17),
+ KRB5-AUTHDATA-SIGNTICKET-OLD(142),
+ KRB5-AUTHDATA-SIGNTICKET(512)
}
-- checksumtypes
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
index 730737a46a..3f217d38cb 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -862,18 +862,18 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal
int * /*qop_state*/
);
-/*
+/**
*
*/
OM_uint32 GSSAPI_LIB_FUNCTION
-gss_encapsulate_token(gss_buffer_t /* input_token */,
- gss_OID /* oid */,
+gss_encapsulate_token(const gss_buffer_t /* input_token */,
+ const gss_OID /* oid */,
gss_buffer_t /* output_token */);
OM_uint32 GSSAPI_LIB_FUNCTION
-gss_decapsulate_token(gss_buffer_t /* input_token */,
- gss_OID /* oid */,
+gss_decapsulate_token(const gss_buffer_t /* input_token */,
+ const gss_OID /* oid */,
gss_buffer_t /* output_token */);
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
index 1529ab1137..5775db837b 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -263,8 +263,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
if (mech_ret_flags & GSS_C_DELEG_FLAG) {
if (!delegated_cred_handle) {
m->gm_release_cred(minor_status, &delegated_mc);
- if (ret_flags)
- *ret_flags &= ~GSS_C_DELEG_FLAG;
+ mech_ret_flags &=
+ ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
} else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) {
/*
* If the returned mech_type is not the same
diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
index 8db0832d86..95a6c68445 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
@@ -34,8 +34,8 @@
#include "mech_locl.h"
OM_uint32 GSSAPI_LIB_FUNCTION
-gss_decapsulate_token(gss_buffer_t input_token,
- gss_OID oid,
+gss_decapsulate_token(const gss_buffer_t input_token,
+ const gss_OID oid,
gss_buffer_t output_token)
{
GSSAPIContextToken ct;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
index e14b00f9ce..7a3e165364 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
@@ -34,8 +34,8 @@
#include "mech_locl.h"
OM_uint32 GSSAPI_LIB_FUNCTION
-gss_encapsulate_token(gss_buffer_t input_token,
- gss_OID oid,
+gss_encapsulate_token(const gss_buffer_t input_token,
+ const gss_OID oid,
gss_buffer_t output_token)
{
GSSAPIContextToken ct;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
index 19ab75a84c..6ae2302abd 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
@@ -138,6 +138,31 @@ _gss_import_export_name(OM_uint32 *minor_status,
return (GSS_S_COMPLETE);
}
+/**
+ * Import a name internal or mechanism name
+ *
+ * Type of name and their format:
+ * - GSS_C_NO_OID
+ * - GSS_C_NT_USER_NAME
+ * - GSS_C_NT_HOSTBASED_SERVICE
+ * - GSS_C_NT_EXPORT_NAME
+ * - GSS_C_NT_ANONYMOUS
+ * - GSS_KRB5_NT_PRINCIPAL_NAME
+ *
+ * For more information about @ref internalVSmechname.
+ *
+ * @param minor_status minor status code
+ * @param input_name_buffer import name buffer
+ * @param input_name_type type of the import name buffer
+ * @param output_name the resulting type, release with
+ * gss_release_name(), independent of input_name
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_import_name(OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
index dfebe26109..1bcc639345 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
@@ -44,6 +44,63 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
return GSS_C_NO_CREDENTIAL;
}
+/**
+ * As the initiator build a context with an acceptor.
+ *
+ * Returns in the major
+ * - GSS_S_COMPLETE - if the context if build
+ * - GSS_S_CONTINUE_NEEDED - if the caller needs to continue another
+ * round of gss_i nit_sec_context
+ * - error code - any other error code
+ *
+ * @param minor_status minor status code.
+ *
+ * @param context_handle a pointer to a context handle, will be
+ * returned as long as there is not an error.
+ *
+ * @param target_name the target name of acceptor, created using
+ * gss_import_name(). The name is can be of any name types the
+ * mechanism supports, check supported name types with
+ * gss_inquire_names_for_mech().
+ *
+ * @param input_mech_type mechanism type to use, if GSS_C_NO_OID is
+ * used, Kerberos (GSS_KRB5_MECHANISM) will be tried. Other
+ * available mechanism are listed in the @ref gssapi_mechs_intro
+ * section.
+ *
+ * @param req_flags flags using when building the context, see @ref
+ * gssapi_context_ flags
+ *
+ * @param time_req time requested this context should be valid in
+ * seconds, common used value is GSS_C_INDEFINITE
+ *
+ * @param input_chan_bindings Channel bindings used, if not exepected
+ * otherwise, used GSS_C_NO_CHANNEL_BINDINGS
+ *
+ * @param input_token input token sent from the acceptor, for the
+ * initial packet the buffer of { NULL, 0 } should be used.
+ *
+ * @param actual_mech_type the actual mech used, MUST NOT be freed
+ * since it pointing to static memory.
+ *
+ * @param output_token if there is an output token, regardless of
+ * complete, continue_needed, or error it should be sent to the
+ * acceptor
+ *
+ * @param ret_flags return what flags was negotitated, caller should
+ * check if they are accetable. For example, if
+ * GSS_C_MUTUAL_FLAG was negotiated with the acceptor or not.
+ *
+ * @param time_rec amount of time this context is valid for
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
+
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_init_sec_context(OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
index 84553ee05d..47786725ac 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -28,6 +28,21 @@
#include "mech_locl.h"
+/**
+ * Free a name
+ *
+ * import_name can point to NULL or be NULL, or a pointer to a
+ * gss_name_t structure. If it was a pointer to gss_name_t, the
+ * pointer will be set to NULL on success and failure.
+ *
+ * @param minor_status minor status code
+ * @param input_name name to free
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_name(OM_uint32 *minor_status,
gss_name_t *input_name)
diff --git a/source4/heimdal/lib/hcrypto/hmac.c b/source4/heimdal/lib/hcrypto/hmac.c
index dcd836d0be..d11bd98769 100644
--- a/source4/heimdal/lib/hcrypto/hmac.c
+++ b/source4/heimdal/lib/hcrypto/hmac.c
@@ -52,12 +52,12 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx)
ctx->buf = NULL;
}
if (ctx->opad) {
- memset(ctx->ipad, 0, ctx->key_length);
+ memset(ctx->opad, 0, EVP_MD_block_size(ctx->md));
free(ctx->opad);
ctx->opad = NULL;
}
if (ctx->ipad) {
- memset(ctx->ipad, 0, ctx->key_length);
+ memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md));
free(ctx->ipad);
ctx->ipad = NULL;
}
diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c
index 4c1f33da59..63dc97fbfa 100644
--- a/source4/heimdal/lib/hcrypto/rand-unix.c
+++ b/source4/heimdal/lib/hcrypto/rand-unix.c
@@ -46,8 +46,8 @@
* Unix /dev/random
*/
-static int
-get_device_fd(int flags)
+int
+_hc_unix_device_fd(int flags, char **fn)
{
static const char *rnd_devices[] = {
"/dev/urandom",
@@ -61,6 +61,8 @@ get_device_fd(int flags)
for(p = rnd_devices; *p; p++) {
int fd = open(*p, flags | O_NDELAY);
if(fd >= 0) {
+ if (fn)
+ *fn = *p;
rk_cloexec(fd);
return fd;
}
@@ -76,7 +78,7 @@ unix_seed(const void *indata, int size)
if (size <= 0)
return;
- fd = get_device_fd(O_WRONLY);
+ fd = _hc_unix_device_fd(O_WRONLY, NULL);
if (fd < 0)
return;
@@ -97,7 +99,7 @@ unix_bytes(unsigned char *outdata, int size)
else if (size == 0)
return 1;
- fd = get_device_fd(O_RDONLY);
+ fd = _hc_unix_device_fd(O_RDONLY, NULL);
if (fd < 0)
return 0;
@@ -139,7 +141,7 @@ unix_status(void)
{
int fd;
- fd = get_device_fd(O_RDONLY);
+ fd = _hc_unix_device_fd(O_RDONLY, NULL);
if (fd < 0)
return 0;
close(fd);
diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c
index 9f0438a34e..d360ffcab4 100644
--- a/source4/heimdal/lib/hcrypto/rand.c
+++ b/source4/heimdal/lib/hcrypto/rand.c
@@ -342,23 +342,32 @@ RAND_write_file(const char *filename)
const char *
RAND_file_name(char *filename, size_t size)
{
- const char *e = NULL;
+ char *e = NULL;
int pathp = 0, ret;
if (!issuid()) {
e = getenv("RANDFILE");
- if (e == NULL) {
+ if (e == NULL)
e = getenv("HOME");
- if (e)
- pathp = 1;
- }
+ if (e)
+ pathp = 1;
}
/*
* Here we really want to call getpwuid(getuid()) but this will
* cause recursive lookups if the nss library uses
* gssapi/krb5/hcrypto to authenticate to the ldap servers.
+ *
+ * So at least return the unix /dev/random if we have one
*/
+#ifndef _WIN32
+ if (e == NULL) {
+ int fd;
+ fd = _hc_unix_device_fd(O_RDONLY, &e);
+ if (fd >= 0)
+ close(fd);
+ }
+#endif
if (e == NULL)
return NULL;
diff --git a/source4/heimdal/lib/hcrypto/randi.h b/source4/heimdal/lib/hcrypto/randi.h
index c6c617af22..a6d921413a 100644
--- a/source4/heimdal/lib/hcrypto/randi.h
+++ b/source4/heimdal/lib/hcrypto/randi.h
@@ -45,5 +45,6 @@ extern const RAND_METHOD hc_rand_timer_method;
extern const RAND_METHOD hc_rand_w32crypto_method;
const RAND_METHOD * RAND_timer_method(void);
+int _hc_unix_device_fd(int, char **);
#endif /* _HEIM_RANDI_H */
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 91b6753722..d118555121 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -158,6 +158,8 @@ typedef struct HDB{
krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
/**
* Rename the data base.
+ *
+ * Assume that the database is not hdb_open'ed and not locked.
*/
krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
/**
diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c
index d97a98ed6b..bad3c49742 100644
--- a/source4/heimdal/lib/hdb/ndbm.c
+++ b/source4/heimdal/lib/hdb/ndbm.c
@@ -131,40 +131,59 @@ NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry)
}
static krb5_error_code
-NDBM_rename(krb5_context context, HDB *db, const char *new_name)
+open_lock_file(krb5_context context, const char *db_name, int *fd)
{
- /* XXX this function will break */
- struct ndbm_db *d = db->hdb_db;
+ char *lock_file;
+
+ /* lock old and new databases */
+ asprintf(&lock_file, "%s.lock", db_name);
+ if(lock_file == NULL) {
+ krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
+ return ENOMEM;
+ }
+
+ *fd = open(lock_file, O_RDWR | O_CREAT, 0600);
+ free(lock_file);
+ if(*fd < 0) {
+ int ret = errno;
+ krb5_set_error_message(context, ret, "open(%s): %s", lock_file,
+ strerror(ret));
+ return ret;
+ }
+ return 0;
+}
+
+static krb5_error_code
+NDBM_rename(krb5_context context, HDB *db, const char *new_name)
+{
int ret;
char *old_dir, *old_pag, *new_dir, *new_pag;
- char *new_lock;
- int lock_fd;
+ int old_lock_fd, new_lock_fd;
/* lock old and new databases */
- ret = db->hdb_lock(context, db, HDB_WLOCK);
- if(ret)
+ ret = open_lock_file(context, db->hdb_name, &old_lock_fd);
+ if (ret)
+ return ret;
+
+ ret = hdb_lock(old_lock_fd, HDB_WLOCK);
+ if(ret) {
+ close(old_lock_fd);
return ret;
- asprintf(&new_lock, "%s.lock", new_name);
- if(new_lock == NULL) {
- db->hdb_unlock(context, db);
- krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
- return ENOMEM;
}
- lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600);
- if(lock_fd < 0) {
- ret = errno;
- db->hdb_unlock(context, db);
- krb5_set_error_message(context, ret, "open(%s): %s", new_lock,
- strerror(ret));
- free(new_lock);
+
+ ret = open_lock_file(context, new_name, &new_lock_fd);
+ if (ret) {
+ hdb_unlock(old_lock_fd);
+ close(old_lock_fd);
return ret;
}
- free(new_lock);
- ret = hdb_lock(lock_fd, HDB_WLOCK);
+
+ ret = hdb_lock(new_lock_fd, HDB_WLOCK);
if(ret) {
- db->hdb_unlock(context, db);
- close(lock_fd);
+ hdb_unlock(old_lock_fd);
+ close(old_lock_fd);
+ close(new_lock_fd);
return ret;
}
@@ -174,22 +193,25 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name)
asprintf(&new_pag, "%s.pag", new_name);
ret = rename(old_dir, new_dir) || rename(old_pag, new_pag);
+ if (ret) {
+ ret = errno;
+ if (ret == 0)
+ ret = EPERM;
+ krb5_set_error_message(context, ret, "rename: %s", strerror(ret));
+ }
+
free(old_dir);
free(old_pag);
free(new_dir);
free(new_pag);
- hdb_unlock(lock_fd);
- db->hdb_unlock(context, db);
- if(ret) {
- ret = errno;
- close(lock_fd);
- krb5_set_error_message(context, ret, "rename: %s", strerror(ret));
- return ret;
- }
+ hdb_unlock(new_lock_fd);
+ hdb_unlock(old_lock_fd);
+ close(new_lock_fd);
+ close(old_lock_fd);
- close(d->lock_fd);
- d->lock_fd = lock_fd;
+ if(ret)
+ return ret;
free(db->hdb_name);
db->hdb_name = strdup(new_name);
@@ -277,38 +299,31 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode)
{
krb5_error_code ret;
struct ndbm_db *d = malloc(sizeof(*d));
- char *lock_file;
if(d == NULL) {
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
}
- asprintf(&lock_file, "%s.lock", (char*)db->hdb_name);
- if(lock_file == NULL) {
- free(d);
- krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
- return ENOMEM;
- }
+
d->db = dbm_open((char*)db->hdb_name, flags, mode);
if(d->db == NULL){
ret = errno;
free(d);
- free(lock_file);
krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name,
strerror(ret));
return ret;
}
- d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600);
- if(d->lock_fd < 0){
+
+ ret = open_lock_file(context, db->hdb_name, &d->lock_fd);
+ if (ret) {
ret = errno;
dbm_close(d->db);
free(d);
- krb5_set_error_message(context, ret, "open(%s): %s", lock_file,
+ krb5_set_error_message(context, ret, "open(lock file): %s",
strerror(ret));
- free(lock_file);
return ret;
}
- free(lock_file);
+
db->hdb_db = d;
if((flags & O_ACCMODE) == O_RDONLY)
ret = hdb_check_db_format(context, db);
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index bee64c145f..77be4413ac 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -740,7 +740,7 @@ rsa_create_signature(hx509_context context,
if (ret <= 0) {
ret = HX509_CMS_FAILED_CREATE_SIGATURE;
hx509_set_error_string(context, 0, ret,
- "RSA private decrypt failed: %d", ret);
+ "RSA private encrypt failed: %d", ret);
return ret;
}
if (ret > sig->length)
diff --git a/source4/heimdal/lib/hx509/sel-lex.l b/source4/heimdal/lib/hx509/sel-lex.l
index e9bbbc6087..4c9396750a 100644
--- a/source4/heimdal/lib/hx509/sel-lex.l
+++ b/source4/heimdal/lib/hx509/sel-lex.l
@@ -53,6 +53,10 @@ static int lex_input(char *, int);
struct hx_expr_input _hx509_expr_input;
+#ifndef YY_NULL
+#define YY_NULL 0
+#endif
+
#define YY_NO_UNPUT 1
#undef YY_INPUT
diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c
index b85f0cf607..6223fb5d6b 100644
--- a/source4/heimdal/lib/krb5/constants.c
+++ b/source4/heimdal/lib/krb5/constants.c
@@ -42,6 +42,7 @@ KRB5_LIB_VARIABLE const char *krb5_config_file =
"~/Library/Preferences/edu.mit.Kerberos:"
"/Library/Preferences/edu.mit.Kerberos:"
#endif /* __APPLE__ */
+"~/.krb5/config:"
SYSCONFDIR "/krb5.conf"
#ifndef _WIN32
":/etc/krb5.conf"
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c
index dff7a700c4..adcbb703ee 100644
--- a/source4/heimdal/lib/krb5/context.c
+++ b/source4/heimdal/lib/krb5/context.c
@@ -535,7 +535,8 @@ krb5_free_context(krb5_context context)
krb5_set_send_to_kdc_func(context, NULL, NULL);
#ifdef PKINIT
- hx509_context_free(&context->hx509ctx);
+ if (context->hx509ctx)
+ hx509_context_free(&context->hx509ctx);
#endif
HEIMDAL_MUTEX_destroy(context->mutex);
@@ -824,23 +825,33 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_set_default_in_tkt_etypes(krb5_context context,
const krb5_enctype *etypes)
{
+ krb5_error_code ret;
krb5_enctype *p = NULL;
- int i;
+ unsigned int n, m;
if(etypes) {
- for (i = 0; etypes[i]; ++i) {
- krb5_error_code ret;
- ret = krb5_enctype_valid(context, etypes[i]);
- if (ret)
- return ret;
- }
- ++i;
- ALLOC(p, i);
+ for (n = 0; etypes[n]; n++)
+ ;
+ n++;
+ ALLOC(p, n);
if(!p) {
- krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
+ krb5_set_error_message (context, ENOMEM,
+ N_("malloc: out of memory", ""));
return ENOMEM;
}
- memmove(p, etypes, i * sizeof(krb5_enctype));
+ for (n = 0, m = 0; etypes[n]; n++) {
+ ret = krb5_enctype_valid(context, etypes[n]);
+ if (ret)
+ continue;
+ p[m++] = etypes[n];
+ }
+ p[m] = ETYPE_NULL;
+ if (m == 0) {
+ free(p);
+ krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
+ N_("no valid enctype set", ""));
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
}
if(context->etypes)
free(context->etypes);
@@ -1375,6 +1386,7 @@ _krb5_homedir_access(krb5_context context)
* @param allow allow if TRUE home directory
* @return the old value
*
+ * @ingroup krb5
*/
krb5_boolean
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 5906d43f5f..ed8765542c 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -67,6 +67,7 @@ struct krb5_crypto_data {
#define F_PSEUDO 16 /* not a real protocol type */
#define F_SPECIAL 32 /* backwards */
#define F_DISABLED 64 /* enctype/checksum disabled */
+#define F_WEAK 128 /* enctype is considered weak */
struct salt_type {
krb5_salttype type;
@@ -2612,7 +2613,7 @@ static struct encryption_type enctype_des_cbc_crc = {
&keytype_des,
&checksum_crc32,
NULL,
- F_DISABLED,
+ F_DISABLED|F_WEAK,
evp_des_encrypt_key_ivec,
0,
NULL
@@ -2626,7 +2627,7 @@ static struct encryption_type enctype_des_cbc_md4 = {
&keytype_des,
&checksum_rsa_md4,
&checksum_rsa_md4_des,
- F_DISABLED,
+ F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec,
0,
NULL
@@ -2640,7 +2641,7 @@ static struct encryption_type enctype_des_cbc_md5 = {
&keytype_des,
&checksum_rsa_md5,
&checksum_rsa_md5_des,
- F_DISABLED,
+ F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec,
0,
NULL
@@ -2654,7 +2655,7 @@ static struct encryption_type enctype_des_cbc_none = {
&keytype_des,
&checksum_none,
NULL,
- F_PSEUDO|F_DISABLED,
+ F_PSEUDO|F_DISABLED|F_WEAK,
evp_des_encrypt_null_ivec,
0,
NULL
@@ -2668,7 +2669,7 @@ static struct encryption_type enctype_des_cfb64_none = {
&keytype_des_old,
&checksum_none,
NULL,
- F_PSEUDO|F_DISABLED,
+ F_PSEUDO|F_DISABLED|F_WEAK,
DES_CFB64_encrypt_null_ivec,
0,
NULL
@@ -2682,7 +2683,7 @@ static struct encryption_type enctype_des_pcbc_none = {
&keytype_des_old,
&checksum_none,
NULL,
- F_PSEUDO|F_DISABLED,
+ F_PSEUDO|F_DISABLED|F_WEAK,
DES_PCBC_encrypt_key_ivec,
0,
NULL
@@ -3143,8 +3144,14 @@ decrypt_internal(krb5_context context,
krb5_clear_error_message(context);
return KRB5_BAD_MSIZE;
}
-
checksum_sz = CHECKSUMSIZE(et->checksum);
+ if (len < checksum_sz + et->confoundersize) {
+ krb5_set_error_message(context, KRB5_BAD_MSIZE,
+ N_("Encrypted data shorter then "
+ "checksum + confunder", ""));
+ return KRB5_BAD_MSIZE;
+ }
+
p = malloc(len);
if(len != 0 && p == NULL) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
@@ -3206,6 +3213,12 @@ decrypt_internal_special(krb5_context context,
krb5_clear_error_message(context);
return KRB5_BAD_MSIZE;
}
+ if (len < cksum_sz + et->confoundersize) {
+ krb5_set_error_message(context, KRB5_BAD_MSIZE,
+ N_("Encrypted data shorter then "
+ "checksum + confunder", ""));
+ return KRB5_BAD_MSIZE;
+ }
p = malloc (len);
if (p == NULL) {
@@ -4402,6 +4415,33 @@ krb5_enctype_enable(krb5_context context,
return 0;
}
+/**
+ * Enable or disable all weak encryption types
+ *
+ * @param context Kerberos 5 context
+ * @param enable true to enable, false to disable
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_crypto
+ */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_allow_weak_crypto(krb5_context context,
+ krb5_boolean enable)
+{
+ int i;
+
+ for(i = 0; i < num_etypes; i++)
+ if(etypes[i]->flags & F_WEAK) {
+ if(enable)
+ etypes[i]->flags &= ~F_DISABLED;
+ else
+ etypes[i]->flags |= F_DISABLED;
+ }
+ return 0;
+}
+
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_string_to_key_derived(krb5_context context,
diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c
index 3d76391fa8..75e44f0cd4 100644
--- a/source4/heimdal/lib/krb5/get_cred.c
+++ b/source4/heimdal/lib/krb5/get_cred.c
@@ -952,9 +952,7 @@ get_cred_kdc_referral(krb5_context context,
ticket.server))
break;
- if (ticket.server->name.name_string.len != 2 &&
- strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0)
- {
+ if (!krb5_principal_is_krbtgt(context, ticket.server)) {
krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US,
N_("Got back an non krbtgt "
"ticket referrals", ""));
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 4637a6d941..f443788075 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -134,12 +134,12 @@ free_init_creds_ctx(krb5_context context, krb5_init_creds_context ctx)
free (ctx->pre_auth_types);
if (ctx->in_tkt_service)
free(ctx->in_tkt_service);
- if (ctx->password) {
- memset(ctx->password, 0, strlen(ctx->password));
- free(ctx->password);
- }
if (ctx->keytab_data)
free(ctx->keytab_data);
+ if (ctx->password) {
+ memset(ctx->password, 0, strlen(ctx->password));
+ free(ctx->password);
+ }
krb5_data_free(&ctx->req_buffer);
krb5_free_cred_contents(context, &ctx->cred);
free_METHOD_DATA(&ctx->md);
@@ -1436,8 +1436,8 @@ krb5_init_creds_set_password(krb5_context context,
const char *password)
{
if (ctx->password) {
- memset(ctx->password, 0, strlen(ctx->password));
- free(ctx->password);
+ memset(ctx->password, 0, strlen(ctx->password));
+ free(ctx->password);
}
if (password) {
ctx->password = strdup(password);
diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c
index 00c967a72e..8e6341fd62 100644
--- a/source4/heimdal/lib/krb5/principal.c
+++ b/source4/heimdal/lib/krb5/principal.c
@@ -1551,3 +1551,17 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype)
N_("Failed to find name type %s", ""), str);
return KRB5_PARSE_MALFORMED;
}
+
+/**
+ * Check if the cname part of the principal is a krbtgt principal
+ *
+ * @ingroup krb5_principal
+ */
+
+krb5_boolean
+krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p)
+{
+ return p->name.name_string.len == 2 &&
+ strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0;
+
+}
diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c
index 6b2ffbdaac..9f6a85b1a2 100644
--- a/source4/heimdal/lib/krb5/rd_req.c
+++ b/source4/heimdal/lib/krb5/rd_req.c
@@ -821,7 +821,7 @@ out:
* @param inbuf the (AP-REQ) authentication buffer
*
* @param server the server with authenticate as, if NULL the function
- * will try to find any available credential in the keytab
+ * will try to find any avaiable credentintial in the keytab
* that will verify the reply. The function will prefer the
* server the server client specified in the AP-REQ, but if
* there is no mach, it will try all keytab entries for a
diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c
index a9be31e819..9ff52fa545 100644
--- a/source4/heimdal/lib/krb5/send_to_kdc.c
+++ b/source4/heimdal/lib/krb5/send_to_kdc.c
@@ -288,7 +288,7 @@ send_via_proxy (krb5_context context,
return krb5_eai_to_heim_errno(ret, errno);
for (a = ai; a != NULL; a = a->ai_next) {
- s = socket (a->ai_family, a->ai_socktype, a->ai_protocol | SOCK_CLOEXEC);
+ s = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol);
if (s < 0)
continue;
rk_cloexec(s);
diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c
index 4d8da93579..e7d4d9532d 100644
--- a/source4/heimdal/lib/krb5/ticket.c
+++ b/source4/heimdal/lib/krb5/ticket.c
@@ -443,9 +443,7 @@ check_server_referral(krb5_context context,
return KRB5KRB_AP_ERR_MODIFIED;
}
- if (returned->name.name_string.len == 2 &&
- strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
- {
+ if (krb5_principal_is_krbtgt(context, returned)) {
const char *realm = returned->name.name_string.val[1];
if (ref.referred_realm == NULL
@@ -485,7 +483,13 @@ check_server_referral(krb5_context context,
return ret;
noreferral:
- if (krb5_principal_compare(context, requested, returned) == FALSE) {
+ /*
+ * Expect excact match or that we got a krbtgt
+ */
+ if (krb5_principal_compare(context, requested, returned) != TRUE &&
+ (krb5_realm_compare(context, requested, returned) != TRUE &&
+ krb5_principal_is_krbtgt(context, returned) != TRUE))
+ {
krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
N_("Not same server principal returned "
"as requested", ""));
diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c
index 0c0fc1dd92..e112274a68 100644
--- a/source4/heimdal/lib/roken/resolve.c
+++ b/source4/heimdal/lib/roken/resolve.c
@@ -521,8 +521,7 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
{
struct rk_dns_reply *r;
void *reply = NULL;
- int size;
- int len;
+ int size, len;
#if defined(HAVE_DNS_SEARCH)
struct sockaddr_storage from;
uint32_t fromsize = sizeof(from);
@@ -540,15 +539,12 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
return NULL; /* is this the best we can do? */
#endif
- size = 0;
- len = 1000;
- do {
+ len = 1500;
+ while(1) {
if (reply) {
free(reply);
reply = NULL;
}
- if (size <= len)
- size = len;
if (_resolve_debug) {
#if defined(HAVE_DNS_SEARCH)
dns_set_debug(handle, 1);
@@ -556,27 +552,37 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
state.options |= RES_DEBUG;
#endif
fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain,
- rr_class, rk_dns_type_to_string(rr_type), size);
+ rr_class, rk_dns_type_to_string(rr_type), len);
}
- reply = malloc(size);
+ reply = malloc(len);
if (reply == NULL) {
resolve_free_handle(handle);
return NULL;
}
- len = resolve_search(handle, domain, rr_class, rr_type, reply, size);
+ size = resolve_search(handle, domain, rr_class, rr_type, reply, len);
if (_resolve_debug) {
fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
- domain, rr_class, rk_dns_type_to_string(rr_type), len);
- }
- if (len <= 0) {
+ domain, rr_class, rk_dns_type_to_string(rr_type), size);
+ }
+ if (size > len) {
+ /* resolver thinks it know better, go for it */
+ len = size;
+ } else if (size > 0) {
+ /* got a good reply */
+ break;
+ } else if (size <= 0 && len < rk_DNS_MAX_PACKET_SIZE) {
+ len *= 2;
+ if (len > rk_DNS_MAX_PACKET_SIZE)
+ len = rk_DNS_MAX_PACKET_SIZE;
+ } else {
+ /* the end, leave */
resolve_free_handle(handle);
free(reply);
return NULL;
}
- } while (size < len && len < rk_DNS_MAX_PACKET_SIZE);
- resolve_free_handle(handle);
+ }
len = min(len, size);
r = parse_reply(reply, len);
diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in
index 0492db4d6b..76b083c797 100644
--- a/source4/heimdal/lib/roken/roken.h.in
+++ b/source4/heimdal/lib/roken/roken.h.in
@@ -471,7 +471,7 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getdtablesize(void);
ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strerror(int);
#endif
-#if !defined(HAVE_STRERROR_R) && !defined(strerror_r) && !defined(STRERROR_R_PROTO_COMPATIBLE)
+#if (!defined(HAVE_STRERROR_R) && !defined(strerror_r)) || (!defined(STRERROR_R_PROTO_COMPATIBLE) && defined(HAVE_STRERROR_R))
int ROKEN_LIB_FUNCTION rk_strerror_r(int, char *, size_t);
#else
#define rk_strerror_r strerror_r
@@ -652,8 +652,14 @@ ROKEN_LIB_FUNCTION unsigned short ROKEN_LIB_CALL bswap16(unsigned short);
int rk_flock(int fd, int operation);
#endif /* HAVE_FLOCK */
-#if defined(SunOS) || defined(_AIX)
+#ifndef HAVE_DIRFD
+#ifdef HAVE_DIR_DD_FD
#define dirfd(x) ((x)->dd_fd)
+#else
+#ifndef _WIN32 /* Windows code never calls dirfd */
+#error Missing dirfd() and ->dd_fd
+#endif
+#endif
#endif
ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL tm2time (struct tm, int);
@@ -1033,6 +1039,12 @@ void
rk_qsort(void *, size_t, size_t, int (*)(const void *, const void *));
#endif
+#if defined(__linux__) && SOCK_CLOEXEC && !defined(SOCKET_WRAPPER_REPLACE)
+#undef socket
+#define socket(_fam,_type,_prot) rk_socket(_fam,_type,_prot)
+int ROKEN_LIB_FUNCTION rk_socket(int, int, int);
+#endif
+
#ifdef SOCKET_WRAPPER_REPLACE
#include <socket_wrapper.h>
#endif
diff --git a/source4/heimdal/lib/roken/socket.c b/source4/heimdal/lib/roken/socket.c
index bfc4b7102b..bd800ac5a1 100644
--- a/source4/heimdal/lib/roken/socket.c
+++ b/source4/heimdal/lib/roken/socket.c
@@ -315,3 +315,24 @@ socket_to_fd(rk_socket_t sock, int flags)
return _open_osfhandle((intptr_t) sock, flags);
#endif
}
+
+#ifndef HEIMDAL_SMALLER
+#undef socket
+
+int rk_socket(int, int, int);
+
+int
+rk_socket(int domain, int type, int protocol)
+{
+ int s;
+ s = socket (domain, type, protocol);
+#ifdef SOCK_CLOEXEC
+ if ((SOCK_CLOEXEC & type) && s < 0 && errno == EINVAL) {
+ type &= ~SOCK_CLOEXEC;
+ s = socket (domain, type, protocol);
+ }
+#endif
+ return s;
+}
+
+#endif /* HEIMDAL_SMALLER */
diff --git a/source4/heimdal/lib/roken/strerror_r.c b/source4/heimdal/lib/roken/strerror_r.c
index 63dae09a7d..5155c28cb5 100644
--- a/source4/heimdal/lib/roken/strerror_r.c
+++ b/source4/heimdal/lib/roken/strerror_r.c
@@ -33,11 +33,12 @@
#include <config.h>
-#if !defined(HAVE_STRERROR_R) && !defined(STRERROR_R_PROTO_COMPATIBLE)
+#if (!defined(HAVE_STRERROR_R) && !defined(strerror_r)) || (!defined(STRERROR_R_PROTO_COMPATIBLE) && defined(HAVE_STRERROR_R))
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include "roken.h"
#ifdef _MSC_VER
@@ -58,11 +59,6 @@ rk_strerror_r(int eno, char * strerrbuf, size_t buflen)
#else /* _MSC_VER */
-#ifndef HAVE_STRERROR_R
-extern int sys_nerr;
-extern char *sys_errlist[];
-#endif
-
int ROKEN_LIB_FUNCTION
rk_strerror_r(int eno, char *strerrbuf, size_t buflen)
{
@@ -76,11 +72,7 @@ rk_strerror_r(int eno, char *strerrbuf, size_t buflen)
return 0;
#else
int ret;
- if(eno < 0 || eno >= sys_nerr) {
- snprintf(strerrbuf, buflen, "Error %d occurred.", eno);
- return EINVAL;
- }
- ret = snprintf(strerrbuf, buflen, "%s", sys_errlist[eno]);
+ ret = strlcpy(strerrbuf, buflen, strerror(eno));
if (ret > buflen)
return ERANGE;
return 0;