/* * commence key construction */ static struct key *construct_key_and_link(struct key_type *type, const char *description, const char *callout_info, void *aux, struct key *dest_keyring, unsigned long flags) { struct key_user *user; struct key *key; int ret; user = key_user_lookup(current->fsuid); if (!user) return ERR_PTR(-ENOMEM); ret = construct_alloc_key(type, description, dest_keyring, flags, user, &key); key_user_put(user); if (ret == 0) { ret = construct_key(key, callout_info, aux); if (ret < 0) goto construction_failed; } return key; construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); return ERR_PTR(ret); }
/** * complete_request_key - Complete the construction of a key. * @cons: The key construction record. * @error: The success or failute of the construction. * * Complete the attempt to construct a key. The key will be negated * if an error is indicated. The authorisation key will be revoked * unconditionally. */ void complete_request_key(struct key_construction *cons, int error) { kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error); if (error < 0) key_negate_and_link(cons->key, key_negative_timeout, NULL, cons->authkey); else key_revoke(cons->authkey); key_put(cons->key); key_put(cons->authkey); kfree(cons); }
/* * Commence key construction. */ static struct key *construct_key_and_link(struct keyring_search_context *ctx, const char *callout_info, size_t callout_len, void *aux, struct key *dest_keyring, unsigned long flags) { struct key_user *user; struct key *key; int ret; kenter(""); if (ctx->index_key.type == &key_type_keyring) return ERR_PTR(-EPERM); user = key_user_lookup(current_fsuid()); if (!user) return ERR_PTR(-ENOMEM); construct_get_dest_keyring(&dest_keyring); ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key); key_user_put(user); if (ret == 0) { ret = construct_key(key, callout_info, callout_len, aux, dest_keyring); if (ret < 0) { kdebug("cons failed"); goto construction_failed; } } else if (ret == -EINPROGRESS) { ret = 0; } else { goto couldnt_alloc_key; } key_put(dest_keyring); kleave(" = key %d", key_serial(key)); return key; construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); couldnt_alloc_key: key_put(dest_keyring); kleave(" = %d", ret); return ERR_PTR(ret); }
/* * commence key construction */ static struct key *construct_key_and_link(struct key_type *type, const char *description, const char *callout_info, size_t callout_len, void *aux, struct key *dest_keyring, unsigned long flags) { struct key_user *user; struct key *key; int ret; kenter(""); user = key_user_lookup(current_fsuid(), current_user_ns()); if (!user) return ERR_PTR(-ENOMEM); construct_get_dest_keyring(&dest_keyring); ret = construct_alloc_key(type, description, dest_keyring, flags, user, &key); key_user_put(user); if (ret == 0) { ret = construct_key(key, callout_info, callout_len, aux, dest_keyring); if (ret < 0) { kdebug("cons failed"); goto construction_failed; } } key_put(dest_keyring); kleave(" = key %d", key_serial(key)); return key; construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); key_put(dest_keyring); kleave(" = %d", ret); return ERR_PTR(ret); }
/* * negatively instantiate the key with the given timeout (in seconds), and, if * one is given, link the key into the keyring */ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) { struct request_key_auth *rka; struct key *instkey; key_ref_t keyring_ref; long ret; /* find the instantiation authorisation key */ instkey = key_get_instantiation_authkey(id); if (IS_ERR(instkey)) { ret = PTR_ERR(instkey); goto error; } rka = instkey->payload.data; /* find the destination keyring if present (which must also be * writable) */ keyring_ref = NULL; if (ringid) { keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error2; } } /* instantiate the key and link it into a keyring */ ret = key_negate_and_link(rka->target_key, timeout, key_ref_to_ptr(keyring_ref), instkey); key_ref_put(keyring_ref); error2: key_put(instkey); error: return ret; } /* end keyctl_negate_key() */