* Make a database connection with the given parameters. * * An interactive password prompt is automatically issued if needed and * allowed by cparams->prompt_password. * * If allow_password_reuse is true, we will try to re-use any password * given during previous calls to this routine. (Callers should not pass * allow_password_reuse=true unless reconnecting to the same database+user * as
| 29 | * as before, else we might create password exposure hazards.) |
| 30 | */ |
| 31 | PGconn * |
| 32 | connectDatabase(const ConnParams *cparams, const char *progname, |
| 33 | bool echo, bool fail_ok, bool allow_password_reuse) |
| 34 | { |
| 35 | PGconn *conn; |
| 36 | bool new_pass; |
| 37 | static char *password = NULL; |
| 38 | |
| 39 | /* Callers must supply at least dbname; other params can be NULL */ |
| 40 | Assert(cparams->dbname); |
| 41 | |
| 42 | if (!allow_password_reuse && password) |
| 43 | { |
| 44 | free(password); |
| 45 | password = NULL; |
| 46 | } |
| 47 | |
| 48 | if (cparams->prompt_password == TRI_YES && password == NULL) |
| 49 | password = simple_prompt("Password: ", false); |
| 50 | |
| 51 | /* |
| 52 | * Start the connection. Loop until we have a password if requested by |
| 53 | * backend. |
| 54 | */ |
| 55 | do |
| 56 | { |
| 57 | const char *keywords[8]; |
| 58 | const char *values[8]; |
| 59 | int i = 0; |
| 60 | |
| 61 | /* |
| 62 | * If dbname is a connstring, its entries can override the other |
| 63 | * values obtained from cparams; but in turn, override_dbname can |
| 64 | * override the dbname component of it. |
| 65 | */ |
| 66 | keywords[i] = "host"; |
| 67 | values[i++] = cparams->pghost; |
| 68 | keywords[i] = "port"; |
| 69 | values[i++] = cparams->pgport; |
| 70 | keywords[i] = "user"; |
| 71 | values[i++] = cparams->pguser; |
| 72 | keywords[i] = "password"; |
| 73 | values[i++] = password; |
| 74 | keywords[i] = "dbname"; |
| 75 | values[i++] = cparams->dbname; |
| 76 | if (cparams->override_dbname) |
| 77 | { |
| 78 | keywords[i] = "dbname"; |
| 79 | values[i++] = cparams->override_dbname; |
| 80 | } |
| 81 | keywords[i] = "fallback_application_name"; |
| 82 | values[i++] = progname; |
| 83 | keywords[i] = NULL; |
| 84 | values[i++] = NULL; |
| 85 | Assert(i <= lengthof(keywords)); |
| 86 | |
| 87 | new_pass = false; |
| 88 | conn = PQconnectdbParams(keywords, values, true); |
no test coverage detected