The simple answer is: It is not possible to force your users to use your wrapper script.
The reason for this is fairly simple; a shell script is an interpreted program. That means that
bash (or some other shell process) must read the file in order to run the commands that are called in it.
This in turn means that a user who has permission to run the wrapper script, must have permission to do everything that is done in the wrapper script. In the vast majority of cases*, a shell script, even one with lots of internal logic and conditionals, does exactly the same thing when you run it as it would if you typed the entire script into your command prompt, line by line.
If you are merely trying to make it difficult for uneducated users to slow down your system, there are a multitude of ways of doing this, such as what @mikeserv suggests in a comment on your question. I can think of at least five more ways offhand**, many of which could be used in combination; the crucial thing to understand about these is that they're not secure. They don't actually prevent the user from using the command directly instead of the wrapper script, and they also don't (and can't) prevent the user from making his own copy of the wrapper script (which he must have read permissions on to be able to run at all) and modifying it however he likes.
It is possible to write a short C program to perform the function of your wrapper script, which compiles to a binary executable, and then make that C program SUID*** so it is the only way the user can run the command you are talking about, but that's beyond my scope and area of expertise.
Other options involve extremely odd workarounds (hacks) like setting a cronjob to modify your sudoers file to allow permissions to run the command only during specific times of day...but that's getting really, really weird and Bad Idea territory.
I think the standard way to accomplish this (although still without forcing tech-savvy users to use your wrapper script) would be:
(I'll pretend the command to restrict is
- Ensure that inside your script, its call to
date uses the absolute path:
/bin/date (You can find out what this is by running
which date.) Also ensure your script has a proper shebang, so that it can be run without needing to type
bash ./myscript but can just be run as
./myscript, and ensure it is readable and executable by everyone. (
chmod 555 myscript)
- Put your wrapper script in
/usr/local/bin/ and rename it as
- Check that users have
/usr/local/bin at the start of their
$PATH variable. (Just log in as a user and run
echo "$PATH".) They should already have this by default. It doesn't have to be at the very start as long as it's in their path before
/bin (or whatever the location of the original
date command is).
If they don't have it in their path, you can add it by running:
echo 'PATH="/usr/local/bin:$PATH"' | sudo tee /etc/profile.d/my_path_prefix.sh
Now any time a user tries to run the command directly, he will actually be running your wrapper script, because the directory where your wrapper script is appears first in his
A much more hack-y "blackhat" sort of a solution would be to actually mask the original binary, not by putting another version earlier in the path for users, but by putting the wrapper script in place of the command itself, in its original location. Use at your own risk:
- Put the command itself somewhere outside the normal
bin directories so no one has it in their path. You could move it to, for example,
/var/local. (There may be a better place, but this is a hack already, so it doesn't matter much, does it?)
- Ensure that the call to the
date within your wrapper script points to the new location for
date—its absolute path:
/var/local/date in my example.
- Move your wrapper script into
date's old location, with
date's original name.
The main caveat is that every time anyone tries to run that command, including system init scripts, they will get your wrapper script instead.
This is purely a hack and would not qualify as good system administration. But it is possible and you may as well know that it could be done. The better solution is what I posted above.
*The exceptions to this have to do with modifying the environment and programs that behave differently when they are run interactively vs. when they are run from a script. These exceptions have nothing to do with permissions, though, so they're not relevant to this discussion.
**Ask about them in the comments if you are interested and I'll expand on them.
***NOT suid root. If you do this, just create a user, put him in a group which is the only one with permission to run the command you are talking about (
chmod 010 or something) and then
chown your fresh-compiled wrapper binary to be owned by that user and set its suid bit with