Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
53321c3c
Commit
53321c3c
authored
Jan 21, 2019
by
antirez
Browse files
ACL: subcommand matching.
parent
4078755d
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/acl.c
View file @
53321c3c
...
@@ -164,6 +164,15 @@ struct redisCommand *ACLLookupCommand(const char *name) {
...
@@ -164,6 +164,15 @@ struct redisCommand *ACLLookupCommand(const char *name) {
return
cmd
;
return
cmd
;
}
}
/* Flush the array of allowed subcommands for the specified user
* and command ID. */
void
ACLResetSubcommandsForCommand
(
user
*
u
,
unsigned
long
id
)
{
if
(
u
->
allowed_subcommands
&&
u
->
allowed_subcommands
[
id
])
{
zfree
(
u
->
allowed_subcommands
[
id
]);
u
->
allowed_subcommands
[
id
]
=
NULL
;
}
}
/* Set user properties according to the string "op". The following
/* Set user properties according to the string "op". The following
* is a description of what different strings will do:
* is a description of what different strings will do:
*
*
...
@@ -265,12 +274,62 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
...
@@ -265,12 +274,62 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
if
(
ln
==
NULL
)
listAddNodeTail
(
u
->
patterns
,
newpat
);
if
(
ln
==
NULL
)
listAddNodeTail
(
u
->
patterns
,
newpat
);
u
->
flags
&=
~
USER_FLAG_ALLKEYS
;
u
->
flags
&=
~
USER_FLAG_ALLKEYS
;
}
else
if
(
op
[
0
]
==
'+'
&&
op
[
1
]
!=
'@'
)
{
}
else
if
(
op
[
0
]
==
'+'
&&
op
[
1
]
!=
'@'
)
{
if
(
ACLLookupCommand
(
op
+
1
)
==
NULL
)
{
if
(
strchr
(
op
,
'|'
)
==
NULL
)
{
errno
=
ENOENT
;
if
(
ACLLookupCommand
(
op
+
1
)
==
NULL
)
{
return
C_ERR
;
errno
=
ENOENT
;
return
C_ERR
;
}
unsigned
long
id
=
ACLGetCommandID
(
op
+
1
);
ACLSetUserCommandBit
(
u
,
id
,
1
);
ACLResetSubcommandsForCommand
(
u
,
id
);
}
else
{
/* Split the command and subcommand parts. */
char
*
copy
=
zstrdup
(
op
+
1
);
char
*
sub
=
strchr
(
copy
,
'|'
);
sub
[
0
]
=
'\0'
;
sub
++
;
/* Check if the command exists. We can't check the
* subcommand to see if it is valid. */
if
(
ACLLookupCommand
(
copy
)
==
NULL
)
{
errno
=
ENOENT
;
return
C_ERR
;
}
unsigned
long
id
=
ACLGetCommandID
(
copy
);
/* The subcommand cannot be empty, so things like DEBUG|
* are syntax errors of course. */
if
(
strlen
(
sub
)
==
0
)
{
zfree
(
copy
);
errno
=
EINVAL
;
return
C_ERR
;
}
/* If this is the first subcommand to be configured for
* this user, we have to allocate the subcommands array. */
if
(
u
->
allowed_subcommands
==
NULL
)
{
u
->
allowed_subcommands
=
zcalloc
(
USER_MAX_COMMAND_BIT
*
sizeof
(
sds
*
));
}
/* We also need to enlarge the allocation pointing to the
* null terminated SDS array, to make space for this one. */
long
items
=
0
;
if
(
u
->
allowed_subcommands
[
id
])
{
while
(
u
->
allowed_subcommands
[
items
])
items
++
;
}
items
+=
2
;
/* Make space for the new item and the null term. */
u
->
allowed_subcommands
[
id
]
=
zrealloc
(
u
->
allowed_subcommands
[
id
],
sizeof
(
sds
)
*
items
);
u
->
allowed_subcommands
[
id
][
items
-
2
]
=
sdsnew
(
sub
);
u
->
allowed_subcommands
[
id
][
items
-
1
]
=
NULL
;
/* We have to clear the command bit so that we force the
* subcommand check. */
ACLSetUserCommandBit
(
u
,
id
,
0
);
zfree
(
copy
);
}
}
unsigned
long
id
=
ACLGetCommandID
(
op
+
1
);
ACLSetUserCommandBit
(
u
,
id
,
1
);
}
else
if
(
op
[
0
]
==
'-'
&&
op
[
1
]
!=
'@'
)
{
}
else
if
(
op
[
0
]
==
'-'
&&
op
[
1
]
!=
'@'
)
{
if
(
ACLLookupCommand
(
op
+
1
)
==
NULL
)
{
if
(
ACLLookupCommand
(
op
+
1
)
==
NULL
)
{
errno
=
ENOENT
;
errno
=
ENOENT
;
...
@@ -279,6 +338,7 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
...
@@ -279,6 +338,7 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) {
unsigned
long
id
=
ACLGetCommandID
(
op
+
1
);
unsigned
long
id
=
ACLGetCommandID
(
op
+
1
);
ACLSetUserCommandBit
(
u
,
id
,
0
);
ACLSetUserCommandBit
(
u
,
id
,
0
);
u
->
flags
&=
~
USER_FLAG_ALLCOMMANDS
;
u
->
flags
&=
~
USER_FLAG_ALLCOMMANDS
;
ACLResetSubcommandsForCommand
(
u
,
id
);
}
else
{
}
else
{
errno
=
EINVAL
;
errno
=
EINVAL
;
return
C_ERR
;
return
C_ERR
;
...
@@ -504,7 +564,7 @@ void aclCommand(client *c) {
...
@@ -504,7 +564,7 @@ void aclCommand(client *c) {
numflags
++
;
numflags
++
;
}
}
if
(
u
->
flags
&
USER_FLAG_ALLCOMMANDS
)
{
if
(
u
->
flags
&
USER_FLAG_ALLCOMMANDS
)
{
addReplyBulkCString
(
c
,
"allcomm
n
ads"
);
addReplyBulkCString
(
c
,
"allcomma
n
ds"
);
numflags
++
;
numflags
++
;
}
}
if
(
u
->
flags
&
USER_FLAG_NOPASS
)
{
if
(
u
->
flags
&
USER_FLAG_NOPASS
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment