-su: /dev/tty: No such device or address - linux

could please someone explain to me why this happens?
# su - someone -s /bin/bash -c "ls -la /dev/tty"
crw-rw-rw- 1 nobody nogroup 5, 0 Dec 7 20:53 /dev/tty
# BUT:
# su - someone -s /bin/bash -c "echo hello > /dev/tty"
-su: /dev/tty: No such device or address
I'm trieng to build a docker Container which has two services inside. Those services a startet by a Shell-Script:
CMD ["./starter.sh"]
Withing the Dockerfile I have redirected the Logs to /dev/stderr or /dev/tty
# None of the following works:
RUN ln -sf /dev/tty /var/log/thelog.log
RUN ln -sf /dev/stdout /var/log/thelog.log
RUN ln -sf /dev/stderr /var/log/thelog.log
The problem is that I'm trying to run one of the services as not root (su -
someone -c "service"), which give's the following error:
unable to open log file [/var/log/thelog.log]: [6] No such device or address
How could I solve this problem? I want the logs to be linked to /dev/* AND want to run the User as non-root. Also I tried to add the User to the group tty, which did not work out.
Thanks.

The manpage for su states that the executed command will have no controlling terminal. Any writes to /dev/tty will return the ENXIO error:
$ errno ENXIO
ENXIO 6 No such device or address
sudo does allocate a controlling terminal:
sudo -u someone /bin/bash -c "echo hello > /dev/tty"
There's no need for you to make a symbolic link to /dev/tty (/dev/stdout and /dev/stderr is enough) or use sudo if you use the USER directive in the Dockerfile or supervisor.

Related

Why commands like "su", "passwd" in busybox cannot work properly?

Background:
Debugging linux kernel 6.0 with qemu-system-x86_64. The start commandline is as follows:
qemu-system-x86_64 -kernel ./bzImage -initrd ./rootfs.img -serial stdio -append " console=ttyS0 nokaslr"
The initrd rootfs.img is made by busybox-1.35.0 using the following commands:
$ make menuconfig #choose [*] Build static binary (no shared libs)
$ make && make install
$ cd _install
$ ls
bin linuxrc sbin usr
$ mkdir -p dev proc etc sys\kernel\debug sys\dev
$ vim init
The init file is filled with:
#!/bin/sh
echo "{==DBG==} INIT SCRIPT"
mkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t tmpfs none /tmp
mdev -s
echo -e "{==DBG==} Boot took $(cut -d' ' -f1 /proc/uptime) seconds"
# normal user
setsid /bin/cttyhack setuidgid 1000 /bin/sh
$ find . | cpio -o --format=newc > ./rootfs.img
================================================================
The problem:
When I runqemu-system-x86_64 -kernel ./bzImage -initrd ./rootfs.img -serial stdio -append " console=ttyS0 nokaslr" to start qemu. And enter the kernel successfully. But when I run "su" the problem occurs:
{==DBG==} INIT SCRIPT
{==DBG==} Boot took 2.63 seconds
/ $ su
su: must be suid to work properly
/ $
================================================================
What I tried:
I tried to google the problem. But only find to escalate the privilege.
Then I tried:
/ $ cd bin
/bin $ chmod u+s busybox
/bin $ ls -l busybox
-rwsr-xr-x 1 1000 1000 2408664 Oct 11 12:57 busybox
/bin $ su
su: must be suid to work properly
/bin $
Obviously the 'solution' failed.
================================================================
So what can I do to solve this problem? Or what causes this problem? Any help would be appreciated! Thanks in advance!
The suid bit that you added with chmod u+s busybox changes the current user to the owner of /bin/busybox, which as you can see is 1000.
So you want to change /bin/busybox to be owned by root:
$ chown root:root /bin/busybox
But you won't be able to do that from within your non-root shell; you must make this change in the root image rootfs.img.
It probably makes sense to have all files in the image owned by root. You don't need to change the ownership in the host file system, because you can do it while building the image:
$ find . | cpio -o --format=newc --owner=+0:+0 > ./rootfs.img
^^^^^^^^^^^^^

What's the best way to test if a user can sudo in Bash?

Reading the sudo man page, I see that the -v flag can be used to check if the user has sudo privileges in his workstation. I have a piece of script that needs to test it. If the user has not sudo privileges, it prints on screen:
Sorry, user tester may not run sudo on debian.
How can I suppress this message and just execute the rest of the code?
Try to append >/dev/null in your command. In case the message is printed in stderr then use 2>/dev/null or as advised in comments use &>/dev/null to redirect both stdout and stderr to null.
Using sudo -l or --list
As per the man page, sudo can be used with -l or --list to get the list of allowed and forbidden commands for any particular user.
The syntax would be: sudo -l [-AknS] [-a type] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
If we use sudo --list without any arguments, then it will print the list of allowed and forbidden commands for the user who is executing the sudo command
sudo --list
User root may run the following commands on client:
(ALL) ALL
Depends on what you mean by "can user sudo"
Short answer:
If can_auto_sudo=$(sudo -l -n sudo &>/dev/null; echo $?) is 0, you can sudo as much as you want.
Long Answer
Do you need to test before or can you just handle error cases?
How much do you need to know, the sudoers real username is a valid piece of data to want, for example.
This question is often asking several different but related questions. So I will ask those more precisely and then answer for each.
1. Is this script being run using sudo?
[ $EUID -eq 0 ] || exit 1 # Exit if not effectively root
2. Can this user run a specific command as root using sudo?
sudo -l /usr/bin/program &>/dev/null || exit 2 # Exit if it can't run this as sudo
3. Can this user run sudo without interacting?
sudo -l -n /usr/bin/program &>/dev/null || exit 3 # Exit if requires interaction
4. Can I check all that ahead of time?
`sudo -ll -U $USER # tells you which commands can be runs with sudo by user (have to parse yourself)
5. Script being run with sudo or actually root?
[[ "$(printenv SUDO_USER)" = "" ]] || echo "$SUDO_USER is sudoing!" && exit 5

Handle permissions with groups in linux

I can't understand how exactly this works in Linux.
For example, I want only users in some group have access to execute some file (I hope this is possible without visudo).
I create a system user and system group like:
useradd -K UID_MIN=100 -K UID_MAX=499 -K GID_MIN=100 -K GID_MAX=499 -p \* -s /sbin/nologin -c "testusr daemon,,," -d "/var/testusr" testusr
I add my current user user to the group testusr (may be not cross platform):
adduser user testusr
I create some test shell file and set permissions:
touch test.sh
chmod ug+x test.sh
sudo chown testusr:testusr test.sh
But I still can't start test.sh as user:
./test.sh
-> Error
Now I look for some system groups like cdrom to check how they work. My user is in cdrom group and can use the cd rom on my computer:
$ ls -al /dev/cdrom
lrwxrwxrwx 1 root root 3 апр. 17 12:55 /dev/cdrom -> sr0
$ ls -al /dev/sr0
brw-rw----+ 1 root cdrom 11, 0 апр. 17 12:55 /dev/sr0
Addition:
./test.sh command starts to work as I want after system reboot. Strange...
I'm on Ubuntu Studio 15.10
The group changes are reflected only upon re-login.

su command in shell script

I have a script which copies a file, then untar and install it (agent-service) on multiple systems (IPs are read from systems.txt file). In the script, I wanted to start the agent-service as user "test". However after the script execution, when I check the target system, the agent-service is shown as running as "root" user. What could be wrong here? Am I not using su command correct within the script?
~]# ps -ef | grep agent-service
root 23511 15196 0 02:12 pts/3 00:00:00 agent-service
Script>
#!/bin/bash
export AGENT=linux-5.8.1.tar.gz
while read host; do
scp $AGENT root#$host:/opt
ssh -n root#$host 'cd /opt/linux;
tar zxvf linux-5.8.1.tar.gz;
mkdir /opt/hyperic;
useradd -m test;
chown -R test:test /opt/linux;
su - test;
/opt/linux/agent-service start'
done < systems.txt
Using su as you do here spawns a new shell that has nothing to do thus exits immediately.
Either pass the command to su:
su - test -c /opt/linux/agent-service start
Or use sudo in a similar manner:
sudo -u test /opt/linux/agent-service start

Clear cache in remote server using ssh

I had been trying to clear cache in a remote server and i got these commands.
First login as root user and execute
sync; echo 3 > /proc/sys/vm/drop_caches
But I had to automate this in a script, so i used this
ssh user#ipaddress "sudo su; sync; echo 3 > /proc/sys/vm/drop_caches";
But I am not able to get the root user privileges by sudo su and I thought removing sudo su and instead use
ssh user#ipaddress "sudo sync;sudo echo 3 > /proc/sys/vm/drop_caches";
But this says it dose'nt have enough permissions.
What am I missing??
When you do this sudo echo 3 > .... only echo will be with "sudo" user permissions, redirection is with current user.
try something like this :
ssh user#ipaddress "sudo sh -c \"sync; echo 3 > /proc/sys/vm/drop_caches\"";
Use tee as an alternate to redirection that works well with sudo:
ssh user#ipaddress 'echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null'
The redirection to /dev/null is optional, if you want to avoid "3" being echoed to your terminal as well.
Also If you experience this message
>> sudo: sorry, you must have a tty to run sudo
as I had, you can fix it by editing /etc/sudoers and comment Defaults requiretty -> #Defaults requiretty.

Resources