diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index a848a7edd11..e826c19698c 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1163,21 +1163,22 @@ include_dir 'conf.d' - password_encryption (boolean) + password_encryption (enum) password_encryption configuration parameter - When a password is specified in or - - without writing either ENCRYPTED or - UNENCRYPTED, this parameter determines whether the - password is to be encrypted. The default is on - (encrypt the password). + When a password is specified in or + without writing either ENCRYPTED + or UNENCRYPTED, this parameter determines whether the + password is to be encrypted. The default value is md5, which + stores the password as an MD5 hash. Setting this to plain stores + it in plaintext. on and off are also accepted, as + aliases for md5 and plain, respectively. + diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 4027c89b143..adc6b99b215 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -44,7 +44,7 @@ Oid binary_upgrade_next_pg_authid_oid = InvalidOid; /* GUC parameter */ -extern bool Password_encryption; +int Password_encryption = PASSWORD_TYPE_MD5; /* Hook to check passwords in CreateRole() and AlterRole() */ check_password_hook_type check_password_hook = NULL; @@ -80,7 +80,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) ListCell *item; ListCell *option; char *password = NULL; /* user password */ - bool encrypt_password = Password_encryption; /* encrypt password? */ + int password_type = Password_encryption; char encrypted_password[MD5_PASSWD_LEN + 1]; bool issuper = false; /* Make the user a superuser? */ bool inherit = true; /* Auto inherit privileges? */ @@ -140,9 +140,9 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) parser_errposition(pstate, defel->location))); dpassword = defel; if (strcmp(defel->defname, "encryptedPassword") == 0) - encrypt_password = true; + password_type = PASSWORD_TYPE_MD5; else if (strcmp(defel->defname, "unencryptedPassword") == 0) - encrypt_password = false; + password_type = PASSWORD_TYPE_PLAINTEXT; } else if (strcmp(defel->defname, "sysid") == 0) { @@ -393,7 +393,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) if (password) { - if (!encrypt_password || isMD5(password)) + if (password_type == PASSWORD_TYPE_PLAINTEXT || isMD5(password)) new_record[Anum_pg_authid_rolpassword - 1] = CStringGetTextDatum(password); else @@ -505,7 +505,7 @@ AlterRole(AlterRoleStmt *stmt) ListCell *option; char *rolename = NULL; char *password = NULL; /* user password */ - bool encrypt_password = Password_encryption; /* encrypt password? */ + int password_type = Password_encryption; char encrypted_password[MD5_PASSWD_LEN + 1]; int issuper = -1; /* Make the user a superuser? */ int inherit = -1; /* Auto inherit privileges? */ @@ -550,9 +550,9 @@ AlterRole(AlterRoleStmt *stmt) errmsg("conflicting or redundant options"))); dpassword = defel; if (strcmp(defel->defname, "encryptedPassword") == 0) - encrypt_password = true; + password_type = PASSWORD_TYPE_MD5; else if (strcmp(defel->defname, "unencryptedPassword") == 0) - encrypt_password = false; + password_type = PASSWORD_TYPE_PLAINTEXT; } else if (strcmp(defel->defname, "superuser") == 0) { @@ -804,7 +804,7 @@ AlterRole(AlterRoleStmt *stmt) /* password */ if (password) { - if (!encrypt_password || isMD5(password)) + if (password_type == PASSWORD_TYPE_PLAINTEXT || isMD5(password)) new_record[Anum_pg_authid_rolpassword - 1] = CStringGetTextDatum(password); else diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ce4eef950b4..cced814d6ab 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -34,6 +34,7 @@ #include "catalog/namespace.h" #include "commands/async.h" #include "commands/prepare.h" +#include "commands/user.h" #include "commands/vacuum.h" #include "commands/variable.h" #include "commands/trigger.h" @@ -393,6 +394,24 @@ static const struct config_enum_entry force_parallel_mode_options[] = { {NULL, 0, false} }; +/* + * password_encryption used to be a boolean, so accept all the likely + * variants of "on" and "off", too. + */ +static const struct config_enum_entry password_encryption_options[] = { + {"plain", PASSWORD_TYPE_PLAINTEXT, false}, + {"md5", PASSWORD_TYPE_MD5, false}, + {"off", PASSWORD_TYPE_PLAINTEXT, false}, + {"on", PASSWORD_TYPE_MD5, false}, + {"true", PASSWORD_TYPE_MD5, true}, + {"false", PASSWORD_TYPE_PLAINTEXT, true}, + {"yes", PASSWORD_TYPE_MD5, true}, + {"no", PASSWORD_TYPE_PLAINTEXT, true}, + {"1", PASSWORD_TYPE_MD5, true}, + {"0", PASSWORD_TYPE_PLAINTEXT, true}, + {NULL, 0, false} +}; + /* * Options for enum values stored in other modules */ @@ -423,8 +442,6 @@ bool check_function_bodies = true; bool default_with_oids = false; bool SQL_inheritance = true; -bool Password_encryption = true; - int log_min_error_statement = ERROR; int log_min_messages = WARNING; int client_min_messages = NOTICE; @@ -1313,17 +1330,6 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, - { - {"password_encryption", PGC_USERSET, CONN_AUTH_SECURITY, - gettext_noop("Encrypt passwords."), - gettext_noop("When a password is specified in CREATE USER or " - "ALTER USER without writing either ENCRYPTED or UNENCRYPTED, " - "this parameter determines whether the password is to be encrypted.") - }, - &Password_encryption, - true, - NULL, NULL, NULL - }, { {"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT, gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."), @@ -3810,6 +3816,18 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"password_encryption", PGC_USERSET, CONN_AUTH_SECURITY, + gettext_noop("Encrypt passwords."), + gettext_noop("When a password is specified in CREATE USER or " + "ALTER USER without writing either ENCRYPTED or UNENCRYPTED, " + "this parameter determines whether the password is to be encrypted.") + }, + &Password_encryption, + PASSWORD_TYPE_MD5, password_encryption_options, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index b1c3aea9ee0..05b1373594b 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -85,7 +85,7 @@ #ssl_key_file = 'server.key' # (change requires restart) #ssl_ca_file = '' # (change requires restart) #ssl_crl_file = '' # (change requires restart) -#password_encryption = on +#password_encryption = md5 # md5 or plain #db_user_namespace = off #row_security = on diff --git a/src/include/commands/user.h b/src/include/commands/user.h index 1f0cfcc86f9..102c2a5861f 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -16,10 +16,19 @@ #include "parser/parse_node.h" -/* Hook to check passwords in CreateRole() and AlterRole() */ -#define PASSWORD_TYPE_PLAINTEXT 0 -#define PASSWORD_TYPE_MD5 1 +/* + * Types of password, for Password_encryption GUC and the password_type + * argument of the check-password hook. + */ +typedef enum PasswordType +{ + PASSWORD_TYPE_PLAINTEXT = 0, + PASSWORD_TYPE_MD5 +} PasswordType; +extern int Password_encryption; /* GUC */ + +/* Hook to check passwords in CreateRole() and AlterRole() */ typedef void (*check_password_hook_type) (const char *username, const char *password, int password_type, Datum validuntil_time, bool validuntil_null); extern PGDLLIMPORT check_password_hook_type check_password_hook;