[Greater-commits] r391 - trunk/GREAT-ER-DB/impl/postgresql
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Jul 8 17:36:36 CEST 2011
Author: bricks
Date: 2011-07-08 17:36:35 +0200 (Fri, 08 Jul 2011)
New Revision: 391
Modified:
trunk/GREAT-ER-DB/impl/postgresql/datypes_pg.h
trunk/GREAT-ER-DB/impl/postgresql/gdagreater_pg.pgc
Log:
Fix: check if data could be loaded in gda_get_bin_obj. This resulted in invalid data passed to the client in the past
Fix: check if data could be written in gda_insert_bin_obj
Fix: If a bin_obj was inserted with no data, gda_get_bin_obj will also return no data. Client MUST check if data is not NULL.
Fix: In Postges >= 9 it's necessary to grant access to each large binary object. By default only the owner is able to access to bin object.
All permissions will be granted to DA_STANDARD_ROLE. DA_STANDARD_ROLE is a define which is set to "greater_standard_role"
Fix indentation
Modified: trunk/GREAT-ER-DB/impl/postgresql/datypes_pg.h
===================================================================
--- trunk/GREAT-ER-DB/impl/postgresql/datypes_pg.h 2011-07-08 15:00:11 UTC (rev 390)
+++ trunk/GREAT-ER-DB/impl/postgresql/datypes_pg.h 2011-07-08 15:36:35 UTC (rev 391)
@@ -80,6 +80,7 @@
*/
#define DA_ERRTYP_INT 'I' /* error type = Internal error */
+#define DA_STANDARD_ROLE "greater_standard_role"
/**************************************************************************
Modified: trunk/GREAT-ER-DB/impl/postgresql/gdagreater_pg.pgc
===================================================================
--- trunk/GREAT-ER-DB/impl/postgresql/gdagreater_pg.pgc 2011-07-08 15:00:11 UTC (rev 390)
+++ trunk/GREAT-ER-DB/impl/postgresql/gdagreater_pg.pgc 2011-07-08 15:36:35 UTC (rev 391)
@@ -8920,6 +8920,7 @@
int v_access_right= DA_A_NONE;
int fd;
+ int buf_read_len;
char *v_file_obj_ptr = NULL;
// not used: unsigned int v_file_obj_size = 0;
@@ -9040,15 +9041,15 @@
"REMARK, "
"to_char(CRE_DATE, '%s'), "
"to_char(MOD_DATE, '%s'), "
- "FILE_OBJ "
+ "FILE_OBJ "
"FROM BIN_OBJ_TAB "
- "WHERE %s",
+ "WHERE %s",
h_fmt_date, h_fmt_date, h_where_clause);
EXEC SQL PREPARE get_state FROM :h_query;
errln = 20;
- EXEC SQL DECLARE bin_obj_csr CURSOR FOR get_state;
+ EXEC SQL DECLARE bin_obj_csr CURSOR FOR get_state;
errln = 30;
EXEC SQL OPEN bin_obj_csr;
@@ -9104,33 +9105,54 @@
* PRIV-CHK: User is allowed access data in req. mode
* --------------------------------------------------------- */
- if ((h_ind_oid != -1) && (vp_get_file_obj == DA_YES))
+ if ((h_ind_oid != -1) && (h_oid != 0) && (vp_get_file_obj == DA_YES))
{
- connection = PQsetdbLogin(db_con->host, db_con->port, NULL, NULL, db_con->db_name, db_con->user_id, db_con->user_passwd);
-
- if (PQstatus(connection) == CONNECTION_BAD)
- {
- PQfinish(connection);
- v_status = DA_FAIL;
- }
- else
- {
- res = PQexec(connection, "begin");
- PQclear(res);
+ connection = PQsetdbLogin(db_con->host, db_con->port, NULL, NULL, db_con->db_name, db_con->user_id, db_con->user_passwd);
+ if (PQstatus(connection) == CONNECTION_BAD)
+ {
+ PQfinish(connection);
+ v_status = DA_FAIL;
+ }
+ else
+ {
+ res = PQexec(connection, "begin");
+ PQclear(res);
+
/* load BLOB value from database */
- lobjOid = h_oid;
-
- fd = lo_open(connection, lobjOid, INV_READ);
- v_file_obj_ptr = (char *) malloc((size_t) v_bin_obj_buf.file_size);
- lo_read(connection, fd, v_file_obj_ptr, v_bin_obj_buf.file_size);
- lo_close(connection, fd);
-
+ lobjOid = h_oid;
+
+ fd = lo_open(connection, lobjOid, INV_READ);
+ v_file_obj_ptr = (char *) malloc((size_t) v_bin_obj_buf.file_size);
+ buf_read_len = lo_read(connection, fd, v_file_obj_ptr, v_bin_obj_buf.file_size);
+ if (buf_read_len != v_bin_obj_buf.file_size)
+ {
+ vp_errinfo->err_type = DA_ERRTYP_PG;
+ vp_errinfo->err_no = errln;
+ sprintf (vp_errinfo->err_param, "%s - could not load bin_obj '%d' from database. "\
+ "Expected '%d' bytes but '%d' bytes were loaded",
+ v_module, v_bin_obj_buf.bin_obj_id, v_bin_obj_buf.file_size, buf_read_len);
+ free(v_file_obj_ptr);
+ lo_close(connection, fd);
+
+ res = PQexec(connection, "end");
+ PQclear(res);
+ PQfinish(connection);
+
+ EXEC SQL WHENEVER SQLERROR CONTINUE;
+ EXEC SQL CLOSE bin_obj_csr;
+ gda_db_rollback(db_con, vp_errinfo);
+
+ return DA_FAIL;
+ }
+
+ lo_close(connection, fd);
+
res = PQexec(connection, "end");
PQclear(res);
PQfinish(connection);
- }
+ }
}
if (v_status == DA_SUCCESS)
@@ -9175,6 +9197,9 @@
{
v_new_elem_ptr->file_size = v_bin_obj_buf.file_size;
}
+ else {
+ v_new_elem_ptr->file_size = 0;
+ }
/* reset pointer to next list element */
v_new_elem_ptr->next_element = NULL;
@@ -9832,8 +9857,8 @@
\return DA_SUCCESS \n DA_FAIL
*/
-int gda_insert_bin_obj(DB_con *db_con,
- DA_T_bin_obj *vp_bin_obj,
+int gda_insert_bin_obj(DB_con *db_con,
+ DA_T_bin_obj *vp_bin_obj,
DA_T_errinfo *vp_errinfo)
{
DA_T_MODULE_NAME v_module = "gda_insert_bin_obj";
@@ -9843,6 +9868,7 @@
unsigned int v_file_obj_size ;
int fd;
+ int buf_write_len;
Oid lobjOid;
PGconn *connection;
@@ -9875,7 +9901,9 @@
/* for insertion of CRE_DATE + MOD_DATE */
char h_fmt_date[30];
char h_fmt_date2[30];
-
+
+ char h_grant_statement[200];
+
EXEC SQL END DECLARE SECTION;
/* ------------------ *
@@ -9898,7 +9926,7 @@
EXEC SQL SET CONNECTION TO :h_con_name;
connection = PQsetdbLogin(db_con->host, db_con->port, NULL, NULL, db_con->db_name, db_con->user_id, db_con->user_passwd);
-
+
if (PQstatus(connection) == CONNECTION_BAD)
{
PQfinish(connection);
@@ -9942,25 +9970,45 @@
if(vp_bin_obj->file_obj)
{
- res = PQexec(connection, "begin");
- PQclear(res);
- lobjOid = lo_creat(connection, INV_READ|INV_WRITE);
- if (lobjOid == 0)
- {
- return (DA_FAIL);
- }
- fd = lo_open(connection, lobjOid, INV_WRITE);
- lo_write(connection, fd, vp_bin_obj->file_obj, v_file_obj_size);
- lo_close(connection, fd);
- h_file_obj = lobjOid;
- res = PQexec(connection, "end");
- PQclear(res);
- PQfinish(connection);
-
+ res = PQexec(connection, "begin");
+ PQclear(res);
+ lobjOid = lo_creat(connection, INV_READ|INV_WRITE);
+ if (lobjOid == 0)
+ {
+ return (DA_FAIL);
+ }
+ fd = lo_open(connection, lobjOid, INV_WRITE);
+ buf_write_len = lo_write(connection, fd, vp_bin_obj->file_obj, v_file_obj_size);
+ if (buf_write_len != v_file_obj_size) {
+ vp_errinfo->err_type = DA_ERRTYP_PG;
+ vp_errinfo->err_no = errln;
+ sprintf (vp_errinfo->err_param, "%s - could not write bin_obj '%s' into database. "\
+ "Tried to write '%d' bytes but '%d' bytes were written",
+ v_module, h_bin_obj.name, v_file_obj_size, buf_write_len);
+
+ lo_close(connection, fd);
+ h_file_obj = lobjOid;
+ res = PQexec(connection, "end");
+ PQclear(res);
+ PQfinish(connection);
+
+ return DA_FAIL;
+ }
+ lo_close(connection, fd);
+ h_file_obj = lobjOid;
+ res = PQexec(connection, "end");
+ PQclear(res);
+ PQfinish(connection);
+
+ errln = 20;
+ sprintf (h_grant_statement, "GRANT ALL ON LARGE OBJECT %d TO %s",
+ h_file_obj, DA_STANDARD_ROLE);
+ EXEC SQL EXECUTE IMMEDIATE :h_grant_statement;
+
}
/* full path for file of blob data is given in vp_bin_obj->name */
else
- h_file_obj = 0;
+ h_file_obj = 0;
/* Insert passed record and fill the BLOB */
errln = 30;
@@ -10536,7 +10584,7 @@
if (vp_filepath[strlen(vp_filepath)-1] == '\\')
sprintf(v_inputfile, "%s%s", vp_filepath, vp_filename);
else
- sprintf(v_inputfile, "%s/%s", vp_filepath, vp_filename);
+ sprintf(v_inputfile, "%s/%s", vp_filepath, vp_filename);
/* open input file in "binary" mode (rb) */
errln = 20;
More information about the Greater-commits
mailing list