rbd, mount.ceph: use pre-stored secret if available

If a secret is specified, store and use it, but otherwise
check for a pre-existing secret to use.

Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
This commit is contained in:
Josh Durgin 2011-11-28 17:02:15 -08:00
parent 0ad0fbfe3a
commit 274f4890dc
4 changed files with 53 additions and 33 deletions

View File

@ -49,7 +49,7 @@ int read_secret_from_file(const char *filename, char *secret, size_t max_len)
return 0;
}
static int add_secret_to_kernel(const char *secret, const char *key_name)
static int set_kernel_secret(const char *secret, const char *key_name)
{
/* try to submit key to kernel via the keys api */
key_serial_t serial;
@ -80,27 +80,41 @@ int is_kernel_secret(const char *key_name)
return serial != -1;
}
int get_secret_option(const char *secret, const char *key_name, char *secret_option, size_t max_len)
int get_secret_option(const char *secret, const char *key_name,
char *secret_option, size_t max_len)
{
int ret;
int olen = strlen(secret) + strlen(key_name) + 7;
int ret = 0;
int olen = strlen(key_name) + 7;
if (secret) {
olen += strlen(secret);
}
char option[olen+1];
char error_buf[80];
int use_key = 1;
option[olen] = '\0';
ret = add_secret_to_kernel(secret, key_name);
if (ret < 0) {
if (ret == -ENODEV || ret == -ENOSYS) {
/* running against older kernel; fall back to secret= in options */
snprintf(option, olen, "secret=%s", secret);
ret = 0;
} else {
fprintf(stderr, "adding ceph secret key to kernel failed: %s.\n",
strerror_r(-ret, error_buf, sizeof(error_buf)));
return ret;
if (!key_name) {
return -EINVAL;
}
if (secret) {
ret = set_kernel_secret(secret, key_name);
if (ret < 0) {
if (ret == -ENODEV || ret == -ENOSYS) {
/* running against older kernel; fall back to secret= in options */
snprintf(option, olen, "secret=%s", secret);
ret = 0;
use_key = 0;
} else {
fprintf(stderr, "adding ceph secret key to kernel failed: %s.\n",
strerror_r(-ret, error_buf, sizeof(error_buf)));
return ret;
}
}
} else {
}
if (use_key) {
/* add key= option to identify key to use */
snprintf(option, olen, "key=%s", key_name);
}

View File

@ -11,7 +11,8 @@ int read_secret_from_file(const char *filename, char *secret, size_t max_len);
* Attempts to add the secret to the kernel, but falls back to
* the old secret= option if the kernel is too old.
*/
int get_secret_option(const char *secret, const char *key_name, char *secret_option, size_t secret_option_len);
int get_secret_option(const char *secret, const char *key_name,
char *secret_option, size_t secret_option_len);
int is_kernel_secret(const char *key_name);

View File

@ -86,6 +86,9 @@ static char *parse_options(const char *data, int *filesys_flags)
int word_len;
int skip;
int pos = 0;
char *name = NULL;
int name_len = 0;
int name_pos = 0;
char secret[MAX_SECRET_LEN];
char *saw_name = NULL;
char *saw_secret = NULL;
@ -219,24 +222,22 @@ static char *parse_options(const char *data, int *filesys_flags)
data = next_keyword;
} while (data);
if (saw_secret) {
name_pos = safe_cat(&name, &name_len, name_pos, "client.");
if (!saw_name) {
name_pos = safe_cat(&name, &name_len, name_pos, CEPH_AUTH_NAME_DEFAULT);
} else {
name_pos = safe_cat(&name, &name_len, name_pos, saw_name);
}
if (saw_secret || is_kernel_secret(name)) {
int ret;
char secret_option[MAX_SECRET_OPTION_LEN];
char *name = NULL;
int name_len = 0;
int name_pos = 0;
name_pos = safe_cat(&name, &name_len, name_pos, "client.");
if (!saw_name) {
name_pos = safe_cat(&name, &name_len, name_pos, CEPH_AUTH_NAME_DEFAULT);
} else {
name_pos = safe_cat(&name, &name_len, name_pos, saw_name);
}
ret = get_secret_option(saw_secret, name, secret_option, sizeof(secret_option));
if (ret < 0) {
return NULL;
} else {
if (pos)
if (pos) {
pos = safe_cat(&out, &out_len, pos, ",");
}
pos = safe_cat(&out, &out_len, pos, secret_option);
}
}

View File

@ -586,19 +586,23 @@ static int do_kernel_add(const char *poolname, const char *imgname,
oss << " name=" << user;
char key_name[strlen(user) + strlen("client.")];
snprintf(key_name, sizeof(key_name), "client.%s", user);
char secret_buf[MAX_SECRET_LEN];
char *secret = NULL;
if (secretfile) {
char secret[MAX_SECRET_LEN];
r = read_secret_from_file(secretfile, secret, sizeof(secret));
r = read_secret_from_file(secretfile, secret_buf, sizeof(secret_buf));
if (r < 0)
return r;
secret = secret_buf;
}
if (secret || is_kernel_secret(key_name)) {
char option[MAX_SECRET_LEN + 7];
char key_name[strlen(user) + strlen("client.")];
snprintf(key_name, sizeof(key_name), "client.%s", user);
r = get_secret_option(secret, key_name, option, sizeof(option));
if (r < 0)
if (r < 0) {
return r;
}
oss << "," << option;
}