From 427165d1b7cec207609048f7b45f289359d8ee16 Mon Sep 17 00:00:00 2001 From: 0x1eef <0x1eef@protonmail.com> Date: Wed, 20 Mar 2024 18:34:15 -0300 Subject: [PATCH] Add BSD::Control::Feature#sysdef! --- ext/bsdcontrol.rb/bsdcontrol.c | 1 + ext/bsdcontrol.rb/feature.c | 28 ++++++++++++++ ext/bsdcontrol.rb/feature.h | 1 + lib/bsd/control/feature.rb | 18 ++++----- lib/{hbsdctl.rb => bsdcontrol.rb} | 0 test/setup.rb | 2 +- test/superuser/sysdef_feature_test.rb | 37 +++++++++++++++++++ ...{sysdef_test.rb => sysdef_feature_test.rb} | 0 8 files changed, 76 insertions(+), 11 deletions(-) rename lib/{hbsdctl.rb => bsdcontrol.rb} (100%) create mode 100644 test/superuser/sysdef_feature_test.rb rename test/unprivileged/{sysdef_test.rb => sysdef_feature_test.rb} (100%) diff --git a/ext/bsdcontrol.rb/bsdcontrol.c b/ext/bsdcontrol.rb/bsdcontrol.c index 9ed99f9..baa6d79 100644 --- a/ext/bsdcontrol.rb/bsdcontrol.c +++ b/ext/bsdcontrol.rb/bsdcontrol.c @@ -18,5 +18,6 @@ Init_bsdcontrol(void) bsdcontrol_context_available_features, 0); rb_define_method(rb_cFeature, "status", bsdcontrol_feature_status, 1); + rb_define_method(rb_cFeature, "sysdef!", bsdcontrol_feature_sysdef, 1); rb_define_private_method(rb_cFeature, "set!", bsdcontrol_feature_set, 2); } diff --git a/ext/bsdcontrol.rb/feature.c b/ext/bsdcontrol.rb/feature.c index 5b0c143..6586fe4 100644 --- a/ext/bsdcontrol.rb/feature.c +++ b/ext/bsdcontrol.rb/feature.c @@ -66,3 +66,31 @@ bsdcontrol_feature_set(VALUE self, VALUE path, VALUE rbstate) return Qtrue; } } + +/* + * BSD::Control::Feature#sysdef! + */ +VALUE +bsdcontrol_feature_sysdef(VALUE self, VALUE path) +{ + int fd; + VALUE rbcontext; + hbsdctrl_feature_t *feature; + hbsdctrl_ctx_t *ctx; + rbcontext = rb_funcall(self, rb_intern("context"), 0); + fd = bsdcontrol_open(path); + ctx = bsdcontrol_unwrap(rbcontext); + feature = bsdcontrol_find_feature(ctx, self); + errno = 0; + if (feature->hf_unapply(ctx, feature, &fd, NULL) == RES_FAIL) + { + close(fd); + errno == 0 ? rb_raise(rb_eSystemCallError, "hf_unapply") + : rb_syserr_fail(errno, "hf_unapply"); + } + else + { + close(fd); + return Qtrue; + } +} diff --git a/ext/bsdcontrol.rb/feature.h b/ext/bsdcontrol.rb/feature.h index e01534d..0f347cb 100644 --- a/ext/bsdcontrol.rb/feature.h +++ b/ext/bsdcontrol.rb/feature.h @@ -1,3 +1,4 @@ #include VALUE bsdcontrol_feature_status(VALUE, VALUE); VALUE bsdcontrol_feature_set(VALUE,VALUE,VALUE); +VALUE bsdcontrol_feature_sysdef(VALUE, VALUE); diff --git a/lib/bsd/control/feature.rb b/lib/bsd/control/feature.rb index c5ae8e4..abc4768 100644 --- a/lib/bsd/control/feature.rb +++ b/lib/bsd/control/feature.rb @@ -41,19 +41,17 @@ module BSD::Control end ## - # Restore system defaults for a given file. + # @!method sysdef!(path) + # Restore system defaults for a given file. # - # @param [String] path - # The path to a file. + # @param [String] path + # The path to a file. # - # @raise [SystemCallError] - # Might raise a number of Errno exceptions. + # @raise [SystemCallError] + # Might raise a number of Errno exceptions. # - # @return [Boolean] - # Returns true on success. - def sysdef!(path) - # FIXME: implement. - end + # @return [Boolean] + # Returns true on success. # @endgroup diff --git a/lib/hbsdctl.rb b/lib/bsdcontrol.rb similarity index 100% rename from lib/hbsdctl.rb rename to lib/bsdcontrol.rb diff --git a/test/setup.rb b/test/setup.rb index 017ac51..eb6ffbe 100644 --- a/test/setup.rb +++ b/test/setup.rb @@ -1,2 +1,2 @@ require "test/unit" -require "hbsdctl" +require "bsdcontrol" diff --git a/test/superuser/sysdef_feature_test.rb b/test/superuser/sysdef_feature_test.rb new file mode 100644 index 0000000..0a9f7f5 --- /dev/null +++ b/test/superuser/sysdef_feature_test.rb @@ -0,0 +1,37 @@ +require_relative "../setup" +module BSD::Control + class SysDefFeatureTest < Test::Unit::TestCase + require 'fileutils' + include FileUtils + + def test_sysdef_pageexec + touch(file) + assert BSD::Control.feature(:pageexec).enable!(file), + "The enable! method should have returned true" + assert_equal( + BSD::Control.feature(:pageexec).status(file), + :enabled + ) + assert BSD::Control.feature(:pageexec).sysdef!(file), + "The sysdef! method should have returned true" + assert_equal( + BSD::Control.feature(:pageexec).status(file), + :sysdef + ) + ensure + rm(file) + end + + def test_enable_pageexec_nonexistent_file + assert_raises(Errno::ENOENT) do + BSD::Control.feature(:pageexec).sysdef!(file) + end + end + + private + + def file + File.join(__dir__, "file") + end + end +end diff --git a/test/unprivileged/sysdef_test.rb b/test/unprivileged/sysdef_feature_test.rb similarity index 100% rename from test/unprivileged/sysdef_test.rb rename to test/unprivileged/sysdef_feature_test.rb