diff options
author | Madelyn Olson <matolson@amazon.com> | 2019-02-23 23:15:48 +0000 |
---|---|---|
committer | Madelyn Olson <matolson@amazon.com> | 2019-02-26 02:04:29 +0000 |
commit | 075a3b889355c38cc831aac002cf6eb61cc5f36e (patch) | |
tree | 7cd7b5ee84e5ee6a2a3569bf88c4d11096737d6c /src/acl.c | |
parent | 07473feaebd9af228baddd6c28ded0da42dab255 (diff) | |
download | redis-075a3b889355c38cc831aac002cf6eb61cc5f36e.tar.gz |
Updated acl setuser to be all or nothing
Diffstat (limited to 'src/acl.c')
-rw-r--r-- | src/acl.c | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -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; |