diff options
Diffstat (limited to 'lib/hdb/common.c')
| -rw-r--r-- | lib/hdb/common.c | 164 | 
1 files changed, 114 insertions, 50 deletions
| diff --git a/lib/hdb/common.c b/lib/hdb/common.c index 680b666564b8..2715adf63dca 100644 --- a/lib/hdb/common.c +++ b/lib/hdb/common.c @@ -1,49 +1,47 @@  /* - * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden).  - * All rights reserved.  + * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved.   * - * Redistribution and use in source and binary forms, with or without  - * modification, are permitted provided that the following conditions  - * are met:  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met:   * - * 1. Redistributions of source code must retain the above copyright  - *    notice, this list of conditions and the following disclaimer.  + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.   * - * 2. Redistributions in binary form must reproduce the above copyright  - *    notice, this list of conditions and the following disclaimer in the  - *    documentation and/or other materials provided with the distribution.  + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution.   * - * 3. Neither the name of the Institute nor the names of its contributors  - *    may be used to endorse or promote products derived from this software  - *    without specific prior written permission.  + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission.   * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  - * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  - * SUCH DAMAGE.  + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE.   */  #include "hdb_locl.h" -RCSID("$Id: common.c 20236 2007-02-16 23:52:29Z lha $"); -  int  hdb_principal2key(krb5_context context, krb5_const_principal p, krb5_data *key)  {      Principal new; -    size_t len; +    size_t len = 0;      int ret;      ret = copy_Principal(p, &new); -    if(ret)  +    if(ret)  	return ret;      new.name.name_type = 0; @@ -63,9 +61,9 @@ hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p)  int  hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)  { -    size_t len; +    size_t len = 0;      int ret; -     +      ASN1_MALLOC_ENCODE(hdb_entry, value->data, value->length, ent, &len, ret);      if (ret == 0 && value->length != len)  	krb5_abortx(context, "internal asn.1 encoder error"); @@ -79,14 +77,14 @@ hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent)  }  int -hdb_entry_alias2value(krb5_context context,  +hdb_entry_alias2value(krb5_context context,  		      const hdb_entry_alias *alias,  		      krb5_data *value)  { -    size_t len; +    size_t len = 0;      int ret; -     -    ASN1_MALLOC_ENCODE(hdb_entry_alias, value->data, value->length,  + +    ASN1_MALLOC_ENCODE(hdb_entry_alias, value->data, value->length,  		       alias, &len, ret);      if (ret == 0 && value->length != len)  	krb5_abortx(context, "internal asn.1 encoder error"); @@ -94,20 +92,39 @@ hdb_entry_alias2value(krb5_context context,  }  int -hdb_value2entry_alias(krb5_context context, krb5_data *value,  +hdb_value2entry_alias(krb5_context context, krb5_data *value,  		      hdb_entry_alias *ent)  {      return decode_hdb_entry_alias(value->data, value->length, ent, NULL);  }  krb5_error_code -_hdb_fetch(krb5_context context, HDB *db, krb5_const_principal principal, -	   unsigned flags, hdb_entry_ex *entry) +_hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, +		unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry)  { +    krb5_principal enterprise_principal = NULL;      krb5_data key, value; +    krb5_error_code ret;      int code; +    if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { +	if (principal->name.name_string.len != 1) { +	    ret = KRB5_PARSE_MALFORMED; +	    krb5_set_error_message(context, ret, "malformed principal: " +				   "enterprise name with %d name components", +				   principal->name.name_string.len); +	    return ret; +	} +	ret = krb5_parse_name(context, principal->name.name_string.val[0], +			      &enterprise_principal); +	if (ret) +	    return ret; +	principal = enterprise_principal; +    } +      hdb_principal2key(context, principal, &key); +    if (enterprise_principal) +	krb5_free_principal(context, enterprise_principal);      code = db->hdb__get(context, db, key, &value);      krb5_data_free(&key);      if(code) @@ -154,14 +171,14 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)      krb5_error_code code;      hdb_entry oldentry;      krb5_data value; -    int i; +    size_t i;      code = db->hdb__get(context, db, *key, &value);      if (code == HDB_ERR_NOENTRY)  	return 0;      else if (code)  	return code; -	     +      code = hdb_value2entry(context, &value, &oldentry);      krb5_data_free(&value);      if (code) @@ -188,22 +205,22 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)  }  static krb5_error_code -hdb_add_aliases(krb5_context context, HDB *db,  +hdb_add_aliases(krb5_context context, HDB *db,  		unsigned flags, hdb_entry_ex *entry)  {      const HDB_Ext_Aliases *aliases;      krb5_error_code code;      krb5_data key, value; -    int i; -     +    size_t i; +      code = hdb_entry_get_aliases(&entry->entry, &aliases);      if (code || aliases == NULL)  	return code; -     +      for (i = 0; i < aliases->aliases.len; i++) {  	hdb_entry_alias entryalias;  	entryalias.principal = entry->entry.principal; -	 +  	hdb_principal2key(context, &aliases->aliases.val[i], &key);  	code = hdb_entry_alias2value(context, &entryalias, &value);  	if (code) { @@ -219,17 +236,64 @@ hdb_add_aliases(krb5_context context, HDB *db,      return 0;  } +static krb5_error_code +hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry) +{ +    const HDB_Ext_Aliases *aliases; +    int code; +    size_t i; + +    /* check if new aliases already is used */ + +    code = hdb_entry_get_aliases(&entry->entry, &aliases); +    if (code) +	return code; + +    for (i = 0; aliases && i < aliases->aliases.len; i++) { +	hdb_entry_alias alias; +	krb5_data akey, value; + +	hdb_principal2key(context, &aliases->aliases.val[i], &akey); +	code = db->hdb__get(context, db, akey, &value); +	krb5_data_free(&akey); +	if (code == HDB_ERR_NOENTRY) +	    continue; +	else if (code) +	    return code; + +	code = hdb_value2entry_alias(context, &value, &alias); +	krb5_data_free(&value); + +	if (code == ASN1_BAD_ID) +	    return HDB_ERR_EXISTS; +	else if (code) +	    return code; + +	code = krb5_principal_compare(context, alias.principal, +				      entry->entry.principal); +	free_hdb_entry_alias(&alias); +	if (code == 0) +	    return HDB_ERR_EXISTS; +    } +    return 0; +} +  krb5_error_code  _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)  {      krb5_data key, value;      int code; +    /* check if new aliases already is used */ +    code = hdb_check_aliases(context, db, entry); +    if (code) +	return code; +      if(entry->entry.generation == NULL) {  	struct timeval t;  	entry->entry.generation = malloc(sizeof(*entry->entry.generation));  	if(entry->entry.generation == NULL) { -	    krb5_set_error_string(context, "malloc: out of memory"); +	    krb5_set_error_message(context, ENOMEM, "malloc: out of memory");  	    return ENOMEM;  	}  	gettimeofday(&t, NULL); @@ -238,12 +302,12 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)  	entry->entry.generation->gen = 0;      } else  	entry->entry.generation->gen++; -    hdb_principal2key(context, entry->entry.principal, &key); +      code = hdb_seal_keys(context, db, &entry->entry); -    if (code) { -	krb5_data_free(&key); +    if (code)  	return code; -    } + +    hdb_principal2key(context, entry->entry.principal, &key);      /* remove aliases */      code = hdb_remove_aliases(context, db, &key); | 
