How to use sbin command in Makefile? - linux

I need to use mkfs.vfat in Makefile mymake.mk,
but this command is locate in /sbin/
$ which mkfs.vfat
/sbin/mkfs.vfat
current user is not root, and I build my project then got error "command not found".
How to use sbin command in Makefile?

The problem you have is probably these two points:
The current user does not have /sbin/ in his $PATH.
The current user is not allowed to write to the block device to create a file system on it.
The first problem is easily amended by just writing the full path instead of just the command in the Makefile:
target: sources …
/sbin/mkfs.vfat ……
The second problem only occurs if you really want to write to a block device you haven't write permissions to. In this case consider what you are doing. Does it really make sense? Typically this makes only sense in a make install situation, and this should be executed by user root only, so then you'd have write permissions. In practice, one typically types sudo make install to gain root access for that installation step only.
If, however, this is a special case, then you can add that sudo to your Makefile as well:
target: sources …
sudo /sbin/mkfs.vfat ……
(This would lead to being asked for the password when running the Makefile.)
And, last not least, you can use that mkfs to create a file, containing the newly created file system. In that case you don't need any special permissions (besides write permissions to that file you want to create:
target: sources …
/sbin/mkfs.vfat -C /path/to/my/filesystem ……

Have somewhere in the header
PATH:=$(PATH):/sbin

Related

Execute a bash script without typing ./ [duplicate]

I feel like I'm missing something very basic so apologies if this question is obtuse. I've been struggling with this problem for as long as I've been using the bash shell.
Say I have a structure like this:
├──bin
├──command (executable)
This will execute:
$ bin/command
then I symlink bin/command to the project root
$ ln -s bin/command c
like so
├──c (symlink to bin/command)
├──bin
├──command (executable)
I can't do the following (errors with -bash: c: command not found)
$ c
I must do?
$ ./c
What's going on here? — is it possible to execute a command from the current directory without preceding it with ./ and also without using a system wide alias? It would be very convenient for distributed executables and utility scripts to give them one letter folder specific shortcuts on a per project basis.
It's not a matter of bash not allowing execution from the current directory, but rather, you haven't added the current directory to your list of directories to execute from.
export PATH=".:$PATH"
$ c
$
This can be a security risk, however, because if the directory contains files which you don't trust or know where they came from, a file existing in the currently directory could be confused with a system command.
For example, say the current directory is called "foo" and your colleague asks you to go into "foo" and set the permissions of "bar" to 755. As root, you run "chmod foo 755"
You assume chmod really is chmod, but if there is a file named chmod in the current directory and your colleague put it there, chmod is really a program he wrote and you are running it as root. Perhaps "chmod" resets the root password on the box or something else dangerous.
Therefore, the standard is to limit command executions which don't specify a directory to a set of explicitly trusted directories.
Beware that the accepted answer introduces a serious vulnerability!
You might add the current directory to your PATH but not at the beginning of it. That would be a very risky setting.
There are still possible vulnerabilities when the current directory is at the end but far less so this is what I would suggest:
PATH="$PATH":.
Here, the current directory is only searched after every directory already present in the PATH is explored so the risk to have an existing command overloaded by an hostile one is no more present. There is still a risk for an uninstalled command or a typo to be exploited, but it is much lower. Just make sure the dot is always at the end of the PATH when you add new directories in it.
You could add . to your PATH. (See kamituel's answer for details)
Also there is ~/.local/bin for user specific binaries on many distros.
What you can do is add the current dir (.) to the $PATH:
export PATH=.:$PATH
But this can pose a security issue, so be aware of that. See this ServerFault answer on why it's not so good idea, especially for the root account.

Using mkdir in my bash script and getting permission denied

i have script that is owned by root in a directory owned by root. part of the script is to make a directory that will hold the inputs/outputs of that script. i also have a sim link to that script so any user can run it from anywhere. i don't use the temp directory so this info can be used as logs later.
Problem: when a user tries to run the script they get an error that the directory cannot be created because of permission denied.
Questions: why won't the script make the directory so root owns it independent of what user runs it? how can the script make the directory so root owns it instead of the user that ran it? only the script needs this info, not the user.
Additional info:
the directory is: drws--s--x.
the script is: -rwxr-xr-x.
(if you need to know) the line in the script is simply: mkdir $tempdirname
i am matching the permissions of other scripts on the same server that output text files correctly, but since mine is a directory i'm getting permission errors.
i have tried adding the permissions for suid and sgid. suid sounded like the correct solution since it should make the script run as if it were run by the user that owns the script. (why isn't this the correct solution?)
i would like any user to be able to type in the sim link name, that will run the script that is owned by root in the directory that is owned by root, and the directories created by that script will stay in its own directory. and the end user has no knowledge or access to the inner workings of this process. (hence owned by root)
Scripts run as the user that runs them; the owner of the file and/or the directory it's in are irrelevant (except that the user needs read and execute permission to the file and directory). Binary executables can have their setuid bit set to make them always run as the file's owner. Old unixes allowed this for scripts as well but this caused a security hole, so setuid is ignored on scripts in modern unixes/Linuxes.
If you need to let regular users run a script as root, there are a couple of other ways to do this. One is to add the script to your /etc/sudoers file, so that users can use sudo to run it as root. WARNING: if you mess up your /etc/sudoers file, it can be hard to recover access to clean it up and get back to normal. Make a backup first, don't edit it with anything except visudo, and I recommend having a root shell open so if something goes wrong you'll have the root access you need to fix it without having to promote via sudo. The line you'll need to add will be something like this:
%everyone ALL=NOPASSWD: /path/to/script
If you want to make this automatic, so that users don't have to explicitly use sudo to run the script, you can start the script like this:
#!/bin/bash
if [[ $EUID -ne 0 ]];
then
exec sudo "$BASH_SOURCE" "$#"
fi
EDIT: A simpler version occurred to me; rather than having the script re-run itself under sudo, just replace the symlink with a stub script like this:
#!/bin/bash
exec sudo /path/to/real/script "$#"
Note that with this option, the /etc/sudoers entry must refer to the real script's path, not that of the symlink. Also, if the script doesn't take arguments, you can leave the "$#" off. Or use it, it won't do any harm either.
If messing with /etc/sudoers sounds too scary, there's another option: you could "compile" the script with shc (which actually just makes a binary executable wrapper around it), and make that setuid root (chmod 4755 /path/to/compiled-script; chown root /path/to/compiled-script). Since it's in a binary wrapper, setuid will work.

Shell Command that Combines chmod and chgrp

Is there a combine variant for chmod and chgrp that sets both permissions and groups in one single system call for each file?
There is no such a variant because the two operations chmod(2) and chown(2) are implemented by distinct system calls.
Getting away with chmod and chown
You might be looking for such a variant of chmod and chown because of security issues. If this is the case, you can use the following strategy:
Strip mode flags to a very conservative set (possibly empty) on the target file.
Change owner and group of the target file.
Give the target file the desired mode flags.
This way you avoid potential security issues associated to successive calls to chmod and chown or to chown and chmod.
The install/open trick
The only system call setting mode flags and ownership information at the same time might be open(2). So, you could use a process impersonating the target owner opening the file with the appropriate mode. This is probably what install does, so if this is an option:
Rename the old file.
Copy the old file to the new file with the desired ownership and access mode information using the install command.
Delete the old file.
Doing this will break hard links, however. The solution based on chown and chmod does not have that issue.
AFAIK, no.
Furthermore, since the file access mode and owner / group information are set using different syscalls (see man 2 chmod and man 2 chown), I don't think it would be possible to implement such a command ... at least on a mainstream Unix-like system.
(Obviously, one could modify a GNU/Linux kernel to add a combined system call, but then the hypothetical command that used the syscall wouldn't be portable.)

Symbolic links to folders whose parent directory has no execute permission

I am trying to do a soft link from one directory to another, the directory I am trying to access I have read and execute. However, its parent directory I do NOT have execute permissions.
Is there a way to do a soft link, to my desired directory without giving me execute permission to the parent directory?
Below is the code I used:
ln -s /home/dir1/dir2/desired_directory symbolic_link_name
the link just comes up as red with grey background.
Thank you.
Although this is not possible with symlinks, you could do it with mount --bind. Note that if the whole point is to circumvent security, then this is probably a very bad idea.
Your command would be
mount --bind /home/dir1/dir2/desired_directory mount_dir
There are a few issues to be aware of:
The target directory mount_dir must exist before (same as any mount point)
Root access is required to execute the mount commmand
The created "link" will not persist after a reboot unless a corresponding line is added to /etc/fstab
If the origin directory contains mounted file systems, these will not be transferred to the target. The mount points will appear as empty directories.
Using mount --bind may be considered bad practice because most programs are not aware that the "link" is not a standard directory. For instance it allows the creation of loops in the directory tree which make any tree parsing application (think "ls -R") enter a possibly infinite loop.
It may be hazardous when combined with recursive delete operations. See for instance Yet another warning about mount --bind and rm -rf.
Symbolic links are not a way to circumvent permissions set on their targets. No, there is no way to do what you want. If it was possible it would be a serious security issue.

symlinking and running an installation command

In the installation guide of some soft, user is told to run this
sudo ln -s /opt/local/somesoft/somsoft* /opt/local/bin
Is this command dangerous ? Should /opt/local/bin be prevented from calling something else tha n itself ?
This command does few things
sudo gives root permissions to the 'ln' binary
ln is instructed to go through all files matching pattern /opt/local/somesoft/somsoft*
for every such file it tries to create symbolic link in /opt/local/bin directory
this created symbolic link will have the same name as the file just being processed
Your first question is, is it dangerous? Most probably not, there are few things which might go wrong
your $PATH environment contains some strange directory, so instead of calling /usr/bin/ln (as was the original intention I believe) you wold be tricked into calling some different executable. For example if your PATH=.:/tmp:/usr/bin, 'ln' is first searched in your current directory, then in /tmp and then in /usr/bin. And it's called with superuser permissions ...
there are no such files as /opt/local/somesoft/somsoft* . In such case ln will create symbolic link '/opt/local/bin/somsoft*' (including the star in it's name). That's probably not what you wanted
/opt/local/bin already contains the files with the same names as /opt/local/somesoft/somsoft* . In such case ln will not create new files there (is it good or bad? that is the question)
You don't have /opt/local/bin . In such cases there are several ways of how the command fails (depending whether you have /opt/local directory and how many files match the pattern /opt/local/somesoft/somsoft*)
Your second question does not make much sense. /opt/local/bin is a directory, and directory can't "call" anything. So it can't be prevented to do so. If you ask whether the symbolic links should be created there, I would say why not. The whole idea behind the command is to
install somesoft into special directory so that you won't pollute your /usr/bin or any other common directory
to be able to run the commands without the need of specifying every time full path /opt/local/somesoft/somsoft... you may want to create symbolic links in /opt/local/bin. And make sure that your /opt/local/bin is in your directory.

Resources