27 #include "access/xact.h"
28 #include "executor/spi.h"
29 #include "commands/trigger.h"
30 #include "utils/lsyscache.h"
31 #include "utils/rel.h"
32 #include "../postgis_config.h"
33 #include "lwgeom_pg.h"
35 #define ABORT_ON_AUTH_FAILURE 1
51 TriggerData *trigdata = (TriggerData *) fcinfo->context;
53 HeapTuple rettuple_ok;
54 HeapTuple rettuple_fail;
58 const char *pk_id = NULL;
59 SPITupleTable *tuptable;
62 char *authtable =
"authorization_table";
68 if ( ! CALLED_AS_TRIGGER(fcinfo) )
70 elog(ERROR,
"check_authorization: not fired by trigger manager");
73 if ( ! TRIGGER_FIRED_BEFORE(trigdata->tg_event) )
75 elog(ERROR,
"check_authorization: not fired *before* event");
78 if ( TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) )
80 rettuple_ok = trigdata->tg_newtuple;
84 else if ( TRIGGER_FIRED_BY_DELETE(trigdata->tg_event) )
86 rettuple_ok = trigdata->tg_trigtuple;
92 elog(ERROR,
"check_authorization: not fired by update or delete");
97 tupdesc = trigdata->tg_relation->rd_att;
100 SPIcode = SPI_connect();
102 if (SPIcode != SPI_OK_CONNECT)
104 elog(ERROR,
"check_authorization: could not connect to SPI");
108 colname = trigdata->tg_trigger->tgargs[0];
109 pk_id = SPI_getvalue(trigdata->tg_trigtuple, tupdesc,
110 SPI_fnumber(tupdesc, colname));
112 POSTGIS_DEBUG(3,
"check_authorization called");
114 snprintf(query,
sizeof(query),
"SELECT authid FROM \"%s\" WHERE expires >= now() AND toid = '%d' AND rid = '%s'", authtable, trigdata->tg_relation->rd_id, pk_id);
116 POSTGIS_DEBUGF(3 ,
"about to execute :%s", query);
118 SPIcode = SPI_exec(query,0);
119 if (SPIcode !=SPI_OK_SELECT )
120 elog(ERROR,
"couldnt execute to test for lock :%s",query);
124 POSTGIS_DEBUGF(3,
"there is NO lock on row '%s'", pk_id);
127 return PointerGetDatum(rettuple_ok);
132 tuptable = SPI_tuptable;
133 tupdesc = tuptable->tupdesc;
134 tuple = tuptable->vals[0];
135 lockcode = SPI_getvalue(tuple, tupdesc, 1);
137 POSTGIS_DEBUGF(3,
"there is a lock on row '%s' (auth: '%s').", pk_id, lockcode);
143 snprintf(query,
sizeof(query),
"SELECT * FROM pg_class WHERE relname = 'temp_lock_have_table'");
144 SPIcode = SPI_exec(query,0);
145 if (SPIcode != SPI_OK_SELECT )
146 elog(ERROR,
"couldnt execute to test for lockkey temp table :%s",query);
147 if (SPI_processed==0)
152 snprintf(query,
sizeof(query),
"SELECT * FROM temp_lock_have_table WHERE xideq( transid, getTransactionID() ) AND lockcode ='%s'", lockcode);
154 POSTGIS_DEBUGF(3,
"about to execute :%s", query);
156 SPIcode = SPI_exec(query,0);
157 if (SPIcode != SPI_OK_SELECT )
158 elog(ERROR,
"couldnt execute to test for lock acquire: %s", query);
160 if (SPI_processed >0)
162 POSTGIS_DEBUG(3,
"I own the lock - I can modify the row");
165 return PointerGetDatum(rettuple_ok);
170 snprintf(err_msg,
sizeof(err_msg),
"%s where \"%s\" = '%s' requires authorization '%s'",
171 op, colname, pk_id, lockcode);
172 err_msg[
sizeof(err_msg)-1] =
'\0';
174 #ifdef ABORT_ON_AUTH_FAILURE
175 elog(ERROR,
"%s", err_msg);
177 elog(NOTICE,
"%s", err_msg);
181 return PointerGetDatum(rettuple_fail);
189 TransactionId xid = GetCurrentTransactionId();
190 PG_RETURN_DATUM( TransactionIdGetDatum(xid) );
Datum getTransactionID(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(check_authorization)
Datum check_authorization(PG_FUNCTION_ARGS)