Project

General

Profile

Feature #16960 » 16960.patch

Jim Pingle, 07/21/2026 04:20 PM

View differences:

src/etc/inc/priv/user.priv.inc
$priv_list['page-openvpn-client-advanced']['descr'] = gettext("Allow edit access to the 'OpenVPN: Servers' Advanced settings field.");
$priv_list['page-openvpn-client-advanced']['warn'] = "standard-warning-root";
$priv_list['page-services-dhcpserver-custom'] = array();
$priv_list['page-services-dhcpserver-custom']['name'] = gettext("WebCfg - Services: DHCP Server: Edit Custom Configuration");
$priv_list['page-services-dhcpserver-custom']['descr'] = gettext("Allow edit access to the 'Services: DHCP Server' Custom Configuration fields.");
$priv_list['page-services-dhcpserver-custom']['warn'] = "standard-warning-root";
$priv_list['page-services-dhcpv6server-custom'] = array();
$priv_list['page-services-dhcpv6server-custom']['name'] = gettext("WebCfg - Services: DHCPv6 Server: Edit Custom Configuration");
$priv_list['page-services-dhcpv6server-custom']['descr'] = gettext("Allow edit access to the 'Services: DHCPv6 Server' Custom Configuration fields.");
$priv_list['page-services-dhcpv6server-custom']['warn'] = "standard-warning-root";
?>
src/usr/local/pfSense/include/www/services_dhcp.inc
require_once('interfaces.inc');
require_once('pfsense-utils.inc');
/* custom config can run commands as root, so it has its own privilege */
function dhcp_can_edit_custom_config(bool $v6 = false): bool {
$user_entry = getUserEntry($_SESSION['Username']);
$user_entry = $user_entry['item'];
$priv = $v6 ? 'page-services-dhcpv6server-custom'
: 'page-services-dhcpserver-custom';
return (isAdminUID($_SESSION['Username']) ||
userHasPrivilege($user_entry, $priv) ||
userHasPrivilege($user_entry, 'page-all'));
}
function kea_log_levels() {
return [
'DEBUG' => gettext('Debug'),
......
}
}
if (!empty($_POST['custom_kea_config'])) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($_POST['custom_kea_config']));
$custom_priv_error = false;
if (dhcp_can_edit_custom_config()) {
if (!empty($_POST['custom_kea_config'])) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($_POST['custom_kea_config']));
} else {
array_del_path($pconfig, 'custom_kea_config');
}
} else {
array_del_path($pconfig, 'custom_kea_config');
$old_custom = base64_decode(array_get_path($old_config, 'custom_kea_config', ''));
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $old_custom)) {
$custom_priv_error = true;
}
/* preserve stored value */
if (!empty($old_custom)) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($old_custom));
} else {
array_del_path($pconfig, 'custom_kea_config');
}
}
/* don't leave empty ha config section */
......
}
$input_errors = dhcp_validate_settings_post($pconfig);
if ($custom_priv_error) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
if (!$input_errors && ($pconfig !== $old_config)) {
config_set_path('kea', $pconfig);
write_config(gettext('DHCP Server - Settings changed'));
......
}
}
if (!empty($_POST['custom_kea_config'])) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($_POST['custom_kea_config']));
$custom_priv_error = false;
if (dhcp_can_edit_custom_config(true)) {
if (!empty($_POST['custom_kea_config'])) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($_POST['custom_kea_config']));
} else {
array_del_path($pconfig, 'custom_kea_config');
}
} else {
array_del_path($pconfig, 'custom_kea_config');
$old_custom = base64_decode(array_get_path($old_config, 'custom_kea_config', ''));
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $old_custom)) {
$custom_priv_error = true;
}
/* preserve stored value */
if (!empty($old_custom)) {
array_set_path($pconfig, 'custom_kea_config', base64_encode($old_custom));
} else {
array_del_path($pconfig, 'custom_kea_config');
}
}
/* don't leave empty ha config section */
......
}
$input_errors = dhcp_validate_settings_post($pconfig);
if ($custom_priv_error) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
if (!$input_errors && ($pconfig !== $old_config)) {
config_set_path('kea6', $pconfig);
write_config(gettext('DHCPv6 Server - Settings changed'));
src/usr/local/www/services_dhcp.php
/* validate custom config */
if (dhcp_is_backend('kea')) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
if (dhcp_can_edit_custom_config()) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
}
}
} else {
$stored_custom = base64_decode(array_get_path($dhcpdconf, 'custom_kea_config', ''));
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $stored_custom)) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
/* show the stored value, not the submitted one */
$pconfig['custom_kea_config'] = $stored_custom;
}
}
......
$dhcpdconf['omapi_key_algorithm'] = $_POST['omapi_key_algorithm'];
}
if (dhcp_is_backend('kea')) {
if (dhcp_is_backend('kea') && dhcp_can_edit_custom_config()) {
$dhcpdconf['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
}
......
if (dhcp_is_backend('kea')):
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), $kea_section, '<br/>');
);
if (!dhcp_can_edit_custom_config()) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), $kea_section, '<br/>');
$form->add($section);
endif;
src/usr/local/www/services_dhcp_edit.php
/* validate custom config */
if (dhcp_is_backend('kea')) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
if (dhcp_can_edit_custom_config()) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
}
}
} else {
$stored_custom = is_array($this_map_config) ? base64_decode(array_get_path($this_map_config, 'custom_kea_config', '')) : '';
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $stored_custom)) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
/* show the stored value, not the submitted one */
$pconfig['custom_kea_config'] = $stored_custom;
}
}
......
$mapent['numberoptions'] = $pconfig['numberoptions'];
if (dhcp_is_backend('kea')) {
$mapent['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
if (dhcp_can_edit_custom_config()) {
$mapent['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
} elseif (!empty($this_map_config['custom_kea_config'])) {
/* preserve stored value */
$mapent['custom_kea_config'] = $this_map_config['custom_kea_config'];
}
}
if ($this_map_config) {
......
if (dhcp_is_backend('kea')):
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'reservation', '<br/>');
);
if (!dhcp_can_edit_custom_config()) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'reservation', '<br/>');
$form->add($section);
endif;
src/usr/local/www/services_dhcp_settings.php
$form->add($section);
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'Dhcp4', '<br/>');
);
if (!dhcp_can_edit_custom_config()) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv4 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'Dhcp4', '<br/>');
$form->add($section);
$form->addGlobal(new Form_Input(
src/usr/local/www/services_dhcpv6.php
/* validate custom config */
if (dhcp_is_backend('kea')) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
if (dhcp_can_edit_custom_config(true)) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
}
}
} else {
$stored_custom = base64_decode(array_get_path($dhcpdconf, 'custom_kea_config', ''));
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $stored_custom)) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
/* show the stored value, not the submitted one */
$pconfig['custom_kea_config'] = $stored_custom;
}
}
......
$dhcpdconf['numberoptions'] = $numberoptions;
if (dhcp_is_backend('kea')) {
if (dhcp_is_backend('kea') && dhcp_can_edit_custom_config(true)) {
$dhcpdconf['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
}
......
if (dhcp_is_backend('kea')):
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), $kea_section, '<br/>');
);
if (!dhcp_can_edit_custom_config(true)) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), $kea_section, '<br/>');
$form->add($section);
endif;
src/usr/local/www/services_dhcpv6_edit.php
/* validate custom config */
if (dhcp_is_backend('kea')) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
if (dhcp_can_edit_custom_config(true)) {
if (!empty($_POST['custom_kea_config'])) {
$json = json_decode($_POST['custom_kea_config'], true);
if (!is_array($json) || (json_last_error() !== JSON_ERROR_NONE)) {
$input_errors[] = gettext('Custom configuration is not a well formed JSON object.');
}
}
} else {
$stored_custom = is_array($this_map_config) ? base64_decode(array_get_path($this_map_config, 'custom_kea_config', '')) : '';
if (isset($_POST['custom_kea_config']) && ($_POST['custom_kea_config'] !== $stored_custom)) {
$input_errors[] = gettext('This user does not have sufficient privileges to edit the Custom Configuration field.');
}
/* show the stored value, not the submitted one */
$pconfig['custom_kea_config'] = $stored_custom;
}
}
......
if (!empty($_POST['pdprefix'])) {
$mapent['pdprefix'] = text_to_compressed_ip6($_POST['pdprefix']);
}
$mapent['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
if (dhcp_can_edit_custom_config(true)) {
$mapent['custom_kea_config'] = base64_encode($_POST['custom_kea_config']);
} elseif (!empty($this_map_config['custom_kea_config'])) {
/* preserve stored value */
$mapent['custom_kea_config'] = $this_map_config['custom_kea_config'];
}
}
if ($this_map_config) {
......
if (dhcp_is_backend('kea')):
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'reservation', '<br/>');
);
if (!dhcp_can_edit_custom_config(true)) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'reservation', '<br/>');
$form->add($section);
endif;
src/usr/local/www/services_dhcpv6_settings.php
$form->add($section);
$section = new Form_Section(gettext('Custom Configuration'));
$section->addInput(new Form_Textarea(
$custom_config = new Form_Textarea(
'custom_kea_config',
gettext('JSON Configuration'),
array_get_path($pconfig, 'custom_kea_config')
))->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'Dhcp6', '<br/>');
);
if (!dhcp_can_edit_custom_config(true)) {
$custom_config->setDisabled();
}
$section->addInput($custom_config)->setWidth(8)->setHelp(gettext('JSON to be merged into the "%1$s" section of the generated Kea DHCPv6 configuration.%2$sThe input must be a well formed JSON object and should not include the "%1$s" key itself.'), 'Dhcp6', '<br/>');
$form->add($section);
$form->addGlobal(new Form_Input(
(1-1/2)