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

Domain socket error: Not working via sudo is a geany bug, not a feature or bug in sudo #1150

Closed
doublemeat opened this issue Jul 26, 2016 · 40 comments

Comments

@doublemeat
Copy link

There are good reason for running geany via sudo, as opposed to gksudo.

I'm aware of bug #294, and why this happens with sudo and not gksudo. (In short, because gksudo sets $HOME to /root, while sudo leaves $HOME to same as user - and if user is already running geany in their user session, an attempt to open the same config file will be made, and fail).

Please allow me to explain why this shouldn't be dismissed as "not a bug", just because there is a workaround. The problem is not just that sudo works differently than gksudo. The problem is that, and Geany's flawed implementation of config file (or "domain socket" or whatever is going on with that file).

Like many Linux administrators / power users, I use GUI tools with sudo very often, for three related reasons: 1) I prefer working in a terminal; 2) I prefer GUI terminals for ease-of-use [e.g. highlight/copy/paste, color, resize]; and 3) I prefer using sudo in a GUI terminal instead of gksudo, so that I don't have to input my password every single time I open a system configuration file for editing - which is often.

I use many GUI tools this way, and none of them have the problems Geany has. I love Geany - both for system configuration file editing as well as personal file editing, but have had to quit using it because this bug prevents productivity way too often.

It is a bug because a very simple and common use case is prohibited for no good reason, shouldn't be prohibted, and no other similar tools have the same prohibition.

A fix should be simple, in theory. Either:

  1. Don't use temporary config files [or whatever is being referenced by "domain socket error"], or
  2. Detect if $USER == "root" but $HOME points to somewhere in /home. If so, use /root if it exists, or %TMP% as a fallback (in a unique and secure way that has been exhaustively documented elsewhere on the nets).

Sure, the second one - without additional smarts - might not catch all distributions and/or custom installs, but would cover 99%+ of the user base. And for that tiny percentage that it might not cover, their situation wouldn't be any worse that it is now.

@b4n
Copy link
Member

b4n commented Jul 26, 2016

As I reply everyone raising this "bug", get a properly configured sudo. Even though I don't recommend using Geany as root, I can just fine run sudo geany on my Debian machine and it works flawlessly (as far as I can tell without doing it daily, though), whether or not I have other Geanys running. It properly uses /root/.config/geany as the configuration directory.

Anything that would lead to another user (including root) to writing in a user's home directory should be avoided. If you did write there as root, the user would be left with root-owned file in his home, files he couldn't modify. That's not a good thing.

And while I don't want special code for handling sudo use, I don't think any is needed: proof being I can use sudo just fine on my machine. Yes, Debian does have Defaults env_reset.

If you really want us to change something, you'll need to detail why you'd need inheriting the environment (including HOME and XDG_*, and possibly other) in your sudo session, and what you'd want us to do to fix it (by that I mean actual changes, not "fix it").


If "many other GUI tools" work, it might be for a number of reasons, one possibly being that they use DBus (anything using dconf comes to mind), which may or may not use $USER rather than $HOME/$XDG_*. Or other special handling. Or possibly simply not have to do any IPC and happily mess up your user's home directory.
If really other tools to something meaningful and it's not a hack, maybe it could be a basis for proposing a change.

Out of curiosity, do you have root-owned stuff in your dotfiles? (cd && find -path './.*' -user root)


I'm not closing it just now, but I still do consider this invalid at least for the moment

@b4n b4n added the invalid label Jul 26, 2016
@b4n
Copy link
Member

b4n commented Jul 26, 2016

(FTR, we put the socket inside whatever the GLib give us with g_get_user_config_dir())

@elextr
Copy link
Member

elextr commented Jul 26, 2016

@doublemeat as #294 sat for a year before it was closed during one of the regular issue pogroms shows that none of the regular Geany developers or contributors has the need/interest to address this.

If you feel you have a use-case, remember, that suggests it is your use-case, not anybody elses. On that basis you would be more likely to succeed if you presented a small, simple, well written and documented pull-request rather than trying to persuade others it is their problem.

(Or use the workarounds like -c or different sudo configuration)

@codebrainz
Copy link
Member

This happens on Ubuntu 16.04 if you have an existing instance open. Doesn't happen if you fire up a new instance (using -i option). It seems like reasonable behaviour to me.

@elextr
Copy link
Member

elextr commented Jul 26, 2016

Thats three workarounds, seems reasonable to close.

@elextr elextr closed this as completed Jul 26, 2016
@codebrainz
Copy link
Member

FTR, we put the socket inside whatever the GLib give us with g_get_user_config_dir()

It seems weird that we're putting a socket file in a config directory. We should probably use g_get_user_runtime_dir().

@elextr
Copy link
Member

elextr commented Jul 26, 2016

Actually we put it in app->configdir so its either the default config dir or overridden by the -c option.

But the default could be either place IMO (and they are the same on Windows anyway).

@codebrainz
Copy link
Member

But the default could be either place

I'm no XDG/LSB expert, but I don't think runtime objects like sockets are supposed to go into a config file directory.

@b4n
Copy link
Member

b4n commented Jul 26, 2016

It seems weird that we're putting a socket file in a config directory. We should probably use g_get_user_runtime_dir().

Maybe, but it's mostly irrelevant to the OP's point, because either way it'd be in the same place as the user's one.

Also, while indeed it sounds like a socket is a good candidate for a runtime directory, it would make it harder for us as we -- for the moment -- still want to let the user change it (-c), so then we'd need 2 separate flags, or different relative socket location depending on whether -c was passed or not. IMO, we should rather not change anything here until we have a compelling reason to.

@codebrainz
Copy link
Member

Maybe, but it's mostly irrelevant to the OP's point

Indeed, I was just noting it since you mentioned the socket being in the config dir.

it would make it harder for us as we -- for the moment -- still want to let the user change it (-c), so then we'd need 2 separate flags

Why does the user care where some runtime Unix socket file node is? I agree it's probably not worth changing much at this point though. A (non-portable) solution that could solve this issue would be to detect the presence of and use the /run/user/N directory maintained by systemd for this kind of use. Another long term option would be using GtkApplication, which I assume handles multi-user multi-instance, but that's a whole other Issue :)

@elextr
Copy link
Member

elextr commented Jul 27, 2016

Another long term option would be using GtkApplication, which I assume handles multi-user multi-instance, but that's a whole other Issue :)

Looooooooooooooooooooooong term, as in when we drop gtk2 support (since application is since 3.0).

@b4n
Copy link
Member

b4n commented Jul 27, 2016

Why does the user care where some runtime Unix socket file node is?

He doesn't directly, but it has to be different to allow separate instances/config as they are now. So until we have proper single instance, we should have multiple sockets.

@codebrainz
Copy link
Member

but it has to be different to allow separate instances/config

Yeah, each instance would need a uniquely named handle, but that's pretty simple (temp filename, incremented counter filename, etc). As a side note, there's already a unique name for the socket file, at least here, the socket file in ~/.config links to a tmpfile kind of name in /tmp.

@elextr
Copy link
Member

elextr commented Jul 27, 2016

As a side note, there's already a unique name for the socket file, at least here, the socket file in ~/.config links to a tmpfile kind of name in /tmp.

Thats because the tmpfile is unique, but its semi-random, and therefore it is not discoverable when a geany wants to see it its the first instance, but the link is discoverable since its not random.

@codebrainz
Copy link
Member

codebrainz commented Jul 27, 2016

Most tmpfile implementations I've used (including GLib IIRC) allow specifying a prefix and/or suffix, something like /tmp/geany_001_x2d23k4sss4q.socket has both qualities (discoverable and semi-random) in this context. It's more complicated than a fixed file, but it's still pretty easy.

@elextr
Copy link
Member

elextr commented Jul 27, 2016

It is called geany_socket. but that doesn't help picking the right one when there are more than one.

@codebrainz
Copy link
Member

codebrainz commented Jul 27, 2016

I meant like geany_001_<rand>.socket, geany_002_<rand>.socket, geany_003_<rand>.socket, etc.

@elextr
Copy link
Member

elextr commented Jul 27, 2016

how does that help? How does a new geany decide it should talk to geany_001.socket or geany_002.socket?

@codebrainz
Copy link
Member

I guess it doesn't help with this specifically (more multi-session support), but in any case you can still generate a random-ish temp file that is discoverable (removing the need for the link in ~/.config).

@elextr
Copy link
Member

elextr commented Jul 27, 2016

Actually the socket has to be config specific, if -c is specified (or the default used) you must look for a config specific socket, or otherwise the expected config won't be used. So looking in the config for the socket is the simplest solution.

@codebrainz
Copy link
Member

So looking in the config for the socket is the simplest solution.

I don't argue that, just that putting a virtual socket file mixed in with the textual config files is weird.

@elextr
Copy link
Member

elextr commented Jul 27, 2016

Pull requests with better solutions are welcome :)

@codebrainz
Copy link
Member

codebrainz commented Jul 27, 2016

Note to future implementor: the socket filename could be in /tmp or /var/run/<uid> but use some kind of prefix (hierarchy or base64 encoded string, for example) to keep separate -c directories-related sockets.

Examples:

  • /var/run/1000/geany/home/me/.config/socket.file
  • /var/run/1000/geany/tmp/deleteme-config/socket.file
  • /tmp/geany/1000/aG9tZS9tZS8uY29uZmln/socket.file (/home/me/.config in base64 encoding)

And so on.

@doublemeat
Copy link
Author

@elextr thanks for responding. I should comment on something you said, which I think gets to the heart of the matter:

If you feel you have a use-case, remember, that suggests it is your use-case, not anybody elses. On that basis you would be more likely to succeed if you presented a small, simple, well written and documented pull-request rather than trying to persuade others it is their problem.

(Or use the workarounds like -c or different sudo configuration)

Answers to your two questions:

  1. Although I'm a developer and contribute to the open-source community on other fronts, I don't write in C; but more importantly, have no time or bandwidth as a guy just wanting to get other stuff done, in issuing a pull request on every project that has a bug. If I can't use my skills of logic to "persuade others it is their problem", then I guess it will have to go unfixed, and I use any one of a couple dozen other lightweight GUI editors.
  2. As a regular desktop user who just wants to get stuff done and not muck around with command-line options (unless I'm actually developing something myself), I have already implemented a workaround: I use another editor now. I've updated my three scripts that I use for almost everything text-related, to just invoke a different editor. Problem solved. None of the other common editors out there has this problem. Not gedit, leafpad, mousepad, brackets, etc. (Nor vi or nano either, for that matter.)

No one working on geany getting paid, presumably, but there is a reason you do this, right? I don't know what those reasons are, but I know I for one like to have more and more satisfied users. At least, that drives me and studies show drives many other open-source developers.

You guys made one of the best lightweight editors around. It just seems such a shame to lose users for no good reason - and in fact for a pointlessly, rigidly dogmatic reason. You can blame it all day long on the sudo program, but the bottom line is there are close to a dozen similar editors - just that I know of first-hand - that don't exhibit this behavior. (In fact no other editor I've tried, period.)

Working around underlying bugs in the stack that we have no control over is an inevitable part of developing software. I'd wager half of any code base that consumes underlying services is doing just that. Refusing to do so doesn't make it any less of your bug, because it still affects your users.

It doesn't affect "just" me. If you google this problem you'll get back pages of very specific results pointing to countless user forums.

Like I said, you guys are volunteers (presumably) doing fantastic work. I can't be "upset" at some of these responses that don't "get it". (Get it? Gedit?). And by "get it", I mean from the perspective of their users who don't care that it's a bug in one of the most commonly used programs in all of *nix, or care about c domain sockets, nor worry about how a temp file shouldn't exist in a user profile directory. All that means is that some of your users can't sudo geany and will have to find a different editor, and most of the time you'll never hear about it.

Trust me, I understand that breaking time-honored conventions can cause more problems for everyone now and down the road. I'm not suggesting the solution is that you store a temp file in a user configuration directory. But isn't this seemingly "intractable problem" why c library functions like mktemp exist?

Thanks guys. While I'm set for now with a different editor, I'm sad to see geany go from my workflow, and will check back once every several months or so to see if I can, as a test case:

geany &> /dev/null & disown; sudo geany

@elextr
Copy link
Member

elextr commented Aug 31, 2016

@doublemeat thank you for continuing to contribute.

Your two numbered points:

  1. Of course you can try to persuade others to enhance Geany if you don't have the time or knowledge. If you persuade somebody, as I said, a PR that addresses the problem is welcome.
  2. And thats a fourth workaround :) To paraphrase Stallman, the father of open source, "we make the software because we want to, we are happy if its useful to others, but we do not gain from having users, and we are sad but we do not lose if they use another tool".

The problem only exists if users don't use one of the published solutions. Saying "use a specific command line option" is not dogma when so far nobody has a solution that will still support Geanys current feature set, which as it is a lightweight IDE, is more complex than other plain editors.

A number of the contributors to Geany do so to support its use as a software development tool rather than a simple editor, (and I'm one) so their focus is on those features, not what they consider (wrongly in your opinion, but they disagree) a minor plain editor usage which has several workarounds. And several contributors have expressed the opinion that they won't ever use a full GUI IDE as root because its too risky, so they won't be fixing it.

It isn't clear if gedit supports specifying which of multiple instances to use.

But isn't this seemingly "intractable problem" why c library functions like mktemp exist?

If you persuade somebody to make a PR have them read the comments above, that point out why that doesn't work.

To reiterate, part of a mktemp name is variable so multiple temp files with the same base can be present. But as it starts, an instance of Geany has to look for a particular socket, not just any socket, so a name that is variable isn't any use. Other issues around using the chosen config are also noted above.

@doublemeat
Copy link
Author

@elextr Thanks for the thoughtful response.

I did actually use Geany for Javascript and Bash script development. Mostly bash. (And system config file editing. Fstab, apt sources, interfaces, etc.) And also as an omnipresent notes app.

I have two really useful scripts that conditionally launch editors various ways. The two most useful tools I think I have. I know others who do similar things. One script opens up a specified file normally with nano, if the user is in a terminal and there is no GUI environment available. But if there is a GUI environment available (whether in a terminal or not), it launches (formerly Geany). The other one is even more handy, it's for opening a file via gk/sudo. If launched from a terminal window, it prompts for sudo if necessary. Then if there is a GUI, it used Geany via sudo to open the file. If no GUI, nano. This is a huge time-saver when editing multiple files sequentially with sudo, to avoid typing in password every time. If it is not invoked from a terminal (e.g. "run" dialog), then it gets sudo via gksudo.

I can't imagine setting up new systems or administering existing ones without this. (And I'm not a fan of leaving a terminal open via sudo bash, but even if I did the same problem would exist.)

So, maybe that helps illustrate a good use case, or maybe not.

But either way, I'm left with the question: Why do the half-dozen other "lightweight" editors not suffer from this problem? What/how are they doing different? When I run any of them with sudo and then regularly, at the same time, regardless of order, there is no conflict and no anomolies of mixed-up states. I'm not even sure what you need a "socket" for in the first place, or why you call it that. (Presumably this isn't a TCP socket?) I'm guessing it's just a temp file having something to do with maintaining state. I'm assuming that's my own lack of knowledge of some established architecture paradigm you are using, and although I am genuinely curious, I can't imagine anyone losing sleep over me not knowing.

If you really are just using it to maintain state, why not just do so in memory and let OS-level paging take care of "physical instantiation"? And why does Geany need to know where this socket is at startup? Why can't it instantiate a tempfile at startup? So what if there are multiple temp files, possibly unused ones stacking up in the case of unclean Geany shutdowns? (That's a big reason why some /tmp directories map to RAM, and almost all are deleted at startup.)

Again, I'm not expecting an answer. We're all busy. I'm just curious.

@doublemeat
Copy link
Author

One more question/idea - how hard would it be to just check for a userid of 0, but a home directory of [not /root]? And in that case, just go ahead and use whatever $HOME says, but add "root" somewhere in the name (or something like that)? I mean, I get it that sudo is broken in that regard. But it will probably never be "fixed" because too much relies on it's very specific behavior. So why not just work with it? There's quite a bit that can be known about the environment we're running in and how we got there. Why not use it, to address the problem of propagating a very well-known and understood bug in a lower level, up to higher-level users?

Granted I'm probably mixing up the specific locations you use. (I actually recall the "domain socket" files existing in /tmp, not /home/user. But the same concept would apply.)

This would give you a predictable starting location and name, while also allowing geany users to not be inconvenienced by the very inconsiderate sudo bug. I know for a fact from Google that I'm not the only user that experiences this, but even if it were - say, five users, and the fix was literally a 15 minute change to a few lines plus some testing...wouldn't that be satisfying?

@elextr
Copy link
Member

elextr commented Aug 31, 2016

@doublemeat I suspect that the nitty gritty details need to be described.

  1. "socket" in this context is a unix domain socket, somewhat like a TCP socket, but restricted to the same machine and appears in the filesystem namespace. But its not a plain file, its a communication endpoint.

  2. When Geany is started from the command line with filenames it looks for a socket of an existing instance which it then uses to communicate the filenames from the command line so they open in the other instance. So the socket has to have a name that can be found, a unique temp file is no good [1]. So Geany looks in ~/.config/geany for an object named geany_socket_<hostname>_<display> so it will only try to open files in an instance on this host and this display. If it finds such a file it uses it to send the filenames to open, and then it exits. So without the annoying test, your root instance would find a user instance socket and it would open the files in the user instance, which isn't of course what you want.

  3. The config directory can be specified on the command line with -c and then it looks in that config directory for the socket. This is to ensure that the files are opened in an instance using the right configuration. The annoying test also to ensures this won't open files in the instance of another user that happens to be using this configuration directory already. This capability of having differing configurations is generally not supported by other simple editors.

  4. And then (with or without -c) geany can be started with -i which will not look for the socket and will not create one, it is always an independent instance.

  5. And finally, not only but also, the socket file can be specified with --socket-file= so it can be completely independent of selected config, username, host, whatever.

Since you are running from a script, using extra command line options should be no problem. Are you sure that you can't find a combination of options here that makes your root instance suitably separate from a preceding user instance? Using --socket-file=/tmp/geany_root_socket maybe?

Note also that Geany rolls its own here because of its unique requirements, its ability to work on windows as well, and its independence of the various incompatible session management mechanisms used by different distros.

[1] technically the socket is created in /tmp with a unique name, but a link with a known name pointing to the temporary is placed in the config dir. The link is what Geany looks for.

@doublemeat
Copy link
Author

Interesting. Grateful that you took the time to explain, and hopefully it will help others understand as well.

It also helped that you pointed out that this needed to work across distros and platforms. I didn't even know Geany ran on Windows. And I do get the "domain socket" communication endpoint concept now, and why it must be known before any one instance of Geany even starts.

Ultimately, it boils down to a single feature or requirement, and how it relates to a second, more fundamental requirement: 1) Open new files not in a new Geany instance, but in a new tab in the same instance. And 2) Work the same way across distros and platforms.

If you ditched the first requirement, the problem could disappear. (Not that it's a bad requirement. It's a good requirement I think. And not that there aren't other ways to mitigate the problem while keeping both feature/requirements. But for me, personally - and I'm sure I'm in the minority on this specific point - I'd rather it work with sudo and not sudo at the same time, and open single-file multiple instances. If that was the only choice.)

So, to make Geany work as designed but also accommodate the sudo bug, I could update my scripts - really just one - to detect when user id = 0, and use one of the flags to point it to a unique or just different pre-known instance.

I could even just write a wrapper script called "geany" and put it first in path. For *nix (presumably Windows doesn't have this problem):

#!/bin/bash
if [ "$EUID" == "0" ]; then
/usr/bin/geany -c /tmp/geany_root_socket $@
else
/usr/bin/geany $@
fi

But if I can do it that succinctly in a script, could it be nearly as simple in code? (I mean, I know it could be exactly that simple, but in reality probably isn't due to related code existing in different places, and also cross-platform concerns - I'm only worried about two, and a third environment [Windows] doesn't have the problem.)

Here's a way to conditionally check for OS in makefile. But again, it doesn't have to be that complex - just two of those tests ("linux" and "darwin") would cover an overwhelming swath, and almost all the rest would be Windows (already OK without anything extra). Anything else not covered, would just experience the bug, but would solve the problem for, perhaps, 99.9% of your users.

Perhaps much more simply, the install script could test for the existence of "bash" in the path (and that we're running on a unix-like machine, such as checking for the existence of $MACHTYPE being populated with anything), and if so, name the binary /usr/bin/geany-bin and the bash script above to /usr/bin/geany. (Or create a symlink in /usr/bin to the script instead of binary, etc.)

Just some thoughts.

@doublemeat
Copy link
Author

doublemeat commented Aug 31, 2016

@b4n, thanks for the response. Your response of

get a properly configured sudo

may be a technically correct response, but it dismisses reality. The overwhelming majority of installed *unixes - and in fact the majority of cloud computing - ship by default with a not "properly configured sudo". (Ubuntu.) As a result, a fair amount of bash scripts as well as habit, in fact relies on the "improperly" configured sudo.

There is a ton of stuff in Linux (and BSD and Windows) where "improper" eventually became "standard", and tools & apps that consume their services either have to assume "improper" function, or at least be able not fail in the face of it. Like I said before, I've never seen a base of code yet, that consumes lower-level services as a significant portion of it's function, that doesn't have a significant if not majority share of code devoted to working around flaws. Nirvana would be stuff that works as expected. Whether or not stuff below it works as expected.

I could be wrong and it's just an opinion, but it feels like your response is one of dogmatic ideology, and does nothing to address the world as it is. That's just my reading. I know that's an attractive stance in the open-source world. (And to be fair, there is an important place at the table for hyper-rigid idealistic purity - but it can't be the only voice. We need the inflexible purists hashing things out with the end users. When those two don't talk, things get bad.)

The world as it is contains a fair amount, possibly a majority, of improperly configured sudo. The world as it is includes a fair amount of people that invoke GUI tools from command-line sudo. To deny either reality, or say we shouldn't or aren't going to recognize their existence, is a fundamental failure.

/soapbox

To answer your question, yes I do have dotfiles owned by root. Most people do if they use dbus or gvfs. I also have a couple of paths put there by installers, apparently incorrectly. ...But...I've broken things before by assuming nothing but me should have ownership in my own directory ;-). Nothing geany-related anyway. Why do you ask?

@codebrainz
Copy link
Member

You could probably also make an alias like alias rooteany='sudo -H -u root geany' (untested).

@elextr
Copy link
Member

elextr commented Sep 18, 2016

For the information of people who read this issue in the future.

It is mentioned above that some developers won't use Geany as root because of the risks. But it was not explained what the risk is.

The risk is because, as Geany is an IDE, it has the capability to run random commands, and as it has a plugin interface, it can run random code. If a root instance of Geany was to use the user configuration it could run, as root, commands or code installed as user. This could be any rubbish a user was experimenting with, or it could be malicious code installed with user privileges. Running user code as root is an archetypal privilege escalation attack.

@b4n
Copy link
Member

b4n commented Sep 18, 2016

As a result, a fair amount of bash scripts as well as habit, in fact *relies on the "improperly" configured sudo.

Is there? I don't see this myself, and can't really imagine why it would be a problem. The only thing that change is the environment, and the large majority of scripts don't pass much data though the environment.
And even if they did, all it takes is putting sudo at the start of the line instead of the command, sudo FOO=bar script instead of FOO=bar sudo script -- ok, that means user changing habits, and that's hard.

And apparently Debian changed sudo's default without too much issues, or at least I didn't hear about them, so it sounds very possible.

There is a ton of stuff in Linux (and BSD and Windows) where "improper" eventually became "standard", and tools & apps that consume their services either have to assume "improper" function, or at least be able not fail in the face of it. Like I said before, I've never seen a base of code yet, that consumes lower-level services as a significant portion of it's function, that doesn't have a significant if not majority share of code devoted to working around flaws. Nirvana would be stuff that works as expected. Whether or not stuff below it works as expected.

I could be wrong and it's just an opinion, but it feels like your response is one of dogmatic ideology, and does nothing to address the world as it is. That's just my reading. I know that's an attractive stance in the open-source world. (And to be fair, there is an important place at the table for hyper-rigid idealistic purity - but it can't be the only voice. We need the inflexible purists hashing things out with the end users. When those two don't talk, things get bad.)

Well, you're kind of right. I'm reluctant to make a change I don't feel good about in Geany for something I don't think is a Geany problem. If we "fix" Geany, there will be N-1 applications that suffers from the issue. If sudo is "fixed", there will be 0. If the platform layer we use is "fixed", there will be N - apps_using_glib (where apps_using_glib is guaranteed to be >= 1).

I get that you have the problem with Geany because you use Geany, but if GLib "fixes" it, Geany will be "fixed" as long with a long list of other apps. Plus a long list of apps will show a consistent behavior, instead of each using its own version of the hack with its own pros and cons.

And yeah, I'm really sad writing apps requires fixing bugs in the platform, so I generally try and fix the platform layer when I can.

So… yeah we could make a change to get you and few other users happy. I do like happy users. But I'm also reluctant to participate to the hack party without trying to improve the situation.

To answer your question, yes I do have dotfiles owned by root. Most people do if they use dbus or gvfs. I also have a couple of paths put there by installers, apparently incorrectly. ...But...I've broken things before by assuming nothing but me should have ownership in my own directory ;-). Nothing geany-related anyway. Why do you ask?

I don't, and I do use apps using DBUS and GVFS.

And I ask because actually, if you do have files not owned by your user in your dotfiles, there's a lot more problems than just Geany. If a file is owned by root, your user won't be able to touch it, resulting generally in not being able to save settings, state, history, etc., or worse fail to start because realizing something's fishy is going on.

I know several years ago I had that problem with the nano editor: it would not be able to write its history file after having been used by root, and would complain at each startup -- and using such a basic editor as root is a lot more common.
I don't know if they did something in nano itself or it just got fixed when Debian started to env_reset by default though.

Anyway, my points is that:

  1. every application writing user config/state files suffers from this "bug" unless they have specific handling for it. There however are many ways to avoid this without changing applications, addressing the root cause of the problem, and most have been suggested here:
    • env_reset in sudo configuration (pick this one!!)
    • sudo -H instead of sudo
    • su - instead of su
    • Otherwise making sure to update environment variables like HOME, XDG_CONFIG_HOME, XDG_DATA_HOME, etc.
  2. If really root user should be sepcial-cased, it should be done lower in the stack, like in the XDG specification, and then its implementations (like g_get_user_config_dir() and friends), so it's "fixed" for many people, and not just one application at a time.
    And it should still be possible to override it if a power-user really knows he wants to mess with its stuff, so the simple hard-coded logic of "if you're root, ignore the environment" seems flawed to me.

In the end, I'm not strictly against adding a workaround to Geany, given it's good enough in every case, and reasonably simple. It probably would involve getpwuid() and getting the home directory that way, and it might involve some extra trickiness to really be sure we never access $HOME/$XDG_CONFIG_HOME directly then, even through platform code.

@b4n
Copy link
Member

b4n commented Sep 18, 2016

Hum, just reading the documentation of g_get_home_dir(), it suggests it might have worked like you want in GLib before 2.36.

@b4n
Copy link
Member

b4n commented Sep 18, 2016

…or not, not sure. S/a https://sourceforge.net/p/geany/bugs/471/

b4n added a commit to b4n/geany that referenced this issue Sep 18, 2016
This tries to determine whether the default configuration directory is
owned by the calling user, and falls back to a directory under that
user's home directory if not.

This doesn't solve the case where the first run would create the
directory in another user's home, but on the other hand handles any
combination of actual user and environment, not only root.

This however also doesn't work if the user is expected not to actually
own the files in hist home directory but e.g. only is part of the group
and still has write privileges.

Closes geany#294.
Closes geany#1150.
Closes https://sourceforge.net/p/geany/bugs/471/.
@b4n
Copy link
Member

b4n commented Sep 18, 2016

Possible "fix": 8e27b27 9f05f3a (edit: added missing include).
But I guess it has many flaws, too. And it's really not trivial to "properly" "fix" this: if you only take root into account, it'll still fail the same when becoming another user than root (lest common, but totally valid). If you try and play with SUDO_UID, it'll only work for sudo. If… etc.

@elextr
Copy link
Member

elextr commented Sep 18, 2016

@b4n, and what about -c specified configs?

@b4n
Copy link
Member

b4n commented Sep 18, 2016

@elextr if the user specified -c, I don't think it's a good idea to change it because they gave a bad one.

@b4n
Copy link
Member

b4n commented Sep 18, 2016

(

if (alternate_config)
)

@elextr
Copy link
Member

elextr commented Sep 18, 2016

@b4n, its ok, I read your hack wrong, its user configs only :)

b4n added a commit to b4n/geany that referenced this issue Sep 19, 2016
This tries to determine whether the default configuration directory is
owned by the calling user, and falls back to a directory under that
user's home directory if not.

This doesn't solve the case where the first run would create the
directory in another user's home, but on the other hand handles any
combination of actual user and environment, not only root.

This however also doesn't work if the user is expected not to actually
own the files in hist home directory but e.g. only is part of the group
and still has write privileges.

Closes geany#294.
Closes geany#1150.
Closes https://sourceforge.net/p/geany/bugs/471/.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants