Skip to content

Commit 613c6d2

Browse files
committed
Fix incorrect error message reported for non-existent users
Previously, lookups of non-existent user names could return "Success"; it will now return "User does not exist" by resetting errno. This also centralizes the user name lookup code in libpgport. Report and analysis by Nicolas Marchildon; patch by me
1 parent 11ac4c7 commit 613c6d2

File tree

19 files changed

+129
-157
lines changed

19 files changed

+129
-157
lines changed

contrib/pg_upgrade/util.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -203,32 +203,25 @@ quote_identifier(const char *s)
203203

204204
/*
205205
* get_user_info()
206-
* (copied from initdb.c) find the current user
207206
*/
208207
int
209208
get_user_info(char **user_name)
210209
{
211210
int user_id;
211+
char *errstr;
212212

213213
#ifndef WIN32
214-
struct passwd *pw = getpwuid(geteuid());
215-
216214
user_id = geteuid();
217-
#else /* the windows code */
218-
struct passwd_win32
219-
{
220-
int pw_uid;
221-
char pw_name[128];
222-
} pass_win32;
223-
struct passwd_win32 *pw = &pass_win32;
224-
DWORD pwname_size = sizeof(pass_win32.pw_name) - 1;
225-
226-
GetUserName(pw->pw_name, &pwname_size);
227-
215+
#else
228216
user_id = 1;
229217
#endif
230218

231-
*user_name = pg_strdup(pw->pw_name);
219+
*user_name = get_user_name(&errstr);
220+
if (!*user_name)
221+
pg_fatal("%s\n", errstr);
222+
223+
/* make a copy */
224+
*user_name = pg_strdup(*user_name);
232225

233226
return user_id;
234227
}

src/backend/libpq/auth.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,7 +1771,8 @@ auth_peer(hbaPort *port)
17711771
char ident_user[IDENT_USERNAME_MAX + 1];
17721772
uid_t uid;
17731773
gid_t gid;
1774-
struct passwd *pass;
1774+
const char *user_name;
1775+
char *errstr;
17751776

17761777
errno = 0;
17771778
if (getpeereid(port->sock, &uid, &gid) != 0)
@@ -1788,17 +1789,15 @@ auth_peer(hbaPort *port)
17881789
return STATUS_ERROR;
17891790
}
17901791

1791-
pass = getpwuid(uid);
1792-
1793-
if (pass == NULL)
1792+
user_name = get_user_name(&errstr);
1793+
if (!user_name)
17941794
{
1795-
ereport(LOG,
1796-
(errmsg("local user with ID %d does not exist",
1797-
(int) uid)));
1795+
ereport(LOG, (errmsg_internal("%s", errstr)));
1796+
pfree(errstr);
17981797
return STATUS_ERROR;
17991798
}
18001799

1801-
strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
1800+
strlcpy(ident_user, user_name, IDENT_USERNAME_MAX + 1);
18021801

18031802
return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
18041803
}

src/backend/main/main.c

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
*/
2121
#include "postgres.h"
2222

23-
#include <pwd.h>
2423
#include <unistd.h>
2524

2625
#if defined(__alpha) && defined(__osf__) /* no __alpha__ ? */
@@ -49,7 +48,6 @@ const char *progname;
4948
static void startup_hacks(const char *progname);
5049
static void help(const char *progname);
5150
static void check_root(const char *progname);
52-
static char *get_current_username(const char *progname);
5351

5452

5553
/*
@@ -191,7 +189,7 @@ main(int argc, char *argv[])
191189
else if (argc > 1 && strcmp(argv[1], "--single") == 0)
192190
PostgresMain(argc, argv,
193191
NULL, /* no dbname */
194-
get_current_username(progname)); /* does not return */
192+
strdup(get_user_name_or_exit(progname))); /* does not return */
195193
else
196194
PostmasterMain(argc, argv); /* does not return */
197195
abort(); /* should not get here */
@@ -372,36 +370,3 @@ check_root(const char *progname)
372370
}
373371
#endif /* WIN32 */
374372
}
375-
376-
377-
378-
static char *
379-
get_current_username(const char *progname)
380-
{
381-
#ifndef WIN32
382-
struct passwd *pw;
383-
384-
pw = getpwuid(geteuid());
385-
if (pw == NULL)
386-
{
387-
write_stderr("%s: invalid effective UID: %d\n",
388-
progname, (int) geteuid());
389-
exit(1);
390-
}
391-
/* Allocate new memory because later getpwuid() calls can overwrite it. */
392-
return strdup(pw->pw_name);
393-
#else
394-
unsigned long namesize = 256 /* UNLEN */ + 1;
395-
char *name;
396-
397-
name = malloc(namesize);
398-
if (!GetUserName(name, &namesize))
399-
{
400-
write_stderr("%s: could not determine user name (GetUserName failed)\n",
401-
progname);
402-
exit(1);
403-
}
404-
405-
return name;
406-
#endif
407-
}

src/bin/initdb/initdb.c

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -770,15 +770,14 @@ exit_nicely(void)
770770
/*
771771
* find the current user
772772
*
773-
* on unix make sure it isn't really root
773+
* on unix make sure it isn't root
774774
*/
775775
static char *
776776
get_id(void)
777777
{
778-
#ifndef WIN32
779-
780-
struct passwd *pw;
778+
const char *username;
781779

780+
#ifndef WIN32
782781
if (geteuid() == 0) /* 0 is root's uid */
783782
{
784783
fprintf(stderr,
@@ -789,35 +788,11 @@ get_id(void)
789788
progname);
790789
exit(1);
791790
}
792-
793-
pw = getpwuid(geteuid());
794-
if (!pw)
795-
{
796-
fprintf(stderr,
797-
_("%s: could not obtain information about current user: %s\n"),
798-
progname, strerror(errno));
799-
exit(1);
800-
}
801-
#else /* the windows code */
802-
803-
struct passwd_win32
804-
{
805-
int pw_uid;
806-
char pw_name[128];
807-
} pass_win32;
808-
struct passwd_win32 *pw = &pass_win32;
809-
DWORD pwname_size = sizeof(pass_win32.pw_name) - 1;
810-
811-
pw->pw_uid = 1;
812-
if (!GetUserName(pw->pw_name, &pwname_size))
813-
{
814-
fprintf(stderr, _("%s: could not get current user name: %s\n"),
815-
progname, strerror(errno));
816-
exit(1);
817-
}
818791
#endif
819792

820-
return pg_strdup(pw->pw_name);
793+
username = get_user_name_or_exit(progname);
794+
795+
return pg_strdup(username);
821796
}
822797

823798
static char *

src/bin/psql/command.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,13 @@ exec_command(const char *cmd,
265265
#ifndef WIN32
266266
struct passwd *pw;
267267

268+
errno = 0; /* clear errno before call */
268269
pw = getpwuid(geteuid());
269270
if (!pw)
270271
{
271-
psql_error("could not get home directory: %s\n", strerror(errno));
272+
psql_error("could not get home directory for user id %d: %s\n",
273+
(int) geteuid(), errno ?
274+
strerror(errno) : "user does not exist");
272275
exit(EXIT_FAILURE);
273276
}
274277
dir = pw->pw_dir;

src/bin/psql/help.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
#include "postgres_fe.h"
99

1010
#ifndef WIN32
11-
#ifdef HAVE_PWD_H
12-
#include <pwd.h> /* for getpwuid() */
13-
#endif
1411
#include <sys/types.h> /* (ditto) */
1512
#include <unistd.h> /* for geteuid() */
1613
#else
@@ -52,31 +49,18 @@ usage(void)
5249
{
5350
const char *env;
5451
const char *user;
55-
56-
#ifndef WIN32
57-
struct passwd *pw = NULL;
58-
#endif
52+
char *errstr;
5953

6054
/* Find default user, in case we need it. */
6155
user = getenv("PGUSER");
6256
if (!user)
6357
{
64-
#if !defined(WIN32) && !defined(__OS2__)
65-
pw = getpwuid(geteuid());
66-
if (pw)
67-
user = pw->pw_name;
68-
else
58+
user = get_user_name(&errstr);
59+
if (!user)
6960
{
70-
psql_error("could not get current user name: %s\n", strerror(errno));
61+
psql_error("%s\n", errstr);
7162
exit(EXIT_FAILURE);
7263
}
73-
#else /* WIN32 */
74-
char buf[128];
75-
DWORD bufsize = sizeof(buf) - 1;
76-
77-
if (GetUserName(buf, &bufsize))
78-
user = buf;
79-
#endif /* WIN32 */
8064
}
8165

8266
printf(_("psql is the PostgreSQL interactive terminal.\n\n"));

src/bin/scripts/clusterdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ main(int argc, char *argv[])
160160
else if (getenv("PGUSER"))
161161
dbname = getenv("PGUSER");
162162
else
163-
dbname = get_user_name(progname);
163+
dbname = get_user_name_or_exit(progname);
164164
}
165165

166166
if (tables.head != NULL)

src/bin/scripts/common.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
#include "postgres_fe.h"
1616

17-
#include <pwd.h>
1817
#include <signal.h>
1918
#include <unistd.h>
2019

@@ -29,38 +28,6 @@ static PGcancel *volatile cancelConn = NULL;
2928
static CRITICAL_SECTION cancelConnLock;
3029
#endif
3130

32-
/*
33-
* Returns the current user name.
34-
*/
35-
const char *
36-
get_user_name(const char *progname)
37-
{
38-
#ifndef WIN32
39-
struct passwd *pw;
40-
41-
pw = getpwuid(geteuid());
42-
if (!pw)
43-
{
44-
fprintf(stderr, _("%s: could not obtain information about current user: %s\n"),
45-
progname, strerror(errno));
46-
exit(1);
47-
}
48-
return pw->pw_name;
49-
#else
50-
static char username[128]; /* remains after function exit */
51-
DWORD len = sizeof(username) - 1;
52-
53-
if (!GetUserName(username, &len))
54-
{
55-
fprintf(stderr, _("%s: could not get current user name: %s\n"),
56-
progname, strerror(errno));
57-
exit(1);
58-
}
59-
return username;
60-
#endif
61-
}
62-
63-
6431
/*
6532
* Provide strictly harmonized handling of --help and --version
6633
* options.

src/bin/scripts/common.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ enum trivalue
2222

2323
typedef void (*help_handler) (const char *progname);
2424

25-
extern const char *get_user_name(const char *progname);
26-
2725
extern void handle_help_version_opts(int argc, char *argv[],
2826
const char *fixed_progname,
2927
help_handler hlp);

src/bin/scripts/createdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ main(int argc, char *argv[])
174174
else if (getenv("PGUSER"))
175175
dbname = getenv("PGUSER");
176176
else
177-
dbname = get_user_name(progname);
177+
dbname = get_user_name_or_exit(progname);
178178
}
179179

180180
initPQExpBuffer(&sql);

src/bin/scripts/createlang.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ main(int argc, char *argv[])
127127
else if (getenv("PGUSER"))
128128
dbname = getenv("PGUSER");
129129
else
130-
dbname = get_user_name(progname);
130+
dbname = get_user_name_or_exit(progname);
131131
}
132132

133133
initPQExpBuffer(&sql);

src/bin/scripts/createuser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ main(int argc, char *argv[])
193193
if (getenv("PGUSER"))
194194
newuser = getenv("PGUSER");
195195
else
196-
newuser = get_user_name(progname);
196+
newuser = get_user_name_or_exit(progname);
197197
}
198198
}
199199

src/bin/scripts/droplang.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ main(int argc, char *argv[])
126126
else if (getenv("PGUSER"))
127127
dbname = getenv("PGUSER");
128128
else
129-
dbname = get_user_name(progname);
129+
dbname = get_user_name_or_exit(progname);
130130
}
131131

132132
initPQExpBuffer(&sql);

src/bin/scripts/reindexdb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ main(int argc, char *argv[])
188188
else if (getenv("PGUSER"))
189189
dbname = getenv("PGUSER");
190190
else
191-
dbname = get_user_name(progname);
191+
dbname = get_user_name_or_exit(progname);
192192
}
193193

194194
reindex_system_catalogs(dbname, host, port, username, prompt_password,
@@ -203,7 +203,7 @@ main(int argc, char *argv[])
203203
else if (getenv("PGUSER"))
204204
dbname = getenv("PGUSER");
205205
else
206-
dbname = get_user_name(progname);
206+
dbname = get_user_name_or_exit(progname);
207207
}
208208

209209
if (indexes.head != NULL)

src/bin/scripts/vacuumdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ main(int argc, char *argv[])
202202
else if (getenv("PGUSER"))
203203
dbname = getenv("PGUSER");
204204
else
205-
dbname = get_user_name(progname);
205+
dbname = get_user_name_or_exit(progname);
206206
}
207207

208208
if (tables.head != NULL)

src/include/port.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ extern pqsigfunc pqsignal(int signo, pqsigfunc func);
473473
/* port/quotes.c */
474474
extern char *escape_single_quotes_ascii(const char *src);
475475

476+
/* port/username.c */
477+
extern const char *get_user_name(char **errstr);
478+
extern const char *get_user_name_or_exit(const char *progname);
479+
476480
/* port/wait_error.c */
477481
extern char *wait_result_to_str(int exit_status);
478482

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy