mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Make the world at least marginally safe for usernames with embedded spaces.
Per recent gripe.
This commit is contained in:
@ -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 @@
|
|||||||
#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);
|
|||||||
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;
|
s++;
|
||||||
|
/* This test had better match what putid() does, below */
|
||||||
|
for (;
|
||||||
|
*s != '\0' &&
|
||||||
|
(isalnum((unsigned char) *s) ||
|
||||||
|
*s == '_' ||
|
||||||
|
*s == '"' ||
|
||||||
|
in_quotes);
|
||||||
|
s++)
|
||||||
|
{
|
||||||
if (*s == '"')
|
if (*s == '"')
|
||||||
{
|
{
|
||||||
in_quotes = 1;
|
in_quotes = !in_quotes;
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
for (id = s, len = 0;
|
|
||||||
isalnum((unsigned char) *s) || *s == '_' || in_quotes;
|
|
||||||
++len, ++s)
|
|
||||||
{
|
{
|
||||||
if (in_quotes && *s == '"')
|
if (len >= NAMEDATALEN-1)
|
||||||
{
|
elog(ERROR, "identifier must be less than %d characters",
|
||||||
len--;
|
|
||||||
in_quotes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (len >= NAMEDATALEN)
|
|
||||||
elog(ERROR, "getid: identifier must be <%d characters",
|
|
||||||
NAMEDATALEN);
|
NAMEDATALEN);
|
||||||
if (len > 0)
|
n[len++] = *s;
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
# 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"
|
|||||||
$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;
|
||||||
|
Reference in New Issue
Block a user