Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita91ad1a

Browse files
committed
Missed a few files from Todd's patch...oops :)
1 parent4c04f77 commita91ad1a

File tree

4 files changed

+598
-0
lines changed

4 files changed

+598
-0
lines changed

‎src/backend/commands/user.c‎

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* user.c--
4+
* use pg_eval to create a new user in the catalog
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
*
9+
*
10+
*-------------------------------------------------------------------------
11+
*/
12+
#include<stdio.h>/* for sprintf() */
13+
#include<string.h>
14+
15+
#include<postgres.h>
16+
17+
#include<miscadmin.h>
18+
#include<catalog/catname.h>
19+
#include<catalog/pg_database.h>
20+
#include<catalog/pg_user.h>
21+
#include<libpq/crypt.h>
22+
#include<access/heapam.h>
23+
#include<access/xact.h>
24+
#include<storage/bufmgr.h>
25+
#include<storage/lmgr.h>
26+
#include<tcop/tcopprot.h>
27+
#include<utils/acl.h>
28+
#include<utils/palloc.h>
29+
#include<utils/rel.h>
30+
#include<commands/user.h>
31+
32+
/*---------------------------------------------------------------------
33+
* UpdatePgPwdFile
34+
*
35+
* copy the modified contents of pg_user to a file used by the postmaster
36+
* for user authentication. The file is stored as $PGDATA/pg_pwd.
37+
*---------------------------------------------------------------------
38+
*/
39+
static
40+
voidUpdatePgPwdFile(char*sql) {
41+
42+
char*filename;
43+
44+
filename=crypt_getpwdfilename();
45+
sprintf(sql,"copy %s to '%s' using delimiters '#'",UserRelationName,filename);
46+
pg_eval(sql, (char**)NULL, (Oid*)NULL,0);
47+
}
48+
49+
/*---------------------------------------------------------------------
50+
* DefineUser
51+
*
52+
* Add the user to the pg_user relation, and if specified make sure the
53+
* user is specified in the desired groups of defined in pg_group.
54+
*---------------------------------------------------------------------
55+
*/
56+
voidDefineUser(CreateUserStmt*stmt) {
57+
58+
char*pg_user;
59+
Relationpg_user_rel;
60+
TupleDescpg_user_dsc;
61+
HeapScanDescscan;
62+
HeapTupletuple;
63+
Datumdatum;
64+
Bufferbuffer;
65+
charsql[512];
66+
char*sql_end;
67+
boolexists= false,
68+
n,
69+
inblock;
70+
intmax_id=-1;
71+
72+
if (!(inblock=IsTransactionBlock()))
73+
BeginTransactionBlock();
74+
75+
/* Make sure the user attempting to create a user can insert into the pg_user
76+
* relation.
77+
*/
78+
pg_user=GetPgUserName();
79+
if (pg_aclcheck(UserRelationName,pg_user,ACL_RD |ACL_WR |ACL_AP)!=ACLCHECK_OK) {
80+
UserAbortTransactionBlock();
81+
elog(WARN,"defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"",
82+
pg_user,UserRelationName);
83+
return;
84+
}
85+
86+
/* Scan the pg_user relation to be certain the user doesn't already exist.
87+
*/
88+
pg_user_rel=heap_openr(UserRelationName);
89+
pg_user_dsc=RelationGetTupleDescriptor(pg_user_rel);
90+
/* Secure a write lock on pg_user so we can be sure of what the next usesysid
91+
* should be.
92+
*/
93+
RelationSetLockForWrite(pg_user_rel);
94+
95+
scan=heap_beginscan(pg_user_rel, false, false,0,NULL);
96+
while (HeapTupleIsValid(tuple=heap_getnext(scan,0,&buffer))) {
97+
datum=heap_getattr(tuple,buffer,Anum_pg_user_usename,pg_user_dsc,&n);
98+
99+
if (!exists&& !strncmp((char*)datum,stmt->user,strlen(stmt->user)))
100+
exists= true;
101+
102+
datum=heap_getattr(tuple,buffer,Anum_pg_user_usesysid,pg_user_dsc,&n);
103+
if ((int)datum>max_id)
104+
max_id= (int)datum;
105+
106+
ReleaseBuffer(buffer);
107+
}
108+
heap_endscan(scan);
109+
110+
if (exists) {
111+
RelationUnsetLockForWrite(pg_user_rel);
112+
heap_close(pg_user_rel);
113+
UserAbortTransactionBlock();
114+
elog(WARN,"defineUser: user \"%s\" has already been created",stmt->user);
115+
return;
116+
}
117+
118+
/* Build the insert statment to be executed.
119+
*/
120+
sprintf(sql,"insert into %s(usename,usesysid,usecreatedb,usetrace,usesuper,usecatupd,passwd",UserRelationName);
121+
/* if (stmt->password)
122+
strcat(sql, ",passwd"); -- removed so that insert empty string when no password */
123+
if (stmt->validUntil)
124+
strcat(sql,",valuntil");
125+
126+
sql_end=sql+strlen(sql);
127+
sprintf(sql_end,") values('%s',%d",stmt->user,max_id+1);
128+
if (stmt->createdb&&*stmt->createdb)
129+
strcat(sql_end,",'t','t'");
130+
else
131+
strcat(sql_end,",'f','t'");
132+
if (stmt->createuser&&*stmt->createuser)
133+
strcat(sql_end,",'t','t'");
134+
else
135+
strcat(sql_end,",'f','t'");
136+
sql_end+=strlen(sql_end);
137+
if (stmt->password) {
138+
sprintf(sql_end,",'%s'",stmt->password);
139+
sql_end+=strlen(sql_end);
140+
}else {
141+
strcpy(sql_end,",''");
142+
sql_end+=strlen(sql_end);
143+
}
144+
if (stmt->validUntil) {
145+
sprintf(sql_end,",'%s'",stmt->validUntil);
146+
sql_end+=strlen(sql_end);
147+
}
148+
strcat(sql_end,")");
149+
150+
pg_eval(sql, (char**)NULL, (Oid*)NULL,0);
151+
152+
/* Add the stuff here for groups.
153+
*/
154+
155+
RelationUnsetLockForWrite(pg_user_rel);
156+
heap_close(pg_user_rel);
157+
158+
UpdatePgPwdFile(sql);
159+
160+
if (IsTransactionBlock()&& !inblock)
161+
EndTransactionBlock();
162+
}
163+
164+
165+
externvoidAlterUser(AlterUserStmt*stmt) {
166+
167+
char*pg_user;
168+
Relationpg_user_rel;
169+
TupleDescpg_user_dsc;
170+
HeapScanDescscan;
171+
HeapTupletuple;
172+
Datumdatum;
173+
Bufferbuffer;
174+
charsql[512];
175+
char*sql_end;
176+
boolexists= false,
177+
n,
178+
inblock;
179+
intmax_id=-1;
180+
181+
if (!(inblock=IsTransactionBlock()))
182+
BeginTransactionBlock();
183+
184+
/* Make sure the user attempting to create a user can insert into the pg_user
185+
* relation.
186+
*/
187+
pg_user=GetPgUserName();
188+
if (pg_aclcheck(UserRelationName,pg_user,ACL_RD |ACL_WR)!=ACLCHECK_OK) {
189+
UserAbortTransactionBlock();
190+
elog(WARN,"alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"",
191+
pg_user,UserRelationName);
192+
return;
193+
}
194+
195+
/* Scan the pg_user relation to be certain the user exists.
196+
*/
197+
pg_user_rel=heap_openr(UserRelationName);
198+
pg_user_dsc=RelationGetTupleDescriptor(pg_user_rel);
199+
200+
scan=heap_beginscan(pg_user_rel, false, false,0,NULL);
201+
while (HeapTupleIsValid(tuple=heap_getnext(scan,0,&buffer))) {
202+
datum=heap_getattr(tuple,buffer,Anum_pg_user_usename,pg_user_dsc,&n);
203+
204+
if (!strncmp((char*)datum,stmt->user,strlen(stmt->user))) {
205+
exists= true;
206+
ReleaseBuffer(buffer);
207+
break;
208+
}
209+
}
210+
heap_endscan(scan);
211+
heap_close(pg_user_rel);
212+
213+
if (!exists) {
214+
UserAbortTransactionBlock();
215+
elog(WARN,"alterUser: user \"%s\" does not exist",stmt->user);
216+
return;
217+
}
218+
219+
/* Create the update statement to modify the user.
220+
*/
221+
sprintf(sql,"update %s set",UserRelationName);
222+
sql_end=sql;
223+
if (stmt->password) {
224+
sql_end+=strlen(sql_end);
225+
sprintf(sql_end," passwd = '%s'",stmt->password);
226+
}
227+
if (stmt->createdb) {
228+
if (sql_end!=sql)
229+
strcat(sql_end,",");
230+
sql_end+=strlen(sql_end);
231+
if (*stmt->createdb)
232+
strcat(sql_end," usecreatedb = 't'");
233+
else
234+
strcat(sql_end," usecreatedb = 'f'");
235+
}
236+
if (stmt->createuser) {
237+
if (sql_end!=sql)
238+
strcat(sql_end,",");
239+
sql_end+=strlen(sql_end);
240+
if (*stmt->createuser)
241+
strcat(sql_end," usesuper = 't'");
242+
else
243+
strcat(sql_end," usesuper = 'f'");
244+
}
245+
if (stmt->validUntil) {
246+
if (sql_end!=sql)
247+
strcat(sql_end,",");
248+
sql_end+=strlen(sql_end);
249+
sprintf(sql_end," valuntil = '%s'",stmt->validUntil);
250+
}
251+
if (sql_end!=sql) {
252+
sql_end+=strlen(sql_end);
253+
sprintf(sql_end," where usename = '%s'",stmt->user);
254+
pg_eval(sql, (char**)NULL, (Oid*)NULL,0);
255+
}
256+
257+
/* do the pg_group stuff here */
258+
259+
UpdatePgPwdFile(sql);
260+
261+
if (IsTransactionBlock()&& !inblock)
262+
EndTransactionBlock();
263+
}
264+
265+
266+
externvoidRemoveUser(char*user) {
267+
268+
char*pg_user;
269+
Relationpg_rel;
270+
TupleDescpg_dsc;
271+
HeapScanDescscan;
272+
HeapTupletuple;
273+
Datumdatum;
274+
Bufferbuffer;
275+
charsql[256];
276+
booln,
277+
inblock;
278+
intusesysid=-1,
279+
ndbase=0;
280+
char**dbase=NULL;
281+
282+
if (!(inblock=IsTransactionBlock()))
283+
BeginTransactionBlock();
284+
285+
/* Make sure the user attempting to create a user can delete from the pg_user
286+
* relation.
287+
*/
288+
pg_user=GetPgUserName();
289+
if (pg_aclcheck(UserRelationName,pg_user,ACL_RD |ACL_WR)!=ACLCHECK_OK) {
290+
UserAbortTransactionBlock();
291+
elog(WARN,"removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"",
292+
pg_user,UserRelationName);
293+
return;
294+
}
295+
296+
/* Perform a scan of the pg_user relation to find the usesysid of the user to
297+
* be deleted. If it is not found, then return a warning message.
298+
*/
299+
pg_rel=heap_openr(UserRelationName);
300+
pg_dsc=RelationGetTupleDescriptor(pg_rel);
301+
302+
scan=heap_beginscan(pg_rel, false, false,0,NULL);
303+
while (HeapTupleIsValid(tuple=heap_getnext(scan,0,&buffer))) {
304+
datum=heap_getattr(tuple,buffer,Anum_pg_user_usename,pg_dsc,&n);
305+
306+
if (!strncmp((char*)datum,user,strlen(user))) {
307+
usesysid= (int)heap_getattr(tuple,buffer,Anum_pg_user_usesysid,pg_dsc,&n);
308+
ReleaseBuffer(buffer);
309+
break;
310+
}
311+
ReleaseBuffer(buffer);
312+
}
313+
heap_endscan(scan);
314+
heap_close(pg_rel);
315+
316+
if (usesysid==-1) {
317+
UserAbortTransactionBlock();
318+
elog(WARN,"removeUser: user \"%s\" does not exist",user);
319+
return;
320+
}
321+
322+
/* Perform a scan of the pg_database relation to find the databases owned by
323+
* usesysid. Then drop them.
324+
*/
325+
pg_rel=heap_openr(DatabaseRelationName);
326+
pg_dsc=RelationGetTupleDescriptor(pg_rel);
327+
328+
scan=heap_beginscan(pg_rel, false, false,0,NULL);
329+
while (HeapTupleIsValid(tuple=heap_getnext(scan,0,&buffer))) {
330+
datum=heap_getattr(tuple,buffer,Anum_pg_database_datdba,pg_dsc,&n);
331+
332+
if ((int)datum==usesysid) {
333+
datum=heap_getattr(tuple,buffer,Anum_pg_database_datname,pg_dsc,&n);
334+
if (memcmp((void*)datum,"template1",9)) {
335+
dbase= (char**)repalloc((void*)dbase,sizeof(char*)* (ndbase+1));
336+
dbase[ndbase]= (char*)palloc(NAMEDATALEN+1);
337+
memcpy((void*)dbase[ndbase], (void*)datum,NAMEDATALEN);
338+
dbase[ndbase++][NAMEDATALEN]='\0';
339+
}
340+
}
341+
ReleaseBuffer(buffer);
342+
}
343+
heap_endscan(scan);
344+
heap_close(pg_rel);
345+
346+
while (ndbase--) {
347+
elog(NOTICE,"Dropping database %s",dbase[ndbase]);
348+
sprintf(sql,"drop database %s",dbase[ndbase]);
349+
pfree((void*)dbase[ndbase]);
350+
pg_eval(sql, (char**)NULL, (Oid*)NULL,0);
351+
}
352+
if (dbase)
353+
pfree((void*)dbase);
354+
355+
/* Since pg_user is global over all databases, one of two things must be done
356+
* to insure complete consistency. First, pg_user could be made non-global.
357+
* This would elminate the code above for deleting database and would require
358+
* the addition of code to delete tables, views, etc owned by the user.
359+
*
360+
* The second option would be to create a means of deleting tables, view,
361+
* etc. owned by the user from other databases. Pg_user is global and so
362+
* this must be done at some point.
363+
*
364+
* Let us not forget that the user should be removed from the pg_groups also.
365+
*
366+
* Todd A. Brandys 11/18/1997
367+
*
368+
*/
369+
370+
/* Remove the user from the pg_user table
371+
*/
372+
sprintf(sql,"delete from %s where usename = '%s'",UserRelationName,user);
373+
pg_eval(sql, (char**)NULL, (Oid*)NULL,0);
374+
375+
UpdatePgPwdFile(sql);
376+
377+
if (IsTransactionBlock()&& !inblock)
378+
EndTransactionBlock();
379+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp