Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/func.sgml,v retrieving revision 1.202 diff -u -r1.202 func.sgml --- doc/src/sgml/func.sgml 14 May 2004 21:42:27 -0000 1.202 +++ doc/src/sgml/func.sgml 18 May 2004 18:59:37 -0000 @@ -6593,6 +6593,30 @@ + inet_client_addr + inet + address of the remote connection + + + + inet_client_port + int4 + port of the remote connection + + + + inet_server_addr + inet + address of the local connection + + + + inet_server_port + int4 + port of the local connection + + + session_user name session user name @@ -6646,6 +6670,17 @@ they must be called without trailing parentheses. + + + inet_client_addr and + inet_server_addr return the IPv4 or IPv6 (if + configured) address of the remote or local host connecting to the + database, respectively. inet_client_port + and inet_server_port return the port number + of the remote or local host connecting to the database, + respectively. If the connection is not a network connection, + these functions will return NULL. + current_schema returns the name of the schema that is Index: src/backend/catalog/aclchk.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/catalog/aclchk.c,v retrieving revision 1.98 diff -u -r1.98 aclchk.c --- src/backend/catalog/aclchk.c 11 May 2004 17:36:12 -0000 1.98 +++ src/backend/catalog/aclchk.c 18 May 2004 18:59:37 -0000 @@ -1342,16 +1342,26 @@ bool isNull; Acl *acl; - /* - * If we have been assigned this namespace as a temp namespace, assume - * we have all grantable privileges on it. - */ - if (isTempNamespace(nsp_oid)) - return mask; - /* Superusers bypass all permission checking. */ if (superuser_arg(userid)) return mask; + + /* + * If we have been assigned this namespace as a temp + * namespace, check to make sure we have CREATE permissions on + * the database. + * + * Instead of returning ACLCHECK_NO_PRIV, should we return via + * ereport() with a message about trying to create an object + * in a TEMP namespace when GetUserId() doesn't have perms? + */ + if (isTempNamespace(nsp_oid)) { + if (pg_database_aclcheck(MyDatabaseId, GetUserId(), + ACL_CREATE_TEMP) == ACLCHECK_OK) + return ACLCHECK_OK; + else + return ACLCHECK_NO_PRIV; + } /* * Get the schema's ACL from pg_namespace Index: src/backend/catalog/namespace.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/catalog/namespace.c,v retrieving revision 1.63 diff -u -r1.63 namespace.c --- src/backend/catalog/namespace.c 13 Feb 2004 01:08:20 -0000 1.63 +++ src/backend/catalog/namespace.c 18 May 2004 18:59:38 -0000 @@ -1640,11 +1640,11 @@ * tables. We use a nonstandard error message here since * "databasename: permission denied" might be a tad cryptic. * - * Note we apply the check to the session user, not the currently active - * userid, since we are not going to change our minds about temp table - * availability during the session. + * ACL_CREATE_TEMP perms are also checked in + * pg_namespace_aclcheck() that way only users who have TEMP + * perms can create objects. */ - if (pg_database_aclcheck(MyDatabaseId, GetSessionUserId(), + if (pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE_TEMP) != ACLCHECK_OK) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), Index: src/backend/libpq/hba.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/hba.c,v retrieving revision 1.120 diff -u -r1.120 hba.c --- src/backend/libpq/hba.c 2 Feb 2004 16:58:30 -0000 1.120 +++ src/backend/libpq/hba.c 18 May 2004 18:59:38 -0000 @@ -1296,8 +1296,11 @@ hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv); - if (rc || !ident_serv) + if (rc || !ident_serv) { + if (ident_serv) + freeaddrinfo_all(hints.ai_family, ident_serv); return false; /* we don't expect this to happen */ + } hints.ai_flags = AI_NUMERICHOST; hints.ai_family = local_addr.addr.ss_family; @@ -1308,8 +1311,11 @@ hints.ai_addr = NULL; hints.ai_next = NULL; rc = getaddrinfo_all(local_addr_s, NULL, &hints, &la); - if (rc || !la) + if (rc || !la) { + if (la) + freeaddrinfo_all(hints.ai_family, la); return false; /* we don't expect this to happen */ + } sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype, ident_serv->ai_protocol); Index: src/backend/libpq/ip.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/ip.c,v retrieving revision 1.25 diff -u -r1.25 ip.c --- src/backend/libpq/ip.c 24 Apr 2004 20:10:34 -0000 1.25 +++ src/backend/libpq/ip.c 18 May 2004 18:59:38 -0000 @@ -73,11 +73,11 @@ *result = NULL; #ifdef HAVE_UNIX_SOCKETS - if (hintp != NULL && hintp->ai_family == AF_UNIX) + if (hintp->ai_family == AF_UNIX) return getaddrinfo_unix(servname, hintp, result); #endif - /* NULL has special meaning to getaddrinfo */ + /* NULL has special meaning to getaddrinfo(). */ return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname, servname, hintp, result); } Index: src/backend/libpq/pqcomm.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/libpq/pqcomm.c,v retrieving revision 1.168 diff -u -r1.168 pqcomm.c --- src/backend/libpq/pqcomm.c 12 Dec 2003 18:45:08 -0000 1.168 +++ src/backend/libpq/pqcomm.c 18 May 2004 18:59:38 -0000 @@ -251,7 +251,8 @@ ereport(LOG, (errmsg("could not translate service \"%s\" to address: %s", service, gai_strerror(ret)))); - freeaddrinfo_all(hint.ai_family, addrs); + if (addrs) + freeaddrinfo_all(hint.ai_family, addrs); return STATUS_ERROR; } Index: src/backend/utils/adt/geo_ops.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/geo_ops.c,v retrieving revision 1.84 diff -u -r1.84 geo_ops.c --- src/backend/utils/adt/geo_ops.c 12 May 2004 22:38:44 -0000 1.84 +++ src/backend/utils/adt/geo_ops.c 18 May 2004 18:59:40 -0000 @@ -1313,6 +1313,27 @@ *---------------------------------------------------------*/ Datum +path_area(PG_FUNCTION_ARGS) +{ + PATH *path = PG_GETARG_PATH_P(0); + double area = 0.0; + int i,j; + + if (!path->closed) + PG_RETURN_NULL(); + + for (i = 0; i < path->npts; i++) { + j = (i + 1) % path->npts; + area += path->p[i].x * path->p[j].y; + area -= path->p[i].y * path->p[j].x; + } + + area *= 0.5; + PG_RETURN_FLOAT8(area < 0.0 ? -area : area); +} + + +Datum path_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); Index: src/backend/utils/adt/network.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/network.c,v retrieving revision 1.49 diff -u -r1.49 network.c --- src/backend/utils/adt/network.c 1 Dec 2003 18:50:19 -0000 1.49 +++ src/backend/utils/adt/network.c 18 May 2004 18:59:40 -0000 @@ -14,7 +14,10 @@ #include #include "catalog/pg_type.h" +#include "libpq/ip.h" +#include "libpq/libpq-be.h" #include "libpq/pqformat.h" +#include "miscadmin.h" #include "utils/builtins.h" #include "utils/inet.h" @@ -129,6 +132,110 @@ PG_RETURN_INET_P(network_in(src, 1)); } + +/* INET that the client is connecting from */ +Datum +inet_client_addr(PG_FUNCTION_ARGS) +{ + Port *port = MyProcPort; + + if (port == NULL) + PG_RETURN_NULL(); + + switch (port->raddr.addr.ss_family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + default: + PG_RETURN_NULL(); + } + + PG_RETURN_INET_P(network_in(port->remote_host, 0)); +} + + +/* port that the client is connecting from */ +Datum +inet_client_port(PG_FUNCTION_ARGS) +{ + Port *port = MyProcPort; + + if (port == NULL) + PG_RETURN_NULL(); + + PG_RETURN_INT32(DirectFunctionCall1(int4in, CStringGetDatum(port->remote_port))); +} + + +/* server INET that the client connected to */ +Datum +inet_server_addr(PG_FUNCTION_ARGS) +{ + Port *port = MyProcPort; + char local_host[NI_MAXHOST]; + int ret; + + if (port == NULL) + PG_RETURN_NULL(); + + switch (port->laddr.addr.ss_family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + default: + PG_RETURN_NULL(); + } + + local_host[0] = '\0'; + + ret = getnameinfo_all(&port->laddr.addr, port->laddr.salen, + local_host, sizeof(local_host), + NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret) + PG_RETURN_NULL(); + + PG_RETURN_INET_P(network_in(local_host, 0)); +} + + +/* port that the server accepted the connection on */ +Datum +inet_server_port(PG_FUNCTION_ARGS) +{ + Port *port = MyProcPort; + char local_port[NI_MAXSERV]; + int ret; + + if (port == NULL) + PG_RETURN_NULL(); + + switch (port->laddr.addr.ss_family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + default: + PG_RETURN_NULL(); + } + + local_port[0] = '\0'; + + ret = getnameinfo_all(&port->laddr.addr, port->laddr.salen, + NULL, 0, + local_port, sizeof(local_port), + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret) + PG_RETURN_NULL(); + + PG_RETURN_INT32(DirectFunctionCall1(int4in, CStringGetDatum(local_port))); +} + /* * INET address output function. Index: src/backend/utils/fmgr/dfmgr.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/fmgr/dfmgr.c,v retrieving revision 1.72 diff -u -r1.72 dfmgr.c --- src/backend/utils/fmgr/dfmgr.c 17 May 2004 14:35:31 -0000 1.72 +++ src/backend/utils/fmgr/dfmgr.c 18 May 2004 18:59:40 -0000 @@ -350,7 +350,7 @@ strncmp(name, "$libdir", strlen("$libdir")) != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), - errmsg("invalid macro name in dynamic library path"))); + errmsg("invalid macro name in dynamic library path: %s", name))); ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1); Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v retrieving revision 1.329 diff -u -r1.329 pg_proc.h --- src/include/catalog/pg_proc.h 14 May 2004 21:42:28 -0000 1.329 +++ src/include/catalog/pg_proc.h 18 May 2004 18:59:41 -0000 @@ -1259,6 +1259,8 @@ DESCR("box height"); DATA(insert OID = 978 ( box_distance PGNSP PGUID 12 f f t f i 2 701 "603 603" _null_ box_distance - _null_ )); DESCR("distance between boxes"); +DATA(insert OID = 979 ( area PGNSP PGUID 12 f f t f i 1 701 "602" _null_ path_area - _null_ )); +DESCR("area of a closed path"); DATA(insert OID = 980 ( box_intersect PGNSP PGUID 12 f f t f i 2 603 "603 603" _null_ box_intersect - _null_ )); DESCR("box intersection (another box)"); DATA(insert OID = 981 ( diagonal PGNSP PGUID 12 f f t f i 1 601 "603" _null_ box_diagonal - _null_ )); @@ -2343,6 +2345,15 @@ DESCR("I/O"); DATA(insert OID = 911 ( inet_out PGNSP PGUID 12 f f t f i 1 2275 "869" _null_ inet_out - _null_ )); DESCR("I/O"); + +DATA(insert OID = 912 ( inet_client_addr PGNSP PGUID 12 f f f f s 0 869 "" _null_ inet_client_addr - _null_ )); +DESCR("Returns the INET address of the client connected to the backend"); +DATA(insert OID = 913 ( inet_client_port PGNSP PGUID 12 f f f f s 0 23 "" _null_ inet_client_port - _null_ )); +DESCR("Returns the client's port number for this connection"); +DATA(insert OID = 914 ( inet_server_addr PGNSP PGUID 12 f f f f s 0 869 "" _null_ inet_server_addr - _null_ )); +DESCR("Returns the INET address that the backend is using to service the connection"); +DATA(insert OID = 915 ( inet_server_port PGNSP PGUID 12 f f f f s 0 23 "" _null_ inet_server_port - _null_ )); +DESCR("Returns the servers's port number for this connection"); /* for cidr type support */ DATA(insert OID = 1267 ( cidr_in PGNSP PGUID 12 f f t f i 1 650 "2275" _null_ cidr_in - _null_ )); Index: src/include/utils/builtins.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v retrieving revision 1.238 diff -u -r1.238 builtins.h --- src/include/utils/builtins.h 14 May 2004 21:42:30 -0000 1.238 +++ src/include/utils/builtins.h 18 May 2004 18:59:41 -0000 @@ -645,6 +645,10 @@ void *dst, size_t size); /* network.c */ +extern Datum inet_client_addr(PG_FUNCTION_ARGS); +extern Datum inet_client_port(PG_FUNCTION_ARGS); +extern Datum inet_server_addr(PG_FUNCTION_ARGS); +extern Datum inet_server_port(PG_FUNCTION_ARGS); extern Datum inet_in(PG_FUNCTION_ARGS); extern Datum inet_out(PG_FUNCTION_ARGS); extern Datum inet_recv(PG_FUNCTION_ARGS); Index: src/include/utils/geo_decls.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/utils/geo_decls.h,v retrieving revision 1.43 diff -u -r1.43 geo_decls.h --- src/include/utils/geo_decls.h 29 Nov 2003 22:41:15 -0000 1.43 +++ src/include/utils/geo_decls.h 18 May 2004 18:59:41 -0000 @@ -305,6 +305,7 @@ extern Datum box_div(PG_FUNCTION_ARGS); /* public path routines */ +extern Datum path_area(PG_FUNCTION_ARGS); extern Datum path_in(PG_FUNCTION_ARGS); extern Datum path_out(PG_FUNCTION_ARGS); extern Datum path_recv(PG_FUNCTION_ARGS); Index: src/interfaces/libpq/fe-connect.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v retrieving revision 1.269 diff -u -r1.269 fe-connect.c --- src/interfaces/libpq/fe-connect.c 24 Mar 2004 03:44:59 -0000 1.269 +++ src/interfaces/libpq/fe-connect.c 18 May 2004 18:59:42 -0000 @@ -945,7 +945,8 @@ printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"), portstr, gai_strerror(ret)); - freeaddrinfo_all(hint.ai_family, addrs); + if (addrs) + freeaddrinfo_all(hint.ai_family, addrs); goto connect_errReturn; } Index: src/backend/postmaster/postmaster.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v retrieving revision 1.388 diff -u -r1.388 postmaster.c --- src/backend/postmaster/postmaster.c 17 May 2004 14:35:29 -0000 1.388 +++ src/backend/postmaster/postmaster.c 18 May 2004 19:24:37 -0000 @@ -2471,10 +2471,14 @@ remote_port, sizeof(remote_port), (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) { - getnameinfo_all(&port->raddr.addr, port->raddr.salen, + int ret = getnameinfo_all(&port->raddr.addr, port->raddr.salen, remote_host, sizeof(remote_host), remote_port, sizeof(remote_port), NI_NUMERICHOST | NI_NUMERICSERV); + if (ret) + ereport(WARNING, + (errmsg("getnameinfo_all() failed: %s", + gai_strerror(ret)))); } snprintf(remote_ps_data, sizeof(remote_ps_data), remote_port[0] == '\0' ? "%s" : "%s(%s)",