|
| 1 | +-- When you do "ALTER ROLE ... PASSWORD '...';" manually in psql, |
| 2 | +-- password goes to log files, psql/bash history files, AWS logfiles, etc. |
| 3 | +-- This is insecure. |
| 4 | +-- This interactive script solves this problem. |
| 5 | + |
| 6 | +-- Usage (run in psql): |
| 7 | +-- 1) Set messages level to DEBUG (and keep logging level higher, to avoid having password in logs): |
| 8 | +-- set client_min_messages to DEBUG; |
| 9 | +-- 2) Run interactive script in psql: |
| 10 | +-- \i /path/to/PostgresDBA/roles/alter_user_with_random_password.psql |
| 11 | + |
| 12 | +\prompt "Username?" postgres_dba_username |
| 13 | +\prompt "Superuser? (1 if yes, 0 if no)" postgres_dba_is_superuser |
| 14 | +\prompt "Login? (1 if yes, 0 if no)" postgres_dba_login |
| 15 | + |
| 16 | +\set q_postgres_dba_username '\'' :postgres_dba_username '\'' |
| 17 | +\set q_postgres_dba_is_superuser '\'' :postgres_dba_is_superuser '\'' |
| 18 | +\set q_postgres_dba_login '\'' :postgres_dba_login '\'' |
| 19 | + |
| 20 | +begin; |
| 21 | + |
| 22 | +\o /dev/null |
| 23 | +select set_config('postgres_dba.username', :q_postgres_dba_username, true); |
| 24 | +select set_config('postgres_dba.is_superuser', :q_postgres_dba_is_superuser, true); |
| 25 | +select set_config('postgres_dba.login', :q_postgres_dba_login, true); |
| 26 | +\o |
| 27 | + |
| 28 | +do $$ |
| 29 | +declare |
| 30 | + pwd text; |
| 31 | + j int4; |
| 32 | + allowed text; |
| 33 | + allowed_len int4; |
| 34 | + sql text; |
| 35 | +begin |
| 36 | + if current_setting('postgres_dba.username')::text = '' then |
| 37 | + raise exception 'Username is not specified.'; |
| 38 | + end if; |
| 39 | + allowed := '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'; |
| 40 | + allowed_len := length(allowed); |
| 41 | + pwd := ''; |
| 42 | + while length(pwd) < 16 loop |
| 43 | + j := int4(random() * allowed_len); |
| 44 | + pwd := pwd || substr(allowed, j+1, 1); |
| 45 | + end loop; |
| 46 | + sql := 'alter role ' || current_setting('postgres_dba.username')::text || ' password ''' || pwd || ''';'; |
| 47 | + raise debug 'SQL: %', sql; |
| 48 | + execute sql; |
| 49 | + sql := 'alter role ' || current_setting('postgres_dba.username')::text |
| 50 | + || (case when lower(current_setting('postgres_dba.is_superuser')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' superuser' else '' end) |
| 51 | + || ';'; |
| 52 | + raise debug 'SQL: %', sql; |
| 53 | + execute sql; |
| 54 | + sql := 'alter role ' || current_setting('postgres_dba.username')::text |
| 55 | + || (case when lower(current_setting('postgres_dba.login')::text) not in ('0', '', 'no', 'false', 'n', 'f') then ' login' else '' end) |
| 56 | + || ';'; |
| 57 | + raise debug 'SQL: %', sql; |
| 58 | + execute sql; |
| 59 | + raise debug 'User % altered, password: %', current_setting('postgres_dba.username')::text, pwd; |
| 60 | +end; |
| 61 | +$$ language plpgsql; |
| 62 | + |
| 63 | +commit; |
| 64 | + |
| 65 | +\unset postgres_dba_username |
| 66 | +\unset postgres_dba_is_superuser |
| 67 | +\unset postgres_dba_login |
| 68 | +\unset q_postgres_dba_username |
| 69 | +\unset q_postgres_dba_is_superuser |
| 70 | +\unset q_postgres_dba_login |
| 71 | + |
0 commit comments