# No password prompt



## ralphbsz (Jan 25, 2021)

I have a few accounts that shall have no password. You just type the username, and the account logs in. Now, before you get all bent out of shape "this is a terrible security hole": these accounts don't run a normal shell. Instead they run a single executable that has one function. And they are restricted so they can only log in on the console. For example, the account named "date" simply prints out the current time and date, and exits. Or the account named "halt" simply powers down the machine. In case of a power outage, it's very convenient to be able to shut down the computer very quickly, without having to fish around for the root password, or figuring out how to press "control alt delete" (*).

It is easy to set an account to not have a password. For example use the command "passwd date", and hit enter twice: done. My problem is: Even for accounts that have no password, the login program will prompt for a password. I can change the password prompt in /etc/login.conf (even specifically for that account, by using a specific login class), but I can't get rid of the user having to hit enter again.

Any known solution for that?

Footnote: Control Alt Delete is actually quite difficult to type. There are at least two "delete" keys on the keyboard, and on compact or laptop keyboards, they can be in funny places (and backspace does not actually work, only delete does, even if most backspace keys actually say "delete" on them) And Alt can be outright hard to find. For example, the keyboard I'm typing on has Command, Option, Function and Control, and no key that says "Alt". The keyboard in the next room has a windows key and a hamburger menu key on the right side (but at least one key that says "Alt" on it).


----------



## im (Jan 25, 2021)

Do you need "local" or "remote" passwordless login?

In case of remote: ssh with passwordless keys seems to be a good solution.

In case of "power outage": APC's UPS and sysutils/apcupsd works perfect for me.


----------



## obsigna (Jan 26, 2021)

ralphbsz, I knew it, I saw this working in the past already.

So I added quickly the FreeBSD-13.0-ALPHA2-amd64-...-disc1 snapshot to a VirtualBox machine. I skipped the Installation dialog by typing escape. Then I come to the login prompt, I type root and press enter once — Voilà.

Now, don't ask me how the FreeBSD wizards managed to allow root login without a password prompt for the installation ISO. Vaguely, I remember something about removing the password which is not quite the same as a zero length password. Although, I maybe wrong.


----------



## obsigna (Jan 26, 2021)

Remove the password from a user entry with the following command:

`# pw usermod example_user -w none`

Afterwards, example_user may login without a password prompt.


----------



## ralphbsz (Jan 26, 2021)

im said:


> Do you need "local" or "remote" passwordless login?


Local (meaning console) is the one that really matters. Remote (meaning ssh) wouldn't hurt, but is not vital. The script that performs the powerdown is already prepared for that: it checks the login client, and makes sure that it is on the local network, meaning inside the house.



> In case of remote: ssh with passwordless keys seems to be a good solution.


That's probably a good solution. You'll see why below in my reply to obsigna.



> In case of "power outage": APC's UPS and sysutils/apcupsd works perfect for me.


We already have an APC UPS, and are running the daemon. And I have a big auto-starting generator, and in the last few weeks, have been tinkering with GenMon, a nice little Python program to monitor the generator. But sometime, you just want to shut down. For example when there is a long power outage, you want to do that at midnight, so you can turn the (big, noisy) generator off and sleep in peace and quiet. And midnight is not a good time to search for the root password (not everyone in the household knows it by heart).



obsigna said:


> Remove the password from a user entry with the following command:
> 
> `# pw usermod example_user -w none`


That worked! Thank you so much. For some reason, just setting the password to nothing by hand with "passwd" does not work.

Here's the funny thing though: While now on the console login is passwordless, this also completely breaks logging in via ssh. I bet that could be fixed by tweaking config parameters in /etc/ssh/sshd_config, but for that im's suggestion of using keys and passwordless login (which I used for many other accounts anyway) is much better.

Problem nearly solved. Now I just need to finish setting up doas or sudo. I spent an hour last night writing the script itself (I was bored, because the power was out and we were running on generator, and the Internet was also out). Here is the riotous color scheme of the command:


----------



## olli@ (Jan 26, 2021)

Seems like this thread is already solved. Nonetheless I’d like to explain how I’m doing this; maybe you or others can learn some useful details.

I have a few of such local pseudo-accounts, too. In particular, I have a user “off” that powers down the machine (after requesting confirmation; it also offers the option to reboot and to select a different kernel via nextboot(8)), and a user “x11” that starts X11 (xdm).
 
The important thing is that the user does not have a password _at all_. When you use passwd(1) and just press Enter, there still _is_ a password – it’s an empty string. This makes a difference. Personally I use vipw(8) (as root) to edit the master passwd file directly. Just clear the second field. This is how it looks for my “off” user:
 

```
off::666:5:shutdown:0:0:Shutdown Pseudo User:/var/empty:/usr/local/sbin/shutdown-shell
```
Note the UID 666.    GID 5 is the operator group, so the shutdown-shell script can execute shutdown(8).
 
It is *important* to take some precautions for such local password-less users:
*1.* Add the users to /etc/ftpusers in order to disable FTP logins for them. There might be other programs that read /etc/ftpusers in order to recognize pseudo-accounts.
*2.* Create a mail alias that forwards all mail for this user to a real user or root (or to /dev/null). This prevents mail accumulating for this user in /var/mail that nobody ever reads and that just wastes space. So, add an entry to /etc/aliases and use newaliases(1) to rebuild the database (this is for sendmail; other MDAs might work slightly different). Believe me, sooner or later spammers will discover accounts with simple names like “off”. This is only relevant if the machine is configured to receive mail at all, of course. But even if it’s not, locally generated mails might be delivered to that user, e.g. by other curious users or by cron jobs. It doesn’t hurt to create a mail alias, even if you believe that it doesn’t matter.
*3.* Make entries in /etc/login.access in order to restrict login to local VTYs, see login.access(5):

```
+:off x11:console ttyv0 ttyv1 ttyv2 ttyv3
-:off x11:ALL
```
*4.* Create an appropriate login class in /etc/login.conf (see login.conf(5)) and use cap_mkdb(1) to rebuild its *.db file. Useful settings depend on the type of pseudo-user; in the case of my “off” user i have these:

```
shutdown:\
        :hushlogin:\
        :ignorenologin:\
        :nocheckmail:\
        :host.deny=*:\
        :tc=default:
```
*5.* Finally, sometimes the pseudo-user requires special privileges. In the case of my “x11” user, root privileges are required in order to start xdm(8). Personally I don’t like sudo because it has a rather fragile configuration syntax, so it’s easy to make mistakes – this is dangerous, IMHO. So I prefer to use “super” (security/super). For my “x11” user I have the following line in /usr/local/etc/super.tab (see super(5)):

```
x11-xdm-shell    /usr/local/sbin/x11-xdm-shell    nargs=0 x11:wheel u+g=root umask=022
```
The x11-xdm-shell script has a small snippet at the beginning that checks if it’s running with UID 0 (root). If it isn’t, it restarts itself using super(1):

```
#!/bin/sh -
set -Cefu
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
if [ $(id -u) != 0 ]; then
        exec super "${0##*/}"
        exit 1   # if exec'ing super(1) failed, just exit silently.
fi
```
Of course, shell scripts that run with root privileges should be written _very_ carefully. Always consider what evil ideas could come to the mind of someone looking at the script.


----------



## ralphbsz (Jan 26, 2021)

Thank you for the tip about disabling mail and ftp; I forgot about those.

I don't like sudo either; the config file format for it is a mess, and it always takes me a few tries until I get it right. I've switched to using doas instead (available in packages too).

And: For the program that the restricted account runs, I don't use a shell. Probably, a real shell expert could make that secure, but I don't trust myself that much in shell programming. For example, what if the user hits Control C at just the right time: will they get a shell prompt? For now, it's a 30-line Python program, and when I have a free evening, it will become a C program. In such programming languages, I can do error handling and catch signals.


----------



## olli@ (Jan 26, 2021)

ralphbsz said:


> And: For the program that the restricted account runs, I don't use a shell. Probably, a real shell expert could make that secure, but I don't trust myself that much in shell programming. For example, what if the user hits Control C at just the right time: will they get a shell prompt?


When you terminate a shell script, that shell process _never_ goes into interactive mode, not even when you set the `-i` option. Otherwise we would have a whole lot of security problems. The shell process is a child of login(1), so when you terminate the script, control goes back to the login process, which also terminates, causing init(8) to spawn a new getty process on that terminal.
 


> For now, it's a 30-line Python program, and when I have a free evening, it will become a C program. In such programming languages, I can do error handling and catch signals.


Well, of course you can do it in Python or C. But it can be done as well in /bin/sh if you know what you’re doing.
 
By the way, in Python it _is_ possible to enter interactive mode when a script terminates, see the `-i` option in python’s manual page. So, in this regard, Python is less secure than /bin/sh.


----------



## ralphbsz (Jan 27, 2021)

olli@ said:


> But it can be done as well in /bin/sh if you know what you’re doing.


And in shell, I don't know what I'm doing. Not an expert. So for a security-critical task, I personally will not use shell. Others may be able to, but I just don't know enough.


----------

