aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/user.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/user.c')
-rw-r--r--src/backend/commands/user.c223
1 files changed, 174 insertions, 49 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 3d003616c09..e840b9109f8 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.77 2001/06/14 01:09:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.78 2001/07/10 22:09:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -197,14 +197,80 @@ CreateUser(CreateUserStmt *stmt)
char new_record_nulls[Natts_pg_shadow];
bool user_exists = false,
sysid_exists = false,
- havesysid;
+ havesysid = false;
int max_id = -1;
- List *item;
-
- havesysid = stmt->sysid > 0;
+ List *item, *option;
+ char *password = NULL; /* PostgreSQL user password */
+ int sysid = 0; /* PgSQL system id (valid if havesysid) */
+ bool createdb = false; /* Can the user create databases? */
+ bool createuser = false; /* Can this user create users? */
+ List *groupElts = NIL; /* The groups the user is a member of */
+ char *validUntil = NULL; /* The time the login is valid until */
+ DefElem *dpassword = NULL;
+ DefElem *dsysid = NULL;
+ DefElem *dcreatedb = NULL;
+ DefElem *dcreateuser = NULL;
+ DefElem *dgroupElts = NULL;
+ DefElem *dvalidUntil = NULL;
+
+ /* Extract options from the statement node tree */
+ foreach(option, stmt->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(option);
+
+ if (strcasecmp(defel->defname, "password") == 0) {
+ if (dpassword)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dpassword = defel;
+ }
+ else if (strcasecmp(defel->defname, "sysid") == 0) {
+ if (dsysid)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dsysid = defel;
+ }
+ else if (strcasecmp(defel->defname, "createdb") == 0) {
+ if (dcreatedb)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dcreatedb = defel;
+ }
+ else if (strcasecmp(defel->defname, "createuser") == 0) {
+ if (dcreateuser)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dcreateuser = defel;
+ }
+ else if (strcasecmp(defel->defname, "groupElts") == 0) {
+ if (dgroupElts)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dgroupElts = defel;
+ }
+ else if (strcasecmp(defel->defname, "validUntil") == 0) {
+ if (dvalidUntil)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dvalidUntil = defel;
+ }
+ else
+ elog(ERROR,"CREATE USER: option \"%s\" not recognized",
+ defel->defname);
+ }
+
+ if (dcreatedb)
+ createdb = intVal(dcreatedb->arg) != 0;
+ if (dcreateuser)
+ createuser = intVal(dcreateuser->arg) != 0;
+ if (dsysid)
+ {
+ sysid = intVal(dsysid->arg);
+ havesysid = true;
+ }
+ if (dvalidUntil)
+ validUntil = strVal(dvalidUntil->arg);
+ if (dpassword)
+ password = strVal(dpassword->arg);
+ if (dgroupElts)
+ groupElts = (List *) dgroupElts->arg;
/* Check some permissions first */
- if (stmt->password)
+ if (password)
CheckPgUserAclNotNull();
if (!superuser())
@@ -235,7 +301,7 @@ CreateUser(CreateUserStmt *stmt)
pg_shadow_dsc, &null);
Assert(!null);
if (havesysid) /* customized id wanted */
- sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
+ sysid_exists = (DatumGetInt32(datum) == sysid);
else
{
/* pick 1 + max */
@@ -249,30 +315,33 @@ CreateUser(CreateUserStmt *stmt)
elog(ERROR, "CREATE USER: user name \"%s\" already exists",
stmt->user);
if (sysid_exists)
- elog(ERROR, "CREATE USER: sysid %d is already assigned",
- stmt->sysid);
+ elog(ERROR, "CREATE USER: sysid %d is already assigned", sysid);
+
+ /* If no sysid given, use max existing id + 1 */
+ if (! havesysid)
+ sysid = max_id + 1;
/*
* Build a tuple to insert
*/
- new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein,
- CStringGetDatum(stmt->user));
- new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1);
+ new_record[Anum_pg_shadow_usename - 1] =
+ DirectFunctionCall1(namein, CStringGetDatum(stmt->user));
+ new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid);
- AssertState(BoolIsValid(stmt->createdb));
- new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb);
+ AssertState(BoolIsValid(createdb));
+ new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb);
new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false);
- AssertState(BoolIsValid(stmt->createuser));
- new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser);
+ AssertState(BoolIsValid(createuser));
+ new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser);
/* superuser gets catupd right by default */
- new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(stmt->createuser);
+ new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser);
- if (stmt->password)
+ if (password)
new_record[Anum_pg_shadow_passwd - 1] =
- DirectFunctionCall1(textin, CStringGetDatum(stmt->password));
- if (stmt->validUntil)
+ DirectFunctionCall1(textin, CStringGetDatum(password));
+ if (validUntil)
new_record[Anum_pg_shadow_valuntil - 1] =
- DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil));
+ DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
new_record_nulls[Anum_pg_shadow_usename - 1] = ' ';
new_record_nulls[Anum_pg_shadow_usesysid - 1] = ' ';
@@ -282,8 +351,8 @@ CreateUser(CreateUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' ';
- new_record_nulls[Anum_pg_shadow_passwd - 1] = stmt->password ? ' ' : 'n';
- new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n';
+ new_record_nulls[Anum_pg_shadow_passwd - 1] = password ? ' ' : 'n';
+ new_record_nulls[Anum_pg_shadow_valuntil - 1] = validUntil ? ' ' : 'n';
tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls);
@@ -310,15 +379,14 @@ CreateUser(CreateUserStmt *stmt)
* Add the user to the groups specified. We'll just call the below
* AlterGroup for this.
*/
- foreach(item, stmt->groupElts)
+ foreach(item, groupElts)
{
AlterGroupStmt ags;
ags.name = strVal(lfirst(item)); /* the group name to add
* this in */
ags.action = +1;
- ags.listUsers = makeList1(makeInteger(havesysid ?
- stmt->sysid : max_id + 1));
+ ags.listUsers = makeList1(makeInteger(sysid));
AlterGroup(&ags, "CREATE USER");
}
@@ -348,21 +416,69 @@ AlterUser(AlterUserStmt *stmt)
HeapTuple tuple,
new_tuple;
bool null;
+ List *option;
+ char *password = NULL; /* PostgreSQL user password */
+ int createdb = -1; /* Can the user create databases? */
+ int createuser = -1; /* Can this user create users? */
+ char *validUntil = NULL; /* The time the login is valid until */
+ DefElem *dpassword = NULL;
+ DefElem *dcreatedb = NULL;
+ DefElem *dcreateuser = NULL;
+ DefElem *dvalidUntil = NULL;
+
+ /* Extract options from the statement node tree */
+ foreach(option,stmt->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(option);
- if (stmt->password)
+ if (strcasecmp(defel->defname, "password") == 0) {
+ if (dpassword)
+ elog(ERROR, "ALTER USER: conflicting options");
+ dpassword = defel;
+ }
+ else if (strcasecmp(defel->defname, "createdb") == 0) {
+ if (dcreatedb)
+ elog(ERROR, "ALTER USER: conflicting options");
+ dcreatedb = defel;
+ }
+ else if (strcasecmp(defel->defname, "createuser") == 0) {
+ if (dcreateuser)
+ elog(ERROR, "ALTER USER: conflicting options");
+ dcreateuser = defel;
+ }
+ else if (strcasecmp(defel->defname, "validUntil") == 0) {
+ if (dvalidUntil)
+ elog(ERROR, "ALTER USER: conflicting options");
+ dvalidUntil = defel;
+ }
+ else
+ elog(ERROR,"ALTER USER: option \"%s\" not recognized",
+ defel->defname);
+ }
+
+ if (dcreatedb)
+ createdb = intVal(dcreatedb->arg);
+ if (dcreateuser)
+ createuser = intVal(dcreateuser->arg);
+ if (dvalidUntil)
+ validUntil = strVal(dvalidUntil->arg);
+ if (dpassword)
+ password = strVal(dpassword->arg);
+
+ if (password)
CheckPgUserAclNotNull();
/* must be superuser or just want to change your own password */
if (!superuser() &&
- !(stmt->createdb == 0 &&
- stmt->createuser == 0 &&
- !stmt->validUntil &&
- stmt->password &&
+ !(createdb < 0 &&
+ createuser < 0 &&
+ !validUntil &&
+ password &&
strcmp(GetUserName(GetUserId()), stmt->user) == 0))
elog(ERROR, "ALTER USER: permission denied");
/* changes to the flat password file cannot be rolled back */
- if (IsTransactionBlock() && stmt->password)
+ if (IsTransactionBlock() && password)
elog(NOTICE, "ALTER USER: password changes cannot be rolled back");
/*
@@ -391,7 +507,7 @@ AlterUser(AlterUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usesysid - 1] = null ? 'n' : ' ';
/* createdb */
- if (stmt->createdb == 0)
+ if (createdb < 0)
{
/* don't change */
new_record[Anum_pg_shadow_usecreatedb - 1] = heap_getattr(tuple, Anum_pg_shadow_usecreatedb, pg_shadow_dsc, &null);
@@ -399,7 +515,7 @@ AlterUser(AlterUserStmt *stmt)
}
else
{
- new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb > 0 ? true : false);
+ new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb > 0);
new_record_nulls[Anum_pg_shadow_usecreatedb - 1] = ' ';
}
@@ -408,7 +524,7 @@ AlterUser(AlterUserStmt *stmt)
new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' ';
/* createuser (superuser) */
- if (stmt->createuser == 0)
+ if (createuser < 0)
{
/* don't change */
new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null);
@@ -416,14 +532,14 @@ AlterUser(AlterUserStmt *stmt)
}
else
{
- new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser > 0 ? true : false);
+ new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0);
new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' ';
}
/* catupd - set to false if someone's superuser priv is being yanked */
- if (stmt->createuser < 0)
+ if (createuser == 0)
{
- new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (false);
+ new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(false);
new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' ';
}
else
@@ -434,10 +550,10 @@ AlterUser(AlterUserStmt *stmt)
}
/* password */
- if (stmt->password)
+ if (password)
{
new_record[Anum_pg_shadow_passwd - 1] =
- DirectFunctionCall1(textin, CStringGetDatum(stmt->password));
+ DirectFunctionCall1(textin, CStringGetDatum(password));
new_record_nulls[Anum_pg_shadow_passwd - 1] = ' ';
}
else
@@ -449,10 +565,10 @@ AlterUser(AlterUserStmt *stmt)
}
/* valid until */
- if (stmt->validUntil)
+ if (validUntil)
{
new_record[Anum_pg_shadow_valuntil - 1] =
- DirectFunctionCall1(nabstimein, CStringGetDatum(stmt->validUntil));
+ DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
new_record_nulls[Anum_pg_shadow_valuntil - 1] = ' ';
}
else
@@ -761,9 +877,10 @@ CreateGroup(CreateGroupStmt *stmt)
else
max_id++;
- new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
- new_record[Anum_pg_group_grosysid - 1] = (Datum) (max_id);
- new_record[Anum_pg_group_grolist - 1] = (Datum) userarray;
+ new_record[Anum_pg_group_groname - 1] =
+ DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+ new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(max_id);
+ new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(userarray);
new_record_nulls[Anum_pg_group_groname - 1] = ' ';
new_record_nulls[Anum_pg_group_grosysid - 1] = ' ';
@@ -832,7 +949,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
* create user */
{
Datum new_record[Natts_pg_group];
- char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
+ char new_record_nulls[Natts_pg_group];
ArrayType *newarray,
*oldarray;
List *newlist = NULL,
@@ -914,9 +1031,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
/*
* Form a tuple with the new array and write it back.
*/
- new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
+ new_record[Anum_pg_group_groname - 1] =
+ DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+ new_record_nulls[Anum_pg_group_groname - 1] = ' ';
new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
+ new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' ';
new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray);
+ new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n';
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);
@@ -950,7 +1071,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
{
HeapTuple tuple;
Datum new_record[Natts_pg_group];
- char new_record_nulls[Natts_pg_group] = {' ', ' ', ' '};
+ char new_record_nulls[Natts_pg_group];
ArrayType *oldarray,
*newarray;
List *newlist = NULL,
@@ -1014,9 +1135,13 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
/*
* Insert the new tuple with the updated user list
*/
- new_record[Anum_pg_group_groname - 1] = (Datum) (stmt->name);
+ new_record[Anum_pg_group_groname - 1] =
+ DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
+ new_record_nulls[Anum_pg_group_groname - 1] = ' ';
new_record[Anum_pg_group_grosysid - 1] = heap_getattr(group_tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
+ new_record_nulls[Anum_pg_group_grosysid - 1] = null ? 'n' : ' ';
new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray);
+ new_record_nulls[Anum_pg_group_grolist - 1] = newarray ? ' ' : 'n';
tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
simple_heap_update(pg_group_rel, &group_tuple->t_self, tuple);