Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Your personal settings will not be saved #4573

Closed
720720 opened this issue Dec 2, 2017 · 7 comments
Closed

Your personal settings will not be saved #4573

720720 opened this issue Dec 2, 2017 · 7 comments
Labels

Comments

@720720
Copy link

720720 commented Dec 2, 2017

root@test ~# uname -a
FreeBSD test 11.1-RELEASE FreeBSD 11.1-RELEASE #0 r321309
root@test ~# pkg info fish
fish-2.6.0
Name           : fish
Version        : 2.6.0
Installed on   : Thu Nov 30 11:46:23 2017 UTC
Origin         : shells/fish
Architecture   : FreeBSD:11:amd64
Prefix         : /usr/local
Categories     : shells
Licenses       : GPLv2
Maintainer     : asomers@FreeBSD.org
WWW            : http://fishshell.com/
Comment        : User friendly command line shell

While playing around with FreeBSD services I found the underlying cause of #3959
The problem occurs when fish is the root shell and a service starts a process with a system account like www.

root@test ~# env HOME=/ su -m www -c env
<E> fish: Your personal settings will not be saved.
<E> fish: Unable to locate config directory derived from $HOME: '//.config/fish'.
<E> fish: The error was 'Permission denied'.
<E> fish: Please set $HOME to a directory where you have write access.

BLOCKSIZE=K
BROWSER=links
HOME=/
LANG=en_US.UTF-8
LOGNAME=root
MAIL=/var/mail/root
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin
PWD=/root
SHELL=/usr/local/bin/fish
SHLVL=2
SSH_TTY=/dev/pts/0
TERM=xterm-256color
USER=root
_FISH_WARNED_config=1

fish: Your personal settings will not be saved.

root@test ~# cat /etc/passwd
root:*:0:0:Charlie &:/root:/usr/local/bin/fish
www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin

https://www.freebsd.org/cgi/man.cgi?query=su
-m Leave the environment unmodified. The invoked shell is your login shell, and no directory changes are made.

www has no login shell and fish is used as fallback

fish: Unable to locate config directory derived from $HOME: '//.config/fish'.

https://www.freebsd.org/cgi/man.cgi?service
When used to run rc.d scripts the service command sets HOME to / and PATH to /sbin:/bin:/usr/sbin:/usr/bin which is how they are set in /etc/rc at boot time.

service sets HOME to /

fish: The error was 'Permission denied'.

drwx------ 3 root wheel /.config
drwx------ 2 root wheel /.config/fish
-rw-r--r-- 1 root wheel /.config/fish/fishd.test

www has no permissions on /.config

Someone could argue that its bad pratice to change root login shells, but I really want to use fish for root on my local test systems.

@faho
Copy link
Member

faho commented Dec 2, 2017

The error occurs because fish cannot write to its configuration directory. If you give it one to write to it'll go away.

So set either $HOME or $XDG_CONFIG_HOME (fish will fall back to $HOME/.config if this is unset, which is how it is coming up with /.config) to somewhere that fish can write to. Or is something stopping you from doing that?

@faho
Copy link
Member

faho commented Dec 2, 2017

Though note that, if you don't need to save settings, this message is safe to ignore.

@720720
Copy link
Author

720720 commented Dec 2, 2017

Im just not sure why /.config is 700 while all other .config directories are created with 755

drwx------ 3 root wheel /.config
drwxr-xr-x 5 root wheel /root/.config

@faho
Copy link
Member

faho commented Dec 3, 2017

Im just not sure why /.config is 700 while all other .config directories are created with 755

That's probably because fish created those directories while running as root (with a $HOME of /), and something else created /root/.config. Note that, on my system, directories in .config are split between 755 and 700, so there doesn't seem to be a consensus on those. Either way, fish would actually require write permissions here (to persist universal variables or do funcsave or similar), so 755 with the wrong owner still wouldn't improve the situation.

Your situation is quite weird - you have a non-user executing fish with a non-$HOME that you apparently also used with root. It also appears (from #3959) that your system is using your login shell to run unrelated scripts, which as I've said is something that is likely to cause issues.

I can't see much we can do here - we could silence the message, but that would mean that other people won't notice an honest case of misconfiguration.

The easiest thing to do is probably for you to just ignore the message - if you don't use universal variables or funcsave or such as those users, then you don't need fish to write to that directory. So just for a quick debugging or testing session you'll be okay.

@720720
Copy link
Author

720720 commented Dec 3, 2017

In some cases FreeBSD services start a process with a different user via su -m.
Service sets HOME to / and if the user has no login shell fish is used as fallback.
Now fish is not happy with / as HOME.

fish: The error was 'Permission denied'.

int create_directory(const wcstring &d) {
    bool ok = false;
    struct stat buf;
    int stat_res = 0;

    while ((stat_res = wstat(d, &buf)) != 0) {
        if (errno != EAGAIN) break;
    }

    if (stat_res == 0) {
        if (S_ISDIR(buf.st_mode)) ok = true;
    } else if (errno == ENOENT) {
        wcstring dir = wdirname(d);
        if (!create_directory(dir) && !wmkdir(d, 0700)) ok = true;
    }

    return ok ? 0 : -1;
}

Fish does not find its directories and creates /.config and /.local with 700.
If we use the default FreeBSD umask 022 here the directories had 755 and everything would be fine.
Fish will never require write permissions since the service just starts a process with it.

fish: Unable to locate config directory derived from $HOME: '//.config/fish'.

static void path_create(wcstring &path, const wcstring &xdg_var, const wcstring &which_dir,
                        const wcstring &custom_error_msg) {
    bool path_done = false;
    bool using_xdg = false;
    int saved_errno = 0;

    // The vars we fetch must be exported. Allowing them to be universal doesn't make sense and
    // allowing that creates a lock inversion that deadlocks the shell since we're called before
    // uvars are available.
    const auto xdg_dir = env_get(xdg_var, ENV_GLOBAL | ENV_EXPORT);
    if (!xdg_dir.missing_or_empty()) {
        using_xdg = true;
        path = xdg_dir->as_string() + L"/fish";
        if (create_directory(path) != -1) {
            path_done = true;
        } else {
            saved_errno = errno;
        }
    } else {
        const auto home = env_get(L"HOME", ENV_GLOBAL | ENV_EXPORT);
        if (!home.missing_or_empty()) {
            path = home->as_string() +
                   (which_dir == L"config" ? L"/.config/fish" : L"/.local/share/fish");
            if (create_directory(path) != -1) {
                path_done = true;
            } else {
                saved_errno = errno;
            }
        }
    }

    if (!path_done) {
        maybe_issue_path_warning(which_dir, custom_error_msg, using_xdg, xdg_var, path,
                                 saved_errno);
        path.clear();
    }

    return;
}

If HOME is / fish creates the path //.config/fish.
FreeBSD can resolve the path but the correct path should be /.config/fish.

@faho
Copy link
Member

faho commented Dec 3, 2017

If HOME is / fish creates the path //.config/fish.
FreeBSD can resolve the path but the correct path should be /.config/fish.

That shouldn't make a difference. Like you said, "The error was 'Permission denied'". Fish can't read /.config, so it has no permissions to see /.config/fish.

Though the standard leaves some ambiguity here:

A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.

I don't think that any particular implementation actually does something different here for exactly two leading slashes (and I have no idea why that's even in there).

Now fish is not happy with / as HOME.

It tells you that it can't write to its config directory (because it can't). If you don't need it to, you can ignore that.

If we use the default FreeBSD umask 022 here the directories had 755 and everything would be fine.

No, it wouldn't. 755 is write permissions for the owner only, but you're not launching fish as the owner here! Fish would find the configuration file (and could read it), but it would be the wrong user's configuration file, so it's not clear that it should read it.

Fish will never require write permissions since the service just starts a process with it.

Fish will require write permissions if it is instructed to write universal variables or save a function. But we want the error message to appear before that, so users who have made an honest configuration mistake are informed before they've tried to make a bunch of changes.


Let me just ask directly: What do you expect us to do here?

@720720
Copy link
Author

720720 commented Dec 4, 2017

It turns out that fish is just more verbose than other shells in this particular case.

I will follow your advice and just ignore the messages.

Thanks for your support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants