* Validate a proposed option setting for GUCArrayAdd/Delete/Reset. * * name is the option name. value is the proposed value for the Add case, * or NULL for the Delete/Reset cases. If skipIfNoPermissions is true, it's * not an error to have no permissions to set the option. * * Returns true if OK, false if skipIfNoPermissions is true and user does not * have permission to change this optio
| 11890 | * error being thrown). |
| 11891 | */ |
| 11892 | static bool |
| 11893 | validate_option_array_item(const char *name, const char *value, |
| 11894 | bool skipIfNoPermissions) |
| 11895 | |
| 11896 | { |
| 11897 | struct config_generic *gconf; |
| 11898 | |
| 11899 | /* |
| 11900 | * There are three cases to consider: |
| 11901 | * |
| 11902 | * name is a known GUC variable. Check the value normally, check |
| 11903 | * permissions normally (i.e., allow if variable is USERSET, or if it's |
| 11904 | * SUSET and user is superuser). |
| 11905 | * |
| 11906 | * name is not known, but exists or can be created as a placeholder (i.e., |
| 11907 | * it has a valid custom name). We allow this case if you're a superuser, |
| 11908 | * otherwise not. Superusers are assumed to know what they're doing. We |
| 11909 | * can't allow it for other users, because when the placeholder is |
| 11910 | * resolved it might turn out to be a SUSET variable; |
| 11911 | * define_custom_variable assumes we checked that. |
| 11912 | * |
| 11913 | * name is not known and can't be created as a placeholder. Throw error, |
| 11914 | * unless skipIfNoPermissions is true, in which case return false. |
| 11915 | */ |
| 11916 | gconf = find_option(name, true, skipIfNoPermissions, ERROR); |
| 11917 | if (!gconf) |
| 11918 | { |
| 11919 | /* not known, failed to make a placeholder */ |
| 11920 | return false; |
| 11921 | } |
| 11922 | |
| 11923 | if (gconf->flags & GUC_CUSTOM_PLACEHOLDER) |
| 11924 | { |
| 11925 | /* |
| 11926 | * We cannot do any meaningful check on the value, so only permissions |
| 11927 | * are useful to check. |
| 11928 | */ |
| 11929 | if (superuser()) |
| 11930 | return true; |
| 11931 | if (skipIfNoPermissions) |
| 11932 | return false; |
| 11933 | ereport(ERROR, |
| 11934 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
| 11935 | errmsg("permission denied to set parameter \"%s\"", name))); |
| 11936 | } |
| 11937 | |
| 11938 | /* manual permissions check so we can avoid an error being thrown */ |
| 11939 | if (gconf->context == PGC_USERSET) |
| 11940 | /* ok */ ; |
| 11941 | else if (gconf->context == PGC_SUSET && superuser()) |
| 11942 | /* ok */ ; |
| 11943 | else if (skipIfNoPermissions) |
| 11944 | return false; |
| 11945 | /* if a permissions error should be thrown, let set_config_option do it */ |
| 11946 | |
| 11947 | /* test for permissions and valid option value */ |
| 11948 | (void) set_config_option(name, value, |
| 11949 | superuser() ? PGC_SUSET : PGC_USERSET, |
no test coverage detected