/* key.c: basic authentication token and access key management
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
key->serial = 2;
key_serial_next = key->serial + 1;
- if (!parent->rb_parent)
+ if (!rb_parent(parent))
p = &key_serial_tree.rb_node;
- else if (parent->rb_parent->rb_left == parent)
- p = &parent->rb_parent->rb_left;
+ else if (rb_parent(parent)->rb_left == parent)
+ p = &(rb_parent(parent)->rb_left);
else
- p = &parent->rb_parent->rb_right;
+ p = &(rb_parent(parent)->rb_right);
parent = rb_next(parent);
if (!parent)
* instantiate the key or discard it before returning
*/
struct key *key_alloc(struct key_type *type, const char *desc,
- uid_t uid, gid_t gid, key_perm_t perm,
- int not_in_quota)
+ uid_t uid, gid_t gid, struct task_struct *ctx,
+ key_perm_t perm, int not_in_quota)
{
struct key_user *user = NULL;
struct key *key;
* its description */
if (!not_in_quota) {
spin_lock(&user->lock);
- if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS &&
+ if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
)
goto no_quota;
#endif
/* let the security module know about the key */
- ret = security_key_alloc(key);
+ ret = security_key_alloc(key, ctx);
if (ret < 0)
goto security_error;
key_check(keyring);
+ key_ref = ERR_PTR(-ENOTDIR);
+ if (keyring->type != &key_type_keyring)
+ goto error_2;
+
down_write(&keyring->sem);
/* if we're going to allocate a new key, we're going to have
goto error_3;
}
- /* search for an existing key of the same type and description in the
- * destination keyring
+ /* if it's possible to update this type of key, search for an existing
+ * key of the same type and description in the destination keyring and
+ * update that instead if possible
*/
- key_ref = __keyring_search_one(keyring_ref, ktype, description, 0);
- if (!IS_ERR(key_ref))
- goto found_matching_key;
+ if (ktype->update) {
+ key_ref = __keyring_search_one(keyring_ref, ktype, description,
+ 0);
+ if (!IS_ERR(key_ref))
+ goto found_matching_key;
+ }
/* decide on the permissions we want */
perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
/* allocate a new key */
key = key_alloc(ktype, description, current->fsuid, current->fsgid,
- perm, not_in_quota);
+ current, perm, not_in_quota);
if (IS_ERR(key)) {
key_ref = ERR_PTR(PTR_ERR(key));
goto error_3;