Skip to content

Commit 6561372

Browse files
committed
Fix up problems in write_auth_file and parsing of the auth file.
In particular, make hba.c cope with zero-length tokens, which it never did properly before. Also, enforce rolcanlogin.
1 parent 0eaa36a commit 6561372

File tree

4 files changed

+235
-147
lines changed

4 files changed

+235
-147
lines changed

src/backend/commands/user.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.153 2005/06/28 19:51:22 tgl Exp $
9+
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.154 2005/06/28 22:16:44 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -859,6 +859,9 @@ RenameRole(const char *oldname, const char *newname)
859859
ReleaseSysCache(oldtuple);
860860
heap_close(rel, NoLock);
861861

862+
/*
863+
* Set flag to update flat auth file at commit.
864+
*/
862865
auth_file_update_needed();
863866
}
864867

@@ -902,6 +905,11 @@ GrantRole(GrantRoleStmt *stmt)
902905
stmt->grantee_roles, grantee_ids,
903906
stmt->admin_opt);
904907
}
908+
909+
/*
910+
* Set flag to update flat auth file at commit.
911+
*/
912+
auth_file_update_needed();
905913
}
906914

907915
/*

src/backend/libpq/hba.c

Lines changed: 71 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.143 2005/06/28 05:08:56 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.144 2005/06/28 22:16:45 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -96,17 +96,23 @@ pg_isblank(const char c)
9696

9797
/*
9898
* Grab one token out of fp. Tokens are strings of non-blank
99-
* characters bounded by blank characters, beginning of line, and
100-
* end of line. Blank means space or tab. Return the token as
101-
* *buf. Leave file positioned at the character immediately after the
102-
* token or EOF, whichever comes first. If no more tokens on line,
103-
* return empty string as *buf and position the file to the beginning
104-
* of the next line or EOF, whichever comes first. Allow spaces in
105-
* quoted strings. Terminate on unquoted commas. Handle
106-
* comments. Treat unquoted keywords that might be role names or
99+
* characters bounded by blank characters, commas, beginning of line, and
100+
* end of line. Blank means space or tab. Tokens can be delimited by
101+
* double quotes (and usually are, in current usage).
102+
*
103+
* The token, if any, is returned at *buf (a buffer of size bufsz).
104+
*
105+
* If successful: store null-terminated token at *buf and return TRUE.
106+
* If no more tokens on line: set *buf = '\0' and return FALSE.
107+
*
108+
* Leave file positioned at the character immediately after the token or EOF,
109+
* whichever comes first. If no more tokens on line, position the file to the
110+
* beginning of the next line or EOF, whichever comes first.
111+
*
112+
* Handle comments. Treat unquoted keywords that might be role names or
107113
* database names specially, by appending a newline to them.
108114
*/
109-
static void
115+
static bool
110116
next_token(FILE *fp, char *buf, int bufsz)
111117
{
112118
int c;
@@ -125,7 +131,7 @@ next_token(FILE *fp, char *buf, int bufsz)
125131
if (c == EOF || c == '\n')
126132
{
127133
*buf = '\0';
128-
return;
134+
return false;
129135
}
130136

131137
/*
@@ -200,32 +206,35 @@ next_token(FILE *fp, char *buf, int bufsz)
200206
*buf++ = '\n';
201207
*buf = '\0';
202208
}
209+
210+
return (saw_quote || buf > start_buf);
203211
}
204212

205213
/*
206214
* Tokenize file and handle file inclusion and comma lists. We have
207215
* to break apart the commas to expand any file names then
208216
* reconstruct with commas.
209217
*
210-
* The result is always a palloc'd string. If it's zero-length then
211-
* we have reached EOL.
218+
* The result is a palloc'd string, or NULL if we have reached EOL.
212219
*/
213220
static char *
214221
next_token_expand(const char *filename, FILE *file)
215222
{
216223
char buf[MAX_TOKEN];
217224
char *comma_str = pstrdup("");
225+
bool got_something = false;
218226
bool trailing_comma;
219227
char *incbuf;
220228
int needed;
221229

222230
do
223231
{
224-
next_token(file, buf, sizeof(buf));
225-
if (!buf[0])
232+
if (!next_token(file, buf, sizeof(buf)))
226233
break;
227234

228-
if (buf[strlen(buf) - 1] == ',')
235+
got_something = true;
236+
237+
if (strlen(buf) > 0 && buf[strlen(buf) - 1] == ',')
229238
{
230239
trailing_comma = true;
231240
buf[strlen(buf) - 1] = '\0';
@@ -249,6 +258,12 @@ next_token_expand(const char *filename, FILE *file)
249258
pfree(incbuf);
250259
} while (trailing_comma);
251260

261+
if (!got_something)
262+
{
263+
pfree(comma_str);
264+
return NULL;
265+
}
266+
252267
return comma_str;
253268
}
254269

@@ -402,7 +417,7 @@ tokenize_file(const char *filename, FILE *file,
402417
buf = next_token_expand(filename, file);
403418

404419
/* add token to list, unless we are at EOL or comment start */
405-
if (buf[0])
420+
if (buf)
406421
{
407422
if (current_line == NIL)
408423
{
@@ -423,8 +438,6 @@ tokenize_file(const char *filename, FILE *file,
423438
current_line = NIL;
424439
/* Advance line number whenever we reach EOL */
425440
line_number++;
426-
/* Don't forget to pfree the next_token_expand result */
427-
pfree(buf);
428441
}
429442
}
430443
}
@@ -462,44 +475,58 @@ get_role_line(const char *role)
462475

463476

464477
/*
465-
* Does member belong to role?
478+
* Does user belong to role?
479+
*
480+
* user is always the name given as the attempted login identifier.
481+
* We check to see if it is a member of the specified role name.
466482
*/
467483
static bool
468-
check_member(const char *role, const char *member)
484+
is_member(const char *user, const char *role)
469485
{
470486
List **line;
471-
List **line2;
472487
ListCell *line_item;
473488

474-
if ((line = get_role_line(member)) == NULL)
475-
return false; /* if member not exist, say "no" */
489+
if ((line = get_role_line(user)) == NULL)
490+
return false; /* if user not exist, say "no" */
476491

477-
if ((line2 = get_role_line(role)) == NULL)
478-
return false; /* if role not exist, say "no" */
492+
/* A user always belongs to its own role */
493+
if (strcmp(user, role) == 0)
494+
return true;
479495

480-
/* skip over the role name, password, valuntil, examine all the members */
481-
for_each_cell(line_item, lfourth(*line2))
496+
/*
497+
* skip over the role name, password, valuntil, examine all the
498+
* membership entries
499+
*/
500+
if (list_length(*line) < 4)
501+
return false;
502+
for_each_cell(line_item, lnext(lnext(lnext(list_head(*line)))))
482503
{
483-
if (strcmp((char *) lfirst(line_item), member) == 0)
504+
if (strcmp((char *) lfirst(line_item), role) == 0)
484505
return true;
485506
}
486507

487508
return false;
488509
}
489510

490511
/*
491-
* Check comma member list for a specific role, handle role names.
512+
* Check comma-separated list for a match to role, allowing group names.
513+
*
514+
* NB: param_str is destructively modified! In current usage, this is
515+
* okay only because this code is run after forking off from the postmaster,
516+
* and so it doesn't matter that we clobber the stored hba info.
492517
*/
493518
static bool
494-
check_role(char *role, char *param_str)
519+
check_role(const char *role, char *param_str)
495520
{
496521
char *tok;
497522

498-
for (tok = strtok(param_str, MULTI_VALUE_SEP); tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
523+
for (tok = strtok(param_str, MULTI_VALUE_SEP);
524+
tok != NULL;
525+
tok = strtok(NULL, MULTI_VALUE_SEP))
499526
{
500527
if (tok[0] == '+')
501528
{
502-
if (check_member(tok + 1, role))
529+
if (is_member(role, tok + 1))
503530
return true;
504531
}
505532
else if (strcmp(tok, role) == 0 ||
@@ -512,13 +539,19 @@ check_role(char *role, char *param_str)
512539

513540
/*
514541
* Check to see if db/role combination matches param string.
542+
*
543+
* NB: param_str is destructively modified! In current usage, this is
544+
* okay only because this code is run after forking off from the postmaster,
545+
* and so it doesn't matter that we clobber the stored hba info.
515546
*/
516547
static bool
517-
check_db(char *dbname, char *role, char *param_str)
548+
check_db(const char *dbname, const char *role, char *param_str)
518549
{
519550
char *tok;
520551

521-
for (tok = strtok(param_str, MULTI_VALUE_SEP); tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
552+
for (tok = strtok(param_str, MULTI_VALUE_SEP);
553+
tok != NULL;
554+
tok = strtok(NULL, MULTI_VALUE_SEP))
522555
{
523556
if (strcmp(tok, "all\n") == 0)
524557
return true;
@@ -530,7 +563,7 @@ check_db(char *dbname, char *role, char *param_str)
530563
else if (strcmp(tok, "samegroup\n") == 0 ||
531564
strcmp(tok, "samerole\n") == 0)
532565
{
533-
if (check_member(dbname, role))
566+
if (is_member(role, dbname))
534567
return true;
535568
}
536569
else if (strcmp(tok, dbname) == 0)
@@ -981,8 +1014,7 @@ read_pg_database_line(FILE *fp, char *dbname,
9811014

9821015
if (feof(fp))
9831016
return false;
984-
next_token(fp, buf, sizeof(buf));
985-
if (!buf[0])
1017+
if (!next_token(fp, buf, sizeof(buf)))
9861018
return false;
9871019
if (strlen(buf) >= NAMEDATALEN)
9881020
elog(FATAL, "bad data in flat pg_database file");
@@ -1000,8 +1032,7 @@ read_pg_database_line(FILE *fp, char *dbname,
10001032
if (!isdigit((unsigned char) buf[0]))
10011033
elog(FATAL, "bad data in flat pg_database file");
10021034
/* expect EOL next */
1003-
next_token(fp, buf, sizeof(buf));
1004-
if (buf[0])
1035+
if (next_token(fp, buf, sizeof(buf)))
10051036
elog(FATAL, "bad data in flat pg_database file");
10061037
return true;
10071038
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy