diff -Naur pgsql.virg/src/backend/utils/adt/acl.c pgsql.dev/src/backend/utils/adt/acl.c --- pgsql.virg/src/backend/utils/adt/acl.c Sat Jun 9 23:21:55 2001 +++ pgsql.dev/src/backend/utils/adt/acl.c Sun Jun 10 02:10:34 2001 @@ -31,6 +31,12 @@ 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" @@ -709,4 +715,753 @@ ret = pstrdup(str.data); 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; } diff -Naur pgsql.virg/src/include/catalog/pg_proc.h pgsql.dev/src/include/catalog/pg_proc.h --- pgsql.virg/src/include/catalog/pg_proc.h Sun Jun 10 01:59:22 2001 +++ pgsql.dev/src/include/catalog/pg_proc.h Sat Jun 9 20:44:39 2001 @@ -2627,6 +2627,35 @@ DATA(insert OID = 1915 ( numeric_uplus PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100 numeric_uplus - )); DESCR("unary plus"); +DATA(insert OID = 1920 ( has_table_privilege PGUID 12 f t f t 3 f 16 "25 25 25" 100 0 0 100 has_table_privilege_tname_tname - )); +DESCR("user privilege on relation by text username, text relname"); +DATA(insert OID = 1921 ( has_table_privilege PGUID 12 f t f t 3 f 16 "25 19 25" 100 0 0 100 has_table_privilege_tname_name - )); +DESCR("user privilege on relation by text username, name relname"); +DATA(insert OID = 1922 ( has_table_privilege PGUID 12 f t f t 3 f 16 "19 25 25" 100 0 0 100 has_table_privilege_name_tname - )); +DESCR("user privilege on relation by name username, text relname"); +DATA(insert OID = 1923 ( has_table_privilege PGUID 12 f t f t 3 f 16 "19 19 25" 100 0 0 100 has_table_privilege_name_name - )); +DESCR("user privilege on relation by name username, name relname"); +DATA(insert OID = 1924 ( has_table_privilege PGUID 12 f t f t 2 f 16 "25 25" 100 0 0 100 has_table_privilege_tname - )); +DESCR("current user privilege on relation by text relname"); +DATA(insert OID = 1925 ( has_table_privilege PGUID 12 f t f t 2 f 16 "19 25" 100 0 0 100 has_table_privilege_name - )); +DESCR("current user privilege on relation by name relname"); + +DATA(insert OID = 1926 ( has_table_privilege PGUID 12 f t f t 3 f 16 "25 26 25" 100 0 0 100 has_table_privilege_tname_id - )); +DESCR("user privilege on relation by text username, rel oid"); +DATA(insert OID = 1927 ( has_table_privilege PGUID 12 f t f t 3 f 16 "19 26 25" 100 0 0 100 has_table_privilege_name_id - )); +DESCR("user privilege on relation by text username, rel oid"); +DATA(insert OID = 1928 ( has_table_privilege PGUID 12 f t f t 2 f 16 "26 25" 100 0 0 100 has_table_privilege_id - )); +DESCR("current user privilege on relation by rel oid"); + +DATA(insert OID = 1929 ( has_table_privilege PGUID 12 f t f t 3 f 16 "26 25 25" 100 0 0 100 has_table_privilege_id_tname - )); +DESCR("user privilege on relation by usesysid, relname"); +DATA(insert OID = 1930 ( has_table_privilege PGUID 12 f t f t 3 f 16 "26 19 25" 100 0 0 100 has_table_privilege_id_name - )); +DESCR("user privilege on relation by usesysid, relname"); + +DATA(insert OID = 1931 ( has_table_privilege PGUID 12 f t f t 3 f 16 "26 26 25" 100 0 0 100 has_table_privilege_id_id - )); +DESCR("user privilege on relation by usesysid, rel oid"); + + /* * prototypes for functions pg_proc.c */ diff -Naur pgsql.virg/src/include/utils/acl.h pgsql.dev/src/include/utils/acl.h --- pgsql.virg/src/include/utils/acl.h Sun Jun 10 01:59:24 2001 +++ pgsql.dev/src/include/utils/acl.h Sun Jun 10 00:47:42 2001 @@ -193,6 +193,22 @@ extern Datum aclcontains(PG_FUNCTION_ARGS); extern void ExecuteChangeACLStmt(ChangeACLStmt *stmt); +extern Datum has_table_privilege_tname_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_tname_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_tname_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_id_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS); + /* * prototypes for functions in aclchk.c */ diff -Naur pgsql.virg/src/include/utils/builtins.h pgsql.dev/src/include/utils/builtins.h --- pgsql.virg/src/include/utils/builtins.h Sun Jun 10 01:59:26 2001 +++ pgsql.dev/src/include/utils/builtins.h Sat Jun 9 20:34:02 2001 @@ -22,6 +22,24 @@ /* * Defined in adt/ */ + +/* acl.c */ +extern Datum has_table_privilege_tname_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_tname_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_tname_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_id_tname(PG_FUNCTION_ARGS); +extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS); + +extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS); + /* bool.c */ extern Datum boolin(PG_FUNCTION_ARGS); extern Datum boolout(PG_FUNCTION_ARGS); diff -Naur pgsql.virg/src/test/regress/expected/has_table_priv.out pgsql.dev/src/test/regress/expected/has_table_priv.out --- pgsql.virg/src/test/regress/expected/has_table_priv.out Thu Jan 1 00:00:00 1970 +++ pgsql.dev/src/test/regress/expected/has_table_priv.out Sun Jun 10 00:27:38 2001 @@ -0,0 +1,479 @@ +\connect - postgres + +-- +-- user postgres, NULL input +-- + +select has_table_privilege(NULL,'pg_shadow','select'); + has_table_privilege +--------------------- + +(1 row) + + +-- +-- user postgres, bad relname +-- + +select has_table_privilege('postgres','pg_shad','select'); +ERROR: has_table_privilege: invalid relname pg_shad + +-- +-- user postgres, bad usename +-- + +select has_table_privilege('post','pg_shadow','select'); +ERROR: has_table_privilege: invalid user name post + +-- +-- user postgres, bad priv_type +-- + +select has_table_privilege('postgres','pg_shadow','sel'); +ERROR: has_table_privilege: invalid privilege type sel + +-- +-- user postgres, bad usesysid +-- + +select has_table_privilege(-999999,'pg_shadow','update'); +ERROR: pg_aclcheck: invalid user id 4293967297 + +-- +-- user postgres, bad rel oid +-- + +select has_table_privilege('postgres',-999999,'rule'); +ERROR: has_table_privilege: invalid relation oid -999999 + +-- +-- user postgres, rel pg_shadow +-- + +select has_table_privilege('postgres','pg_shadow','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('postgres','pg_shadow','insert'); + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t2.usesysid,'pg_shadow','update') from (select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,'pg_shadow','delete') from (select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_shadow') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'pg_shadow') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege('pg_shadow','update'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('pg_shadow','delete'); + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_shadow') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +-- +-- create rel testtable +-- + +create table testtable(f1 int, f2 text); + +-- +-- user postgres, rel testtable +-- + +select has_table_privilege('postgres','TESTtable','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('postgres','TESTtable','insert'); + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege('testtable','update'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('testtable','delete'); + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +-- +-- create new user, grant on testtable, and connect +-- + +create user foo; +grant select on testtable to foo; +grant update on testtable to foo; +grant rule on testtable to foo; +\connect - foo + +-- +-- user foo, rel pg_shadow +-- + +select has_table_privilege('foo','pg_class','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('foo','pg_class','insert'); + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t2.usesysid,'pg_class','update') from (select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege(t2.usesysid,'pg_class','delete') from (select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_class') as t1; + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'pg_class') as t1; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege('pg_class','update'); + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('pg_class','delete'); + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_class') as t1; + has_table_privilege +--------------------- + f +(1 row) + + +-- +-- user foo, rel testtable +-- + +select has_table_privilege('foo','testtable','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('foo','testtable','insert'); + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege('testtable','update'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('testtable','delete'); + has_table_privilege +--------------------- + f +(1 row) + + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1; + has_table_privilege +--------------------- + f +(1 row) + + +-- +-- create rel "Quoted RelName" +-- + +\connect - postgres +create table "Quoted RelName" (f1 int, f2 text); + +-- +-- user postgres, rel "Quoted RelName", name based variants +-- + +select has_table_privilege('postgres','"Quoted RelName"','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('postgres',t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.usename,'"Quoted RelName"','select') from (select usename from pg_user where usename = 'postgres') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.usename,t2.relname,'select') from (select usename from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('"Quoted RelName"','select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.usename,t2.oid,'rule') from (select usename from pg_user where usename = 'postgres') as t1, (select oid from pg_class where relname = 'Quoted RelName') as t2; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1; + has_table_privilege +--------------------- + t +(1 row) + + +select has_table_privilege(t1.usesysid,'"Quoted RelName"','select') from (select usesysid from pg_user where usename = 'postgres') as t1; + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege(t1.usesysid,t2.relname,'select') from (select usesysid from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2; + has_table_privilege +--------------------- + t +(1 row) + + +-- +-- Clean up +-- + +drop user foo; +drop table testtable; +drop table "Quoted RelName"; diff -Naur pgsql.virg/src/test/regress/parallel_schedule pgsql.dev/src/test/regress/parallel_schedule --- pgsql.virg/src/test/regress/parallel_schedule Sun Jun 10 01:59:42 2001 +++ pgsql.dev/src/test/regress/parallel_schedule Sat Jun 9 20:08:18 2001 @@ -62,6 +62,7 @@ test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index test: privileges +test: has_table_priv test: misc # ---------- diff -Naur pgsql.virg/src/test/regress/serial_schedule pgsql.dev/src/test/regress/serial_schedule --- pgsql.virg/src/test/regress/serial_schedule Sun Jun 10 01:59:43 2001 +++ pgsql.dev/src/test/regress/serial_schedule Sat Jun 9 19:50:29 2001 @@ -69,6 +69,7 @@ test: btree_index test: hash_index test: privileges +test: has_table_priv test: misc test: select_views test: alter_table diff -Naur pgsql.virg/src/test/regress/sql/has_table_priv.sql pgsql.dev/src/test/regress/sql/has_table_priv.sql --- pgsql.virg/src/test/regress/sql/has_table_priv.sql Thu Jan 1 00:00:00 1970 +++ pgsql.dev/src/test/regress/sql/has_table_priv.sql Sun Jun 10 00:59:52 2001 @@ -0,0 +1,174 @@ +\connect - postgres + +-- +-- user postgres, NULL input +-- + +select has_table_privilege(NULL,'pg_shadow','select'); + +-- +-- user postgres, bad relname +-- + +select has_table_privilege('postgres','pg_shad','select'); + +-- +-- user postgres, bad usename +-- + +select has_table_privilege('post','pg_shadow','select'); + +-- +-- user postgres, bad priv_type +-- + +select has_table_privilege('postgres','pg_shadow','sel'); + +-- +-- user postgres, bad usesysid +-- + +select has_table_privilege(-999999,'pg_shadow','update'); + +-- +-- user postgres, bad rel oid +-- + +select has_table_privilege('postgres',-999999,'rule'); + +-- +-- user postgres, rel pg_shadow +-- + +select has_table_privilege('postgres','pg_shadow','select'); +select has_table_privilege('postgres','pg_shadow','insert'); + +select has_table_privilege(t2.usesysid,'pg_shadow','update') from (select usesysid from pg_user where usename = 'postgres') as t2; +select has_table_privilege(t2.usesysid,'pg_shadow','delete') from (select usesysid from pg_user where usename = 'postgres') as t2; + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_shadow') as t1; +select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'pg_shadow') as t1; + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + +select has_table_privilege('pg_shadow','update'); +select has_table_privilege('pg_shadow','delete'); + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1; +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_shadow') as t1; + +-- +-- create rel testtable +-- + +create table testtable(f1 int, f2 text); + +-- +-- user postgres, rel testtable +-- + +select has_table_privilege('postgres','TESTtable','select'); +select has_table_privilege('postgres','TESTtable','insert'); + +select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'postgres') as t2; +select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'postgres') as t2; + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; +select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1; + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2; + +select has_table_privilege('testtable','update'); +select has_table_privilege('testtable','delete'); + +select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1; + +-- +-- create new user, grant on testtable, and connect +-- + +create user foo; +grant select on testtable to foo; +grant update on testtable to foo; +grant rule on testtable to foo; +\connect - foo + +-- +-- user foo, rel pg_shadow +-- + +select has_table_privilege('foo','pg_class','select'); +select has_table_privilege('foo','pg_class','insert'); + +select has_table_privilege(t2.usesysid,'pg_class','update') from (select usesysid from pg_user where usename = 'foo') as t2; +select has_table_privilege(t2.usesysid,'pg_class','delete') from (select usesysid from pg_user where usename = 'foo') as t2; + +select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_class') as t1; +select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'pg_class') as t1; + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2; +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + +select has_table_privilege('pg_class','update'); +select has_table_privilege('pg_class','delete'); + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1; +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_class') as t1; + +-- +-- user foo, rel testtable +-- + +select has_table_privilege('foo','testtable','select'); +select has_table_privilege('foo','testtable','insert'); + +select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'foo') as t2; +select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'foo') as t2; + +select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1; +select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1; + +select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2; +select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2; + +select has_table_privilege('testtable','update'); +select has_table_privilege('testtable','delete'); + +select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1; +select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1; + +-- +-- create rel "Quoted RelName" +-- + +\connect - postgres +create table "Quoted RelName" (f1 int, f2 text); + +-- +-- user postgres, rel "Quoted RelName", name based variants +-- + +select has_table_privilege('postgres','"Quoted RelName"','select'); +select has_table_privilege('postgres',t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1; +select has_table_privilege(t1.usename,'"Quoted RelName"','select') from (select usename from pg_user where usename = 'postgres') as t1; +select has_table_privilege(t1.usename,t2.relname,'select') from (select usename from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2; +select has_table_privilege('"Quoted RelName"','select'); +select has_table_privilege(t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1; + +select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1; +select has_table_privilege(t1.usename,t2.oid,'rule') from (select usename from pg_user where usename = 'postgres') as t1, (select oid from pg_class where relname = 'Quoted RelName') as t2; +select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1; + +select has_table_privilege(t1.usesysid,'"Quoted RelName"','select') from (select usesysid from pg_user where usename = 'postgres') as t1; +select has_table_privilege(t1.usesysid,t2.relname,'select') from (select usesysid from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2; + +-- +-- Clean up +-- + +drop user foo; +drop table testtable; +drop table "Quoted RelName";