" -R Do a online restart\n"
" -q Run quietly\n"
" -v Increase verbosity\n"
+" -u <username> Assume identity of <username>\n"
" -V Show version\n"
" -h Show this help screen and exit\n";
int cf_shutdown = 0;
int cf_reboot = 0;
int cf_syslog = 0;
+char *cf_username = "";
char *cf_syslog_facility = "daemon";
static char *cf_config_file;
{"default_pool_size", true, CF_INT, &cf_default_pool_size},
{"syslog", true, CF_INT, &cf_syslog},
{"syslog_facility", true, CF_STR, &cf_syslog_facility},
+{"user", false, CF_STR, &cf_username},
{"server_reset_query", true, CF_STR, &cf_server_reset_query},
{"server_check_query", true, CF_STR, &cf_server_check_query},
{
int c;
bool did_takeover = false;
+ char *arg_username = NULL;
/* parse cmdline */
- while ((c = getopt(argc, argv, "avhdVR")) != EOF) {
+ while ((c = getopt(argc, argv, "avhdVRu:")) != EOF) {
switch (c) {
case 'R':
cf_reboot = 1;
case 'q':
cf_quiet = 1;
break;
+ case 'u':
+ arg_username = optarg;
+ break;
case 'h':
usage(0, argv[0]);
default:
init_caches();
admin_setup();
+ /* prefer cmdline over config for username */
+ if (arg_username)
+ cf_username = arg_username;
+
+ /* switch user is needed */
+ if (*cf_username)
+ change_user(cf_username);
+
+ /* disallow running as root */
+ if (getuid() == 0)
+ fatal("PgBouncer should not run as root");
+
/* need to do that after loading config */
check_limits();
#include <sys/ucred.h>
#endif
+#include <pwd.h>
+
/*
* Minimal spec-conforming implementations of strlcpy(), strlcat().
*/
}
#endif
+void change_user(const char *user)
+{
+ const struct passwd *pw;
+ gid_t gset[1];
+
+ /* check for a valid username */
+ pw = getpwnam(user);
+ if (pw == NULL)
+ fatal("could not find user '%s' to switch to", user);
+
+ gset[0] = pw->pw_gid;
+ if (getuid() == 0) {
+ if (setgroups(1, gset) < 0)
+ fatal_perror("failed to reset groups");
+ }
+
+ if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0)
+ fatal_perror("failed to assume identity of user '%s'", user);
+
+ if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
+ fatal("setuid() failed to work");
+}
+