cerr << " --auth_uid=<auid> librados uid\n";
cerr << " --secret=<key> S3 key\n";
cerr << " --os-secret=<key> OpenStack key\n";
+ cerr << " --access=<access> Set access permissions for sub-user, should be one\n";
+ cerr << " of read, write, readwrite, full\n";
cerr << " --display-name=<name>\n";
cerr << " --bucket=<bucket>\n";
cerr << " --object=<object>\n";
OPT_LOG_SHOW,
};
+static uint32_t str_to_perm(const char *str)
+{
+ if (strcasecmp(str, "read") == 0)
+ return RGW_PERM_READ;
+ else if (strcasecmp(str, "write") == 0)
+ return RGW_PERM_WRITE;
+ else if (strcasecmp(str, "readwrite") == 0)
+ return RGW_PERM_READ | RGW_PERM_WRITE;
+ else if (strcasecmp(str, "full") == 0)
+ return RGW_PERM_FULL_CONTROL;
+
+ usage();
+ return 0; // unreachable
+}
+
+struct rgw_flags_desc {
+ int mask;
+ const char *str;
+};
+
+static struct rgw_flags_desc rgw_perms[] = {
+ { RGW_PERM_FULL_CONTROL, "full-control" },
+ { RGW_PERM_READ | RGW_PERM_WRITE, "read-write" },
+ { RGW_PERM_READ, "read" },
+ { RGW_PERM_WRITE, "write" },
+ { RGW_PERM_READ_ACP, "read-acp" },
+ { RGW_PERM_WRITE_ACP, "read-acp" },
+ { 0, NULL }
+};
+
+static void perm_to_str(uint32_t mask, char *buf, int len)
+{
+ const char *sep = "";
+ int pos = 0;
+ while (mask) {
+ int orig_mask = mask;
+ for (int i = 0; rgw_perms[i].mask; i++) {
+ struct rgw_flags_desc *desc = &rgw_perms[i];
+ if ((mask & desc->mask) == desc->mask) {
+ pos += snprintf(buf + pos, len - pos, "%s%s", sep, desc->str);
+ if (pos == len)
+ return;
+ sep = ", ";
+ mask &= ~desc->mask;
+ if (!mask)
+ return;
+ }
+ }
+ if (mask == orig_mask) // no change
+ break;
+ }
+}
+
static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
{
*need_more = false;
const char *openstack_key = 0;
const char *date = 0;
char *subuser = 0;
+ const char *access = 0;
+ uint32_t perm_mask = 0;
uint64_t auid = 0;
RGWUserInfo info;
RGWAccess *store;
CEPH_ARGPARSE_SET_ARG_VAL(&openstack_key, OPT_STR);
} else if (CEPH_ARGPARSE_EQ("date", '\0')) {
CEPH_ARGPARSE_SET_ARG_VAL(&date, OPT_STR);
+ } else if (CEPH_ARGPARSE_EQ("access", '\0')) {
+ CEPH_ARGPARSE_SET_ARG_VAL(&access, OPT_STR);
+ perm_mask = str_to_perm(access);
} else {
if (!opt_cmd) {
opt_cmd = get_cmd(CEPH_ARGPARSE_VAL, prev_cmd, &need_more);
if (subuser) {
RGWSubUser u;
u.name = subuser;
+ u.perm_mask = perm_mask;
info.subusers[subuser] = u;
}
for (uiter = info.subusers.begin(); uiter != info.subusers.end(); ++uiter) {
RGWSubUser& u = uiter->second;
cout << " Name: " << info.user_id << ":" << u.name << std::endl;
+ char buf[256];
+ perm_to_str(u.perm_mask, buf, sizeof(buf));
+ cout << " Permissions: " << buf << std::endl;
}
cout << "Display Name: " << info.display_name << std::endl;
cout << "Email: " << info.user_email << std::endl;
return get(s);
}
-bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm)
+bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int user_perm_mask, int perm)
{
if (!policy)
return false;
- int acl_perm = policy->get_perm(uid, perm);
+ int acl_perm = policy->get_perm(uid, perm) & user_perm_mask;
return (perm == acl_perm);
}
bool verify_permission(struct req_state *s, int perm)
{
- return verify_permission(s->acl, s->user.user_id, perm);
+ return verify_permission(s->acl, s->user.user_id, s->perm_mask, perm);
}
static char hex_to_num(char c)
struct RGWSubUser {
string name;
- uint32_t flags;
+ uint32_t perm_mask;
- RGWSubUser() {}
+ RGWSubUser() : perm_mask(0) {}
void encode(bufferlist& bl) const {
__u32 ver = 1;
::encode(ver, bl);
::encode(name, bl);
- ::encode(flags, bl);
+ ::encode(perm_mask, bl);
}
void decode(bufferlist::iterator& bl) {
__u32 ver;
::decode(ver, bl);
::decode(name, bl);
- ::decode(flags, bl);
+ ::decode(perm_mask, bl);
}
};
WRITE_CLASS_ENCODER(RGWSubUser);
uint64_t bytes_received; // data received
uint64_t obj_size;
bool should_log;
+ uint32_t perm_mask;
XMLArgs args;
/** */
extern int parse_time(const char *time_str, time_t *time);
/** Check if a user has a permission on that ACL */
-extern bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int perm);
+extern bool verify_permission(RGWAccessControlPolicy *policy, string& uid, int user_perm_mask, int perm);
/** Check if the req_state's user has the necessary permissions
* to do the requested action */
extern bool verify_permission(struct req_state *s, int perm);
#include "rgw_rest.h"
#include "rgw_rest_s3.h"
+#include "rgw_acl.h"
#include "common/armor.h"
const char *key = k.key.c_str();
int key_len = k.key.size();
+ if (!k.subuser.empty()) {
+ map<string, RGWSubUser>::iterator uiter = s->user.subusers.find(k.subuser);
+ if (uiter == s->user.subusers.end()) {
+ RGW_LOG(0) << "ERROR: could not find subuser: " << k.subuser << dendl;
+ return false;
+ }
+ RGWSubUser& subuser = uiter->second;
+ s->perm_mask = subuser.perm_mask;
+ } else
+ s->perm_mask = RGW_PERM_FULL_CONTROL;
+
char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);