0

For some component testing, in my C++ testapp on Ubuntu 14.04, I'd like to rename /sbin/reboot temporarily to prevent my system under test (another big c++ app started inside testapp) from calling system("/sbin/reboot") and after the test I want to restore /sbin/reboot to its full glory.

So on the cmd shell I call

sudo setcap cap_chown,cap_dac_override,cap_setfcap=+ep testapp

in order to enable my testapp to call system("chown user /sbin/reboot") furthermore system("chgrp developer /sbin/reboot") and system("mv /sbin/reboot /sbin/reboot.tmp")

But testapp stops with chown: changing ownership of ‘/sbin/reboot’: Operation not permitted

So, what has to be done to enable renaming this particular file from within an app not running sudo?

x y
  • 911
  • 9
  • 27
  • 4
    You're asking a [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). The problem you want to solve is *"how can I test an application that calls `/sbin/reboot` without that leading to a system restart?"* The solution **is not** to rename that program. The solution is to test your application within a sandbox/container that offers a clean environment for testing, in which `/sbin/reboot` is a no-op. You should ask how to create such a sandbox and use that. – datenwolf Mar 31 '17 at 13:57
  • 2
    Also I think I should point out the irony of a user named "x y" to ask a XY problem. You can't make up something like that :) – datenwolf Mar 31 '17 at 13:59
  • Thank you for telling me, what the solution *not* is - especially if you give such deep insights of how the sandbox approach has to look like ... – x y Mar 31 '17 at 14:04
  • 2
    not knowing the full details of what you're doing, only recommendation i can offer is you need a **test system**. It sounds like you are currently developing and testing on a production type system - otherwise you should not be worried about doing a simple changing of permissions on `sbin/reboot`. Then create a simple script named `/sbin/reboot` that does nothing more than `echo "/sbin/reboot was called"` – ron Mar 31 '17 at 14:09
  • 1
    or in your C++ app change the variable or constant (which you should have) that points to `/sbin/reboot` and instead point it to `/your_c++_app/testing/sbin_reboot` which only does an echo statement. When you get everything working, then do the final change in your c++ app and point everything back to system files such as for `/sbin/reboot`. – ron Mar 31 '17 at 14:13
  • 1
    @xy: How can I offer you a viable solution if you're not putting up a question that describes your actual problem. At some point you mentally navigated into a corner that makes you think that messing with `/sbin/reboot` would be a viable approach. No matter what your actual problem is, I can definitely tell you that messing with a system level binary **never** is a viable option. By deduction this leads to the conclusion that your problem is something different. And by your vague description we can infer that it's the lack of a proper testing environment. – datenwolf Mar 31 '17 at 14:51
  • For clarification: my testapp is a GoogleTest application, starting (testing) another app - the system under test - which calls "system reboot". So I cannot change any variables pointing to somewhere, I just want to avoid the effect of rebooting the system while running the test. And this should be done without manual interaction ;) – x y Mar 31 '17 at 14:52
  • 1
    @xy: However how exactly to setup such a testing environment depends on your original problem "X". You were asking for how to do "Y", but this is not what you actually need to know. So tell us your actual problem "X" is and we can offer solutions. – datenwolf Mar 31 '17 at 14:52
  • 1
    @xy: Then simply set up a test system. Most simple solution would be to put up a `lxc` container with the test environment. It's not even necessary to create new filesystems or such for that. You can use overlay mounts to use your regular system's environment with tmpfs overlaid so that changes don't "punch through" and start the container without rebooting capabilities. – datenwolf Mar 31 '17 at 14:54
  • For simplicity, just add answer - or contribute a solution - to the question "how to rename sbin/reboot from within a C++ application not running as sudo" ;) – x y Mar 31 '17 at 14:55
  • @datenwolf For all linux capability experts in the www: the question was - "Which of the linux capabilities does my app need to rename /sbin/reboot withou sudo - to get the same effect as calling sudo mv /sbin/reboot /sbin/reboot.tmp in a shell. Without beeing impolite, but if I ask into the crowd "What's the time"? an answer like "you asked the wrong question, because I don't have a watch, but I have a humidity meter, so if you ask about humidity, I am glad to help you" does not help me at all. – x y Apr 01 '17 at 10:50

1 Answers1

0

For all linux capability experts in the www: the question was - "Which of the linux capabilities does my app need to rename /sbin/reboot withou sudo - to get the same effect as calling sudo mv /sbin/reboot /sbin/reboot.tmp in a shell.

@datenwolf: Without beeing impolite, but if I ask into the crowd "What's the time"? an answer like "you asked the wrong question, because I don't have a watch, but I have a humidity meter, so if you ask about humidity, I am glad to help you" does not help me at all.

The solution to rename a root owned file is, to only set

sudo setcap cap_dac_override=+ep MyTestApp

on commandline, and instead of using

system("mv file1 file2");

in MyTestApp source-code, switch back to

rename("file1" "file2");

Then everything works like a charm.

x y
  • 911
  • 9
  • 27