From: Steve Dickson <SteveD@redhat.com>
To: Benjamin Coddington <bcodding@uvm.edu>, linux-nfs@vger.kernel.org
Subject: Re: [PATCH] nfsidmap: use multiple child keyrings
Date: Mon, 24 Mar 2014 13:00:17 -0400 [thread overview]
Message-ID: <533064A1.2080502@RedHat.com> (raw)
In-Reply-To: <201403241150.s2OBonLC010685@hobo-dev.uvm.edu>
On 03/21/2014 05:08 PM, Benjamin Coddington wrote:
> The kernel keyring has a max of ~508 entries on 64-bit systems.
> For installations with more distict users than this limit, create
> a specified number of child keyrings and fill them evenly.
A couple things...
1) no Signed-off-by: line
2) Its seems you can create key rings but can't delete them.
Here is what I'm doing:
in /etc/request-key.d/id_resolver.conf I have
create id_resolver * * /usr/sbin/nfsidmap -n 10 %k %d
but when I tried to delete the keys
# nfsidmap -vc
nfsidmap: clearing '08aa156c I--Q--- 1 perm 3f010000 0 0 keyring .id_resolver_child_10: empty'
nfsidmap: keyctl_clear(0x8aa156c) failed: Permission denied
> ---
> utils/nfsidmap/nfsidmap.c | 76 +++++++++++++++++++++++++++++++++---------
> utils/nfsidmap/nfsidmap.man | 5 ++-
> 2 files changed, 63 insertions(+), 18 deletions(-)
>
> diff --git a/utils/nfsidmap/nfsidmap.c b/utils/nfsidmap/nfsidmap.c
> index 2518ed6..41abede 100644
> --- a/utils/nfsidmap/nfsidmap.c
> +++ b/utils/nfsidmap/nfsidmap.c
> @@ -15,7 +15,7 @@
> #include "conffile.h"
>
> int verbose = 0;
> -char *usage="Usage: %s [-v] [-c || [-u|-g|-r key] || [-t timeout] key desc]";
> +char *usage="Usage: %s [-v] [-c || [-u|-g|-r key] || [-t timeout] [-n count] key desc]";
>
> #define MAX_ID_LEN 11
> #define IDMAP_NAMESZ 128
> @@ -24,7 +24,7 @@ char *usage="Usage: %s [-v] [-c || [-u|-g|-r key] || [-t timeout] key desc]";
>
> #define PROCKEYS "/proc/keys"
> #ifndef DEFAULT_KEYRING
> -#define DEFAULT_KEYRING "id_resolver"
> +#define DEFAULT_KEYRING ".id_resolver"
3) Why is changing the default needed?
Finally, what -n value do plan on using? Maybe a blurb in the man page
on what a good number is and why....
steved.
> #endif
>
> #ifndef PATH_IDMAPDCONF
> @@ -39,7 +39,7 @@ static int keyring_clear(char *keyring);
> /*
> * Find either a user or group id based on the name@domain string
> */
> -int id_lookup(char *name_at_domain, key_serial_t key, int type)
> +int id_lookup(char *name_at_domain, key_serial_t key, int type, key_serial_t dest_keyring)
> {
> char id[MAX_ID_LEN];
> uid_t uid = 0;
> @@ -58,7 +58,7 @@ int id_lookup(char *name_at_domain, key_serial_t key, int type)
> (type == USER ? "nfs4_owner_to_uid" : "nfs4_group_owner_to_gid"));
>
> if (rc == 0) {
> - rc = keyctl_instantiate(key, id, strlen(id) + 1, 0);
> + rc = keyctl_instantiate(key, id, strlen(id) + 1, dest_keyring);
> if (rc < 0) {
> switch(rc) {
> case -EDQUOT:
> @@ -67,9 +67,9 @@ int id_lookup(char *name_at_domain, key_serial_t key, int type)
> /*
> * The keyring is full. Clear the keyring and try again
> */
> - rc = keyring_clear(DEFAULT_KEYRING);
> + rc = keyctl_clear(dest_keyring);
> if (rc == 0)
> - rc = keyctl_instantiate(key, id, strlen(id) + 1, 0);
> + rc = keyctl_instantiate(key, id, strlen(id) + 1, dest_keyring);
> break;
> default:
> break;
> @@ -85,7 +85,7 @@ int id_lookup(char *name_at_domain, key_serial_t key, int type)
> /*
> * Find the name@domain string from either a user or group id
> */
> -int name_lookup(char *id, key_serial_t key, int type)
> +int name_lookup(char *id, key_serial_t key, int type, key_serial_t dest_keyring)
> {
> char name[IDMAP_NAMESZ];
> char domain[NFS4_MAX_DOMAIN_LEN];
> @@ -113,7 +113,7 @@ int name_lookup(char *id, key_serial_t key, int type)
> (type == USER ? "nfs4_uid_to_name" : "nfs4_gid_to_name"));
>
> if (rc == 0) {
> - rc = keyctl_instantiate(key, &name, strlen(name), 0);
> + rc = keyctl_instantiate(key, &name, strlen(name), dest_keyring);
> if (rc < 0)
> xlog_err("name_lookup: keyctl_instantiate failed: %m");
> }
> @@ -127,7 +127,7 @@ static int keyring_clear(char *keyring)
> {
> FILE *fp;
> char buf[BUFSIZ];
> - key_serial_t key;
> + key_serial_t key, child_key;
>
> if (keyring == NULL)
> keyring = DEFAULT_KEYRING;
> @@ -151,6 +151,7 @@ static int keyring_clear(char *keyring)
> */
> *(strchr(buf, ' ')) = '\0';
> sscanf(buf, "%x", &key);
> +
> if (keyctl_clear(key) < 0) {
> xlog_err("keyctl_clear(0x%x) failed: %m", key);
> fclose(fp);
> @@ -159,7 +160,8 @@ static int keyring_clear(char *keyring)
> fclose(fp);
> return 0;
> }
> - xlog_err("'%s' keyring was not found.", keyring);
> + if (strstr(keyring, DEFAULT_KEYRING":"))
> + xlog_err("'%s' keyring was not found.", keyring);
> fclose(fp);
> return 1;
> }
> @@ -232,8 +234,10 @@ int main(int argc, char **argv)
> char *type;
> int rc = 1, opt;
> int timeout = 600;
> - key_serial_t key;
> + int childrings = 0;
> + key_serial_t key, parent_keyring, dest_keyring;
> char *progname, *keystr = NULL;
> + char child_name[BUFSIZ];
> int clearing = 0, keymask = 0;
>
> /* Set the basename */
> @@ -244,7 +248,7 @@ int main(int argc, char **argv)
>
> xlog_open(progname);
>
> - while ((opt = getopt(argc, argv, "u:g:r:ct:v")) != -1) {
> + while ((opt = getopt(argc, argv, "u:g:r:ct:vn:d:")) != -1) {
> switch (opt) {
> case 'u':
> keymask = UIDKEYS;
> @@ -267,6 +271,9 @@ int main(int argc, char **argv)
> case 't':
> timeout = atoi(optarg);
> break;
> + case 'n':
> + childrings = atoi(optarg);
> + break;
> default:
> xlog_warn(usage, progname);
> break;
> @@ -284,9 +291,16 @@ int main(int argc, char **argv)
> rc = key_revoke(keystr, keymask);
> return rc;
> }
> +
> if (clearing) {
> xlog_syslog(0);
> - rc = keyring_clear(DEFAULT_KEYRING);
> + int i = 1;
> + for(rc = 0; rc == 0; i++) {
> + snprintf(child_name, sizeof(child_name), DEFAULT_KEYRING "_child_%d", i);
> + rc = keyring_clear(child_name);
> + }
> +
> + rc = keyring_clear(DEFAULT_KEYRING ":");
> return rc;
> }
>
> @@ -315,14 +329,42 @@ int main(int argc, char **argv)
> key, type, value, timeout);
> }
>
> + if (childrings) {
> + int i;
> + long child_size, smallest_size = 2032;
> + parent_keyring = request_key("keyring", DEFAULT_KEYRING, NULL, KEY_SPEC_THREAD_KEYRING);
> +
> + for (i = 1; i <= childrings; i++) {
> + key_serial_t child_keyring;
> +
> + snprintf(child_name, sizeof(child_name), DEFAULT_KEYRING "_child_%d", i);
> +
> + child_keyring = keyctl_search(parent_keyring, "keyring", child_name, 0);
> + if (child_keyring < 0) {
> + child_keyring = add_key("keyring", child_name, NULL, 0, parent_keyring);
> + xlog_warn("added new child %s: %m", child_name);
> + }
> +
> + child_size = keyctl_read(child_keyring, NULL, 0);
> + if (child_size < smallest_size) {
> + dest_keyring = child_keyring;
> + smallest_size = child_size;
> + }
> + }
> + }
> +
> if (strcmp(type, "uid") == 0)
> - rc = id_lookup(value, key, USER);
> + rc = id_lookup(value, key, USER, dest_keyring);
> else if (strcmp(type, "gid") == 0)
> - rc = id_lookup(value, key, GROUP);
> + rc = id_lookup(value, key, GROUP, dest_keyring);
> else if (strcmp(type, "user") == 0)
> - rc = name_lookup(value, key, USER);
> + rc = name_lookup(value, key, USER, dest_keyring);
> else if (strcmp(type, "group") == 0)
> - rc = name_lookup(value, key, GROUP);
> + rc = name_lookup(value, key, GROUP, dest_keyring);
> +
> + /* if we hung this off a child, unlink from the parent */
> + if (dest_keyring)
> + keyctl_unlink(key, parent_keyring);
>
> /* Set timeout to 10 (600 seconds) minutes */
> if (rc == 0)
> diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man
> index 3a3a523..04f0014 100644
> --- a/utils/nfsidmap/nfsidmap.man
> +++ b/utils/nfsidmap/nfsidmap.man
> @@ -6,7 +6,7 @@
> .SH NAME
> nfsidmap \- The NFS idmapper upcall program
> .SH SYNOPSIS
> -.B "nfsidmap [-v] [-t timeout] key desc"
> +.B "nfsidmap [-v] [-t timeout] [-n count] key desc"
> .br
> .B "nfsidmap [-v] [-c]"
> .br
> @@ -42,6 +42,9 @@ Revoke both the uid and gid key of the given user.
> Set the expiration timer, in seconds, on the key.
> The default is 600 seconds (10 mins).
> .TP
> +.B -n count
> +Set the the number of child keyrings to create.
> +.TP
> .B -u user
> Revoke the uid key of the given user.
> .TP
>
next prev parent reply other threads:[~2014-03-24 17:04 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-21 21:08 [PATCH] nfsidmap: use multiple child keyrings Benjamin Coddington
2014-03-24 17:00 ` Steve Dickson [this message]
2014-03-24 18:00 ` Benjamin Coddington
2014-03-24 19:51 ` Steve Dickson
2014-03-24 21:03 ` Benjamin Coddington
2014-03-24 21:22 ` Steve Dickson
2014-03-24 22:10 ` Anna Schumaker
2014-03-24 23:57 ` Steve Dickson
2014-03-25 0:15 ` Benjamin Coddington
2014-03-25 9:35 ` David Howells
2014-03-25 12:49 ` Benjamin Coddington
2014-03-25 9:29 ` David Howells
2014-03-25 10:41 ` Steve Dickson
2014-03-25 9:34 ` David Howells
2014-03-25 12:56 ` Benjamin Coddington
2014-03-25 13:30 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=533064A1.2080502@RedHat.com \
--to=steved@redhat.com \
--cc=bcodding@uvm.edu \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).