提交 53691902 编写于 作者: T Tom Lane

Make the world at least marginally safe for usernames with embedded spaces.

Per recent gripe.
上级 cb36e74e
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -31,6 +31,7 @@
#define ACL_IDTYPE_UID_KEYWORD "user" #define ACL_IDTYPE_UID_KEYWORD "user"
static const char *getid(const char *s, char *n); static const char *getid(const char *s, char *n);
static void putid(char *p, const char *s);
static Acl *makeacl(int n); static Acl *makeacl(int n);
static const char *aclparse(const char *s, AclItem *aip); static const char *aclparse(const char *s, AclItem *aip);
static bool aclitemeq(const AclItem *a1, const AclItem *a2); static bool aclitemeq(const AclItem *a1, const AclItem *a2);
...@@ -64,42 +65,68 @@ static AclMode convert_schema_priv_string(text *priv_type_text); ...@@ -64,42 +65,68 @@ static AclMode convert_schema_priv_string(text *priv_type_text);
static const char * static const char *
getid(const char *s, char *n) getid(const char *s, char *n)
{ {
unsigned len; int len = 0;
const char *id; bool in_quotes = false;
int in_quotes = 0;
Assert(s && n); Assert(s && n);
while (isspace((unsigned char) *s)) while (isspace((unsigned char) *s))
++s;
if (*s == '"')
{
in_quotes = 1;
s++; s++;
} /* This test had better match what putid() does, below */
for (;
for (id = s, len = 0; *s != '\0' &&
isalnum((unsigned char) *s) || *s == '_' || in_quotes; (isalnum((unsigned char) *s) ||
++len, ++s) *s == '_' ||
*s == '"' ||
in_quotes);
s++)
{ {
if (in_quotes && *s == '"') if (*s == '"')
{ {
len--; in_quotes = !in_quotes;
in_quotes = 0; }
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'; n[len] = '\0';
while (isspace((unsigned char) *s)) while (isspace((unsigned char) *s))
++s; s++;
return 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 * aclparse
* Consumes and parses an ACL specification of the form: * Consumes and parses an ACL specification of the form:
...@@ -304,7 +331,12 @@ aclitemout(PG_FUNCTION_ARGS) ...@@ -304,7 +331,12 @@ aclitemout(PG_FUNCTION_ARGS)
unsigned i; unsigned i;
char *tmpname; 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'; *p = '\0';
switch (ACLITEM_GET_IDTYPE(*aip)) switch (ACLITEM_GET_IDTYPE(*aip))
...@@ -315,36 +347,25 @@ aclitemout(PG_FUNCTION_ARGS) ...@@ -315,36 +347,25 @@ aclitemout(PG_FUNCTION_ARGS)
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(htup)) if (HeapTupleIsValid(htup))
{ {
strncat(p, putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename));
NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename),
NAMEDATALEN);
ReleaseSysCache(htup); ReleaseSysCache(htup);
} }
else else
{ {
/* Generate numeric UID if we don't find an entry */ /* Generate numeric UID if we don't find an entry */
char *tmp; sprintf(p, "%d", aip->ai_grantee);
tmp = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum((int32) aip->ai_grantee)));
strcat(p, tmp);
pfree(tmp);
} }
break; break;
case ACL_IDTYPE_GID: case ACL_IDTYPE_GID:
strcat(p, "group "); strcpy(p, "group ");
p += strlen(p);
tmpname = get_groname(aip->ai_grantee); tmpname = get_groname(aip->ai_grantee);
if (tmpname != NULL) if (tmpname != NULL)
strncat(p, tmpname, NAMEDATALEN); putid(p, tmpname);
else else
{ {
/* Generate numeric GID if we don't find an entry */ /* Generate numeric GID if we don't find an entry */
char *tmp; sprintf(p, "%d", aip->ai_grantee);
tmp = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum((int32) aip->ai_grantee)));
strcat(p, tmp);
pfree(tmp);
} }
break; break;
case ACL_IDTYPE_WORLD: case ACL_IDTYPE_WORLD:
...@@ -375,20 +396,13 @@ aclitemout(PG_FUNCTION_ARGS) ...@@ -375,20 +396,13 @@ aclitemout(PG_FUNCTION_ARGS)
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(htup)) if (HeapTupleIsValid(htup))
{ {
strncat(p, putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename));
NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename),
NAMEDATALEN);
ReleaseSysCache(htup); ReleaseSysCache(htup);
} }
else else
{ {
/* Generate numeric UID if we don't find an entry */ /* Generate numeric UID if we don't find an entry */
char *tmp; sprintf(p, "%d", aip->ai_grantor);
tmp = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum((int32) aip->ai_grantor)));
strcat(p, tmp);
pfree(tmp);
} }
while (*p) while (*p)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # 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" ...@@ -1021,11 +1021,11 @@ echo "ok"
$ECHO_N "setting privileges on built-in objects... "$ECHO_C $ECHO_N "setting privileges on built-in objects... "$ECHO_C
( (
cat <<EOF cat <<EOF
UPDATE pg_class SET relacl = '{"=r/$POSTGRES_SUPERUSERNAME"}' \ UPDATE pg_class SET relacl = '{"=r/\\\\"$POSTGRES_SUPERUSERNAME\\\\""}' \
WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL; WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL;
UPDATE pg_proc SET proacl = '{"=X/$POSTGRES_SUPERUSERNAME"}' \ UPDATE pg_proc SET proacl = '{"=X/\\\\"$POSTGRES_SUPERUSERNAME\\\\""}' \
WHERE proacl IS NULL; WHERE proacl IS NULL;
UPDATE pg_language SET lanacl = '{"=U/$POSTGRES_SUPERUSERNAME"}' \ UPDATE pg_language SET lanacl = '{"=U/\\\\"$POSTGRES_SUPERUSERNAME\\\\""}' \
WHERE lanpltrusted; WHERE lanpltrusted;
GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC; GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;
GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC; GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册