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";
69 if ( ! CALLED_AS_TRIGGER(fcinfo) )
71 elog(ERROR,
"check_authorization: not fired by trigger manager");
74 if ( ! TRIGGER_FIRED_BEFORE(trigdata->tg_event) )
76 elog(ERROR,
"check_authorization: not fired *before* event");
79 if ( TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) )
81 rettuple_ok = trigdata->tg_newtuple;
85 else if ( TRIGGER_FIRED_BY_DELETE(trigdata->tg_event) )
87 rettuple_ok = trigdata->tg_trigtuple;
93 elog(ERROR,
"check_authorization: not fired by update or delete");
98 tupdesc = trigdata->tg_relation->rd_att;
101 SPIcode = SPI_connect();
103 if (SPIcode != SPI_OK_CONNECT)
105 elog(ERROR,
"check_authorization: could not connect to SPI");
109 colname = trigdata->tg_trigger->tgargs[0];
110 pk_id = SPI_getvalue(trigdata->tg_trigtuple, tupdesc,
111 SPI_fnumber(tupdesc, colname));
113 POSTGIS_DEBUG(3,
"check_authorization called");
115 sprintf(query,
"SELECT authid FROM \"%s\" WHERE expires >= now() AND toid = '%d' AND rid = '%s'", authtable, trigdata->tg_relation->rd_id, pk_id);
117 POSTGIS_DEBUGF(3 ,
"about to execute :%s", query);
119 SPIcode = SPI_exec(query,0);
120 if (SPIcode !=SPI_OK_SELECT )
121 elog(ERROR,
"couldnt execute to test for lock :%s",query);
125 POSTGIS_DEBUGF(3,
"there is NO lock on row '%s'", pk_id);
128 return PointerGetDatum(rettuple_ok);
133 tuptable = SPI_tuptable;
134 tupdesc = tuptable->tupdesc;
135 tuple = tuptable->vals[0];
136 lockcode = SPI_getvalue(tuple, tupdesc, 1);
138 POSTGIS_DEBUGF(3,
"there is a lock on row '%s' (auth: '%s').", pk_id, lockcode);
144 sprintf(query,
"SELECT * FROM pg_class WHERE relname = 'temp_lock_have_table'");
145 SPIcode = SPI_exec(query,0);
146 if (SPIcode != SPI_OK_SELECT )
147 elog(ERROR,
"couldnt execute to test for lockkey temp table :%s",query);
148 if (SPI_processed==0)
153 sprintf(query,
"SELECT * FROM temp_lock_have_table WHERE xideq( transid, getTransactionID() ) AND lockcode ='%s'", lockcode);
155 POSTGIS_DEBUGF(3,
"about to execute :%s", query);
157 SPIcode = SPI_exec(query,0);
158 if (SPIcode != SPI_OK_SELECT )
159 elog(ERROR,
"couldnt execute to test for lock acquire: %s", query);
161 if (SPI_processed >0)
163 POSTGIS_DEBUG(3,
"I own the lock - I can modify the row");
166 return PointerGetDatum(rettuple_ok);
171 snprintf(err_msg,
ERRMSGLEN,
"%s where \"%s\" = '%s' requires authorization '%s'",
172 op, colname, pk_id, lockcode);
175 #ifdef ABORT_ON_AUTH_FAILURE 176 elog(ERROR,
"%s", err_msg);
178 elog(NOTICE,
"%s", err_msg);
182 return PointerGetDatum(rettuple_fail);
190 TransactionId xid = GetCurrentTransactionId();
191 PG_RETURN_DATUM( TransactionIdGetDatum(xid) );
Datum getTransactionID(PG_FUNCTION_ARGS)
Datum check_authorization(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(check_authorization)