krb5_error_code krb5_db2_get_principal(krb5_context context, krb5_const_principal searchfor, unsigned int flags, krb5_db_entry **entry) { krb5_db2_context *db_ctx; krb5_error_code retval; DB *db; DBT key, contents; krb5_data keydata, contdata; int trynum, dbret; *entry = NULL; if (!k5db2_inited(context)) return KRB5_KDB_DBNOTINITED; db_ctx = context->dal_handle->db_context; for (trynum = 0; trynum < KRB5_DB2_MAX_RETRY; trynum++) { if ((retval = krb5_db2_lock(context, KRB5_LOCKMODE_SHARED))) { if (db_ctx->db_nb_locks) return (retval); sleep(1); continue; } break; } if (trynum == KRB5_DB2_MAX_RETRY) return KRB5_KDB_DB_INUSE; /* XXX deal with wildcard lookups */ retval = krb5_encode_princ_dbkey(context, &keydata, searchfor); if (retval) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = db_ctx->db; dbret = (*db->get)(db, &key, &contents, 0); retval = errno; krb5_free_data_contents(context, &keydata); switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleanup; case 0: contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, entry); break; } cleanup: (void) krb5_db2_unlock(context); /* unlock read lock */ return retval; }
krb5_error_code krb5_db2_put_principal(krb5_context context, krb5_db_entry *entry, char **db_args) { int dbret; DB *db; DBT key, contents; krb5_data contdata, keydata; krb5_error_code retval; krb5_db2_context *db_ctx; krb5_clear_error_message (context); if (db_args) { /* DB2 does not support db_args DB arguments for principal */ krb5_set_error_message(context, EINVAL, "Unsupported argument \"%s\" for db2", db_args[0]); return EINVAL; } if (!k5db2_inited(context)) return KRB5_KDB_DBNOTINITED; db_ctx = context->dal_handle->db_context; if ((retval = krb5_db2_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) return retval; db = db_ctx->db; if ((retval = krb5_db2_start_update(context))) { (void) krb5_db2_unlock(context); return retval; } retval = krb5_encode_princ_entry(context, &contdata, entry); if (retval) goto cleanup; contents.data = contdata.data; contents.size = contdata.length; retval = krb5_encode_princ_dbkey(context, &keydata, entry->princ); if (retval) { krb5_free_data_contents(context, &contdata); goto cleanup; } key.data = keydata.data; key.size = keydata.length; dbret = (*db->put)(db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &keydata); krb5_free_data_contents(context, &contdata); cleanup: (void) krb5_db2_end_update(context); (void) krb5_db2_unlock(context); /* unlock database */ return (retval); }
krb5_error_code krb5_db2_get_principal(krb5_context context, krb5_const_principal searchfor, unsigned int flags, krb5_db_entry **entry) { krb5_db2_context *dbc; krb5_error_code retval; DB *db; DBT key, contents; krb5_data keydata, contdata; int dbret; *entry = NULL; if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; retval = ctx_lock(context, dbc, KRB5_LOCKMODE_SHARED); if (retval) return retval; /* XXX deal with wildcard lookups */ retval = krb5_encode_princ_dbkey(context, &keydata, searchfor); if (retval) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = dbc->db; dbret = (*db->get)(db, &key, &contents, 0); retval = errno; krb5_free_data_contents(context, &keydata); switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleanup; case 0: contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, entry); break; } cleanup: (void) krb5_db2_unlock(context); /* unlock read lock */ return retval; }
krb5_error_code krb5_db2_delete_principal(krb5_context context, krb5_const_principal searchfor) { krb5_error_code retval; krb5_db_entry *entry; krb5_db2_context *db_ctx; DB *db; DBT key, contents; krb5_data keydata, contdata; int i, dbret; if (!k5db2_inited(context)) return KRB5_KDB_DBNOTINITED; db_ctx = context->dal_handle->db_context; if ((retval = krb5_db2_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) return (retval); if ((retval = krb5_db2_start_update(context))) { (void) krb5_db2_unlock(context); /* unlock write lock */ return (retval); } if ((retval = krb5_encode_princ_dbkey(context, &keydata, searchfor))) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = db_ctx->db; dbret = (*db->get) (db, &key, &contents, 0); retval = errno; switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleankey; case 0: ; } contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, &entry); if (retval) goto cleankey; /* Clear encrypted key contents */ for (i = 0; i < entry->n_key_data; i++) { if (entry->key_data[i].key_data_length[0]) { memset(entry->key_data[i].key_data_contents[0], 0, (unsigned) entry->key_data[i].key_data_length[0]); } } retval = krb5_encode_princ_entry(context, &contdata, entry); krb5_dbe_free(context, entry); if (retval) goto cleankey; contents.data = contdata.data; contents.size = contdata.length; dbret = (*db->put) (db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &contdata); if (retval) goto cleankey; dbret = (*db->del) (db, &key, 0); retval = dbret ? errno : 0; cleankey: krb5_free_data_contents(context, &keydata); cleanup: (void) krb5_db2_end_update(context); (void) krb5_db2_unlock(context); /* unlock write lock */ return retval; }