|
|
|
@ -8,7 +8,7 @@ |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* IDENTIFICATION |
|
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.62 2001/06/12 15:58:34 momjian Exp $ |
|
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.63 2001/06/12 16:34:26 momjian Exp $ |
|
|
|
|
* |
|
|
|
|
*------------------------------------------------------------------------- |
|
|
|
|
*/ |
|
|
|
@ -31,12 +31,6 @@ static const char *getid(const char *s, char *n); |
|
|
|
|
static bool aclitemeq(const AclItem *a1, const AclItem *a2); |
|
|
|
|
static bool aclitemgt(const AclItem *a1, const AclItem *a2); |
|
|
|
|
|
|
|
|
|
AclMode convert_priv_string(text *priv_type_text); |
|
|
|
|
bool has_table_privilege_cname_cname(char *username, char *relname, text *priv_type_text); |
|
|
|
|
bool has_table_privilege_id_cname(Oid usesysid, char *relname, text *priv_type_text); |
|
|
|
|
bool has_table_privilege_cname_id(char *username, Oid reloid, text *priv_type_text); |
|
|
|
|
static char *get_Name(text *relin); |
|
|
|
|
|
|
|
|
|
#define ACL_IDTYPE_GID_KEYWORD "group" |
|
|
|
|
#define ACL_IDTYPE_UID_KEYWORD "user" |
|
|
|
|
|
|
|
|
@ -716,752 +710,3 @@ makeAclString(const char *privileges, const char *grantee, char grant_or_revoke) |
|
|
|
|
pfree(str.data); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_tname_tname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* text usename, text relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_tname_tname(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
text *username_text; |
|
|
|
|
char *username; |
|
|
|
|
text *relname_text; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_text = PG_GETARG_TEXT_P(0); |
|
|
|
|
relname_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username and relname 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = get_Name(username_text); |
|
|
|
|
relname = get_Name(relname_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_cname(username, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_tname_name |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* text usename, name relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_tname_name(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
text *username_text; |
|
|
|
|
char *username; |
|
|
|
|
Name relname_name; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_text = PG_GETARG_TEXT_P(0); |
|
|
|
|
relname_name = PG_GETARG_NAME(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = get_Name(username_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_cname(username, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_name_tname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* name usename, text relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_name_tname(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Name username_name; |
|
|
|
|
char *username; |
|
|
|
|
text *relname_text; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_name = PG_GETARG_NAME(0); |
|
|
|
|
relname_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username 'name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = get_Name(relname_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_cname(username, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_name_name |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* name usename, name relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_name_name(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Name username_name; |
|
|
|
|
char *username; |
|
|
|
|
Name relname_name; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_name = PG_GETARG_NAME(0); |
|
|
|
|
relname_name = PG_GETARG_NAME(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username and relname 'name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name))); |
|
|
|
|
relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_cname(username, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_tname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* text relname and text priv name. |
|
|
|
|
* current_user is assumed |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_tname(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid = (Oid) -1; |
|
|
|
|
text *relname_text; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
relname_text = PG_GETARG_TEXT_P(0); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
|
|
|
|
|
usesysid = GetUserId(); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = get_Name(relname_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_name |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* name relname and text priv name. |
|
|
|
|
* current_user is assumed |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_name(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid = (Oid) -1; |
|
|
|
|
Name relname_name; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
relname_name = PG_GETARG_NAME(0); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
|
|
|
|
|
usesysid = GetUserId(); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'Name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_tname_id |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* text usename, rel oid, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_tname_id(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
text *username_text; |
|
|
|
|
char *username; |
|
|
|
|
Oid reloid = 0; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_text = PG_GETARG_TEXT_P(0); |
|
|
|
|
reloid = PG_GETARG_OID(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = get_Name(username_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_id. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_id(username, reloid, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_name_id |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* name usename, rel oid, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_name_id(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Name username_name; |
|
|
|
|
char *username; |
|
|
|
|
Oid reloid = 0; |
|
|
|
|
text *priv_type_text = NULL; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
username_name = PG_GETARG_NAME(0); |
|
|
|
|
reloid = PG_GETARG_OID(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert username 'name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_id. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_id(username, reloid, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_id |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* rel oid, and text priv name. |
|
|
|
|
* current_user is assumed |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_id(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
char *username; |
|
|
|
|
Oid reloid = 0; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
reloid = PG_GETARG_OID(0); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
username = GetUserName(GetUserId()); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_cname_id. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_cname_id(username, reloid, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_id_tname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* usesysid, text relname, and priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_id_tname(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid; |
|
|
|
|
text *relname_text; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
usesysid = PG_GETARG_OID(0); |
|
|
|
|
relname_text = PG_GETARG_TEXT_P(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'text' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = get_Name(relname_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_id_name |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* usesysid, name relname, and priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_id_name(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid; |
|
|
|
|
Name relname_name; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
usesysid = PG_GETARG_OID(0); |
|
|
|
|
relname_name = PG_GETARG_NAME(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert relname 'name' pattern to null-terminated string |
|
|
|
|
*/ |
|
|
|
|
relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(result); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_id_id |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* usesysid, rel oid, and priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
has_table_privilege_id_id(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid; |
|
|
|
|
Oid reloid; |
|
|
|
|
char *relname; |
|
|
|
|
text *priv_type_text; |
|
|
|
|
HeapTuple tuple; |
|
|
|
|
AclMode mode; |
|
|
|
|
int32 result; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
usesysid = PG_GETARG_OID(0); |
|
|
|
|
reloid = PG_GETARG_OID(1); |
|
|
|
|
priv_type_text = PG_GETARG_TEXT_P(2); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Lookup relname based on rel oid |
|
|
|
|
*/ |
|
|
|
|
tuple = SearchSysCache(RELOID, ObjectIdGetDatum(reloid), 0, 0, 0); |
|
|
|
|
if (!HeapTupleIsValid(tuple)) { |
|
|
|
|
elog(ERROR, "has_table_privilege: invalid relation oid %d", (int) reloid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); |
|
|
|
|
|
|
|
|
|
ReleaseSysCache(tuple); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert priv_type_text to an AclMode |
|
|
|
|
*/ |
|
|
|
|
mode = convert_priv_string(priv_type_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Finally, check for the privilege |
|
|
|
|
*/ |
|
|
|
|
result = pg_aclcheck(relname, usesysid, mode); |
|
|
|
|
|
|
|
|
|
if (result == ACLCHECK_OK) { |
|
|
|
|
PG_RETURN_BOOL(TRUE); |
|
|
|
|
} else { |
|
|
|
|
PG_RETURN_BOOL(FALSE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Internal functions. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* convert_priv_string |
|
|
|
|
* Internal function. |
|
|
|
|
* Return mode from priv_type string |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* AclMode |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
AclMode |
|
|
|
|
convert_priv_string(text *priv_type_text) |
|
|
|
|
{ |
|
|
|
|
char *priv_type = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(priv_type_text))); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Return mode from priv_type string |
|
|
|
|
*/ |
|
|
|
|
if (strcasecmp(priv_type, "SELECT") == 0) |
|
|
|
|
return ACL_SELECT; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "INSERT") == 0) |
|
|
|
|
return ACL_INSERT; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "UPDATE") == 0) |
|
|
|
|
return ACL_UPDATE; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "DELETE") == 0) |
|
|
|
|
return ACL_DELETE; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "RULE") == 0) |
|
|
|
|
return ACL_RULE; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "REFERENCES") == 0) |
|
|
|
|
return ACL_REFERENCES; |
|
|
|
|
|
|
|
|
|
if (strcasecmp(priv_type, "TRIGGER") == 0) |
|
|
|
|
return ACL_TRIGGER; |
|
|
|
|
|
|
|
|
|
elog(ERROR, "has_table_privilege: invalid privilege type %s", priv_type); |
|
|
|
|
/*
|
|
|
|
|
* We should never get here, but stop the compiler from complaining |
|
|
|
|
*/ |
|
|
|
|
return ACL_NO; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_cname_cname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* char *usename, char *relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
bool |
|
|
|
|
has_table_privilege_cname_cname(char *username, char *relname, text *priv_type_text) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
Oid usesysid = (Oid) -1; |
|
|
|
|
HeapTuple tuple; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Lookup userid based on username |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
tuple = SearchSysCache(SHADOWNAME, NameGetDatum(username), 0, 0, 0); |
|
|
|
|
if (!HeapTupleIsValid(tuple)) { |
|
|
|
|
elog(ERROR, "has_table_privilege: invalid user name %s", (char *) username); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
usesysid = (Oid) ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; |
|
|
|
|
ReleaseSysCache(tuple); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_cname_id |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* char *usename, rel oid, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
bool |
|
|
|
|
has_table_privilege_cname_id(char *username, Oid reloid, text *priv_type_text) |
|
|
|
|
{ |
|
|
|
|
Oid usesysid = (Oid) -1; |
|
|
|
|
char *relname = NULL; |
|
|
|
|
HeapTuple tuple; |
|
|
|
|
bool result; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Lookup userid based on username |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
tuple = SearchSysCache(SHADOWNAME, NameGetDatum(username), 0, 0, 0); |
|
|
|
|
if (!HeapTupleIsValid(tuple)) { |
|
|
|
|
elog(ERROR, "has_table_privilege: invalid user name %s", (char *) username); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
usesysid = (Oid) ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; |
|
|
|
|
|
|
|
|
|
ReleaseSysCache(tuple); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Lookup relname based on rel oid |
|
|
|
|
*/ |
|
|
|
|
tuple = SearchSysCache(RELOID, ObjectIdGetDatum(reloid), 0, 0, 0); |
|
|
|
|
if (!HeapTupleIsValid(tuple)) { |
|
|
|
|
elog(ERROR, "has_table_privilege: invalid relation oid %d", (int) reloid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); |
|
|
|
|
|
|
|
|
|
ReleaseSysCache(tuple); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make use of has_table_privilege_id_cname. |
|
|
|
|
* It accepts the arguments we now have. |
|
|
|
|
*/ |
|
|
|
|
result = has_table_privilege_id_cname(usesysid, relname, priv_type_text); |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* has_table_privilege_id_cname |
|
|
|
|
* Check user privileges on a relation given |
|
|
|
|
* usesysid, char *relname, and text priv name. |
|
|
|
|
* |
|
|
|
|
* RETURNS |
|
|
|
|
* a boolean value |
|
|
|
|
* 't' indicating user has the privilege |
|
|
|
|
* 'f' indicating user does not have the privilege |
|
|
|
|
*/ |
|
|
|
|
bool |
|
|
|
|
has_table_privilege_id_cname(Oid usesysid, char *relname, text *priv_type_text) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
HeapTuple tuple; |
|
|
|
|
AclMode mode; |
|
|
|
|
int32 result; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check relname is valid. |
|
|
|
|
* This is needed to deal with the case when usename is a superuser |
|
|
|
|
* in which case pg_aclcheck simply returns ACLCHECK_OK |
|
|
|
|
* without validating relname |
|
|
|
|
*/ |
|
|
|
|
tuple = SearchSysCache(RELNAME, PointerGetDatum(relname), 0, 0, 0); |
|
|
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tuple)) { |
|
|
|
|
elog(ERROR, "has_table_privilege: invalid relname %s", relname); |
|
|
|
|
} |
|
|
|
|
ReleaseSysCache(tuple); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Convert priv_type_text to an AclMode |
|
|
|
|
*/ |
|
|
|
|
mode = convert_priv_string(priv_type_text); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Finally, check for the privilege |
|
|
|
|
*/ |
|
|
|
|
result = pg_aclcheck(relname, usesysid, mode); |
|
|
|
|
|
|
|
|
|
if (result == ACLCHECK_OK) { |
|
|
|
|
return TRUE; |
|
|
|
|
} else { |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Given a 'text' relname parameter to a function, extract the actual |
|
|
|
|
* relname. We downcase the name if it's not double-quoted, |
|
|
|
|
* and truncate it if it's too long. |
|
|
|
|
* |
|
|
|
|
* This is a kluge, really --- should be able to write, e.g. nextval(seqrel). |
|
|
|
|
*/ |
|
|
|
|
static char * |
|
|
|
|
get_Name(text *relin) |
|
|
|
|
{ |
|
|
|
|
char *rawname = DatumGetCString(DirectFunctionCall1(textout, |
|
|
|
|
PointerGetDatum(relin))); |
|
|
|
|
int rawlen = strlen(rawname); |
|
|
|
|
char *relname; |
|
|
|
|
|
|
|
|
|
if (rawlen >= 2 && |
|
|
|
|
rawname[0] == '\"' && rawname[rawlen - 1] == '\"') |
|
|
|
|
{ |
|
|
|
|
/* strip off quotes, keep case */ |
|
|
|
|
rawname[rawlen - 1] = '\0'; |
|
|
|
|
relname = pstrdup(rawname + 1); |
|
|
|
|
pfree(rawname); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
relname = rawname; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* It's important that this match the identifier downcasing code |
|
|
|
|
* used by backend/parser/scan.l. |
|
|
|
|
*/ |
|
|
|
|
for (; *rawname; rawname++) |
|
|
|
|
{ |
|
|
|
|
if (isupper((unsigned char) *rawname)) |
|
|
|
|
*rawname = tolower((unsigned char) *rawname); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Truncate name if it's overlength; again, should match scan.l */ |
|
|
|
|
if (strlen(relname) >= NAMEDATALEN) |
|
|
|
|
{ |
|
|
|
|
#ifdef MULTIBYTE |
|
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
len = pg_mbcliplen(relname, i, NAMEDATALEN-1); |
|
|
|
|
relname[len] = '\0'; |
|
|
|
|
#else |
|
|
|
|
relname[NAMEDATALEN-1] = '\0'; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return relname; |
|
|
|
|
} |
|
|
|
|