diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 427c520b2b38ceca71ce5d6f81c3a77ec1fc625f..84abec04894cba06166ebba9b3349b0a03b961b9 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.86 2003/01/24 21:53:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.87 2003/06/02 19:00:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,6 +31,7 @@ #define ACL_IDTYPE_UID_KEYWORD "user" static const char *getid(const char *s, char *n); +static void putid(char *p, const char *s); static Acl *makeacl(int n); static const char *aclparse(const char *s, AclItem *aip); static bool aclitemeq(const AclItem *a1, const AclItem *a2); @@ -64,42 +65,68 @@ static AclMode convert_schema_priv_string(text *priv_type_text); static const char * getid(const char *s, char *n) { - unsigned len; - const char *id; - int in_quotes = 0; + int len = 0; + bool in_quotes = false; Assert(s && n); while (isspace((unsigned char) *s)) - ++s; - - if (*s == '"') - { - in_quotes = 1; s++; - } - - for (id = s, len = 0; - isalnum((unsigned char) *s) || *s == '_' || in_quotes; - ++len, ++s) + /* This test had better match what putid() does, below */ + for (; + *s != '\0' && + (isalnum((unsigned char) *s) || + *s == '_' || + *s == '"' || + in_quotes); + s++) { - if (in_quotes && *s == '"') + if (*s == '"') { - len--; - in_quotes = 0; + in_quotes = !in_quotes; + } + else + { + if (len >= NAMEDATALEN-1) + elog(ERROR, "identifier must be less than %d characters", + NAMEDATALEN); + n[len++] = *s; } } - if (len >= NAMEDATALEN) - elog(ERROR, "getid: identifier must be <%d characters", - NAMEDATALEN); - if (len > 0) - memmove(n, id, len); n[len] = '\0'; while (isspace((unsigned char) *s)) - ++s; + s++; return s; } +/* + * Write a user or group Name at *p, surrounding it with double quotes if + * needed. There must be at least NAMEDATALEN+2 bytes available at *p. + */ +static void +putid(char *p, const char *s) +{ + const char *src; + bool safe = true; + + for (src = s; *src; src++) + { + /* This test had better match what getid() does, above */ + if (!isalnum((unsigned char) *src) && *src != '_') + { + safe = false; + break; + } + } + if (!safe) + *p++ = '"'; + for (src = s; *src; src++) + *p++ = *src; + if (!safe) + *p++ = '"'; + *p = '\0'; +} + /* * aclparse * Consumes and parses an ACL specification of the form: @@ -304,7 +331,12 @@ aclitemout(PG_FUNCTION_ARGS) unsigned i; char *tmpname; - p = out = palloc(strlen("group = ") + 2 * N_ACL_RIGHTS + 2* NAMEDATALEN + 2); + out = palloc(strlen("group =/") + + 2 * N_ACL_RIGHTS + + 2 * (NAMEDATALEN+2) + + 1); + + p = out; *p = '\0'; switch (ACLITEM_GET_IDTYPE(*aip)) @@ -315,36 +347,25 @@ aclitemout(PG_FUNCTION_ARGS) 0, 0, 0); if (HeapTupleIsValid(htup)) { - strncat(p, - NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename), - NAMEDATALEN); + putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename)); ReleaseSysCache(htup); } else { /* Generate numeric UID if we don't find an entry */ - char *tmp; - - tmp = DatumGetCString(DirectFunctionCall1(int4out, - Int32GetDatum((int32) aip->ai_grantee))); - strcat(p, tmp); - pfree(tmp); + sprintf(p, "%d", aip->ai_grantee); } break; case ACL_IDTYPE_GID: - strcat(p, "group "); + strcpy(p, "group "); + p += strlen(p); tmpname = get_groname(aip->ai_grantee); if (tmpname != NULL) - strncat(p, tmpname, NAMEDATALEN); + putid(p, tmpname); else { /* Generate numeric GID if we don't find an entry */ - char *tmp; - - tmp = DatumGetCString(DirectFunctionCall1(int4out, - Int32GetDatum((int32) aip->ai_grantee))); - strcat(p, tmp); - pfree(tmp); + sprintf(p, "%d", aip->ai_grantee); } break; case ACL_IDTYPE_WORLD: @@ -375,20 +396,13 @@ aclitemout(PG_FUNCTION_ARGS) 0, 0, 0); if (HeapTupleIsValid(htup)) { - strncat(p, - NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename), - NAMEDATALEN); + putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename)); ReleaseSysCache(htup); } else { /* Generate numeric UID if we don't find an entry */ - char *tmp; - - tmp = DatumGetCString(DirectFunctionCall1(int4out, - Int32GetDatum((int32) aip->ai_grantor))); - strcat(p, tmp); - pfree(tmp); + sprintf(p, "%d", aip->ai_grantor); } while (*p) diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index aa5e17aa64dd186b6d3aec3f4846698338530449..0202a7c72b26152b49e85fe743601bb5ed10f3f6 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -27,7 +27,7 @@ # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.191 2003/05/28 18:19:09 tgl Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.192 2003/06/02 19:00:29 tgl Exp $ # #------------------------------------------------------------------------- @@ -1021,11 +1021,11 @@ echo "ok" $ECHO_N "setting privileges on built-in objects... "$ECHO_C ( cat <