[HACKERS] pg_dump

2015-10-28 Thread Dmitry Voronin
Hello, guys.

I have a database testdb with commet 'test comment' and security label 
'classified'. I create dump by pg_dump:

pg_dump -h 127.0.0.1 -d testdb -U postgres --format c dump

So, I want to restore a dump with comment and security label to testdb_restore. 
I run:

pg_restore -h 127.0.0.1 -d testdb_restore dump

So, we have, that SECURITY LABEL and COMMENT will be applied to database testdb 
but not testdb_restore. I think, that it's not good.

-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] New functions

2015-03-22 Thread Dmitry Voronin
Hello, Michael.

Please, attach new version of my patch to commitfest page.

-- 
Best regards, Dmitry Voronin
*** /dev/null
--- b/contrib/sslinfo/sslinfo--1.0--1.1.sql
***
*** 0 
--- 1,21 
+ /* contrib/sslinfo/sslinfo--1.0--1.1.sql */
+ 
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use ALTER EXTENSION sslinfo UPDATE TO '1.1' to load this file. \quit
+ 
+ CREATE OR REPLACE FUNCTION ssl_extension_value(text) RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_extension_value'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_extension_is_critical(text) RETURNS boolean
+ AS 'MODULE_PATHNAME', 'ssl_extension_is_critical'
+ LANGUAGE C STRICT;
+ 
+ CREATE TYPE extension AS (
+ name text,
+ value text
+ );
+ 
+ CREATE OR REPLACE FUNCTION ssl_extension_names() RETURNS SETOF extension 
+ AS 'MODULE_PATHNAME', 'ssl_extension_names'
+ LANGUAGE C STRICT;
*** /dev/null
--- b/contrib/sslinfo/sslinfo--1.1.sql
***
*** 0 
--- 1,58 
+ /* contrib/sslinfo/sslinfo--1.1.sql */
+ 
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use CREATE EXTENSION sslinfo to load this file. \quit
+ 
+ CREATE FUNCTION ssl_client_serial() RETURNS numeric
+ AS 'MODULE_PATHNAME', 'ssl_client_serial'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_is_used() RETURNS boolean
+ AS 'MODULE_PATHNAME', 'ssl_is_used'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_version() RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_version'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_cipher() RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_cipher'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_client_cert_present() RETURNS boolean
+ AS 'MODULE_PATHNAME', 'ssl_client_cert_present'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_client_dn_field(text) RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_client_dn_field'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_issuer_field(text) RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_issuer_field'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_client_dn() RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_client_dn'
+ LANGUAGE C STRICT;
+ 
+ CREATE FUNCTION ssl_issuer_dn() RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_issuer_dn'
+ LANGUAGE C STRICT;
+ 
+ /* new in 1.1 */
+ CREATE OR REPLACE FUNCTION ssl_extension_value(text) RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_extension_value'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_extension_is_critical(text) RETURNS boolean
+ AS 'MODULE_PATHNAME', 'ssl_extension_is_critical'
+ LANGUAGE C STRICT;
+ 
+ CREATE TYPE extension AS (
+ name text,
+ value text
+ );
+ 
+ CREATE OR REPLACE FUNCTION ssl_extension_names() RETURNS SETOF extension 
+ AS 'MODULE_PATHNAME', 'ssl_extension_names'
+ LANGUAGE C STRICT;
*** a/contrib/sslinfo/sslinfo.c
--- b/contrib/sslinfo/sslinfo.c
***
*** 14,21 
--- 14,23 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
+ #include funcapi.h
  
  #include openssl/x509.h
+ #include openssl/x509v3.h
  #include openssl/asn1.h
  
  PG_MODULE_MAGIC;
***
*** 23,28  PG_MODULE_MAGIC;
--- 25,31 
  static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
  static Datum X509_NAME_to_text(X509_NAME *name);
  static Datum ASN1_STRING_to_text(ASN1_STRING *str);
+ static bool get_extension(X509 *cert, const char *ext_name, X509_EXTENSION **extension);
  
  
  /*
***
*** 354,356  ssl_issuer_dn(PG_FUNCTION_ARGS)
--- 357,581 
  		PG_RETURN_NULL();
  	return X509_NAME_to_text(X509_get_issuer_name(MyProcPort-peer));
  }
+ 
+ 
+ /*
+  * Returns extension object by given certificate and extension's name.
+  *
+  * Try to get extension from certificate by extension's name.
+  * We returns at extension param pointer to X509_EXTENSION.
+  *
+  * Returns true, if we have found extension in certificate and false, if we not.
+  */
+ static bool get_extension(X509* cert, const char *ext_name, X509_EXTENSION **extension)
+ {
+ 	int 	nid = 0;
+ 	int 	loc = 0;
+ 
+ 	/* try to convert extension name to ObjectID */
+ 	nid = OBJ_txt2nid(ext_name);
+ 	/* Not success ? */
+ 	if (nid == NID_undef)
+ 		return false;
+ 
+ 	loc = X509_get_ext_by_NID(cert, nid, -1);
+ 
+ 	/* palloc memory for extension and copy it */
+ 	*extension = (X509_EXTENSION *) palloc(sizeof(X509_EXTENSION *));
+ 	memcpy(*extension, X509_get_ext(cert, loc), sizeof(X509_EXTENSION));
+ 
+ 	return true;
+ }
+ 
+ 
+ /* Returns value of extension
+  *
+  * This function returns value of extension by given name in client certificate.
+  *
+  * Returns text datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_value);
+ Datum
+ ssl_extension_value(PG_FUNCTION_ARGS)
+ {
+ 	X509			   *cert = MyProcPort-peer;
+ 	X509_EXTENSION	   *ext = NULL;
+ 	char			   *ext_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+ 	BIO   *membuf = NULL;
+ 	char			   *val = NULL;
+ 	charnullterm = '\0';
+ 	boolerror = false;
+ 
+ 	/* If we have no ssl security

[HACKERS] Question about TEMP tables

2015-03-16 Thread Dmitry Voronin
Hello, all.

We can create temp namespaces and temp objects that contains it. So, for 
example, temp table will be create at pg_temp_N (N - backendID). But afrer 
cluster init we have pg_temp_1 and pg_toast_temp_1 namespaces with OIDs 11333 
and 11334. Those namespaces are visible from any cluster database, but we 
cannot create any temp objects (please, correct me).

So, how can we use those namespaces and what are needed for?

Thank you.

-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] Question about TEMP tables

2015-03-16 Thread Dmitry Voronin
Hello, all.We can create temp namespaces and temp objects that contains it. So, for example, temp table will be create at pg_temp_N (N - backendID). But afrer cluster init we have pg_temp_1 and pg_toast_temp_1 namespaces with OIDs 11333 and 11334. Those namespaces are visible from any cluster database, but we cannot create any temp objects (please, correct me). So, how can we use those namespaces and what are needed for? Thank you. -- Best regards, Dmitry Voronin 



[HACKERS] New functions

2015-03-08 Thread Dmitry Voronin
Hello,
I make an a patch, which adds 4 functions to sslinfo extension module:1) ssl_extension_names() --- get short names of X509v3 extensions from client certificate and it's values;
2) ssl_extension_value(text) --- get value of extension from certificate (argument --- short name of extension);
3) ssl_extension_is_critical(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension).

You can view some information of certificate's extensions via those functions.

What do you think about it?-- Best regards, Dmitry Voronin *** a/contrib/sslinfo/sslinfo.c
--- b/contrib/sslinfo/sslinfo.c
***
*** 14,21 
--- 14,23 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
+ #include funcapi.h
  
  #include openssl/x509.h
+ #include openssl/x509v3.h
  #include openssl/asn1.h
  
  PG_MODULE_MAGIC;
***
*** 23,28  PG_MODULE_MAGIC;
--- 25,31 
  static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
  static Datum X509_NAME_to_text(X509_NAME *name);
  static Datum ASN1_STRING_to_text(ASN1_STRING *str);
+ int get_extension(X509 *cert, const char *ext_name, X509_EXTENSION **extension);
  
  
  /*
***
*** 354,356  ssl_issuer_dn(PG_FUNCTION_ARGS)
--- 357,581 
  		PG_RETURN_NULL();
  	return X509_NAME_to_text(X509_get_issuer_name(MyProcPort-peer));
  }
+ 
+ 
+ /*
+  * Returns extension object by given certificate and extension's name.
+  *
+  * Try to get extension from certificate by extension's name.
+  * We returns at extension param pointer to X509_EXTENSION.
+  *
+  * Returns 0, if we have found extension in certificate and 1, if we not.
+  */
+ int get_extension(X509* cert, const char *ext_name, X509_EXTENSION **extension)
+ {
+ 	int 	nid = 0;
+ 	int 	loc = 0;
+ 
+ 	/* try to convert extension name to ObjectID */
+ 	nid = OBJ_txt2nid(ext_name);
+ 	/* Not success ? */
+ 	if (nid == NID_undef)
+ 		return 1;
+ 
+ 	loc = X509_get_ext_by_NID(cert, nid, -1);
+ 
+ 	/* palloc memory for extension and copy it */
+ 	*extension = (X509_EXTENSION *) palloc(sizeof(X509_EXTENSION *));
+ 	memcpy(*extension, X509_get_ext(cert, loc), sizeof(X509_EXTENSION));
+ 
+ 	return 0;
+ }
+ 
+ 
+ /* Returns value of extension
+  *
+  * This function returns value of extension by given name in client certificate.
+  *
+  * Returns text datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_value);
+ Datum
+ ssl_extension_value(PG_FUNCTION_ARGS)
+ {
+ 	X509 			*cert = MyProcPort-peer;
+ 	X509_EXTENSION 		*ext = NULL;
+ 	char 			*ext_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+ 	BIO 			*membuf = NULL;
+ 	char 			*val = NULL;
+ 	char 			 nullterm = '\0';
+ 	int			 error = 0;
+ 
+ 	/* If we have no ssl security */
+ 	if (cert == NULL)
+ 		PG_RETURN_NULL();
+ 
+ 	/* If extension's converting from text name to extension's OID failed (return NID_undef) */
+ 	if (OBJ_txt2nid(ext_name) == NID_undef)
+ 		ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg(Unknown extension name \%s\, ext_name)));
+ 
+ 	/* Extension's name is correct, try to get extension object from certificate */
+ 	error = get_extension(cert, ext_name, ext);
+ 
+ 	/* Not found? */
+ 	if (error)
+ 		PG_RETURN_NULL();
+ 
+ 	/* Print extension to BIO */
+ 	membuf = BIO_new(BIO_s_mem());
+ 	X509V3_EXT_print(membuf, ext, 0, 0);
+ 	BIO_write(membuf, nullterm, 1);
+ 	BIO_get_mem_data(membuf, val);
+ 
+ 	/* Copy value */
+ 	val = pstrdup(val);
+ 
+ 	/* Clear BIO */
+ 	BIO_free(membuf);
+ 
+ 	/* free extension */
+ 	if (ext)
+ 		pfree(ext);
+ 
+ 	PG_RETURN_TEXT_P(cstring_to_text(val));
+ }
+ 
+ 
+ /* Returns status of extension
+  *
+  * Returns true, if extension is critical and false, if it is not.
+  *
+  * Returns bool datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_is_critical);
+ Datum
+ ssl_extension_is_critical(PG_FUNCTION_ARGS)
+ {
+ 	X509 			*cert = MyProcPort-peer;
+ 	X509_EXTENSION 		*ext = NULL;
+ 	char 			*ext_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+ 	int 			 critical;
+ 	int			 error = 0;
+ 
+ 	/* If we have no ssl security */
+ 	if (cert == NULL)
+ 		PG_RETURN_NULL();
+ 
+ 	/* If extension's converting from text name to extension's OID failed (return NID_undef) */
+ 	if (OBJ_txt2nid(ext_name) == NID_undef)
+ 		ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg(Unknown extension name \%s\, ext_name)));
+ 
+ 	/* Extension's name is correct, try to get extension object from certificate */
+ 	error = get_extension(cert, ext_name, ext);
+ 
+ 	/* Not found? */
+ 	if (error)
+ 		PG_RETURN_NULL();
+ 
+ 	critical = X509_EXTENSION_get_critical(ext);
+ 
+ 	/* free extension */
+ 	if (ext)
+ 		pfree(ext);
+ 
+ 	PG_RETURN_BOOL(critical);
+ }
+ 
+ 
+ /* Returns key-value pairs of extension name and it's value
+  *
+  * This function print extensions of client certificate at table form (extension's name and it's value).
+  *
+  * Returns setof text datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_names

[HACKERS] ereport bug

2015-01-12 Thread Dmitry Voronin
Hello, postgresmen! I found incorrect execution of ereport() macro. If we pass into ereport() function 2 or more arguments, the macro errcontext does not correct execute. So, ereport() call stack is: errstarterrcontext_msgset_errcontext_domainerrmsgerrfinishpg_unreachable This bug causes that error messages (for example, in PL/TCL) are not localized.Solutions:- Wrap all errcontext() macro in brackets, that is errcontext("error message %s", "end message") - (errcontext("error message %s", "end message"))- Rewrite this macro- ??? I am attaching to this letter a test case that shows the behavior errcontext() macro and the way to fix it.I am using postgresql 9.4 and test it on gcc 4.7 and gcc 4.8.1.-- Best regards, Dmitry Voronin#include stdio.h

#define ereport_domain(elevel, domain, rest)	\
	do { \
		const int elevel_ = (elevel); \
		if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
			errfinish rest; \
		if (elevel_ = 2) \
			pg_unreachable(); \
	} while(0)

#define ereport(elevel, rest)	\
	ereport_domain(elevel, TEXTDOMAIN, rest)

#define TEXTDOMAIN NULL
#define PG_FUNCNAME_MACRO NULL
#define ERROR 20

#define errcontext	set_errcontext_domain(TEXTDOMAIN),	errcontext_msg


int set_errcontext_domain(const char *domain)
{
	printf(set_errcontext_domain\n);
}


int
errstart(int elevel, const char *filename, int lineno,
		 const char *funcname, const char *domain)
{
	printf(errstart\n);
	return 1;
}


void pg_unreachable()
{
	printf(pg_unreachable\n);
}


void errfinish(int dummy, ...)
{
	printf(errfinish\n);
}


int
errcontext_msg(const char *fmt,...)
{
	printf(errcontext_msg\n);
	return 0;
}


int errmsg(const char *fmt, ...)
{
	printf(errmsg\n);
	return 0;
}


int main()
{
	/* this is incorrect */
	ereport(ERROR,
 	(errmsg(%s, error message),
 errcontext(%s\nin PL/Tcl function \%s\,
test1, test2)));
	printf(\n);
	/* this is correct */
	ereport(ERROR,
 	(errmsg(%s, error message),
 (errcontext(%s\nin PL/Tcl function \%s\,
test1, test2;

	return 0;
}
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] New functions for sslinfo extension

2014-04-21 Thread Dmitry Voronin
Hello, I make an a patch, which adds 4 functions to sslinfo extension module.  You can view some information of certificate's extensions with those functions. The descriptions of functions I posted in my first letter and in source code. What do you think about it? -- Best regards, Dmitry Voronin --- contrib/sslinfo/sslinfo.c	2014-03-17 23:35:47.0 +0400
+++ contrib/sslinfo/sslinfo.c	2014-04-18 11:09:49.567775647 +0400
@@ -5,6 +5,8 @@
  * This file is distributed under BSD-style license.
  *
  * contrib/sslinfo/sslinfo.c
+ * 
+ * Extension functions written by Dmitry Voronin carriingfat...@yandex.ru, CNIIEISU.
  */
 
 #include postgres.h
@@ -14,9 +16,11 @@
 #include miscadmin.h
 #include utils/builtins.h
 #include mb/pg_wchar.h
+#include funcapi.h
 
 #include openssl/x509.h
 #include openssl/asn1.h
+#include openssl/x509v3.h
 
 
 PG_MODULE_MAGIC;
@@ -35,6 +39,11 @@
 Datum		X509_NAME_to_text(X509_NAME *name);
 Datum		ASN1_STRING_to_text(ASN1_STRING *str);
 
+X509_EXTENSION	*get_extension(X509* certificate, char *name);
+Datum 		ssl_get_extension_value(PG_FUNCTION_ARGS);
+Datum		ssl_is_critical_extension(PG_FUNCTION_ARGS);
+Datum 		ssl_get_count_of_extensions(PG_FUNCTION_ARGS);
+Datum		ssl_get_extension_names(PG_FUNCTION_ARGS);
 
 /*
  * Indicates whether current session uses SSL
@@ -371,3 +380,146 @@
 		PG_RETURN_NULL();
 	return X509_NAME_to_text(X509_get_issuer_name(MyProcPort-peer));
 }
+
+
+X509_EXTENSION *get_extension(X509* certificate, char *name) {
+	int 			extension_nid = 0;
+	int 			locate = 0;
+	
+	extension_nid = OBJ_sn2nid(name);
+	if (extension_nid == NID_undef) {
+		extension_nid = OBJ_ln2nid(name);
+		if (extension_nid == NID_undef) 
+			return NULL;
+	}
+	locate = X509_get_ext_by_NID(certificate, extension_nid,  -1);
+	return X509_get_ext(certificate, locate);
+}
+
+/* Returns value of extension. 
+ * 
+ * This function returns value of extension by short name in client certificate. 
+ * 
+ * Returns text datum. 
+ */
+
+PG_FUNCTION_INFO_V1(ssl_get_extension_value);
+Datum
+ssl_get_extension_value(PG_FUNCTION_ARGS) {	
+	X509 			*certificate = MyProcPort - peer;
+	X509_EXTENSION 		*extension = NULL;
+	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+	BIO 			*bio = NULL;
+	char 			*value = NULL;
+	char 			nullterm = '\0';
+	text 			*result = NULL;
+
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+
+	extension = get_extension(certificate, extension_name);
+	if (extension == NULL)
+		elog(ERROR, Extension by name \%s\ is not found in certificate, extension_name);
+
+	bio = BIO_new(BIO_s_mem());
+	X509V3_EXT_print(bio, extension, -1, -1);
+	BIO_write(bio, nullterm, 1);
+	BIO_get_mem_data(bio, value);
+
+	result = cstring_to_text(value);
+	BIO_free(bio);
+
+	PG_RETURN_TEXT_P(result);
+}
+
+/* Returns status of extension 
+ * 
+ * Returns true, if extension is critical and false, if it is not.
+ * 
+ * Returns bool datum
+ */
+PG_FUNCTION_INFO_V1(ssl_is_critical_extension);
+Datum
+ssl_is_critical_extension(PG_FUNCTION_ARGS) {
+	X509 			*certificate = MyProcPort - peer;
+	X509_EXTENSION 		*extension = NULL;
+	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+	int 			critical = 0;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	extension = get_extension(certificate, extension_name);
+	if (extension == NULL) 
+		elog(ERROR, Extension name \%s\ is not found in certificate, extension_name);
+	
+	critical = X509_EXTENSION_get_critical(extension);
+	PG_RETURN_BOOL(critical);
+}
+
+/* Returns count of extensions in client certificate
+ * 
+ * Returns int datum
+ */
+PG_FUNCTION_INFO_V1(ssl_get_count_of_extensions);
+Datum
+ssl_get_count_of_extensions(PG_FUNCTION_ARGS) {
+	X509 			*certificate = MyProcPort - peer;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	PG_RETURN_INT32(X509_get_ext_count(certificate));
+}
+
+/* Returns short names of extensions in client certificate
+ * 
+ * Returns setof text datum
+ */
+PG_FUNCTION_INFO_V1(ssl_get_extension_names);
+Datum
+ssl_get_extension_names(PG_FUNCTION_ARGS) {
+	X509*certificate = MyProcPort - peer;
+	FuncCallContext 		*funcctx;
+	STACK_OF(X509_EXTENSION) 	*extension_stack = NULL;
+	MemoryContext 			oldcontext;
+	int call = 0;
+	int max_calls = 0;
+	X509_EXTENSION			*extension = NULL;
+	ASN1_OBJECT			*object = NULL;
+	int extension_nid = 0;
+	text*result = NULL;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	extension_stack = certificate - cert_info - extensions;
+	if (extension_stack == NULL) 
+		PG_RETURN_NULL();
+	
+	if (SRF_IS_FIRSTCALL()) {
+		funcctx = SRF_FIRSTCALL_INIT();
+		oldcontext = MemoryContextSwitchTo(funcctx - multi_call_memory_ctx);
+		funcctx - max_calls = X509_get_ext_count(certificate);
+		MemoryContextSwitchTo(oldcontext);
+	}
+	funcctx = SRF_PERCALL_SETUP();
+	
+	call = funcctx - call_cntr;
+	max_calls = funcctx - max_calls;
+	
+	if (call  max_calls) {
+		extension = sk_X509_EXTENSION_value(extension_stack, call);
+		object = X509_EXTENSION_get_object