Thread: Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
> > > > > > > > > Update of /usr/local/cvsroot/pgsql/src/bin/initdb > > > In directory hub.org:/tmp/cvs-serv23999/bin/initdb > > > > > > Modified Files: > > > initdb.sh > > > Log Message: > > > > > > Modify initdb.sh so that it makes pg_user readable through view db_user > > > Modify psql so that it uses db_user instead of pg_user > > > GRANT SELECT on pg_class > > > > I don't know if I like the new name db_user? What do other people > > think? I thought pg_user_no_pwd would be nice. > > > create view pg_users as ... > ERROR: Illegal class name: pg_users -- pg_ is reserved for system catalogs Oops, yep. I guess I just liked that the pg_ stuff was all system stuff. Do you get this error when creating it from postgres, as initdb does? That would be a solution. Worked here. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
On Mon, 23 Feb 1998, Bruce Momjian wrote: > > > > > > > > > > > > > Update of /usr/local/cvsroot/pgsql/src/bin/initdb > > > > In directory hub.org:/tmp/cvs-serv23999/bin/initdb > > > > > > > > Modified Files: > > > > initdb.sh > > > > Log Message: > > > > > > > > Modify initdb.sh so that it makes pg_user readable through view db_user > > > > Modify psql so that it uses db_user instead of pg_user > > > > GRANT SELECT on pg_class > > > > > > I don't know if I like the new name db_user? What do other people > > > think? I thought pg_user_no_pwd would be nice. > > > > > > create view pg_users as ... > > ERROR: Illegal class name: pg_users -- pg_ is reserved for system catalogs > > Oops, yep. > > I guess I just liked that the pg_ stuff was all system stuff. Do you > get this error when creating it from postgres, as initdb does? That > would be a solution. Worked here. My thought was more splitting the difference between a system table (pg_) vs system view (db_) *shrug* Okay, I was grasping here :)
> > > > > > create view pg_users as ... > > > ERROR: Illegal class name: pg_users -- pg_ is reserved for system catalogs > > > > Oops, yep. > > > > I guess I just liked that the pg_ stuff was all system stuff. Do you > > get this error when creating it from postgres, as initdb does? That > > would be a solution. Worked here. > > My thought was more splitting the difference between a system > table (pg_) vs system view (db_) *shrug* Okay, I was grasping here :) > > > I am afraid the db_user is going to confuse people, and they are going to start asking how it got there, or they are going to delete it and ask why \d doesn't work. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
> > > I don't know if I like the new name db_user? What do other people > > > think? I thought pg_user_no_pwd would be nice. > > > > > > create view pg_users as ... > > ERROR: Illegal class name: pg_users -- pg_ is reserved for system catalogs > > Oops, yep. > > I guess I just liked that the pg_ stuff was all system stuff. Do you > get this error when creating it from postgres, as initdb does? That > would be a solution. Worked here. even if running postgres directly from pgsql account. But I think it's right to have views/tables named db_ or sys_ too. Other RDBMS's have them too (Oracle). And I don't know if ALL the places where IsSystemRelationName() is used are happy with things that in fact aren't really hardwired system catalogs. Just let's choose one prefix for all of them and use that then. Maybe we would like to restrict the use of this prefix to superusers only. As I think there could be more information in the catalogs that we want to hide from users in the future, a group of db_ views, where all the completely open catalogs are just mapped by SELECT * wouldn't be a bad idea. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
> > > > > I don't know if I like the new name db_user? What do other people > > > > think? I thought pg_user_no_pwd would be nice. > > > > > > > > > create view pg_users as ... > > > ERROR: Illegal class name: pg_users -- pg_ is reserved for system catalogs > > > > Oops, yep. > > > > I guess I just liked that the pg_ stuff was all system stuff. Do you > > get this error when creating it from postgres, as initdb does? That > > would be a solution. Worked here. > > even if running postgres directly from pgsql account. Here's what I did: echo 'create view pg_x as select * from pg_user' |aspg postgres -F -Q -D /u/pg/data template1 I am suggesting we do this in initdb, just like the others. > > But I think it's right to have views/tables named db_ > or sys_ too. Other RDBMS's have them too (Oracle). > > And I don't know if ALL the places where IsSystemRelationName() > is used are happy with things that in fact aren't really > hardwired system catalogs. > > Just let's choose one prefix for all of them and use > that then. Maybe we would like to restrict the use of > this prefix to superusers only. As I think there could > be more information in the catalogs that we want to > hide from users in the future, a group of db_ views, > where all the completely open catalogs are just mapped > by SELECT * wouldn't be a bad idea. Can I suggest pgview_ then? Another problem is that a \d on an empty database, \d is going to show this view, isn't it. Kind of strange to me. I have a solution. Create the view in initdb as pguser_no_pwd, then after that execute an update statement on pg_class: update pg_class set relname = 'pg_user_no_pwd' where relname = 'pguser_no_pwd'; We are using Jan's cache fix already. I just tried it and it works. And it means it doesn't show up in \d, and a user can't accidentally delete it. Sounds like a real winner. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
On Mon, 23 Feb 1998, Bruce Momjian wrote: > > Can I suggest pgview_ then? Another problem is that a \d on an empty > database, \d is going to show this view, isn't it. Kind of strange to > me. I modified psql already such that: relname !~ '^[pd][bg]_' is ignored :) Marc G. Fournier Systems Administrator @ hub.org primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org
> > On Mon, 23 Feb 1998, Bruce Momjian wrote: > > > > > Can I suggest pgview_ then? Another problem is that a \d on an empty > > database, \d is going to show this view, isn't it. Kind of strange to > > me. > > I modified psql already such that: > > relname !~ '^[pd][bg]_' > > is ignored :) I still disagree. Why not keep the system stuff pg_? This can be done, and it keeps things consistent. The above check also finds pb_ and dg_. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
The Hermit Hacker wrote: > > On Mon, 23 Feb 1998, Bruce Momjian wrote: > > > > > Can I suggest pgview_ then? Another problem is that a \d on an empty > > database, \d is going to show this view, isn't it. Kind of strange to > > me. > > I modified psql already such that: > > relname !~ '^[pd][bg]_' > > is ignored :) Are pb_, db_, dg_ system prefixes now and user can't CREATE TABLE dg_i_like_this_name... ? Vadim
On Mon, 23 Feb 1998, Bruce Momjian wrote: > > > > On Mon, 23 Feb 1998, Bruce Momjian wrote: > > > > > > > > Can I suggest pgview_ then? Another problem is that a \d on an empty > > > database, \d is going to show this view, isn't it. Kind of strange to > > > me. > > > > I modified psql already such that: > > > > relname !~ '^[pd][bg]_' > > > > is ignored :) > > I still disagree. Why not keep the system stuff pg_? This can be done, > and it keeps things consistent. The above check also finds pb_ and dg_. Actually, I'm not married to db_* for views...it was a "quick fix" to ensure that things still worked. Whatever we decide on, both Julie and Peter, at a minimum, need to know relatively soon. I know in Julie's case, she does do a call to pg_user...I let her know tonight that she needs to change it to db_user, for the *current* code... Marc G. Fournier Systems Administrator @ hub.org primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
Bruce wrote: > > And I don't know if ALL the places where IsSystemRelationName() > > is used are happy with things that in fact aren't really > > hardwired system catalogs. > > Can I suggest pgview_ then? Another problem is that a \d on an empty > database, \d is going to show this view, isn't it. Kind of strange to > me. > > I have a solution. Create the view in initdb as pguser_no_pwd, then > after that execute an update statement on pg_class: > > update pg_class > set relname = 'pg_user_no_pwd' > where relname = 'pguser_no_pwd'; > > We are using Jan's cache fix already. I just tried it and it works. > And it means it doesn't show up in \d, and a user can't accidentally > delete it. Sounds like a real winner. Sounds really good - if we can be sure that the pg_ prefix of a view never collides with the IsSystemRelationName() tests somewhere (there are many). You got me. Let's leave all postgres specific stuff in pg_*. But as it was done in most UN*X's, could we rename the pg_user containing the password into pg_shadow and then create a view pg_user that just stars out the password field? This way no existing application code (not even the JDBC etc.) needs any changes, except for the createuser etc. tools that always get installed with the new release. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
I wrote: > > > Bruce wrote: > > > > I have a solution. Create the view in initdb as pguser_no_pwd, then > > after that execute an update statement on pg_class: > > > > update pg_class > > set relname = 'pg_user_no_pwd' > > where relname = 'pguser_no_pwd'; > > > > We are using Jan's cache fix already. I just tried it and it works. > > And it means it doesn't show up in \d, and a user can't accidentally > > delete it. Sounds like a real winner. > > Sounds really good - if we can be sure that the pg_ prefix of > a view never collides with the IsSystemRelationName() tests > somewhere (there are many). You got me. Let's leave all > postgres specific stuff in pg_*. But here it doesn't work. The backend crashes during the rewriting since something doesn't match any longer. Here's another solution that also asures that the views select rule is created with the correct varno names and that the rule itself is named as expected: CREATE TABLE xpg_usr ( usename name, usesysid int4, usecreatedb bool, usetrace bool, usesuper bool, usecatupd bool, passwd text, valuntil abstime); UPDATE pg_class SET relname = 'pg_usr' WHERE relname = 'xpg_usr'; CREATE RULE _RETpg_usr AS ON SELECT TO pg_usr DO INSTEAD SELECT usename, usesysid, usecreatedb, usetrace, usesuper, usecatupd, '********'::text as passwd, valuntil FROM pg_user; REVOKE ALL ON pg_user FROM public; It doesn't look that elegant as creating a view with SELECT * and another rule that hides the password. But this seems to be the only way to create a view with a pg_ name cleanly. The GRANT on pg_class in current initdb.sh is obsolete (change of acldefault() return value). And if the public pg_usr view has the pg_ prefix, there is no need for an explicit grant on that too. A comment in pg_user.h should remind us to update initdb.sh when the structure of pg_user is to be changed. But since changes to system catalogs require dump/reload releases, I expect we will have a beta phase. And during that those things will likely show up and can easy get fixed. > > But as it was done in most UN*X's, could we rename the > pg_user containing the password into pg_shadow and then > create a view pg_user that just stars out the password field? > This way no existing application code (not even the JDBC > etc.) needs any changes, except for the createuser etc. > tools that always get installed with the new release. Still vote for this. And as soon as we finally choose one name for the public pg_user view we must fix createuser.sh, createdb.sh and so on to make their checks on the public accessible view so they still print the proper error messages instead of ERROR: pg_user: Permission denied. createuser: database access failed. Only createuser/destroyuser need to access the real user catalog on the insert/delete. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
On Tue, 24 Feb 1998, Jan Wieck wrote: > CREATE TABLE xpg_usr ( > usename name, > usesysid int4, > usecreatedb bool, > usetrace bool, > usesuper bool, > usecatupd bool, > passwd text, > valuntil abstime); > > UPDATE pg_class SET relname = 'pg_usr' > WHERE relname = 'xpg_usr'; > > CREATE RULE _RETpg_usr AS ON SELECT TO pg_usr > DO INSTEAD > SELECT usename, usesysid, usecreatedb, > usetrace, usesuper, usecatupd, > '********'::text as passwd, valuntil > FROM pg_user; > > REVOKE ALL ON pg_user FROM public; Okay, just so that I don't mess things up in the translation...do you want to send me an appropriate patch for this? > > But as it was done in most UN*X's, could we rename the > > pg_user containing the password into pg_shadow and then > > create a view pg_user that just stars out the password field? > > This way no existing application code (not even the JDBC > > etc.) needs any changes, except for the createuser etc. > > tools that always get installed with the new release. > > Still vote for this. And as soon as we finally choose one > name for the public pg_user view we must fix createuser.sh, > createdb.sh and so on to make their checks on the public > accessible view so they still print the proper error messages > instead of No arguments here...can you include this as part of your patch too?
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
> > On Tue, 24 Feb 1998, Jan Wieck wrote: > > > CREATE TABLE xpg_usr ( > > usename name, > > usesysid int4, > > usecreatedb bool, > > usetrace bool, > > usesuper bool, > > usecatupd bool, > > passwd text, > > valuntil abstime); > > > > UPDATE pg_class SET relname = 'pg_usr' > > WHERE relname = 'xpg_usr'; > > > > CREATE RULE _RETpg_usr AS ON SELECT TO pg_usr > > DO INSTEAD > > SELECT usename, usesysid, usecreatedb, > > usetrace, usesuper, usecatupd, > > '********'::text as passwd, valuntil > > FROM pg_user; > > > > REVOKE ALL ON pg_user FROM public; > > Okay, just so that I don't mess things up in the translation...do > you want to send me an appropriate patch for this? > > > > But as it was done in most UN*X's, could we rename the > > > pg_user containing the password into pg_shadow and then > > > create a view pg_user that just stars out the password field? > > > This way no existing application code (not even the JDBC > > > etc.) needs any changes, except for the createuser etc. > > > tools that always get installed with the new release. > > > > Still vote for this. And as soon as we finally choose one > > name for the public pg_user view we must fix createuser.sh, > > createdb.sh and so on to make their checks on the public > > accessible view so they still print the proper error messages > > instead of > > No arguments here...can you include this as part of your patch > too? Will do so. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
> Actually, I'm not married to db_* for views...it was a "quick fix" > to ensure that things still worked. Whatever we decide on, both Julie and > Peter, at a minimum, need to know relatively soon. I know in Julie's > case, she does do a call to pg_user...I let her know tonight that she > needs to change it to db_user, for the *current* code... Good. I didn't want the db_ namespace pollution. I will call it pg_user_no_passwd, and make it a view, not a rule. Is that OK with everyone? Are the only things you changed psql.c and initdb.sh? -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
On Tue, 24 Feb 1998, Bruce Momjian wrote: > > Actually, I'm not married to db_* for views...it was a "quick fix" > > to ensure that things still worked. Whatever we decide on, both Julie and > > Peter, at a minimum, need to know relatively soon. I know in Julie's > > case, she does do a call to pg_user...I let her know tonight that she > > needs to change it to db_user, for the *current* code... > > Good. I didn't want the db_ namespace pollution. I will call it > pg_user_no_passwd, and make it a view, not a rule. Is that OK with > everyone? Works for me... > Are the only things you changed psql.c and initdb.sh? Yes...
> > We are using Jan's cache fix already. I just tried it and it works. > > And it means it doesn't show up in \d, and a user can't accidentally > > delete it. Sounds like a real winner. > > Sounds really good - if we can be sure that the pg_ prefix of > a view never collides with the IsSystemRelationName() tests > somewhere (there are many). You got me. Let's leave all > postgres specific stuff in pg_*. OK, we are basically creating it with a different name, then moving in into the pg_ namespace with UPDATE pg_class. > But as it was done in most UN*X's, could we rename the > pg_user containing the password into pg_shadow and then > create a view pg_user that just stars out the password field? > This way no existing application code (not even the JDBC > etc.) needs any changes, except for the createuser etc. > tools that always get installed with the new release. The only problem with that is that the database administrator now should deal with pg_shadow, and not pg_user, and pg_user is not a real table anymore. Actually, in Unix, this is true too. I don't think we can change the real table to pg_shadow this close to a release, can we? -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
> > On Tue, 24 Feb 1998, Bruce Momjian wrote: > > > > Actually, I'm not married to db_* for views...it was a "quick fix" > > > to ensure that things still worked. Whatever we decide on, both Julie and > > > Peter, at a minimum, need to know relatively soon. I know in Julie's > > > case, she does do a call to pg_user...I let her know tonight that she > > > needs to change it to db_user, for the *current* code... > > > > Good. I didn't want the db_ namespace pollution. I will call it > > pg_user_no_passwd, and make it a view, not a rule. Is that OK with > > everyone? > > Works for me... How? When I create a view the way Bruce explained (update pg_class), my backend crashes on SELECT FROM view during the rewrite. For some reason the rewrite handler cannot get the rule locks correctly. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
On Tue, 24 Feb 1998, Jan Wieck wrote: > > > > On Tue, 24 Feb 1998, Bruce Momjian wrote: > > > > > > Actually, I'm not married to db_* for views...it was a "quick fix" > > > > to ensure that things still worked. Whatever we decide on, both Julie and > > > > Peter, at a minimum, need to know relatively soon. I know in Julie's > > > > case, she does do a call to pg_user...I let her know tonight that she > > > > needs to change it to db_user, for the *current* code... > > > > > > Good. I didn't want the db_ namespace pollution. I will call it > > > pg_user_no_passwd, and make it a view, not a rule. Is that OK with > > > everyone? > > > > Works for me... > > How? When I create a view the way Bruce explained (update pg_class), > my backend crashes on SELECT FROM view during the rewrite. For some > reason the rewrite handler cannot get the rule locks correctly. Ppl are taking me a slight bit too literally :( "Works for me"...I like the idea...not necessarily implemented it though :)
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
> > On Tue, 24 Feb 1998, Jan Wieck wrote: > > > > > > > On Tue, 24 Feb 1998, Bruce Momjian wrote: > > > > > > > > Actually, I'm not married to db_* for views...it was a "quick fix" > > > > > to ensure that things still worked. Whatever we decide on, both Julie and > > > > > Peter, at a minimum, need to know relatively soon. I know in Julie's > > > > > case, she does do a call to pg_user...I let her know tonight that she > > > > > needs to change it to db_user, for the *current* code... > > > > > > > > Good. I didn't want the db_ namespace pollution. I will call it > > > > pg_user_no_passwd, and make it a view, not a rule. Is that OK with > > > > everyone? > > > > > > Works for me... > > > > How? When I create a view the way Bruce explained (update pg_class), > > my backend crashes on SELECT FROM view during the rewrite. For some > > reason the rewrite handler cannot get the rule locks correctly. > > Ppl are taking me a slight bit too literally :( "Works for > me"...I like the idea...not necessarily implemented it though :) I already have the pg_shadow + pg_user-view diff ready. Works really! Must run a regression test and send it after that succeeded. It updates createuser, destroyuser and initdb too. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) #
Re: [HACKERS] Re: [COMMITTERS] 'pgsql/src/bin/initdb initdb.sh'
From
jwieck@debis.com (Jan Wieck)
Date:
Bruce wrote: > > > But as it was done in most UN*X's, could we rename the > > pg_user containing the password into pg_shadow and then > > create a view pg_user that just stars out the password field? > > This way no existing application code (not even the JDBC > > etc.) needs any changes, except for the createuser etc. > > tools that always get installed with the new release. > > The only problem with that is that the database administrator now should > deal with pg_shadow, and not pg_user, and pg_user is not a real table > anymore. Actually, in Unix, this is true too. I don't think we can > change the real table to pg_shadow this close to a release, can we? We can. Here it is. ALL regression tests except for float8 and geometry (only fp differences - diffs checked) passed 'ok'. Checked that createuser and destroyuser work. This patch changes the catalog pg_user into pg_shadow and creates a view pg_user that definitely works. Oridinary user cannot access pg_shadow. Since your greatest need (to stay with all system stuff named pg_) is met, you might like it too. Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) # diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/catalog/Makefile ./backend/catalog/Makefile *** /usr/local/pgsql/sup/pgsql/src/backend/catalog/Makefile Wed Jan 7 13:36:12 1998 --- ./backend/catalog/Makefile Tue Feb 24 14:25:33 1998 *************** *** 27,33 **** GENBKI= ./genbki.sh GLOBALBKI_SRCS= $(addprefix ../../include/catalog/, \ ! pg_database.h pg_variable.h pg_user.h \ pg_group.h pg_log.h \ ) --- 27,33 ---- GENBKI= ./genbki.sh GLOBALBKI_SRCS= $(addprefix ../../include/catalog/, \ ! pg_database.h pg_variable.h pg_shadow.h \ pg_group.h pg_log.h \ ) diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/catalog/aclchk.c ./backend/catalog/aclchk.c *** /usr/local/pgsql/sup/pgsql/src/backend/catalog/aclchk.c Tue Feb 24 10:22:24 1998 --- ./backend/catalog/aclchk.c Tue Feb 24 14:54:08 1998 *************** *** 32,38 **** #include "catalog/pg_aggregate.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" ! #include "catalog/pg_user.h" #include "parser/parse_agg.h" #include "parser/parse_func.h" #include "utils/syscache.h" --- 32,38 ---- #include "catalog/pg_aggregate.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" ! #include "catalog/pg_shadow.h" #include "parser/parse_agg.h" #include "parser/parse_func.h" #include "utils/syscache.h" *************** *** 396,409 **** if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_aclcheck: user \"%s\" not found", usename); ! id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid; /* * for the 'pg_database' relation, check the usecreatedb field before * checking normal permissions */ if (strcmp(DatabaseRelationName, relname) == 0 && ! (((Form_pg_user) GETSTRUCT(htp))->usecreatedb)) { /* --- 396,409 ---- if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_aclcheck: user \"%s\" not found", usename); ! id = (AclId) ((Form_pg_shadow) GETSTRUCT(htp))->usesysid; /* * for the 'pg_database' relation, check the usecreatedb field before * checking normal permissions */ if (strcmp(DatabaseRelationName, relname) == 0 && ! (((Form_pg_shadow) GETSTRUCT(htp))->usecreatedb)) { /* *************** *** 417,428 **** /* * Deny anyone permission to update a system catalog unless ! * pg_user.usecatupd is set. (This is to let superusers protect * themselves from themselves.) */ if (((mode & ACL_WR) || (mode & ACL_AP)) && IsSystemRelationName(relname) && ! !((Form_pg_user) GETSTRUCT(htp))->usecatupd) { elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied", relname); --- 417,428 ---- /* * Deny anyone permission to update a system catalog unless ! * pg_shadow.usecatupd is set. (This is to let superusers protect * themselves from themselves.) */ if (((mode & ACL_WR) || (mode & ACL_AP)) && IsSystemRelationName(relname) && ! !((Form_pg_shadow) GETSTRUCT(htp))->usecatupd) { elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied", relname); *************** *** 432,438 **** /* * Otherwise, superusers bypass all permission-checking. */ ! if (((Form_pg_user) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_aclcheck: \"%s\" is superuser", --- 432,438 ---- /* * Otherwise, superusers bypass all permission-checking. */ ! if (((Form_pg_shadow) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_aclcheck: \"%s\" is superuser", *************** *** 531,542 **** if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_user) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", --- 531,542 ---- if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_shadow) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_shadow) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", *************** *** 597,608 **** if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_func_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_user) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", --- 597,608 ---- if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_func_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_shadow) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_shadow) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser", *************** *** 638,649 **** if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_aggr_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_user) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser", --- 638,649 ---- if (!HeapTupleIsValid(htp)) elog(ERROR, "pg_aggr_ownercheck: user \"%s\" not found", usename); ! user_id = (AclId) ((Form_pg_shadow) GETSTRUCT(htp))->usesysid; /* * Superusers bypass all permission-checking. */ ! if (((Form_pg_shadow) GETSTRUCT(htp))->usesuper) { #ifdef ACLDEBUG_TRACE elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser", diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/commands/copy.c ./backend/commands/copy.c *** /usr/local/pgsql/sup/pgsql/src/backend/commands/copy.c Thu Feb 19 13:05:25 1998 --- ./backend/commands/copy.c Tue Feb 24 14:39:35 1998 *************** *** 32,38 **** #include <access/genam.h> #include <catalog/pg_type.h> #include <catalog/catname.h> ! #include <catalog/pg_user.h> #include <commands/copy.h> #include "commands/trigger.h" #include <storage/fd.h> --- 32,38 ---- #include <access/genam.h> #include <catalog/pg_type.h> #include <catalog/catname.h> ! #include <catalog/pg_shadow.h> #include <commands/copy.h> #include "commands/trigger.h" #include <storage/fd.h> diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/commands/dbcommands.c ./backend/commands/dbcommands.c *** /usr/local/pgsql/sup/pgsql/src/backend/commands/dbcommands.c Wed Feb 4 09:33:29 1998 --- ./backend/commands/dbcommands.c Tue Feb 24 14:45:45 1998 *************** *** 25,31 **** #include "utils/elog.h" #include "catalog/catname.h" #include "catalog/pg_proc.h" ! #include "catalog/pg_user.h" #include "catalog/pg_database.h" #include "utils/syscache.h" #include "commands/dbcommands.h" --- 25,31 ---- #include "utils/elog.h" #include "catalog/catname.h" #include "catalog/pg_proc.h" ! #include "catalog/pg_shadow.h" #include "catalog/pg_database.h" #include "utils/syscache.h" #include "commands/dbcommands.h" *************** *** 211,219 **** userName = GetPgUserName(); utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName), 0, 0, 0); ! *userIdP = ((Form_pg_user) GETSTRUCT(utup))->usesysid; ! use_super = ((Form_pg_user) GETSTRUCT(utup))->usesuper; ! use_createdb = ((Form_pg_user) GETSTRUCT(utup))->usecreatedb; /* Check to make sure user has permission to use createdb */ if (!use_createdb) --- 211,219 ---- userName = GetPgUserName(); utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName), 0, 0, 0); ! *userIdP = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid; ! use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; ! use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; /* Check to make sure user has permission to use createdb */ if (!use_createdb) diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/commands/define.c ./backend/commands/define.c *** /usr/local/pgsql/sup/pgsql/src/backend/commands/define.c Fri Feb 13 18:28:37 1998 --- ./backend/commands/define.c Tue Feb 24 14:39:46 1998 *************** *** 52,58 **** #include <commands/defrem.h> #include <optimizer/xfunc.h> #include <tcop/dest.h> ! #include <catalog/pg_user.h> static char *defGetString(DefElem *def); static int defGetTypeLength(DefElem *def); --- 52,58 ---- #include <commands/defrem.h> #include <optimizer/xfunc.h> #include <tcop/dest.h> ! #include <catalog/pg_shadow.h> static char *defGetString(DefElem *def); static int defGetTypeLength(DefElem *def); diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/commands/proclang.c ./backend/commands/proclang.c *** /usr/local/pgsql/sup/pgsql/src/backend/commands/proclang.c Wed Jan 7 13:36:17 1998 --- ./backend/commands/proclang.c Tue Feb 24 14:39:49 1998 *************** *** 11,17 **** #include "access/heapam.h" #include "catalog/catname.h" ! #include "catalog/pg_user.h" #include "catalog/pg_proc.h" #include "catalog/pg_language.h" #include "utils/syscache.h" --- 11,17 ---- #include "access/heapam.h" #include "catalog/catname.h" ! #include "catalog/pg_shadow.h" #include "catalog/pg_proc.h" #include "catalog/pg_language.h" #include "utils/syscache.h" diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/commands/user.c ./backend/commands/user.c *** /usr/local/pgsql/sup/pgsql/src/backend/commands/user.c Thu Feb 19 22:31:39 1998 --- ./backend/commands/user.c Tue Feb 24 14:52:21 1998 *************** *** 21,27 **** #include <miscadmin.h> #include <catalog/catname.h> #include <catalog/pg_database.h> ! #include <catalog/pg_user.h> #include <libpq/crypt.h> #include <access/heapam.h> #include <access/xact.h> --- 21,27 ---- #include <miscadmin.h> #include <catalog/catname.h> #include <catalog/pg_database.h> ! #include <catalog/pg_shadow.h> #include <libpq/crypt.h> #include <access/heapam.h> #include <access/xact.h> *************** *** 38,44 **** /*--------------------------------------------------------------------- * UpdatePgPwdFile * ! * copy the modified contents of pg_user to a file used by the postmaster * for user authentication. The file is stored as $PGDATA/pg_pwd. *--------------------------------------------------------------------- */ --- 38,44 ---- /*--------------------------------------------------------------------- * UpdatePgPwdFile * ! * copy the modified contents of pg_shadow to a file used by the postmaster * for user authentication. The file is stored as $PGDATA/pg_pwd. *--------------------------------------------------------------------- */ *************** *** 56,66 **** tempname = (char*)malloc(strlen(filename) + 12); sprintf(tempname, "%s.%d", filename, MyProcPid); ! /* Copy the contents of pg_user to the pg_pwd ASCII file using a the SEPCHAR * character as the delimiter between fields. Then rename the file to its * final name. */ ! sprintf(sql, "copy %s to '%s' using delimiters %s", UserRelationName, tempname, CRYPT_PWD_FILE_SEPCHAR); pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0); rename(tempname, filename); free((void*)tempname); --- 56,66 ---- tempname = (char*)malloc(strlen(filename) + 12); sprintf(tempname, "%s.%d", filename, MyProcPid); ! /* Copy the contents of pg_shadow to the pg_pwd ASCII file using a the SEPCHAR * character as the delimiter between fields. Then rename the file to its * final name. */ ! sprintf(sql, "copy %s to '%s' using delimiters %s", ShadowRelationName, tempname, CRYPT_PWD_FILE_SEPCHAR); pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0); rename(tempname, filename); free((void*)tempname); *************** *** 76,90 **** /*--------------------------------------------------------------------- * DefineUser * ! * Add the user to the pg_user relation, and if specified make sure the * user is specified in the desired groups of defined in pg_group. *--------------------------------------------------------------------- */ void DefineUser(CreateUserStmt *stmt) { char* pg_user; ! Relation pg_user_rel; ! TupleDesc pg_user_dsc; HeapScanDesc scan; HeapTuple tuple; Datum datum; --- 76,90 ---- /*--------------------------------------------------------------------- * DefineUser * ! * Add the user to the pg_shadow relation, and if specified make sure the * user is specified in the desired groups of defined in pg_group. *--------------------------------------------------------------------- */ void DefineUser(CreateUserStmt *stmt) { char* pg_user; ! Relation pg_shadow_rel; ! TupleDesc pg_shadow_dsc; HeapScanDesc scan; HeapTuple tuple; Datum datum; *************** *** 101,134 **** if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can insert into the pg_user * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(UserRelationName, pg_user, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"", ! pg_user, UserRelationName); return; } ! /* Scan the pg_user relation to be certain the user doesn't already exist. */ ! pg_user_rel = heap_openr(UserRelationName); ! pg_user_dsc = RelationGetTupleDescriptor(pg_user_rel); ! /* Secure a write lock on pg_user so we can be sure of what the next usesysid * should be. */ ! RelationSetLockForWrite(pg_user_rel); ! scan = heap_beginscan(pg_user_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_user_usename, pg_user_dsc, &n); if (!exists && !strncmp((char*)datum, stmt->user, strlen(stmt->user))) exists = true; ! datum = heap_getattr(tuple, Anum_pg_user_usesysid, pg_user_dsc, &n); if ((int)datum > max_id) max_id = (int)datum; --- 101,134 ---- if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can insert into the pg_shadow * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"", ! pg_user, ShadowRelationName); return; } ! /* Scan the pg_shadow relation to be certain the user doesn't already exist. */ ! pg_shadow_rel = heap_openr(ShadowRelationName); ! pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel); ! /* Secure a write lock on pg_shadow so we can be sure of what the next usesysid * should be. */ ! RelationSetLockForWrite(pg_shadow_rel); ! scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n); if (!exists && !strncmp((char*)datum, stmt->user, strlen(stmt->user))) exists = true; ! datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &n); if ((int)datum > max_id) max_id = (int)datum; *************** *** 137,144 **** heap_endscan(scan); if (exists) { ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); UserAbortTransactionBlock(); elog(ERROR, "defineUser: user \"%s\" has already been created", stmt->user); return; --- 137,144 ---- heap_endscan(scan); if (exists) { ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); UserAbortTransactionBlock(); elog(ERROR, "defineUser: user \"%s\" has already been created", stmt->user); return; *************** *** 146,152 **** /* Build the insert statment to be executed. */ ! sprintf(sql, "insert into %s(usename,usesysid,usecreatedb,usetrace,usesuper,usecatupd,passwd", UserRelationName); /* if (stmt->password) strcat(sql, ",passwd"); -- removed so that insert empty string when no password */ if (stmt->validUntil) --- 146,152 ---- /* Build the insert statment to be executed. */ ! sprintf(sql, "insert into %s(usename,usesysid,usecreatedb,usetrace,usesuper,usecatupd,passwd", ShadowRelationName); /* if (stmt->password) strcat(sql, ",passwd"); -- removed so that insert empty string when no password */ if (stmt->validUntil) *************** *** 186,193 **** /* This goes after the UpdatePgPwdFile to be certain that two backends to not * attempt to write to the pg_pwd file at the same time. */ ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); --- 186,193 ---- /* This goes after the UpdatePgPwdFile to be certain that two backends to not * attempt to write to the pg_pwd file at the same time. */ ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); *************** *** 197,204 **** extern void AlterUser(AlterUserStmt *stmt) { char* pg_user; ! Relation pg_user_rel; ! TupleDesc pg_user_dsc; HeapScanDesc scan; HeapTuple tuple; Datum datum; --- 197,204 ---- extern void AlterUser(AlterUserStmt *stmt) { char* pg_user; ! Relation pg_shadow_rel; ! TupleDesc pg_shadow_dsc; HeapScanDesc scan; HeapTuple tuple; Datum datum; *************** *** 214,242 **** if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can insert into the pg_user * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(UserRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"", ! pg_user, UserRelationName); return; } ! /* Scan the pg_user relation to be certain the user exists. */ ! pg_user_rel = heap_openr(UserRelationName); ! pg_user_dsc = RelationGetTupleDescriptor(pg_user_rel); ! /* Secure a write lock on pg_user so we can be sure that when the dump of * the pg_pwd file is done, there is not another backend doing the same. */ ! RelationSetLockForWrite(pg_user_rel); ! scan = heap_beginscan(pg_user_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_user_usename, pg_user_dsc, &n); if (!strncmp((char*)datum, stmt->user, strlen(stmt->user))) { exists = true; --- 214,242 ---- if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can insert into the pg_shadow * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"", ! pg_user, ShadowRelationName); return; } ! /* Scan the pg_shadow relation to be certain the user exists. */ ! pg_shadow_rel = heap_openr(ShadowRelationName); ! pg_shadow_dsc = RelationGetTupleDescriptor(pg_shadow_rel); ! /* Secure a write lock on pg_shadow so we can be sure that when the dump of * the pg_pwd file is done, there is not another backend doing the same. */ ! RelationSetLockForWrite(pg_shadow_rel); ! scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n); if (!strncmp((char*)datum, stmt->user, strlen(stmt->user))) { exists = true; *************** *** 247,254 **** heap_endscan(scan); if (!exists) { ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); UserAbortTransactionBlock(); elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user); return; --- 247,254 ---- heap_endscan(scan); if (!exists) { ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); UserAbortTransactionBlock(); elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user); return; *************** *** 256,262 **** /* Create the update statement to modify the user. */ ! sprintf(sql, "update %s set", UserRelationName); sql_end = sql; if (stmt->password) { sql_end += strlen(sql_end); --- 256,262 ---- /* Create the update statement to modify the user. */ ! sprintf(sql, "update %s set", ShadowRelationName); sql_end = sql; if (stmt->password) { sql_end += strlen(sql_end); *************** *** 296,303 **** UpdatePgPwdFile(sql); ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); --- 296,303 ---- UpdatePgPwdFile(sql); ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); *************** *** 307,313 **** extern void RemoveUser(char* user) { char* pg_user; ! Relation pg_user_rel, pg_rel; TupleDesc pg_dsc; HeapScanDesc scan; --- 307,313 ---- extern void RemoveUser(char* user) { char* pg_user; ! Relation pg_shadow_rel, pg_rel; TupleDesc pg_dsc; HeapScanDesc scan; *************** *** 324,356 **** if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can delete from the pg_user * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(UserRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"", ! pg_user, UserRelationName); return; } ! /* Perform a scan of the pg_user relation to find the usesysid of the user to * be deleted. If it is not found, then return a warning message. */ ! pg_user_rel = heap_openr(UserRelationName); ! pg_dsc = RelationGetTupleDescriptor(pg_user_rel); ! /* Secure a write lock on pg_user so we can be sure that when the dump of * the pg_pwd file is done, there is not another backend doing the same. */ ! RelationSetLockForWrite(pg_user_rel); ! scan = heap_beginscan(pg_user_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_user_usename, pg_dsc, &n); if (!strncmp((char*)datum, user, strlen(user))) { ! usesysid = (int)heap_getattr(tuple, Anum_pg_user_usesysid, pg_dsc, &n); ReleaseBuffer(buffer); break; } --- 324,356 ---- if (!(inblock = IsTransactionBlock())) BeginTransactionBlock(); ! /* Make sure the user attempting to create a user can delete from the pg_shadow * relation. */ pg_user = GetPgUserName(); ! if (pg_aclcheck(ShadowRelationName, pg_user, ACL_RD | ACL_WR) != ACLCHECK_OK) { UserAbortTransactionBlock(); elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"", ! pg_user, ShadowRelationName); return; } ! /* Perform a scan of the pg_shadow relation to find the usesysid of the user to * be deleted. If it is not found, then return a warning message. */ ! pg_shadow_rel = heap_openr(ShadowRelationName); ! pg_dsc = RelationGetTupleDescriptor(pg_shadow_rel); ! /* Secure a write lock on pg_shadow so we can be sure that when the dump of * the pg_pwd file is done, there is not another backend doing the same. */ ! RelationSetLockForWrite(pg_shadow_rel); ! scan = heap_beginscan(pg_shadow_rel, false, false, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) { ! datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_dsc, &n); if (!strncmp((char*)datum, user, strlen(user))) { ! usesysid = (int)heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_dsc, &n); ReleaseBuffer(buffer); break; } *************** *** 359,366 **** heap_endscan(scan); if (usesysid == -1) { ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); UserAbortTransactionBlock(); elog(ERROR, "removeUser: user \"%s\" does not exist", user); return; --- 359,366 ---- heap_endscan(scan); if (usesysid == -1) { ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); UserAbortTransactionBlock(); elog(ERROR, "removeUser: user \"%s\" does not exist", user); return; *************** *** 399,406 **** if (dbase) free((void*)dbase); ! /* Since pg_user is global over all databases, one of two things must be done ! * to insure complete consistency. First, pg_user could be made non-global. * This would elminate the code above for deleting database and would require * the addition of code to delete tables, views, etc owned by the user. * --- 399,406 ---- if (dbase) free((void*)dbase); ! /* Since pg_shadow is global over all databases, one of two things must be done ! * to insure complete consistency. First, pg_shadow could be made non-global. * This would elminate the code above for deleting database and would require * the addition of code to delete tables, views, etc owned by the user. * *************** *** 414,428 **** * */ ! /* Remove the user from the pg_user table */ ! sprintf(sql, "delete from %s where usename = '%s'", UserRelationName, user); pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0); UpdatePgPwdFile(sql); ! RelationUnsetLockForWrite(pg_user_rel); ! heap_close(pg_user_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); --- 414,428 ---- * */ ! /* Remove the user from the pg_shadow table */ ! sprintf(sql, "delete from %s where usename = '%s'", ShadowRelationName, user); pg_exec_query(sql, (char**)NULL, (Oid*)NULL, 0); UpdatePgPwdFile(sql); ! RelationUnsetLockForWrite(pg_shadow_rel); ! heap_close(pg_shadow_rel); if (IsTransactionBlock() && !inblock) EndTransactionBlock(); *************** *** 431,455 **** /* * CheckPgUserAclNotNull * ! * check to see if there is an ACL on pg_user */ static void CheckPgUserAclNotNull() { HeapTuple htp; ! htp = SearchSysCacheTuple(RELNAME, PointerGetDatum(UserRelationName), 0, 0, 0); if (!HeapTupleIsValid(htp)) { elog(ERROR, "IsPgUserAclNull: class \"%s\" not found", ! UserRelationName); } if (heap_attisnull(htp, Anum_pg_class_relacl)) { ! elog(NOTICE, "To use passwords, you have to revoke permissions on pg_user"); elog(NOTICE, "so normal users can not read the passwords."); ! elog(ERROR, "Try 'REVOKE ALL ON pg_user FROM PUBLIC'"); } return; --- 431,455 ---- /* * CheckPgUserAclNotNull * ! * check to see if there is an ACL on pg_shadow */ static void CheckPgUserAclNotNull() { HeapTuple htp; ! htp = SearchSysCacheTuple(RELNAME, PointerGetDatum(ShadowRelationName), 0, 0, 0); if (!HeapTupleIsValid(htp)) { elog(ERROR, "IsPgUserAclNull: class \"%s\" not found", ! ShadowRelationName); } if (heap_attisnull(htp, Anum_pg_class_relacl)) { ! elog(NOTICE, "To use passwords, you have to revoke permissions on pg_shadow"); elog(NOTICE, "so normal users can not read the passwords."); ! elog(ERROR, "Try 'REVOKE ALL ON pg_shadow FROM PUBLIC'"); } return; diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/libpq/auth.c ./backend/libpq/auth.c *** /usr/local/pgsql/sup/pgsql/src/backend/libpq/auth.c Wed Feb 4 09:33:38 1998 --- ./backend/libpq/auth.c Tue Feb 24 14:52:50 1998 *************** *** 605,611 **** /* * Use the local flat password file if clear passwords are used and the file is ! * specified. Otherwise use the password in the pg_user table, encrypted or * not. */ --- 605,611 ---- /* * Use the local flat password file if clear passwords are used and the file is ! * specified. Otherwise use the password in the pg_shadow table, encrypted or * not. */ diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/libpq/crypt.c ./backend/libpq/crypt.c *** /usr/local/pgsql/sup/pgsql/src/backend/libpq/crypt.c Wed Feb 4 09:33:39 1998 --- ./backend/libpq/crypt.c Tue Feb 24 14:53:38 1998 *************** *** 1,7 **** /*------------------------------------------------------------------------- * * crypt.c-- ! * Look into pg_user and check the encrypted password with the one * passed in from the frontend. * * Modification History --- 1,7 ---- /*------------------------------------------------------------------------- * * crypt.c-- ! * Look into pg_shadow and check the encrypted password with the one * passed in from the frontend. * * Modification History *************** *** 119,125 **** /* We want to delete the flag file before reading the contents of the pg_pwd * file. If result == 0 then the unlink of the reload file was successful. ! * This means that a backend performed a COPY of the pg_user file to * pg_pwd. Therefore we must now do a reload. */ if (!pwd_cache || !result) { --- 119,125 ---- /* We want to delete the flag file before reading the contents of the pg_pwd * file. If result == 0 then the unlink of the reload file was successful. ! * This means that a backend performed a COPY of the pg_shadow file to * pg_pwd. Therefore we must now do a reload. */ if (!pwd_cache || !result) { diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/parser/gram.y ./backend/parser/gram.y *** /usr/local/pgsql/sup/pgsql/src/backend/parser/gram.y Thu Feb 19 13:05:45 1998 --- ./backend/parser/gram.y Tue Feb 24 14:57:11 1998 *************** *** 88,94 **** char chr; char *str; bool boolean; ! bool* pboolean; /* for pg_user privileges */ List *list; Node *node; Value *value; --- 88,94 ---- char chr; char *str; bool boolean; ! bool* pboolean; /* for pg_shadow privileges */ List *list; Node *node; Value *value; diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/rewrite/rewriteHandler.c ./backend/rewrite/rewriteHandler.c *** /usr/local/pgsql/sup/pgsql/src/backend/rewrite/rewriteHandler.c Mon Feb 23 14:21:42 1998 --- ./backend/rewrite/rewriteHandler.c Tue Feb 24 14:45:52 1998 *************** *** 32,38 **** #include "utils/syscache.h" #include "utils/acl.h" ! #include "catalog/pg_user.h" static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule, int rt_index, int relation_level, --- 32,38 ---- #include "utils/syscache.h" #include "utils/acl.h" ! #include "catalog/pg_shadow.h" static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule, int rt_index, int relation_level, *************** *** 827,833 **** view->rd_rel->relowner); } StrNCpy(uname.data, ! ((Form_pg_user) GETSTRUCT(utup))->usename.data, NAMEDATALEN); /* --- 827,833 ---- view->rd_rel->relowner); } StrNCpy(uname.data, ! ((Form_pg_shadow) GETSTRUCT(utup))->usename.data, NAMEDATALEN); /* diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/utils/adt/acl.c ./backend/utils/adt/acl.c *** /usr/local/pgsql/sup/pgsql/src/backend/utils/adt/acl.c Tue Feb 24 10:22:34 1998 --- ./backend/utils/adt/acl.c Tue Feb 24 14:46:02 1998 *************** *** 19,25 **** #include "utils/acl.h" #include "utils/syscache.h" #include "catalog/catalog.h" ! #include "catalog/pg_user.h" #include "miscadmin.h" static char *getid(char *s, char *n); --- 19,25 ---- #include "utils/acl.h" #include "utils/syscache.h" #include "catalog/catalog.h" ! #include "catalog/pg_shadow.h" #include "miscadmin.h" static char *getid(char *s, char *n); *************** *** 158,164 **** 0, 0, 0); if (!HeapTupleIsValid(htp)) elog(ERROR, "aclparse: non-existent user \"%s\"", name); ! aip->ai_id = ((Form_pg_user) GETSTRUCT(htp))->usesysid; break; case ACL_IDTYPE_GID: aip->ai_id = get_grosysid(name); --- 158,164 ---- 0, 0, 0); if (!HeapTupleIsValid(htp)) elog(ERROR, "aclparse: non-existent user \"%s\"", name); ! aip->ai_id = ((Form_pg_shadow) GETSTRUCT(htp))->usesysid; break; case ACL_IDTYPE_GID: aip->ai_id = get_grosysid(name); *************** *** 285,291 **** pfree(tmp); } else ! strncat(p, (char *) &((Form_pg_user) GETSTRUCT(htp))->usename, sizeof(NameData)); break; --- 285,291 ---- pfree(tmp); } else ! strncat(p, (char *) &((Form_pg_shadow) GETSTRUCT(htp))->usename, sizeof(NameData)); break; diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/utils/cache/syscache.c ./backend/utils/cache/syscache.c *** /usr/local/pgsql/sup/pgsql/src/backend/utils/cache/syscache.c Thu Feb 12 14:36:23 1998 --- ./backend/utils/cache/syscache.c Tue Feb 24 14:48:38 1998 *************** *** 48,54 **** #include "catalog/pg_type.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_aggregate.h" ! #include "catalog/pg_user.h" #include "storage/large_object.h" #include "catalog/pg_listener.h" --- 48,54 ---- #include "catalog/pg_type.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_aggregate.h" ! #include "catalog/pg_shadow.h" #include "storage/large_object.h" #include "catalog/pg_listener.h" *************** *** 254,275 **** sizeof(FormData_pg_listener), NULL, (ScanFunc) NULL}, ! {UserRelationName, /* USENAME */ 1, ! {Anum_pg_user_usename, 0, 0, 0}, ! sizeof(FormData_pg_user), NULL, (ScanFunc) NULL}, ! {UserRelationName, /* USESYSID */ 1, ! {Anum_pg_user_usesysid, 0, 0, 0}, ! sizeof(FormData_pg_user), NULL, (ScanFunc) NULL}, {GroupRelationName, /* GRONAME */ --- 254,275 ---- sizeof(FormData_pg_listener), NULL, (ScanFunc) NULL}, ! {ShadowRelationName, /* USENAME */ 1, ! {Anum_pg_shadow_usename, 0, 0, 0}, ! sizeof(FormData_pg_shadow), NULL, (ScanFunc) NULL}, ! {ShadowRelationName, /* USESYSID */ 1, ! {Anum_pg_shadow_usesysid, 0, 0, 0}, ! sizeof(FormData_pg_shadow), NULL, (ScanFunc) NULL}, {GroupRelationName, /* GRONAME */ diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/utils/init/globals.c ./backend/utils/init/globals.c *** /usr/local/pgsql/sup/pgsql/src/backend/utils/init/globals.c Wed Feb 4 09:34:08 1998 --- ./backend/utils/init/globals.c Tue Feb 24 14:44:00 1998 *************** *** 110,116 **** DatabaseRelationName, GroupRelationName, LogRelationName, ! UserRelationName, VariableRelationName, 0 }; --- 110,116 ---- DatabaseRelationName, GroupRelationName, LogRelationName, ! ShadowRelationName, VariableRelationName, 0 }; diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/utils/init/miscinit.c ./backend/utils/init/miscinit.c *** /usr/local/pgsql/sup/pgsql/src/backend/utils/init/miscinit.c Wed Feb 4 09:34:08 1998 --- ./backend/utils/init/miscinit.c Tue Feb 24 14:46:07 1998 *************** *** 32,38 **** #include "miscadmin.h" /* where the declarations go */ #include "catalog/catname.h" ! #include "catalog/pg_user.h" #include "catalog/pg_proc.h" #include "utils/syscache.h" --- 32,38 ---- #include "miscadmin.h" /* where the declarations go */ #include "catalog/catname.h" ! #include "catalog/pg_shadow.h" #include "catalog/pg_proc.h" #include "utils/syscache.h" *************** *** 339,344 **** if (!HeapTupleIsValid(userTup)) elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"", userName, ! UserRelationName); ! UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid; } --- 339,344 ---- if (!HeapTupleIsValid(userTup)) elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"", userName, ! ShadowRelationName); ! UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; } diff -c -r /usr/local/pgsql/sup/pgsql/src/backend/utils/misc/superuser.c ./backend/utils/misc/superuser.c *** /usr/local/pgsql/sup/pgsql/src/backend/utils/misc/superuser.c Mon Sep 8 04:32:00 1997 --- ./backend/utils/misc/superuser.c Tue Feb 24 14:46:13 1998 *************** *** 17,23 **** #include <postgres.h> #include <utils/syscache.h> ! #include <catalog/pg_user.h> bool superuser(void) --- 17,23 ---- #include <postgres.h> #include <utils/syscache.h> ! #include <catalog/pg_shadow.h> bool superuser(void) *************** *** 33,37 **** utup = SearchSysCacheTuple(USENAME, PointerGetDatum(UserName), 0, 0, 0); Assert(utup != NULL); ! return ((Form_pg_user) GETSTRUCT(utup))->usesuper; } --- 33,37 ---- utup = SearchSysCacheTuple(USENAME, PointerGetDatum(UserName), 0, 0, 0); Assert(utup != NULL); ! return ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; } diff -c -r /usr/local/pgsql/sup/pgsql/src/bin/createuser/createuser.sh ./bin/createuser/createuser.sh *** /usr/local/pgsql/sup/pgsql/src/bin/createuser/createuser.sh Wed May 7 04:59:46 1997 --- ./bin/createuser/createuser.sh Tue Feb 24 15:01:24 1998 *************** *** 203,209 **** CANADDUSER=f fi ! QUERY="insert into pg_user \ (usename, usesysid, usecreatedb, usetrace, usesuper, usecatupd) \ values \ ('$NEWUSER', $SYSID, '$CANCREATE', 't', '$CANADDUSER','t')" --- 203,209 ---- CANADDUSER=f fi ! QUERY="insert into pg_shadow \ (usename, usesysid, usecreatedb, usetrace, usesuper, usecatupd) \ values \ ('$NEWUSER', $SYSID, '$CANCREATE', 't', '$CANADDUSER','t')" diff -c -r /usr/local/pgsql/sup/pgsql/src/bin/destroyuser/destroyuser.sh ./bin/destroyuser/destroyuser.sh *** /usr/local/pgsql/sup/pgsql/src/bin/destroyuser/destroyuser.sh Wed May 7 04:59:52 1997 --- ./bin/destroyuser/destroyuser.sh Tue Feb 24 15:01:58 1998 *************** *** 182,188 **** done fi ! QUERY="delete from pg_user where usename = '$DELUSER'" $PSQL -c "$QUERY" template1 if [ $? -ne 0 ] --- 182,188 ---- done fi ! QUERY="delete from pg_shadow where usename = '$DELUSER'" $PSQL -c "$QUERY" template1 if [ $? -ne 0 ] diff -c -r /usr/local/pgsql/sup/pgsql/src/bin/initdb/initdb.sh ./bin/initdb/initdb.sh *** /usr/local/pgsql/sup/pgsql/src/bin/initdb/initdb.sh Tue Feb 24 10:22:35 1998 --- ./bin/initdb/initdb.sh Tue Feb 24 16:42:13 1998 *************** *** 351,371 **** echo "vacuum" | postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "^DEBUG:" ! echo "COPY pg_user TO '$PGDATA/pg_pwd' USING DELIMITERS '\\t'" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! echo "GRANT SELECT ON pg_class TO PUBLIC" |\ ! postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ ! ! echo "CREATE RULE pg_user_hide_pw as on SELECT to pg_user.passwd DO INSTEAD SELECT '********' as passwd;" | \ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! ! echo "create view db_user as select * from pg_user;" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! echo "grant select on db_user to public" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" --- 351,382 ---- echo "vacuum" | postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "^DEBUG:" ! echo "COPY pg_shadow TO '$PGDATA/pg_pwd' USING DELIMITERS '\\t'" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! echo "creating public pg_user view" ! echo "CREATE TABLE xpg_user ( \ ! usename name, \ ! usesysid int4, \ ! usecreatedb bool, \ ! usetrace bool, \ ! usesuper bool, \ ! usecatupd bool, \ ! passwd text, \ ! valuntil abstime);" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! echo "UPDATE pg_class SET relname = 'pg_user' WHERE relname = 'xpg_user';" |\ ! postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ ! grep -v "'DEBUG:" ! echo "CREATE RULE _RETpg_user AS ON SELECT TO pg_user DO INSTEAD \ ! SELECT usename, usesysid, usecreatedb, usetrace, \ ! usesuper, usecatupd, '********'::text as passwd, \ ! valuntil FROM pg_shadow;" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" ! echo "REVOKE ALL on pg_shadow FROM public" |\ postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\ grep -v "'DEBUG:" diff -c -r /usr/local/pgsql/sup/pgsql/src/include/catalog/catname.h ./include/catalog/catname.h *** /usr/local/pgsql/sup/pgsql/src/include/catalog/catname.h Tue Nov 18 11:23:10 1997 --- ./include/catalog/catname.h Tue Feb 24 14:35:39 1998 *************** *** 35,43 **** #define ProcedureRelationName "pg_proc" #define RelationRelationName "pg_class" #define RewriteRelationName "pg_rewrite" #define StatisticRelationName "pg_statistic" #define TypeRelationName "pg_type" - #define UserRelationName "pg_user" #define VariableRelationName "pg_variable" #define VersionRelationName "pg_version" #define AttrDefaultRelationName "pg_attrdef" --- 35,43 ---- #define ProcedureRelationName "pg_proc" #define RelationRelationName "pg_class" #define RewriteRelationName "pg_rewrite" + #define ShadowRelationName "pg_shadow" #define StatisticRelationName "pg_statistic" #define TypeRelationName "pg_type" #define VariableRelationName "pg_variable" #define VersionRelationName "pg_version" #define AttrDefaultRelationName "pg_attrdef" diff -c -r /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_attribute.h ./include/catalog/pg_attribute.h *** /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_attribute.h Thu Feb 19 13:05:54 1998 --- ./include/catalog/pg_attribute.h Tue Feb 24 14:30:35 1998 *************** *** 275,281 **** DATA(insert OID = 0 ( 1255 cmax 29 0 4 -6 0 -1 -1 t f i f f)); /* ---------------- ! * pg_user * ---------------- */ DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 -1 f f i f f)); --- 275,281 ---- DATA(insert OID = 0 ( 1255 cmax 29 0 4 -6 0 -1 -1 t f i f f)); /* ---------------- ! * pg_shadow * ---------------- */ DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 -1 f f i f f)); diff -c -r /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_class.h ./include/catalog/pg_class.h *** /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_class.h Mon Jan 19 09:36:11 1998 --- ./include/catalog/pg_class.h Tue Feb 24 14:31:23 1998 *************** *** 125,131 **** DESCR(""); DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 f f r 14 0 0 f _null_ )); DESCR(""); ! DATA(insert OID = 1260 ( pg_user 86 PGUID 0 0 0 f t r 8 0 0 f _null_ )); DESCR(""); DATA(insert OID = 1261 ( pg_group 87 PGUID 0 0 0 f t s 3 0 0 f _null_ )); DESCR(""); --- 125,131 ---- DESCR(""); DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 f f r 14 0 0 f _null_ )); DESCR(""); ! DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 0 0 f t r 8 0 0 f _null_ )); DESCR(""); DATA(insert OID = 1261 ( pg_group 87 PGUID 0 0 0 f t s 3 0 0 f _null_ )); DESCR(""); *************** *** 146,152 **** #define RelOid_pg_attribute 1249 #define RelOid_pg_proc 1255 #define RelOid_pg_class 1259 ! #define RelOid_pg_user 1260 #define RelOid_pg_group 1261 #define RelOid_pg_database 1262 #define RelOid_pg_variable 1264 --- 146,152 ---- #define RelOid_pg_attribute 1249 #define RelOid_pg_proc 1255 #define RelOid_pg_class 1259 ! #define RelOid_pg_shadow 1260 #define RelOid_pg_group 1261 #define RelOid_pg_database 1262 #define RelOid_pg_variable 1264 diff -c -r /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_type.h ./include/catalog/pg_type.h *** /usr/local/pgsql/sup/pgsql/src/include/catalog/pg_type.h Wed Feb 11 15:25:43 1998 --- ./include/catalog/pg_type.h Tue Feb 24 14:31:53 1998 *************** *** 212,218 **** DATA(insert OID = 75 ( pg_attribute PGUID 1 1 t b t \054 1249 0 foo bar foo bar c _null_)); DATA(insert OID = 81 ( pg_proc PGUID 1 1 t b t \054 1255 0 foo bar foo bar c _null_)); DATA(insert OID = 83 ( pg_class PGUID 1 1 t b t \054 1259 0 foo bar foo bar c _null_)); ! DATA(insert OID = 86 ( pg_user PGUID 1 1 t b t \054 1260 0 foo bar foo bar c _null_)); DATA(insert OID = 87 ( pg_group PGUID 1 1 t b t \054 1261 0 foo bar foo bar c _null_)); DATA(insert OID = 88 ( pg_database PGUID 1 1 t b t \054 1262 0 foo bar foo bar c _null_)); DATA(insert OID = 90 ( pg_variable PGUID 1 1 t b t \054 1264 0 foo bar foo bar c _null_)); --- 212,218 ---- DATA(insert OID = 75 ( pg_attribute PGUID 1 1 t b t \054 1249 0 foo bar foo bar c _null_)); DATA(insert OID = 81 ( pg_proc PGUID 1 1 t b t \054 1255 0 foo bar foo bar c _null_)); DATA(insert OID = 83 ( pg_class PGUID 1 1 t b t \054 1259 0 foo bar foo bar c _null_)); ! DATA(insert OID = 86 ( pg_shadow PGUID 1 1 t b t \054 1260 0 foo bar foo bar c _null_)); DATA(insert OID = 87 ( pg_group PGUID 1 1 t b t \054 1261 0 foo bar foo bar c _null_)); DATA(insert OID = 88 ( pg_database PGUID 1 1 t b t \054 1262 0 foo bar foo bar c _null_)); DATA(insert OID = 90 ( pg_variable PGUID 1 1 t b t \054 1264 0 foo bar foo bar c _null_)); diff -c -r /usr/local/pgsql/sup/pgsql/src/include/utils/acl.h ./include/utils/acl.h *** /usr/local/pgsql/sup/pgsql/src/include/utils/acl.h Tue Feb 24 10:22:45 1998 --- ./include/utils/acl.h Tue Feb 24 14:58:30 1998 *************** *** 39,45 **** typedef uint8 AclIdType; #define ACL_IDTYPE_WORLD 0x00 ! #define ACL_IDTYPE_UID 0x01 /* user id - from pg_user */ #define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */ /* --- 39,45 ---- typedef uint8 AclIdType; #define ACL_IDTYPE_WORLD 0x00 ! #define ACL_IDTYPE_UID 0x01 /* user id - from pg_shadow */ #define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */ /*
> > > > > On Tue, 24 Feb 1998, Jan Wieck wrote: > > > > > CREATE TABLE xpg_usr ( > > > usename name, > > > usesysid int4, > > > usecreatedb bool, > > > usetrace bool, > > > usesuper bool, > > > usecatupd bool, > > > passwd text, > > > valuntil abstime); > > > > > > UPDATE pg_class SET relname = 'pg_usr' > > > WHERE relname = 'xpg_usr'; > > > > > > CREATE RULE _RETpg_usr AS ON SELECT TO pg_usr > > > DO INSTEAD > > > SELECT usename, usesysid, usecreatedb, > > > usetrace, usesuper, usecatupd, > > > '********'::text as passwd, valuntil > > > FROM pg_user; > > > > > > REVOKE ALL ON pg_user FROM public; > > > > Okay, just so that I don't mess things up in the translation...do > > you want to send me an appropriate patch for this? > > > > > > But as it was done in most UN*X's, could we rename the > > > > pg_user containing the password into pg_shadow and then > > > > create a view pg_user that just stars out the password field? > > > > This way no existing application code (not even the JDBC > > > > etc.) needs any changes, except for the createuser etc. > > > > tools that always get installed with the new release. > > > > > > Still vote for this. And as soon as we finally choose one > > > name for the public pg_user view we must fix createuser.sh, > > > createdb.sh and so on to make their checks on the public > > > accessible view so they still print the proper error messages > > > instead of > > > > No arguments here...can you include this as part of your patch > > too? > > Will do so. The more I think about it, the more I like pg_shadow. Maybe we can do that in enough time for testing. No one's code has to change then, and this is a big win. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
> > > my backend crashes on SELECT FROM view during the rewrite. For some > > > reason the rewrite handler cannot get the rule locks correctly. > > > > Ppl are taking me a slight bit too literally :( "Works for > > me"...I like the idea...not necessarily implemented it though :) > > I already have the pg_shadow + pg_user-view diff ready. Works > really! Must run a regression test and send it after that > succeeded. It updates createuser, destroyuser and initdb too. Great news. Go for it. Please back out the psql db_ changes and any initdb stuff we don't need anymore. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
> > > > > my backend crashes on SELECT FROM view during the rewrite. For some > > > > reason the rewrite handler cannot get the rule locks correctly. > > > > > > Ppl are taking me a slight bit too literally :( "Works for > > > me"...I like the idea...not necessarily implemented it though :) > > > > I already have the pg_shadow + pg_user-view diff ready. Works > > really! Must run a regression test and send it after that > > succeeded. It updates createuser, destroyuser and initdb too. > > Great news. Go for it. Please back out the psql db_ changes and any > initdb stuff we don't need anymore. Again, this is very good. I had not thought of making pg_user a different name, but that is the perfect solution. Here is a case where many heads get a nice solution. PostgreSQL is full of those areas where people get good ideas for certain areas, and the whole project gets better. -- Bruce Momjian | 830 Blythe Avenue maillist@candle.pha.pa.us | Drexel Hill, Pennsylvania 19026 + If your life is a hard drive, | (610) 353-9879(w) + Christ can be your backup. | (610) 853-3000(h)
On Tue, 24 Feb 1998, The Hermit Hacker wrote: > Actually, I'm not married to db_* for views...it was a "quick fix" > to ensure that things still worked. Whatever we decide on, both Julie and > Peter, at a minimum, need to know relatively soon. I know in Julie's > case, she does do a call to pg_user...I let her know tonight that she > needs to change it to db_user, for the *current* code... It's only one or two lines to change (and the queries involved are similar to those in psql), so as soon as we decide on what the view is to be called, I'll make the changes. -- Peter T Mount petermount@earthling.net or pmount@maidast.demon.co.uk Main Homepage: http://www.demon.co.uk/finder Work Homepage: http://www.maidstone.gov.uk Work EMail: peter@maidstone.gov.uk
On Tue, 24 Feb 1998, Bruce Momjian wrote: > The only problem with that is that the database administrator now should > deal with pg_shadow, and not pg_user, and pg_user is not a real table > anymore. Actually, in Unix, this is true too. I don't think we can > change the real table to pg_shadow this close to a release, can we? I like the pg_shadow idea. One thing though, although the v6.3 driver is not backward compatible with pre 6.3 backends (because of the network protocol changes), it should be forward compatible. However, if we change the real table to pg_shadow after 6.3, it would break the DatabaseMetaData class. If we change the table's name now, we won't have this problem, and existing code won't break either. -- Peter T Mount petermount@earthling.net or pmount@maidast.demon.co.uk Main Homepage: http://www.demon.co.uk/finder Work Homepage: http://www.maidstone.gov.uk Work EMail: peter@maidstone.gov.uk