summaryrefslogtreecommitdiff
path: root/src/acl.c
diff options
context:
space:
mode:
authorMadelyn Olson <matolson@amazon.com>2019-02-23 23:15:48 +0000
committerMadelyn Olson <matolson@amazon.com>2019-02-26 02:04:29 +0000
commit075a3b889355c38cc831aac002cf6eb61cc5f36e (patch)
tree7cd7b5ee84e5ee6a2a3569bf88c4d11096737d6c /src/acl.c
parent07473feaebd9af228baddd6c28ded0da42dab255 (diff)
downloadredis-075a3b889355c38cc831aac002cf6eb61cc5f36e.tar.gz
Updated acl setuser to be all or nothing
Diffstat (limited to 'src/acl.c')
-rw-r--r--src/acl.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/acl.c b/src/acl.c
index 43db19898..b352148dd 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1378,18 +1378,33 @@ void aclCommand(client *c) {
char *sub = c->argv[1]->ptr;
if (!strcasecmp(sub,"setuser") && c->argc >= 3) {
sds username = c->argv[2]->ptr;
+ /* Create a temporary user to validate and stage all changes against before
+ * applying to an existing user or creating a new user. If all arguments
+ * are valid the user parameters will all be applied together. If there are
+ * any errors then none of the changes will be applied. */
+ user *tempu = ACLCreateUnlinkedUser();
+
user *u = ACLGetUserByName(username,sdslen(username));
- if (!u) u = ACLCreateUser(username,sdslen(username));
- serverAssert(u != NULL);
+ if (u) ACLCopyUser(tempu, u);
+
for (int j = 3; j < c->argc; j++) {
- if (ACLSetUser(u,c->argv[j]->ptr,sdslen(c->argv[j]->ptr)) != C_OK) {
+ if (ACLSetUser(tempu,c->argv[j]->ptr,sdslen(c->argv[j]->ptr)) != C_OK) {
char *errmsg = ACLSetUserStringError();
addReplyErrorFormat(c,
"Error in ACL SETUSER modifier '%s': %s",
(char*)c->argv[j]->ptr, errmsg);
+
+ ACLFreeUser(tempu);
return;
}
}
+
+ if (!u) u = ACLCreateUser(username,sdslen(username));
+ serverAssert(u != NULL);
+
+ ACLCopyUser(u, tempu);
+ ACLFreeUser(tempu);
+
addReply(c,shared.ok);
} else if (!strcasecmp(sub,"deluser") && c->argc >= 3) {
int deleted = 0;