Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uWz0C-004CjD-Kr for pgsql-hackers@arkaria.postgresql.org; Wed, 02 Jul 2025 15:04:00 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uWz0A-002fF5-67 for pgsql-hackers@arkaria.postgresql.org; Wed, 02 Jul 2025 15:03:58 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uWz09-002fEX-OK for pgsql-hackers@lists.postgresql.org; Wed, 02 Jul 2025 15:03:58 +0000 Received: from mail-lj1-x22e.google.com ([2a00:1450:4864:20::22e]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uWz08-005ApA-0v for pgsql-hackers@lists.postgresql.org; Wed, 02 Jul 2025 15:03:57 +0000 Received: by mail-lj1-x22e.google.com with SMTP id 38308e7fff4ca-32ae3e94e57so40553851fa.1 for ; Wed, 02 Jul 2025 08:03:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751468634; x=1752073434; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=biyZlFHOhLmajE3mpbqzGm1nJr6N4JB6WcaNaMG9DcE=; b=fAN/xn3bX8KPkE9lKqSKd3A5NNmZBWDq2GdWAi0NXTWtOwgTaEFc57djbMaJb5im4x bxbndqxXSRJguJPUCJPmq97v9ednmEC3WqQddw0icsVfni9S6jFhTDNniq9V6Izw6bzE M1FBfgIDecTaPFuD8P4n6s6twbR/zSPEl0wb6w4PskfHgdSZZQMwGYR/uKCTNRa7LF6x e0n7nsyseQvANABG2iKrGffilPh/bxtMnJrHt+U8zjiaHggs2zN2f0iTf3ay+a7OIYEQ V5x2QMOswT2/y1/2fiKEyJm6RhIlefzqrANiHKj+O8rC4iokWY7zsSiySaKs6hDmj8T3 pmNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751468634; x=1752073434; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=biyZlFHOhLmajE3mpbqzGm1nJr6N4JB6WcaNaMG9DcE=; b=YWbckCPZDcEgDBrPzfv8vgTKwniYxgRE3VCzVJ81Y9bDsOuPrrhv9wLgrG2As8WQvk zz1rt2YsNHMj9+GazbMVr5DPjFU9KjX88x0HmVnpOARxJXvG7W9l4BYXPi4WVGgYNKEl c1bgruhG889JHcJY9t2kegybaGE10CiqaM4goG7THiKov0ay3wL8n/lUEHGj1rTuBKM0 Ux8XIWwlmpUzQact4Jre6mXQCjZ5ufw/aftq/4/Osmof5lRIejQ9SP6mb68+iLMVlWeh 4OI4CbQCDSyrTIIljgaqkWq0lYfirqUeckJwDB94fAb5a013Yhnq9wzGtYTG+un8v9fm r5qA== X-Gm-Message-State: AOJu0Yy9ACE+nQHT+O0I0/hhHlJPLfnBjv0PpuvwEY6mwMgmGehEoFVz tjmOwVHpKIcRIDgC8ct9cAzztKOCuESg5Eywgfl4agGHdrX5N1TlojBE1dSLgn6L9AKJgXaAJO0 aR1E0jynuyA5oV4yoxqqFOEYU+TLwBOMHcTZKp+4= X-Gm-Gg: ASbGnctDq7GInhLVwtertFAXFdJDH7e6ZVb9A4d3R/WVW3G4DC+EswdABlI1Qdx+Ci0 D5z8SoWObjuyLHd/aQQiWnYCG2C5frjmbLdGFCp2BmXbHaQuEOAYilvb7KFu7fp2NEOg5d6O1Lj JhvGKNP013KFHMfgRrrx+eiYqiKXaITTQUp+eWEdIOfN221Q4nIWrzy56qU2rqIaGWVXpky+YCI Uw5 X-Google-Smtp-Source: AGHT+IHU0R+sH68KHBUQtRjfPedi2rsWwVHmAsetxdJGwpirQxpKLKzoTDH745zk1p/qoZurhs4v5s8hCf36puPtR7w= X-Received: by 2002:a17:907:60d2:b0:ae0:db23:e3e3 with SMTP id a640c23a62f3a-ae3c2bbdd4cmr330514266b.16.1751468621695; Wed, 02 Jul 2025 08:03:41 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Jianghua Yang Date: Wed, 2 Jul 2025 08:03:05 -0700 X-Gm-Features: Ac12FXx51YdHuY8HGASSlxcmu2ddUN0UF7iXJWHwZ1BJcQZQD8dvmSTUfG8PiGY Message-ID: Subject: Re: [PATCH] initdb: Treat empty -U argument as unset username To: Peter Eisentraut Cc: pgsql-hackers@lists.postgresql.org Content-Type: multipart/alternative; boundary="000000000000081cb20638f3913b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000081cb20638f3913b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Peter, Thanks for your detailed analysis. I appreciate you digging deeper into the root cause. For this patch, I'd like to keep the changes to `initdb` minimal and focused on rejecting empty usernames, as that seems to be the consensus from the previous discussion. I'll be happy to discuss the `getid()` and `aclitem` parsing behavior in a separate thread. Best regards, Jianghua Yang Peter Eisentraut =E4=BA=8E2025=E5=B9=B47=E6=9C=882= =E6=97=A5=E5=91=A8=E4=B8=89 07:39=E5=86=99=E9=81=93=EF=BC=9A > On 02.07.25 04:55, Jianghua Yang wrote: > > While working with `initdb`, I noticed that passing an empty string to > > the `-U` option (e.g., `initdb -U ''`) causes it to fail with a > > misleading error: > > > > performing post-bootstrap initialization ... 2025-07-01 19:48:42.006 PD= T > > [14888] FATAL:role """ does not exist at character 72 > > > > 2025-07-01 19:48:42.006 PDT [14888] STATEMENT: > > > > UPDATE pg_class SET relacl =3D (SELECT array_agg(a.acl) FROM(SELECT > > E'=3Dr/""' as acl UNION SELECT unnest(pg_catalog.acldefault(CASE WHEN > > relkind =3D 'S' THEN 's'ELSE 'r' END::"char",10::oid)) ) as a) WHERE > > relkind IN ('r', 'v', 'm', 'S')AND relacl IS NULL; > > > > This happens because `initdb` accepts the empty string as a valid role > > name and attempts to use it as the database superuser, which is not > > intended and fails during bootstrap SQL. > > I'll start by saying, of course an empty user name isn't going to work, > so we should reject it. > > But let's dig a little deeper into why it fails. Observe the error: > > FATAL:role """ does not exist at character 72 > > It thinks that the role name is `"` (a sole double-quote, not empty!). > Why is that? > > This error comes from the literal > > E'=3Dr/""' > > interpreted as an aclitem value. The aclitem parsing ends up in getid() > in src/backend/utils/adt/acl.c, which thinks that an input string > consisting entirely of "" is an escaped double quote. > > Maybe it's worth fixing that, and making putid() also print empty user > names correspondingly. > > Alternatively, it's the fault of initdb that it constructs aclitem > values that don't follow the aclitem-specific quoting rules. > > Another thought is, if we don't allow zero-length names, shouldn't > namein() reject empty input strings? Then this whole thing would fail > as postgres.bki is being loaded. (This is more hypothetical, since this > appears to break a number of other things.) > > All of this is to say, it's worth looking at the actual cause and think > about if there are related problems, maybe other name patterns that we > don't handle well, instead of just papering over it at the top level. > > --000000000000081cb20638f3913b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Peter,

Thanks for your det= ailed analysis. I appreciate you digging deeper into the root cause.
For this patch, I'd like to keep the changes to `initdb`=C2=A0minimal = and focused on rejecting empty usernames, as that seems to be the consensus= from the previous discussion.

I'll be happy to discuss the `get= id()`=C2=A0and `aclitem`=C2=A0parsing behavior in a separate thread.
Best regards,
Jianghua Yang


Peter Eisent= raut <peter@eisentraut.org&g= t; =E4=BA=8E2025=E5=B9=B47=E6=9C=882=E6=97=A5=E5=91=A8=E4=B8=89 07:39=E5=86= =99=E9=81=93=EF=BC=9A
On 02.07.25 04:55, Jianghua Yang wrote:
> While working with `initdb`, I noticed that passing an empty string to=
> the `-U` option (e.g., `initdb -U ''`) causes it to fail with = a
> misleading error:
>
> performing post-bootstrap initialization ... 2025-07-01 19:48:42.006 P= DT
> [14888] FATAL:role """ does not exist at character 72 >
> 2025-07-01 19:48:42.006 PDT [14888] STATEMENT:
>
> UPDATE pg_class SET relacl =3D (SELECT array_agg(a.acl) FROM(SELECT > E'=3Dr/""' as acl UNION SELECT unnest(pg_catalog.acl= default(CASE WHEN
> relkind =3D 'S' THEN 's'ELSE 'r' END::"ch= ar",10::oid)) ) as a) WHERE
> relkind IN ('r', 'v', 'm', 'S')AND rel= acl IS NULL;
>
> This happens because `initdb` accepts the empty string as a valid role=
> name and attempts to use it as the database superuser, which is not > intended and fails during bootstrap SQL.

I'll start by saying, of course an empty user name isn't going to w= ork,
so we should reject it.

But let's dig a little deeper into why it fails.=C2=A0 Observe the erro= r:

=C2=A0 =C2=A0 =C2=A0FATAL:role """ does not exist at charact= er 72

It thinks that the role name is `"` (a sole double-quote, not empty!).=
Why is that?

This error comes from the literal

=C2=A0 =C2=A0 E'=3Dr/""'

interpreted as an aclitem value.=C2=A0 The aclitem parsing ends up in getid= ()
in src/backend/utils/adt/acl.c, which thinks that an input string
consisting entirely of "" is an escaped double quote.

Maybe it's worth fixing that, and making putid() also print empty user =
names correspondingly.

Alternatively, it's the fault of initdb that it constructs aclitem
values that don't follow the aclitem-specific quoting rules.

Another thought is, if we don't allow zero-length names, shouldn't =
namein() reject empty input strings?=C2=A0 Then this whole thing would fail=
as postgres.bki is being loaded.=C2=A0 (This is more hypothetical, since th= is
appears to break a number of other things.)

All of this is to say, it's worth looking at the actual cause and think=
about if there are related problems, maybe other name patterns that we
don't handle well, instead of just papering over it at the top level.
--000000000000081cb20638f3913b--