1

The situation is the following.

  1. I have FreeBSD user M, which is an alias for root, i.e., its UID equals to 0.
  2. I have a daemon started as M (as a shell for an autologin console, if it matters).
  3. The daemon should start screen non-interactively. And it actually does, but here's the quirk: screen also starts as M, thus its socket file is placed to /tmp/screens/M, not /tmp/screens/root where I actually need it to be able to attach as root while still leaving screen in single-user mode).

I've tried the following without success:

USER=root /usr/local/bin/screen ...

and

sudo /usr/local/bin/screen ...

How does it detect the actual username? How can I force it to think it's really root and not M?

vines
  • 131
  • 6
  • @ChrisS: So that I could have the daemon launched by init as a "getty shell", and respawned in case it fails.. Were it some kind of, say, Ubuntu, I'd just added the daemon to `inittab` flagged with `respawn`. – vines Dec 13 '11 at 15:10
  • @ChrisS: Exactly. If I do it for root, I'm going to have to set the daemon as the root shell (or is there some other facility to launch it instead of getty?). But then I'll be unable to login as root, which is an interesting situation =) – vines Dec 13 '11 at 15:24

1 Answers1

2

While looking through the sources of screen, I've found that it utilises POSIX function getlogin() to get the session login. It is not, generally, stored in a variable. BUT there exists the complementary function setlogin(), which does the trick (at least for me on FreeBSD8.2):

#include <stdio.h>
#include <unistd.h>

int main(int argc, char ** argv)
{
    if (argc == 1)
    {
        char * l = getlogin();
        printf("Current login: %s\n", l ? l : "(NULL)");
    }
    else
    {
        int s = setlogin(argv[1]);
        printf("setlogin(\"%s\") returned %d\n", argv[1], s);
        if (s) perror("setlogin");
    }
    return 0;
}

Surely, for setlogin() to succeed, it must be run with the superuser privileges.

vines
  • 131
  • 6