diff --git a/src/config.c b/src/config.c index bc92a423d..663ac404e 100644 --- a/src/config.c +++ b/src/config.c @@ -1917,6 +1917,38 @@ void rewriteConfigSaveOption(struct rewriteConfigState *state) { rewriteConfigMarkAsProcessed(state,"save"); } +/* Rewrite the user option. */ +void rewriteConfigUserOption(struct rewriteConfigState *state) { + /* If there is a user file defined we just mark this configuration + * directive as processed, so that all the lines containing users + * inside the config file gets discarded. */ + if (server.acl_filename[0] != '\0') { + rewriteConfigMarkAsProcessed(state,"user"); + return; + } + + /* Otherwise scan the list of users and rewrite every line. Note that + * in case the list here is empty, the effect will just be to comment + * all the users directive inside the config file. */ + raxIterator ri; + raxStart(&ri,Users); + raxSeek(&ri,"^",NULL,0); + while(raxNext(&ri)) { + user *u = ri.data; + sds line = sdsnew("user "); + line = sdscatsds(line,u->name); + line = sdscatlen(line," ",1); + sds descr = ACLDescribeUser(u); + line = sdscatsds(line,descr); + sdsfree(descr); + rewriteConfigRewriteLine(state,"user",line,1); + } + raxStop(&ri); + + /* Mark "user" as processed in case there are no defined users. */ + rewriteConfigMarkAsProcessed(state,"user"); +} + /* Rewrite the dir option, always using absolute paths.*/ void rewriteConfigDirOption(struct rewriteConfigState *state) { char cwd[1024]; @@ -2186,6 +2218,7 @@ int rewriteConfig(char *path) { rewriteConfigStringOption(state,"syslog-ident",server.syslog_ident,CONFIG_DEFAULT_SYSLOG_IDENT); rewriteConfigSyslogfacilityOption(state); rewriteConfigSaveOption(state); + rewriteConfigUserOption(state); rewriteConfigNumericalOption(state,"databases",server.dbnum,CONFIG_DEFAULT_DBNUM); rewriteConfigYesNoOption(state,"stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err,CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR); rewriteConfigYesNoOption(state,"rdbcompression",server.rdb_compression,CONFIG_DEFAULT_RDB_COMPRESSION); diff --git a/src/server.c b/src/server.c index 72daaedec..de84e430e 100644 --- a/src/server.c +++ b/src/server.c @@ -2267,6 +2267,7 @@ void initServerConfig(void) { server.pidfile = NULL; server.rdb_filename = zstrdup(CONFIG_DEFAULT_RDB_FILENAME); server.aof_filename = zstrdup(CONFIG_DEFAULT_AOF_FILENAME); + server.acl_filename = zstrdup(CONFIG_DEFAULT_ACL_FILENAME); server.rdb_compression = CONFIG_DEFAULT_RDB_COMPRESSION; server.rdb_checksum = CONFIG_DEFAULT_RDB_CHECKSUM; server.stop_writes_on_bgsave_err = CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR; diff --git a/src/server.h b/src/server.h index 02104e6f0..d2c6aa1e0 100644 --- a/src/server.h +++ b/src/server.h @@ -148,6 +148,7 @@ typedef long long mstime_t; /* millisecond time type. */ #define CONFIG_DEFAULT_RDB_SAVE_INCREMENTAL_FSYNC 1 #define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0 #define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10 +#define CONFIG_DEFAULT_ACL_FILENAME "" #define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */ #define NET_PEER_ID_LEN (NET_IP_STR_LEN+32) /* Must be enough for ip:port */ #define CONFIG_BINDADDR_MAX 16 @@ -1337,6 +1338,8 @@ struct redisServer { /* Latency monitor */ long long latency_monitor_threshold; dict *latency_events; + /* ACLs */ + char *acl_filename; /* ACL Users file. NULL if not configured. */ /* Assert & bug reporting */ const char *assert_failed; const char *assert_file; @@ -1725,6 +1728,7 @@ void sendChildInfo(int process_type); void receiveChildInfo(void); /* acl.c -- Authentication related prototypes. */ +extern rax *Users; extern user *DefaultUser; void ACLInit(void); /* Return values for ACLCheckUserCredentials(). */ @@ -1741,6 +1745,7 @@ uint64_t ACLGetCommandCategoryFlagByName(const char *name); int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err); char *ACLSetUserStringError(void); int ACLLoadConfiguredUsers(void); +sds ACLDescribeUser(user *u); /* Sorted sets data type */