Quick coding question with acl fixes
Hi,
Usually i'd ply away at this one until I figured it out, but we're
running out of time :)
If I have the nspForm variable (which is a Form_pg_namespace) struct
pointer, then how do I check if the nspacl field is default (ie.
"NULL"). This is so I can avoid running DatumGetAclP on it, which seems
to cause alloc error reports.
gdb seems to think it's "$3 = {126}", and that doesn't seem to be NULL
or Datum(0) or anything. Anyone know the answer?
Also, there is an implementation question?
When I run through the acl changing all references from the old owner to
the new owner, should I combine the resulting acls if possible? Because
if the new owner already has some acls on that item, they will end up
with two acls.
Chris
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
If I have the nspForm variable (which is a Form_pg_namespace) struct
pointer, then how do I check if the nspacl field is default (ie.
"NULL"). This is so I can avoid running DatumGetAclP on it, which seems
to cause alloc error reports.
Best practice is to use SysCacheGetAttr if you are dealing with a row
from cache or heap_getattr if it's from a table scan. For instance
in aclchk.c there is
aclDatum = SysCacheGetAttr(NAMESPACENAME, tuple,
Anum_pg_namespace_nspacl,
&isNull);
if (isNull)
old_acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId);
else
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
When I run through the acl changing all references from the old owner to
the new owner, should I combine the resulting acls if possible? Because
if the new owner already has some acls on that item, they will end up
with two acls.
If possible ... how painful would it be to do?
regards, tom lane
Tom Lane <tgl@sss.pgh.pa.us> writes:
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
When I run through the acl changing all references from the old owner to
the new owner, should I combine the resulting acls if possible? Because
if the new owner already has some acls on that item, they will end up
with two acls.
If possible ... how painful would it be to do?
Actually it looks like you'd better, because for example aclupdate
assumes there's only one entry for a given grantor/grantee pair.
BTW, are you sure Fabien did not already solve this problem in his
pending patch?
regards, tom lane
If possible ... how painful would it be to do?
I'm yet to do that part, so I guess I'll find out.
Actually it looks like you'd better, because for example aclupdate
assumes there's only one entry for a given grantor/grantee pair.
OK, many thanks for the prompt reply :)
BTW, are you sure Fabien did not already solve this problem in his
pending patch?
You mean schema ownership? I thought that was just upon the first
connection to a database or something? I'm using schemas as my first
case for fixing OWNER TO commands and acls...
Chris
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
BTW, are you sure Fabien did not already solve this problem in his
pending patch?
You mean schema ownership? I thought that was just upon the first
connection to a database or something?
Yeah, but the point was that he was doing an ALTER OWNER and needed to
fix the ACL to match. I thought he claimed to have written the needed
subroutine. I have not yet looked at his patch though.
regards, tom lane
Yeah, but the point was that he was doing an ALTER OWNER and needed to
fix the ACL to match. I thought he claimed to have written the needed
subroutine. I have not yet looked at his patch though.
I think Fabien's owner changing routine will end up being a strict
subset of my routine. I think his just happens to only work on the
newly created public and info_schema in a new db. It's not complex
enough to work on arbitrary acls. Also, his needs to work as a public
SQL function:
+ /* acl acl_switch_grantor(acl, oldgrantor, newgrantor);
+ * switch grantor id in aclitem array.
+ * used internally for fixing owner rights in new databases.
+ * must be STRICT.
+ */
+ Datum acl_switch_grantor(PG_FUNCTION_ARGS)
+ {
+ Acl * acls = PG_GETARG_ACL_P_COPY(0);
+ int i,
+ old_grantor = PG_GETARG_INT32(1),
+ new_grantor = PG_GETARG_INT32(2);
+ AclItem * item;
+
+ for (i=0, item=ACL_DAT(acls); i<ACL_NUM(acls); i++, item++)
+ if (item->ai_grantor == old_grantor)
+ item->ai_grantor = new_grantor;
+
+ PG_RETURN_ACL_P(acls);
+ }
Chris
When I run through the acl changing all references from the old owner to
the new owner, should I combine the resulting acls if possible? Because
if the new owner already has some acls on that item, they will end up
with two acls.If possible ... how painful would it be to do?
I'm pretty close to finishing this. Just applying it to all the
acl'able objects atm. It's a pain when you can only find 15 mins every
other day to work on it :(
Chris