diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index cc7d797..a793f53 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1029,12 +1029,124 @@ INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g - \conninfo - - - Outputs information about the current database connection. - - + \conninfo[+] + + Outputs a string displaying information about the current + database connection. When + is appended, + more details about the connection are displayed in table + format: + + + + Database: The database name of the connection. + + + + Authenticated User: The authenticated database + user of the connection. + + + + Socket Directory: The Unix socket directory of + the connection. NULL if host or hostaddr are specified. + + + + Host: The host name or address of the connection. + NULL if a Unix socket is used. + + + + Server Port: The IP address of the connection. + NULL if a Unix socket is used. + + + + Server Address: The IP address of the host name. + NULL if a Unix socket is used. + + + + Client Address: The IP address of the client connected + to this backend. NULL if a Unix socket is used. + + + + Client Port: The port of the client connected to this + backend. NULL if a Unix socket is used. + + + + Backend PID: The process id of the backend for the connection. + + + + System User: The authentication data provided for this + connection; see the system_user() function in + for more details. + + + + Current User: The user name of the current execution context; + see the current_user() function in + for more details. + + + + Session User: The session user's name; see the + session_user() function in + for more details. + + + + Application Name: psql is the + default for a psql connection unless otherwise specified in + the configuration parameter. + + + + SSL Connection: True if the current connection to the + server uses SSL, and false otherwise. + + + + SSL Protocol: The name of the protocol used for the SSL + connection (e.g., TLSv1.0, TLSv1.1, TLSv1.2 or TLSv1.3). + + + + SSL Cipher: Displays the name of the cipher used + for the SSL connection (e.g., DHE-RSA-AES256-SHA). + + + + SLL Compression: On if SSL compression is in use, off + if not, or NULL if SSL is not in use on this connection. + + + + GSSAPI Authenticated: True if GSSAPI is in use, or false + if GSSAPI is not in use on this connection. + + + + GSSAPI Principal: "Principal" used to authenticate this + connection, or NULL if GSSAPI was not used to authenticate this connection. + This field is truncated if the principal is longer than NAMEDATALEN + (64 characters in a standard build). + + + + GSSAPI Encrypted: True if GSSAPI encryption is in use on + this connection, or false if encryption is not in use. + + + + GSSAPI Credentials Delegated: True if GSSAPI credentials + were delegated on this connection, or false if were not delegated. + + + diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index c005624..43ce50e 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -68,7 +68,8 @@ static backslashResult exec_command_C(PsqlScanState scan_state, bool active_bran static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd); -static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch); +static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch, + const char *cmd); static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch); @@ -318,8 +319,8 @@ exec_command(const char *cmd, status = exec_command_connect(scan_state, active_branch); else if (strcmp(cmd, "cd") == 0) status = exec_command_cd(scan_state, active_branch, cmd); - else if (strcmp(cmd, "conninfo") == 0) - status = exec_command_conninfo(scan_state, active_branch); + else if (strcmp(cmd, "conninfo") == 0 || strcmp(cmd, "conninfo+") == 0) + status = exec_command_conninfo(scan_state, active_branch, cmd); else if (pg_strcasecmp(cmd, "copy") == 0) status = exec_command_copy(scan_state, active_branch); else if (strcmp(cmd, "copyright") == 0) @@ -644,47 +645,79 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd) } /* - * \conninfo -- display information about the current connection + * \conninfo, \conninfo+ -- display information about the current connection */ static backslashResult -exec_command_conninfo(PsqlScanState scan_state, bool active_branch) +exec_command_conninfo(PsqlScanState scan_state, bool active_branch, const char *cmd) { + bool success = true; + if (active_branch) { char *db = PQdb(pset.db); + bool show_verbose; + + show_verbose = strchr(cmd, '+') ? true : false; - if (db == NULL) - printf(_("You are currently not connected to a database.\n")); + /* + * \conninfo+ + */ + if (show_verbose) + success = listConnectionInformation(); + + /* + * \conninfo + */ else { - char *host = PQhost(pset.db); - char *hostaddr = PQhostaddr(pset.db); + PGresult *res; + PQExpBufferData buf; - if (is_unixsock_path(host)) - { - /* hostaddr overrides host */ - if (hostaddr && *hostaddr) - printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), - db, PQuser(pset.db), hostaddr, PQport(pset.db)); - else - printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), - db, PQuser(pset.db), host, PQport(pset.db)); - } + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT inet_server_addr();"); + + res = PSQLexec(buf.data); + + termPQExpBuffer(&buf); + + if (!res) + return PSQL_CMD_ERROR; else { - if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0) - printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"), - db, PQuser(pset.db), host, hostaddr, PQport(pset.db)); + char *host = PQhost(pset.db); + char *hostaddr = PQhostaddr(pset.db); + + if (is_unixsock_path(host)) + { + /* hostaddr overrides host */ + if (hostaddr && *hostaddr) + printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), PQgetvalue(res, 0, 0), PQport(pset.db)); + else + printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), host, PQport(pset.db)); + } else - printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), - db, PQuser(pset.db), host, PQport(pset.db)); + { + if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0) + printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"), + db, PQuser(pset.db), host, PQgetvalue(res, 0, 0), PQport(pset.db)); + else + printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), host, PQport(pset.db)); + } + PQclear(res); + printSSLInfo(); + printGSSInfo(); } - printSSLInfo(); - printGSSInfo(); } } + else + ignore_slash_options(scan_state); - return PSQL_CMD_SKIP_LINE; + return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR; } /* diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 6433497..6170c88 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -26,6 +26,7 @@ #include "fe_utils/mbprint.h" #include "fe_utils/print.h" #include "fe_utils/string_utils.h" +#include "libpq/pqcomm.h" #include "settings.h" #include "variables.h" @@ -901,6 +902,165 @@ error_return: return false; } +/* + * listConnectionInformation + * + * for \conninfo+ + */ +bool +listConnectionInformation(void) +{ + PGresult *res; + PQExpBufferData buf; + printQueryOpt myopt = pset.popt; + + char *host = PQhost(pset.db); + char *hostaddr = PQhostaddr(pset.db); + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT\n" + " pg_catalog.current_database() AS \"%s\",\n" + " '%s' AS \"%s\",\n", + _("Database"), + PQuser(pset.db), + _("Authenticated User")); + if (is_unixsock_path(host) && !(hostaddr && *hostaddr)) + appendPQExpBuffer(&buf, + " '%s' AS \"%s\",\n", + host, + _("Socket Directory")); + else + appendPQExpBuffer(&buf, + " NULL AS \"%s\",\n", + _("Socket Directory")); + appendPQExpBuffer(&buf, + " CASE\n" + " WHEN\n" + " pg_catalog.inet_server_addr() IS NULL\n" + " AND pg_catalog.inet_client_addr() IS NULL\n" + " THEN NULL\n" + " ELSE '%s'\n" + " END AS \"%s\",\n", + _("Host"), + host); + appendPQExpBuffer(&buf, + " pg_catalog.current_setting('port') AS \"%s\",\n" + " pg_catalog.inet_server_addr() AS \"%s\",\n" + " pg_catalog.inet_client_addr() AS \"%s\",\n" + " pg_catalog.inet_client_port() AS \"%s\",\n" + " pg_catalog.pg_backend_pid() AS \"%s\",\n", + _("Server Port"), + _("Server Address"), + _("Client Address"), + _("Client Port"), + _("Backend PID")); + if (pset.sversion >= 160000) + appendPQExpBuffer(&buf, + " pg_catalog.system_user() AS \"%s\",\n", + _("System User")); + else + appendPQExpBuffer(&buf, + " NULL AS \"%s\",\n", + _("System User")); + appendPQExpBuffer(&buf, + " pg_catalog.current_user() AS \"%s\",\n" + " pg_catalog.session_user() AS \"%s\",\n" + " pg_catalog.current_setting('application_name') AS \"%s\",\n", + _("Current User"), + _("Session User"), + _("Application Name")); + if (pset.sversion >= 140000) + appendPQExpBuffer(&buf, + " ssl.ssl AS \"%s\",\n" + " ssl.version AS \"%s\",\n" + " ssl.cipher AS \"%s\",\n" + " NULL AS \"%s\",\n", + _("SSL Connection"), + _("SSL Protocol"), + _("SSL Cipher"), + _("SSL Compression")); + else if (pset.sversion >= 90500) + appendPQExpBuffer(&buf, + " ssl.ssl AS \"%s\",\n" + " ssl.version AS \"%s\",\n" + " ssl.cipher AS \"%s\",\n" + " ssl.compression AS \"%s\",\n", + _("SSL Connection"), + _("SSL Protocol"), + _("SSL Cipher"), + _("SSL Compression")); + else + appendPQExpBuffer(&buf, + " NULL AS \"%s\",\n" + " NULL AS \"%s\",\n" + " NULL AS \"%s\",\n" + " NULL AS \"%s\",\n", + _("SSL Connection"), + _("SSL Protocol"), + _("SSL Cipher"), + _("SSL Compression")); + if (pset.sversion >= 160000) + appendPQExpBuffer(&buf, + " gssapi.gss_authenticated AS \"%s\",\n" + " gssapi.principal AS \"%s\",\n" + " gssapi.\"encrypted\" AS \"%s\",\n" + " gssapi.credentials_delegated AS \"%s\"\n", + _("GSSAPI Authenticated"), + _("GSSAPI Principal"), + _("GSSAPI Encrypted"), + _("GSSAPI Credentials Delegated")); + else if (pset.sversion >= 120000) + appendPQExpBuffer(&buf, + " gssapi.gss_authenticated AS \"%s\",\n" + " gssapi.principal AS \"%s\",\n" + " gssapi.\"encrypted\" AS \"%s\",\n" + " NULL AS \"%s\"\n", + _("GSSAPI Authenticated"), + _("GSSAPI Principal"), + _("GSSAPI Encrypted"), + _("GSSAPI Credentials Delegated")); + else + appendPQExpBuffer(&buf, + " NULL AS \"%s\",\n" + " NULL AS \"%s\",\n" + " NULL AS \"%s\",\n" + " NULL AS \"%s\"\n", + _("GSSAPI Authenticated"), + _("GSSAPI Principal"), + _("GSSAPI Encrypted"), + _("GSSAPI Credentials Delegated")); + if (pset.sversion >= 120000) + appendPQExpBuffer(&buf, + "FROM\n" + " pg_catalog.pg_stat_ssl ssl\n" + "LEFT JOIN\n" + " pg_catalog.pg_stat_gssapi gssapi ON ssl.pid = gssapi.pid\n" + "WHERE\n" + " ssl.pid = pg_catalog.pg_backend_pid()\n"); + if (pset.sversion >= 90500 && pset.sversion < 120000) + appendPQExpBuffer(&buf, + "FROM\n" + " pg_catalog.pg_stat_ssl ssl\n" + "WHERE\n" + " ssl.pid = pg_catalog.pg_backend_pid()\n"); + appendPQExpBuffer(&buf, + ";"); + + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.title = _("Current Connection Information"); + myopt.translate_header = true; + + printQuery(res, &myopt, pset.queryFout, false, pset.logfile); + + PQclear(res); + return true; +} /* * listAllDbs diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 273f974..8a4e83f 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -64,6 +64,9 @@ extern bool listTSDictionaries(const char *pattern, bool verbose); /* \dFt */ extern bool listTSTemplates(const char *pattern, bool verbose); +/* \conninfo */ +extern bool listConnectionInformation(void); + /* \l */ extern bool listAllDbs(const char *pattern, bool verbose); diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 4e79a81..2c5426d 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -310,7 +310,7 @@ slashUsage(unsigned short int pager) else HELP0(" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently no connection)\n"); - HELP0(" \\conninfo display information about current connection\n"); + HELP0(" \\conninfo[+] display information about current connection\n"); HELP0(" \\encoding [ENCODING] show or set client encoding\n"); HELP0(" \\password [USERNAME] securely change the password for a user\n"); HELP0("\n");