+/*****************************************************************************/
+/*
+ * link a freshly minted key to an appropriate destination keyring
+ */
+static void request_key_link(struct key *key, struct key *dest_keyring)
+{
+ struct task_struct *tsk = current;
+ struct key *drop = NULL;
+
+ kenter("{%d},%p", key->serial, dest_keyring);
+
+ /* find the appropriate keyring */
+ if (!dest_keyring) {
+ switch (tsk->jit_keyring) {
+ case KEY_REQKEY_DEFL_DEFAULT:
+ case KEY_REQKEY_DEFL_THREAD_KEYRING:
+ dest_keyring = tsk->thread_keyring;
+ if (dest_keyring)
+ break;
+
+ case KEY_REQKEY_DEFL_PROCESS_KEYRING:
+ dest_keyring = tsk->signal->process_keyring;
+ if (dest_keyring)
+ break;
+
+ case KEY_REQKEY_DEFL_SESSION_KEYRING:
+ rcu_read_lock();
+ dest_keyring = key_get(
+ rcu_dereference(tsk->signal->session_keyring));
+ rcu_read_unlock();
+ drop = dest_keyring;
+
+ if (dest_keyring)
+ break;
+
+ case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
+ dest_keyring = current->user->session_keyring;
+ break;
+
+ case KEY_REQKEY_DEFL_USER_KEYRING:
+ dest_keyring = current->user->uid_keyring;
+ break;
+
+ case KEY_REQKEY_DEFL_GROUP_KEYRING:
+ default:
+ BUG();
+ }
+ }
+
+ /* and attach the key to it */
+ key_link(dest_keyring, key);
+
+ key_put(drop);
+
+ kleave("");
+
+} /* end request_key_link() */
+