Re: grant/revoke bug with delete/update - Mailing list pgsql-bugs

From Bruce Momjian
Subject Re: grant/revoke bug with delete/update
Date
Msg-id 200111262004.fAQK4Ce14165@candle.pha.pa.us
Whole thread Raw
In response to grant/revoke bug with delete/update  (Jerome ALET <alet@unice.fr>)
List pgsql-bugs
This has been fixed in 7.2beta:

    * -Permission to DELETE table also allows UPDATE (Peter E)

---------------------------------------------------------------------------

> Hi,
>
> first I'm sorry to not fill the form, I'm too lazy, and it's not platform
> nor version dependent AFAIK.
>
> I recently posted a question (on Feb 23rd) to pgsql-sql concerning the
> fact that update and insert are considered the same thing when you modify
> permissions with grant and revoke. (Maybe it was the wrong place to post
> it.)
>
> for example a "grant delete" also grants "update" which is completely
> wrong. More importantly the user is not informed, and this could lead to
> VERY IMPORTANT SECURITY PROBLEMS, like someone who should only be able to
> update existing records, have the permission to delete all records...
>
> I've read postgresql documentation, especially the grant and revoke
> manpages, and I've found no mention of this bug, which is IMHO a Big
> Mistake (tm).
>
> attached to this message you'll find a patch for version 6.5.2 wich
> differentiate delete and update, because before they were considered as
> "write". The patch only modifies .c .y and .h files, but no documentation.
>
> the new acl rights look like: arRdu
> a for append
> r for read
> R for rules
> d for delete
> u for update
>
> instead of: arwR
> a for append
> r for read
> w for update AND delete
> R for rules
>
> This patch seems to work at least with what I've tested, you'll find a
> test session at the end of this message.
>
> I hope this patch will help and that it will be easy to incorporate it in
> 7.0, which I haven't the time to do for now.
>
> And for the bug report I posted on Feb 23rd on "drop user" which keeps the
> user's acl in the database, and the deleted user id being reused, I've not
> done anything, but I consider this a major problem. Please consider it for
> a next version.
>
> Because I'm not an expert, I suggest you remove gram.c before applying the
> patch, in order for this file to be generated again from gram.y, but maybe
> this is not necessary.
>
> I'd be very pleased if some people could test this more than I can,
> because I don't use postgresql intensively with special permissions.
>
> I'm not sure for some parts of the patch, especially in execMain.c
> so if a postgresql hacker could examine it, this would be fine.
>
> dump of test session:
> ---------------------
>
> ------- CUT -------
>
> template1=> create database db;
> CREATEDB
> template1=> create user john;
> CREATE USER
> template1=> \connect db
> connecting to new database: db
> db=> create table t (id INT4, name TEXT);
> CREATE
> db=> \z
> Database    = db
>  +----------+--------------------------+
>  | Relation | Grant/Revoke Permissions |
>  +----------+--------------------------+
>  | t        |                          |
>  +----------+--------------------------+
> db=> grant all on t to john;
> CHANGE
> db=> \z
> Database    = db
>  +----------+--------------------------+
>  | Relation | Grant/Revoke Permissions |
>  +----------+--------------------------+
>  | t        | {"=","john=arduR"}       |
>  +----------+--------------------------+
> db=> \connect db john
> connecting to new database: db as user: john
> db=> insert into t (id, name) values (1, 'xxx');
> INSERT 18560 1
> db=> update t set name = 'yyy' where id=1;
> UPDATE 1
> db=> select * from t;
> id|name
> --+----
>  1|yyy
> (1 row)
>
> db=> delete from t;
> DELETE 1
> db=> select * from t;
> id|name
> --+----
> (0 rows)
>
> db=> insert into t (id, name) values (1, 'xxx');
> INSERT 18561 1
> db=> \connect db postgres
> connecting to new database: db as user: postgres
> db=> revoke update on t from john;
> CHANGE
> db=> \z
> Database    = db
>  +----------+--------------------------+
>  | Relation | Grant/Revoke Permissions |
>  +----------+--------------------------+
>  | t        | {"=","john=ardR"}        |
>  +----------+--------------------------+
> db=> \connect db john;
> connecting to new database: db as user: john
> db=> insert into t (id, name) values (2, 'yyy');
> INSERT 18592 1
> db=> update t set name='modified by john' where id=2;
> ERROR:  t: Permission denied.
> db=> delete from t where id=2;
> DELETE 1
> db=> select * from t;
> id|name
> --+----
>  1|xxx
> (1 row)
>
> db=> \connect db postgres
> connecting to new database: db as user: postgres
> db=> revoke insert on t from john;
> CHANGE
> db=> \connect db john;
> connecting to new database: db as user: john
> db=> \z
> Database    = db
>  +----------+--------------------------+
>  | Relation | Grant/Revoke Permissions |
>  +----------+--------------------------+
>  | t        | {"=","john=rdR"}         |
>  +----------+--------------------------+
> db=> insert into t (id, name) values (3, 'I try to insert something');
> ERROR:  t: Permission denied.
> db=> delete from t;
> DELETE 1
> db=> select * from t;
> id|name
> --+----
> (0 rows)
>
> db=> \connect db postgres
> connecting to new database: db as user: postgres
> db=> insert into t (id, name) values (1, 'xxx');
> INSERT 18624 1
> db=> \connect db john;
> connecting to new database: db as user: john
> db=> update t set name='john' where id =1;
> ERROR:  t: Permission denied.
> db=> \connect db postgres
> connecting to new database: db as user: postgres
> db=> revoke delete on t from john;
> CHANGE
> db=> grant update on t to john;
> CHANGE
> db=> \connect db john;
> connecting to new database: db as user: john
> db=> delete from t;
> ERROR:  t: Permission denied.
> db=> update t set name='john' where id=1;
> UPDATE 1
> db=> select * from t;
> id|name
> --+----
>  1|john
> (1 row)
>
> ------- CUT -------
>
> Thank you for reading.
>
> bye,
>
> Jerome ALET - alet@unice.fr - http://cortex.unice.fr/~jerome
> Faculte de Medecine de Nice - http://noe.unice.fr - Tel: 04 93 37 76 30
> 28 Avenue de Valombrose - 06107 NICE Cedex 2 - FRANCE

Content-Description: the 6.5.2 patch

> diff -urbw postgresql-6.5.2/src/backend/catalog/aclchk.c postgresql-6.5.2-patched/src/backend/catalog/aclchk.c
> --- postgresql-6.5.2/src/backend/catalog/aclchk.c    Mon Aug  2 07:56:53 1999
> +++ postgresql-6.5.2-patched/src/backend/catalog/aclchk.c    Wed Mar  1 16:39:44 2000
> @@ -381,7 +381,7 @@
>           * pg_database table, there is still additional permissions
>           * checking in dbcommands.c
>           */
> -        if ((mode & ACL_WR) || (mode & ACL_AP))
> +        if (mode & ACL_AP)
>              return ACLCHECK_OK;
>      }
>
> @@ -390,7 +390,7 @@
>       * pg_shadow.usecatupd is set.    (This is to let superusers protect
>       * themselves from themselves.)
>       */
> -    if (((mode & ACL_WR) || (mode & ACL_AP)) &&
> +    if ((mode & ACL_AP) &&
>          !allowSystemTableMods && IsSystemRelationName(relname) &&
>          !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd)
>      {
> diff -urbw postgresql-6.5.2/src/backend/commands/command.c postgresql-6.5.2-patched/src/backend/commands/command.c
> --- postgresql-6.5.2/src/backend/commands/command.c    Mon Aug  2 07:56:57 1999
> +++ postgresql-6.5.2-patched/src/backend/commands/command.c    Wed Mar  1 16:30:23 2000
> @@ -524,7 +524,9 @@
>      if (lockstmt->mode == AccessShareLock)
>          aclresult = pg_aclcheck(lockstmt->relname, GetPgUserName(), ACL_RD);
>      else
> -        aclresult = pg_aclcheck(lockstmt->relname, GetPgUserName(), ACL_WR);
> +        /* do we really need to have all these permissions at the same time ? */
> +        /* shouldn't we test lockstmt->mode first ? */
> +        aclresult = pg_aclcheck(lockstmt->relname, GetPgUserName(), (ACL_AP | ACL_DE | ACL_UP));
>
>      if (aclresult != ACLCHECK_OK)
>          elog(ERROR, "LOCK TABLE: permission denied");
> diff -urbw postgresql-6.5.2/src/backend/commands/copy.c postgresql-6.5.2-patched/src/backend/commands/copy.c
> --- postgresql-6.5.2/src/backend/commands/copy.c    Sat Jul  3 02:32:39 1999
> +++ postgresql-6.5.2-patched/src/backend/commands/copy.c    Wed Mar  1 16:30:35 2000
> @@ -242,7 +242,8 @@
>      FILE       *fp;
>      Relation    rel;
>      extern char *UserName;        /* defined in global.c */
> -    const AclMode required_access = from ? ACL_WR : ACL_RD;
> +    /* why should we need other permissions than APPEND ? */
> +    const AclMode required_access = from ? ACL_AP : ACL_RD;
>      int            result;
>
>      rel = heap_openr(relname);
> diff -urbw postgresql-6.5.2/src/backend/commands/sequence.c postgresql-6.5.2-patched/src/backend/commands/sequence.c
> --- postgresql-6.5.2/src/backend/commands/sequence.c    Mon Aug  2 07:56:59 1999
> +++ postgresql-6.5.2-patched/src/backend/commands/sequence.c    Wed Mar  1 16:31:05 2000
> @@ -314,7 +314,8 @@
>      Form_pg_sequence seq;
>
>  #ifndef NO_SECURITY
> -    if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK)
> +    /* why should we need more than UPDATE permission ? */
> +    if (pg_aclcheck(seqname, getpgusername(), ACL_UP) != ACLCHECK_OK)
>          elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
>               seqname, seqname);
>  #endif
> diff -urbw postgresql-6.5.2/src/backend/commands/user.c postgresql-6.5.2-patched/src/backend/commands/user.c
> --- postgresql-6.5.2/src/backend/commands/user.c    Mon Aug  2 07:56:59 1999
> +++ postgresql-6.5.2-patched/src/backend/commands/user.c    Wed Mar  1 16:31:38 2000
> @@ -115,7 +115,7 @@
>       * pg_shadow relation.
>       */
>      pg_shadow = GetPgUserName();
> -    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK)
> +    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_AP | ACL_DE | ACL_UP) != ACLCHECK_OK)
>      {
>          UserAbortTransactionBlock();
>          elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"",
> @@ -227,7 +227,8 @@
>       * pg_shadow relation.
>       */
>      pg_shadow = GetPgUserName();
> -    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK)
> +    /* why should we need more than UPDATE ? */
> +    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_UP) != ACLCHECK_OK)
>      {
>          UserAbortTransactionBlock();
>          elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"",
> @@ -329,11 +330,12 @@
>          BeginTransactionBlock();
>
>      /*
> -     * Make sure the user attempting to create a user can delete from the
> +     * Make sure the user attempting to delete a user can delete from the
>       * pg_shadow relation.
>       */
>      pg_shadow = GetPgUserName();
> -    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK)
> +    /* why should we need more than DELETE ? */
> +    if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_DE) != ACLCHECK_OK)
>      {
>          UserAbortTransactionBlock();
>          elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"",
> diff -urbw postgresql-6.5.2/src/backend/executor/execMain.c postgresql-6.5.2-patched/src/backend/executor/execMain.c
> --- postgresql-6.5.2/src/backend/executor/execMain.c    Thu Jun 17 17:15:49 1999
> +++ postgresql-6.5.2-patched/src/backend/executor/execMain.c    Wed Mar  1 18:31:31 2000
> @@ -464,14 +464,16 @@
>              switch (operation)
>              {
>                  case CMD_INSERT:
> -                    ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
> -                        ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
> +                    ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK);
>                      opstr = "append";
>                      break;
>                  case CMD_DELETE:
> +                    ok = ((aclcheck_result = CHECK(ACL_DE)) == ACLCHECK_OK);
> +                    opstr = "delete";
> +                    break;
>                  case CMD_UPDATE:
> -                    ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
> -                    opstr = "write";
> +                    ok = ((aclcheck_result = CHECK(ACL_UP)) == ACLCHECK_OK);
> +                    opstr = "update";
>                      break;
>                  default:
>                      elog(ERROR, "ExecCheckPerms: bogus operation %d",
> @@ -508,8 +510,9 @@
>              StrNCpy(rname.data,
>                      ((Form_pg_class) GETSTRUCT(htup))->relname.data,
>                      NAMEDATALEN);
> -            ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
> -            opstr = "write";
> +            /* is it the right thing to do ? */
> +            ok = ((aclcheck_result = CHECK((ACL_AP | ACL_DE | ACL_UP))) == ACLCHECK_OK);
> +            opstr = "write";    /* unused ? */
>              if (!ok)
>                  elog(ERROR, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
>          }
> diff -urbw postgresql-6.5.2/src/backend/parser/gram.y postgresql-6.5.2-patched/src/backend/parser/gram.y
> --- postgresql-6.5.2/src/backend/parser/gram.y    Tue Sep 14 08:07:35 1999
> +++ postgresql-6.5.2-patched/src/backend/parser/gram.y    Wed Mar  1 16:33:34 2000
> @@ -1694,11 +1694,11 @@
>
>  privileges:  ALL PRIVILEGES
>                  {
> -                 $$ = aclmakepriv("rwaR",0);
> +                 $$ = aclmakepriv("raduR",0);
>                  }
>          | ALL
>                  {
> -                 $$ = aclmakepriv("rwaR",0);
> +                 $$ = aclmakepriv("raduR",0);
>                  }
>          | operation_commalist
>                  {
> @@ -1726,11 +1726,11 @@
>                  }
>          | UPDATE
>                  {
> -                        $$ = ACL_MODE_WR_CHR;
> +                        $$ = ACL_MODE_UP_CHR;
>                  }
>          | DELETE
>                  {
> -                        $$ = ACL_MODE_WR_CHR;
> +                        $$ = ACL_MODE_DE_CHR;
>                  }
>          | RULE
>                  {
> diff -urbw postgresql-6.5.2/src/backend/parser/parse.h postgresql-6.5.2-patched/src/backend/parser/parse.h
> --- postgresql-6.5.2/src/backend/parser/parse.h    Thu Sep 16 02:23:39 1999
> +++ postgresql-6.5.2-patched/src/backend/parser/parse.h    Wed Mar  1 18:34:46 2000
> @@ -29,236 +29,236 @@
>      RuleStmt            *rstmt;
>      InsertStmt            *astmt;
>  } YYSTYPE;
> -#define    ABSOLUTE    257
> -#define    ACTION    258
> -#define    ADD    259
> -#define    ALL    260
> -#define    ALTER    261
> -#define    AND    262
> -#define    ANY    263
> -#define    AS    264
> -#define    ASC    265
> -#define    BEGIN_TRANS    266
> -#define    BETWEEN    267
> -#define    BOTH    268
> -#define    BY    269
> -#define    CASCADE    270
> -#define    CASE    271
> -#define    CAST    272
> -#define    CHAR    273
> -#define    CHARACTER    274
> -#define    CHECK    275
> -#define    CLOSE    276
> -#define    COALESCE    277
> -#define    COLLATE    278
> -#define    COLUMN    279
> -#define    COMMIT    280
> -#define    CONSTRAINT    281
> -#define    CREATE    282
> -#define    CROSS    283
> -#define    CURRENT    284
> -#define    CURRENT_DATE    285
> -#define    CURRENT_TIME    286
> -#define    CURRENT_TIMESTAMP    287
> -#define    CURRENT_USER    288
> -#define    CURSOR    289
> -#define    DAY_P    290
> -#define    DECIMAL    291
> -#define    DECLARE    292
> -#define    DEFAULT    293
> -#define    DELETE    294
> -#define    DESC    295
> -#define    DISTINCT    296
> -#define    DOUBLE    297
> -#define    DROP    298
> -#define    ELSE    299
> -#define    END_TRANS    300
> -#define    EXCEPT    301
> -#define    EXECUTE    302
> -#define    EXISTS    303
> -#define    EXTRACT    304
> -#define    FALSE_P    305
> -#define    FETCH    306
> -#define    FLOAT    307
> -#define    FOR    308
> -#define    FOREIGN    309
> -#define    FROM    310
> -#define    FULL    311
> -#define    GLOBAL    312
> -#define    GRANT    313
> -#define    GROUP    314
> -#define    HAVING    315
> -#define    HOUR_P    316
> -#define    IN    317
> -#define    INNER_P    318
> -#define    INSENSITIVE    319
> -#define    INSERT    320
> -#define    INTERSECT    321
> -#define    INTERVAL    322
> -#define    INTO    323
> -#define    IS    324
> -#define    ISOLATION    325
> -#define    JOIN    326
> -#define    KEY    327
> -#define    LANGUAGE    328
> -#define    LEADING    329
> -#define    LEFT    330
> -#define    LEVEL    331
> -#define    LIKE    332
> -#define    LOCAL    333
> -#define    MATCH    334
> -#define    MINUTE_P    335
> -#define    MONTH_P    336
> -#define    NAMES    337
> -#define    NATIONAL    338
> -#define    NATURAL    339
> -#define    NCHAR    340
> -#define    NEXT    341
> -#define    NO    342
> -#define    NOT    343
> -#define    NULLIF    344
> -#define    NULL_P    345
> -#define    NUMERIC    346
> -#define    OF    347
> -#define    ON    348
> -#define    ONLY    349
> -#define    OPTION    350
> -#define    OR    351
> -#define    ORDER    352
> -#define    OUTER_P    353
> -#define    PARTIAL    354
> -#define    POSITION    355
> -#define    PRECISION    356
> -#define    PRIMARY    357
> -#define    PRIOR    358
> -#define    PRIVILEGES    359
> -#define    PROCEDURE    360
> -#define    PUBLIC    361
> -#define    READ    362
> -#define    REFERENCES    363
> -#define    RELATIVE    364
> -#define    REVOKE    365
> -#define    RIGHT    366
> -#define    ROLLBACK    367
> -#define    SCROLL    368
> -#define    SECOND_P    369
> -#define    SELECT    370
> -#define    SET    371
> -#define    SUBSTRING    372
> -#define    TABLE    373
> -#define    TEMP    374
> -#define    TEMPORARY    375
> -#define    THEN    376
> -#define    TIME    377
> -#define    TIMESTAMP    378
> -#define    TIMEZONE_HOUR    379
> -#define    TIMEZONE_MINUTE    380
> -#define    TO    381
> -#define    TRAILING    382
> -#define    TRANSACTION    383
> -#define    TRIM    384
> -#define    TRUE_P    385
> -#define    UNION    386
> -#define    UNIQUE    387
> -#define    UPDATE    388
> -#define    USER    389
> -#define    USING    390
> -#define    VALUES    391
> -#define    VARCHAR    392
> -#define    VARYING    393
> -#define    VIEW    394
> -#define    WHEN    395
> -#define    WHERE    396
> -#define    WITH    397
> -#define    WORK    398
> -#define    YEAR_P    399
> -#define    ZONE    400
> -#define    TRIGGER    401
> -#define    COMMITTED    402
> -#define    SERIALIZABLE    403
> -#define    TYPE_P    404
> -#define    ABORT_TRANS    405
> -#define    ACCESS    406
> -#define    AFTER    407
> -#define    AGGREGATE    408
> -#define    ANALYZE    409
> -#define    BACKWARD    410
> -#define    BEFORE    411
> -#define    BINARY    412
> -#define    CACHE    413
> -#define    CLUSTER    414
> -#define    COPY    415
> -#define    CREATEDB    416
> -#define    CREATEUSER    417
> -#define    CYCLE    418
> -#define    DATABASE    419
> -#define    DELIMITERS    420
> -#define    DO    421
> -#define    EACH    422
> -#define    ENCODING    423
> -#define    EXCLUSIVE    424
> -#define    EXPLAIN    425
> -#define    EXTEND    426
> -#define    FORWARD    427
> -#define    FUNCTION    428
> -#define    HANDLER    429
> -#define    INCREMENT    430
> -#define    INDEX    431
> -#define    INHERITS    432
> -#define    INSTEAD    433
> -#define    ISNULL    434
> -#define    LANCOMPILER    435
> -#define    LIMIT    436
> -#define    LISTEN    437
> -#define    LOAD    438
> -#define    LOCATION    439
> -#define    LOCK_P    440
> -#define    MAXVALUE    441
> -#define    MINVALUE    442
> -#define    MODE    443
> -#define    MOVE    444
> -#define    NEW    445
> -#define    NOCREATEDB    446
> -#define    NOCREATEUSER    447
> -#define    NONE    448
> -#define    NOTHING    449
> -#define    NOTIFY    450
> -#define    NOTNULL    451
> -#define    OFFSET    452
> -#define    OIDS    453
> -#define    OPERATOR    454
> -#define    PASSWORD    455
> -#define    PROCEDURAL    456
> -#define    RENAME    457
> -#define    RESET    458
> -#define    RETURNS    459
> -#define    ROW    460
> -#define    RULE    461
> -#define    SEQUENCE    462
> -#define    SERIAL    463
> -#define    SETOF    464
> -#define    SHARE    465
> -#define    SHOW    466
> -#define    START    467
> -#define    STATEMENT    468
> -#define    STDIN    469
> -#define    STDOUT    470
> -#define    TRUSTED    471
> -#define    UNLISTEN    472
> -#define    UNTIL    473
> -#define    VACUUM    474
> -#define    VALID    475
> -#define    VERBOSE    476
> -#define    VERSION    477
> -#define    IDENT    478
> -#define    SCONST    479
> -#define    Op    480
> -#define    ICONST    481
> -#define    PARAM    482
> -#define    FCONST    483
> -#define    OP    484
> -#define    UMINUS    485
> -#define    TYPECAST    486
> +#define    ABSOLUTE    258
> +#define    ACTION    259
> +#define    ADD    260
> +#define    ALL    261
> +#define    ALTER    262
> +#define    AND    263
> +#define    ANY    264
> +#define    AS    265
> +#define    ASC    266
> +#define    BEGIN_TRANS    267
> +#define    BETWEEN    268
> +#define    BOTH    269
> +#define    BY    270
> +#define    CASCADE    271
> +#define    CASE    272
> +#define    CAST    273
> +#define    CHAR    274
> +#define    CHARACTER    275
> +#define    CHECK    276
> +#define    CLOSE    277
> +#define    COALESCE    278
> +#define    COLLATE    279
> +#define    COLUMN    280
> +#define    COMMIT    281
> +#define    CONSTRAINT    282
> +#define    CREATE    283
> +#define    CROSS    284
> +#define    CURRENT    285
> +#define    CURRENT_DATE    286
> +#define    CURRENT_TIME    287
> +#define    CURRENT_TIMESTAMP    288
> +#define    CURRENT_USER    289
> +#define    CURSOR    290
> +#define    DAY_P    291
> +#define    DECIMAL    292
> +#define    DECLARE    293
> +#define    DEFAULT    294
> +#define    DELETE    295
> +#define    DESC    296
> +#define    DISTINCT    297
> +#define    DOUBLE    298
> +#define    DROP    299
> +#define    ELSE    300
> +#define    END_TRANS    301
> +#define    EXCEPT    302
> +#define    EXECUTE    303
> +#define    EXISTS    304
> +#define    EXTRACT    305
> +#define    FALSE_P    306
> +#define    FETCH    307
> +#define    FLOAT    308
> +#define    FOR    309
> +#define    FOREIGN    310
> +#define    FROM    311
> +#define    FULL    312
> +#define    GLOBAL    313
> +#define    GRANT    314
> +#define    GROUP    315
> +#define    HAVING    316
> +#define    HOUR_P    317
> +#define    IN    318
> +#define    INNER_P    319
> +#define    INSENSITIVE    320
> +#define    INSERT    321
> +#define    INTERSECT    322
> +#define    INTERVAL    323
> +#define    INTO    324
> +#define    IS    325
> +#define    ISOLATION    326
> +#define    JOIN    327
> +#define    KEY    328
> +#define    LANGUAGE    329
> +#define    LEADING    330
> +#define    LEFT    331
> +#define    LEVEL    332
> +#define    LIKE    333
> +#define    LOCAL    334
> +#define    MATCH    335
> +#define    MINUTE_P    336
> +#define    MONTH_P    337
> +#define    NAMES    338
> +#define    NATIONAL    339
> +#define    NATURAL    340
> +#define    NCHAR    341
> +#define    NEXT    342
> +#define    NO    343
> +#define    NOT    344
> +#define    NULLIF    345
> +#define    NULL_P    346
> +#define    NUMERIC    347
> +#define    OF    348
> +#define    ON    349
> +#define    ONLY    350
> +#define    OPTION    351
> +#define    OR    352
> +#define    ORDER    353
> +#define    OUTER_P    354
> +#define    PARTIAL    355
> +#define    POSITION    356
> +#define    PRECISION    357
> +#define    PRIMARY    358
> +#define    PRIOR    359
> +#define    PRIVILEGES    360
> +#define    PROCEDURE    361
> +#define    PUBLIC    362
> +#define    READ    363
> +#define    REFERENCES    364
> +#define    RELATIVE    365
> +#define    REVOKE    366
> +#define    RIGHT    367
> +#define    ROLLBACK    368
> +#define    SCROLL    369
> +#define    SECOND_P    370
> +#define    SELECT    371
> +#define    SET    372
> +#define    SUBSTRING    373
> +#define    TABLE    374
> +#define    TEMP    375
> +#define    TEMPORARY    376
> +#define    THEN    377
> +#define    TIME    378
> +#define    TIMESTAMP    379
> +#define    TIMEZONE_HOUR    380
> +#define    TIMEZONE_MINUTE    381
> +#define    TO    382
> +#define    TRAILING    383
> +#define    TRANSACTION    384
> +#define    TRIM    385
> +#define    TRUE_P    386
> +#define    UNION    387
> +#define    UNIQUE    388
> +#define    UPDATE    389
> +#define    USER    390
> +#define    USING    391
> +#define    VALUES    392
> +#define    VARCHAR    393
> +#define    VARYING    394
> +#define    VIEW    395
> +#define    WHEN    396
> +#define    WHERE    397
> +#define    WITH    398
> +#define    WORK    399
> +#define    YEAR_P    400
> +#define    ZONE    401
> +#define    TRIGGER    402
> +#define    COMMITTED    403
> +#define    SERIALIZABLE    404
> +#define    TYPE_P    405
> +#define    ABORT_TRANS    406
> +#define    ACCESS    407
> +#define    AFTER    408
> +#define    AGGREGATE    409
> +#define    ANALYZE    410
> +#define    BACKWARD    411
> +#define    BEFORE    412
> +#define    BINARY    413
> +#define    CACHE    414
> +#define    CLUSTER    415
> +#define    COPY    416
> +#define    CREATEDB    417
> +#define    CREATEUSER    418
> +#define    CYCLE    419
> +#define    DATABASE    420
> +#define    DELIMITERS    421
> +#define    DO    422
> +#define    EACH    423
> +#define    ENCODING    424
> +#define    EXCLUSIVE    425
> +#define    EXPLAIN    426
> +#define    EXTEND    427
> +#define    FORWARD    428
> +#define    FUNCTION    429
> +#define    HANDLER    430
> +#define    INCREMENT    431
> +#define    INDEX    432
> +#define    INHERITS    433
> +#define    INSTEAD    434
> +#define    ISNULL    435
> +#define    LANCOMPILER    436
> +#define    LIMIT    437
> +#define    LISTEN    438
> +#define    LOAD    439
> +#define    LOCATION    440
> +#define    LOCK_P    441
> +#define    MAXVALUE    442
> +#define    MINVALUE    443
> +#define    MODE    444
> +#define    MOVE    445
> +#define    NEW    446
> +#define    NOCREATEDB    447
> +#define    NOCREATEUSER    448
> +#define    NONE    449
> +#define    NOTHING    450
> +#define    NOTIFY    451
> +#define    NOTNULL    452
> +#define    OFFSET    453
> +#define    OIDS    454
> +#define    OPERATOR    455
> +#define    PASSWORD    456
> +#define    PROCEDURAL    457
> +#define    RENAME    458
> +#define    RESET    459
> +#define    RETURNS    460
> +#define    ROW    461
> +#define    RULE    462
> +#define    SEQUENCE    463
> +#define    SERIAL    464
> +#define    SETOF    465
> +#define    SHARE    466
> +#define    SHOW    467
> +#define    START    468
> +#define    STATEMENT    469
> +#define    STDIN    470
> +#define    STDOUT    471
> +#define    TRUSTED    472
> +#define    UNLISTEN    473
> +#define    UNTIL    474
> +#define    VACUUM    475
> +#define    VALID    476
> +#define    VERBOSE    477
> +#define    VERSION    478
> +#define    IDENT    479
> +#define    SCONST    480
> +#define    Op    481
> +#define    ICONST    482
> +#define    PARAM    483
> +#define    FCONST    484
> +#define    OP    485
> +#define    UMINUS    486
> +#define    TYPECAST    487
>
>
>  extern YYSTYPE yylval;
> diff -urbw postgresql-6.5.2/src/backend/parser/parse_func.c postgresql-6.5.2-patched/src/backend/parser/parse_func.c
> --- postgresql-6.5.2/src/backend/parser/parse_func.c    Fri Jun 18 00:21:40 1999
> +++ postgresql-6.5.2-patched/src/backend/parser/parse_func.c    Wed Mar  1 16:33:53 2000
> @@ -601,7 +601,8 @@
>
>          if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
>                         (((funcid == F_NEXTVAL) || (funcid == F_SETVAL)) ?
> -                        ACL_WR : ACL_RD)))
> +                        /* if nextval and setval are atomic, which I don't know, update should be enough */
> +                        ACL_UP : ACL_RD)))
>              != ACLCHECK_OK)
>              elog(ERROR, "%s.%s: %s",
>                seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
> diff -urbw postgresql-6.5.2/src/backend/rewrite/locks.c postgresql-6.5.2-patched/src/backend/rewrite/locks.c
> --- postgresql-6.5.2/src/backend/rewrite/locks.c    Sun Feb 14 00:17:44 1999
> +++ postgresql-6.5.2-patched/src/backend/rewrite/locks.c    Wed Mar  1 16:34:20 2000
> @@ -228,8 +228,15 @@
>                          case CMD_INSERT:
>                              reqperm = ACL_AP;
>                              break;
> +                        case CMD_DELETE:
> +                            reqperm = ACL_DE;
> +                            break;
> +                        case CMD_UPDATE:
> +                            reqperm = ACL_UP;
> +                            break;
>                          default:
> -                            reqperm = ACL_WR;
> +                            /* is it The Right Thing To Do (tm) ? */
> +                            reqperm = ACL_AP | ACL_DE | ACL_UP;
>                              break;
>                      }
>                  else
> diff -urbw postgresql-6.5.2/src/backend/rewrite/rewriteHandler.c
postgresql-6.5.2-patched/src/backend/rewrite/rewriteHandler.c
> --- postgresql-6.5.2/src/backend/rewrite/rewriteHandler.c    Sun Jul 11 19:54:30 1999
> +++ postgresql-6.5.2-patched/src/backend/rewrite/rewriteHandler.c    Wed Mar  1 16:35:01 2000
> @@ -2282,8 +2282,15 @@
>                  case CMD_INSERT:
>                      reqperm = ACL_AP;
>                      break;
> +                case CMD_DELETE:
> +                    reqperm = ACL_DE;
> +                    break;
> +                case CMD_UPDATE:
> +                    reqperm = ACL_UP;
> +                    break;
>                  default:
> -                    reqperm = ACL_WR;
> +                    /* is it The Right Thing To Do (tm) ? */
> +                    reqperm = ACL_AP | ACL_DE | ACL_UP;
>                      break;
>              }
>
> diff -urbw postgresql-6.5.2/src/backend/storage/file/fd.c postgresql-6.5.2-patched/src/backend/storage/file/fd.c
> diff -urbw postgresql-6.5.2/src/backend/utils/adt/acl.c postgresql-6.5.2-patched/src/backend/utils/adt/acl.c
> --- postgresql-6.5.2/src/backend/utils/adt/acl.c    Mon Aug  2 07:24:49 1999
> +++ postgresql-6.5.2-patched/src/backend/utils/adt/acl.c    Wed Mar  1 16:35:53 2000
> @@ -154,8 +154,11 @@
>              case ACL_MODE_RD_CHR:
>                  aip->ai_mode |= ACL_RD;
>                  break;
> -            case ACL_MODE_WR_CHR:
> -                aip->ai_mode |= ACL_WR;
> +            case ACL_MODE_DE_CHR:
> +                aip->ai_mode |= ACL_DE;
> +                break;
> +            case ACL_MODE_UP_CHR:
> +                aip->ai_mode |= ACL_UP;
>                  break;
>              case ACL_MODE_RU_CHR:
>                  aip->ai_mode |= ACL_RU;
> @@ -272,7 +275,7 @@
>      if (!aip)
>          aip = &default_aclitem;
>
> -    p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN);
> +    p = out = palloc(strlen("group =arRdu ") + 1 + NAMEDATALEN);
>      if (!out)
>          elog(ERROR, "aclitemout: palloc failed");
>      *p = '\0';
> @@ -605,9 +608,8 @@
>      int            i;
>      int            l;
>
> -    Assert(strlen(old_privlist) < 5);
> -    priv = palloc(5); /* at most "rwaR" */ ;
> -
> +    Assert(strlen(old_privlist) < 6);
> +    priv = palloc(6); /* at most "arduR" */ ;
>      if (old_privlist == NULL || old_privlist[0] == '\0')
>      {
>          priv[0] = new_priv;
> @@ -619,7 +621,7 @@
>
>      l = strlen(old_privlist);
>
> -    if (l == 4)
> +    if (l == 5)
>      {                            /* can't add any more privileges */
>          return priv;
>      }
> diff -urbw postgresql-6.5.2/src/include/utils/acl.h postgresql-6.5.2-patched/src/include/utils/acl.h
> --- postgresql-6.5.2/src/include/utils/acl.h    Fri Jul 30 19:07:22 1999
> +++ postgresql-6.5.2-patched/src/include/utils/acl.h    Wed Mar  1 16:40:50 2000
> @@ -54,9 +54,10 @@
>  #define ACL_NO            0        /* no permissions */
>  #define ACL_AP            (1<<0)    /* append */
>  #define ACL_RD            (1<<1)    /* read */
> -#define ACL_WR            (1<<2)    /* write (append/delete/replace) */
> -#define ACL_RU            (1<<3)    /* place rules */
> -#define N_ACL_MODES        4
> +#define ACL_DE            (1<<2)    /* delete */
> +#define ACL_UP            (1<<3)    /* update/replace */
> +#define ACL_RU            (1<<4)    /* place rules */
> +#define N_ACL_MODES        5
>
>  #define ACL_MODECHG_ADD            1
>  #define ACL_MODECHG_DEL            2
> @@ -65,7 +66,8 @@
>  /* change this line if you want to set the default acl permission  */
>  #define ACL_WORLD_DEFAULT        (ACL_NO)
>  /* #define        ACL_WORLD_DEFAULT        (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
> -#define ACL_OWNER_DEFAULT        (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
> +
> +#define ACL_OWNER_DEFAULT        (ACL_AP|ACL_RD|ACL_RU|ACL_DE|ACL_UP)
>
>  /*
>   * AclItem
> @@ -118,10 +120,12 @@
>  #define ACL_MODECHG_ADD_CHR        '+'
>  #define ACL_MODECHG_DEL_CHR        '-'
>  #define ACL_MODECHG_EQL_CHR        '='
> -#define ACL_MODE_STR            "arwR"    /* list of valid characters */
> +
> +#define ACL_MODE_STR            "arduR"     /* list of valid characters */
>  #define ACL_MODE_AP_CHR            'a'
>  #define ACL_MODE_RD_CHR            'r'
> -#define ACL_MODE_WR_CHR            'w'
> +#define ACL_MODE_DE_CHR            'd'
> +#define ACL_MODE_UP_CHR            'u'
>  #define ACL_MODE_RU_CHR            'R'
>
>  /* result codes for pg_aclcheck */
>
--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

pgsql-bugs by date:

Previous
From: Mike Finn
Date:
Subject: pg_restore --data-only ignored
Next
From: Tom Lane
Date:
Subject: Re: Bug #521: Backup - Restore Problem in VIEWs