mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Allow "-C variable" and "--describe-config" even to root users.
There's no really compelling reason to refuse to do these read-only, non-server-starting options as root, and there's at least one good reason to allow -C: pg_ctl uses -C to find out the true data directory location when pointed at a config-only directory. On Windows, this is done before dropping administrator privileges, which means that pg_ctl fails for administrators if and only if a config-only layout is used. Since the root-privilege check is done so early in startup, it's a bit awkward to check for these switches. Make the somewhat arbitrary decision that we'll only skip the root check if -C is the first switch. This is not just to make the code a bit simpler: it also guarantees that we can't misinterpret a --boot mode switch. (While AuxiliaryProcessMain doesn't currently recognize any such switch, it might have one in the future.) This is no particular problem for pg_ctl, and since the whole behavior is undocumented anyhow, it's not a documentation issue either. (--describe-config only works as the first switch anyway, so this is no restriction for that case either.) Back-patch to 9.2 where pg_ctl first began to use -C. MauMau, heavily edited by me
This commit is contained in:
		
							parent
							
								
									2209c0f861
								
							
						
					
					
						commit
						b203c57bb7
					
				| @ -58,6 +58,8 @@ static void check_root(const char *progname); | |||||||
| int | int | ||||||
| main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||||
| { | { | ||||||
|  | 	bool		do_check_root = true; | ||||||
|  | 
 | ||||||
| 	progname = get_progname(argv[0]); | 	progname = get_progname(argv[0]); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| @ -151,7 +153,8 @@ main(int argc, char *argv[]) | |||||||
| 	unsetenv("LC_ALL"); | 	unsetenv("LC_ALL"); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Catch standard options before doing much else | 	 * Catch standard options before doing much else, in particular before we | ||||||
|  | 	 * insist on not being root. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (argc > 1) | 	if (argc > 1) | ||||||
| 	{ | 	{ | ||||||
| @ -165,12 +168,29 @@ main(int argc, char *argv[]) | |||||||
| 			puts("postgres (PostgreSQL) " PG_VERSION); | 			puts("postgres (PostgreSQL) " PG_VERSION); | ||||||
| 			exit(0); | 			exit(0); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * In addition to the above, we allow "--describe-config" and "-C var" | ||||||
|  | 		 * to be called by root.  This is reasonably safe since these are | ||||||
|  | 		 * read-only activities.  The -C case is important because pg_ctl may | ||||||
|  | 		 * try to invoke it while still holding administrator privileges on | ||||||
|  | 		 * Windows.  Note that while -C can normally be in any argv position, | ||||||
|  | 		 * if you wanna bypass the root check you gotta put it first.  This | ||||||
|  | 		 * reduces the risk that we might misinterpret some other mode's -C | ||||||
|  | 		 * switch as being the postmaster/postgres one. | ||||||
|  | 		 */ | ||||||
|  | 		if (strcmp(argv[1], "--describe-config") == 0) | ||||||
|  | 			do_check_root = false; | ||||||
|  | 		else if (argc > 2 && strcmp(argv[1], "-C") == 0) | ||||||
|  | 			do_check_root = false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Make sure we are not running as root. | 	 * Make sure we are not running as root, unless it's safe for the selected | ||||||
|  | 	 * option. | ||||||
| 	 */ | 	 */ | ||||||
| 	check_root(progname); | 	if (do_check_root) | ||||||
|  | 		check_root(progname); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Dispatch to one of various subprograms depending on first argument. | 	 * Dispatch to one of various subprograms depending on first argument. | ||||||
|  | |||||||
| @ -2034,9 +2034,11 @@ adjust_data_dir(void) | |||||||
| 	else | 	else | ||||||
| 		my_exec_path = pg_strdup(exec_path); | 		my_exec_path = pg_strdup(exec_path); | ||||||
| 
 | 
 | ||||||
| 	snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s -C data_directory" SYSTEMQUOTE, | 	/* it's important for -C to be the first option, see main.c */ | ||||||
| 			 my_exec_path, pgdata_opt ? pgdata_opt : "", post_opts ? | 	snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" -C data_directory %s%s" SYSTEMQUOTE, | ||||||
| 			 post_opts : ""); | 			 my_exec_path, | ||||||
|  | 			 pgdata_opt ? pgdata_opt : "", | ||||||
|  | 			 post_opts ? post_opts : ""); | ||||||
| 
 | 
 | ||||||
| 	fd = popen(cmd, "r"); | 	fd = popen(cmd, "r"); | ||||||
| 	if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL) | 	if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user