88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.86 2003/01/24 21:53 :29 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.87 2003/06/02 19:00 :29 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
3131#define ACL_IDTYPE_UID_KEYWORD "user"
3232
3333static const char * getid (const char * s ,char * n );
34+ static void putid (char * p ,const char * s );
3435static Acl * makeacl (int n );
3536static const char * aclparse (const char * s ,AclItem * aip );
3637static bool aclitemeq (const AclItem * a1 ,const AclItem * a2 );
@@ -64,42 +65,68 @@ static AclMode convert_schema_priv_string(text *priv_type_text);
6465static const char *
6566getid (const char * s ,char * n )
6667{
67- unsigned len ;
68- const char * id ;
69- int in_quotes = 0 ;
68+ int len = 0 ;
69+ bool in_quotes = false;
7070
7171Assert (s && n );
7272
7373while (isspace ((unsignedchar )* s ))
74- ++ s ;
75-
76- if (* s == '"' )
77- {
78- in_quotes = 1 ;
7974s ++ ;
80- }
81-
82- for (id = s ,len = 0 ;
83- isalnum ((unsignedchar )* s )|| * s == '_' || in_quotes ;
84- ++ len ,++ s )
75+ /* This test had better match what putid() does, below */
76+ for (;
77+ * s != '\0' &&
78+ (isalnum ((unsignedchar )* s )||
79+ * s == '_' ||
80+ * s == '"' ||
81+ in_quotes );
82+ s ++ )
8583{
86- if (in_quotes && * s == '"' )
84+ if (* s == '"' )
8785{
88- len -- ;
89- in_quotes = 0 ;
86+ in_quotes = !in_quotes ;
87+ }
88+ else
89+ {
90+ if (len >=NAMEDATALEN - 1 )
91+ elog (ERROR ,"identifier must be less than %d characters" ,
92+ NAMEDATALEN );
93+ n [len ++ ]= * s ;
9094}
9195}
92- if (len >=NAMEDATALEN )
93- elog (ERROR ,"getid: identifier must be <%d characters" ,
94- NAMEDATALEN );
95- if (len > 0 )
96- memmove (n ,id ,len );
9796n [len ]= '\0' ;
9897while (isspace ((unsignedchar )* s ))
99- ++ s ;
98+ s ++ ;
10099return s ;
101100}
102101
102+ /*
103+ * Write a user or group Name at *p, surrounding it with double quotes if
104+ * needed. There must be at least NAMEDATALEN+2 bytes available at *p.
105+ */
106+ static void
107+ putid (char * p ,const char * s )
108+ {
109+ const char * src ;
110+ bool safe = true;
111+
112+ for (src = s ;* src ;src ++ )
113+ {
114+ /* This test had better match what getid() does, above */
115+ if (!isalnum ((unsignedchar )* src )&& * src != '_' )
116+ {
117+ safe = false;
118+ break ;
119+ }
120+ }
121+ if (!safe )
122+ * p ++ = '"' ;
123+ for (src = s ;* src ;src ++ )
124+ * p ++ = * src ;
125+ if (!safe )
126+ * p ++ = '"' ;
127+ * p = '\0' ;
128+ }
129+
103130/*
104131 * aclparse
105132 *Consumes and parses an ACL specification of the form:
@@ -304,7 +331,12 @@ aclitemout(PG_FUNCTION_ARGS)
304331unsigned i ;
305332char * tmpname ;
306333
307- p = out = palloc (strlen ("group = " )+ 2 * N_ACL_RIGHTS + 2 * NAMEDATALEN + 2 );
334+ out = palloc (strlen ("group =/" )+
335+ 2 * N_ACL_RIGHTS +
336+ 2 * (NAMEDATALEN + 2 )+
337+ 1 );
338+
339+ p = out ;
308340* p = '\0' ;
309341
310342switch (ACLITEM_GET_IDTYPE (* aip ))
@@ -315,36 +347,25 @@ aclitemout(PG_FUNCTION_ARGS)
3153470 ,0 ,0 );
316348if (HeapTupleIsValid (htup ))
317349{
318- strncat (p ,
319- NameStr (((Form_pg_shadow )GETSTRUCT (htup ))-> usename ),
320- NAMEDATALEN );
350+ putid (p ,NameStr (((Form_pg_shadow )GETSTRUCT (htup ))-> usename ));
321351ReleaseSysCache (htup );
322352}
323353else
324354{
325355/* Generate numeric UID if we don't find an entry */
326- char * tmp ;
327-
328- tmp = DatumGetCString (DirectFunctionCall1 (int4out ,
329- Int32GetDatum ((int32 )aip -> ai_grantee )));
330- strcat (p ,tmp );
331- pfree (tmp );
356+ sprintf (p ,"%d" ,aip -> ai_grantee );
332357}
333358break ;
334359case ACL_IDTYPE_GID :
335- strcat (p ,"group " );
360+ strcpy (p ,"group " );
361+ p += strlen (p );
336362tmpname = get_groname (aip -> ai_grantee );
337363if (tmpname != NULL )
338- strncat (p ,tmpname , NAMEDATALEN );
364+ putid (p ,tmpname );
339365else
340366{
341367/* Generate numeric GID if we don't find an entry */
342- char * tmp ;
343-
344- tmp = DatumGetCString (DirectFunctionCall1 (int4out ,
345- Int32GetDatum ((int32 )aip -> ai_grantee )));
346- strcat (p ,tmp );
347- pfree (tmp );
368+ sprintf (p ,"%d" ,aip -> ai_grantee );
348369}
349370break ;
350371case ACL_IDTYPE_WORLD :
@@ -375,20 +396,13 @@ aclitemout(PG_FUNCTION_ARGS)
3753960 ,0 ,0 );
376397if (HeapTupleIsValid (htup ))
377398{
378- strncat (p ,
379- NameStr (((Form_pg_shadow )GETSTRUCT (htup ))-> usename ),
380- NAMEDATALEN );
399+ putid (p ,NameStr (((Form_pg_shadow )GETSTRUCT (htup ))-> usename ));
381400ReleaseSysCache (htup );
382401}
383402else
384403{
385404/* Generate numeric UID if we don't find an entry */
386- char * tmp ;
387-
388- tmp = DatumGetCString (DirectFunctionCall1 (int4out ,
389- Int32GetDatum ((int32 )aip -> ai_grantor )));
390- strcat (p ,tmp );
391- pfree (tmp );
405+ sprintf (p ,"%d" ,aip -> ai_grantor );
392406}
393407
394408while (* p )