-/*****************************************************************************/
-/*
- * duplicate a key, potentially with a revised description
- * - must be supported by the keytype (keyrings for instance can be duplicated)
- */
-struct key *key_duplicate(struct key *source, const char *desc)
-{
- struct key *key;
- int ret;
-
- key_check(source);
-
- if (!desc)
- desc = source->description;
-
- down_read(&key_types_sem);
-
- ret = -EINVAL;
- if (!source->type->duplicate)
- goto error;
-
- /* allocate and instantiate a key */
- key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
- source->perm, 0);
- if (IS_ERR(key))
- goto error_k;
-
- down_read(&source->sem);
- ret = key->type->duplicate(key, source);
- up_read(&source->sem);
- if (ret < 0)
- goto error2;
-
- atomic_inc(&key->user->nikeys);
-
- write_lock(&key->lock);
- key->flags |= KEY_FLAG_INSTANTIATED;
- write_unlock(&key->lock);
-
- error_k:
- up_read(&key_types_sem);
- out:
- return key;
-
- error2:
- key_put(key);
- error:
- up_read(&key_types_sem);
- key = ERR_PTR(ret);
- goto out;
-
-} /* end key_duplicate() */
-