On 04May2017 15:03, Wildman <best_...@yahoo.com> wrote:
I tried testing on Mint and Ubuntu and the program would crash.  The
GUI would appear briefly and disappear.  On Ubuntu a crash report was
created so I was able to figure out what was going on.  It had the
traceback and showed that os.getlogin threw an error.  This is from
the crash report:

PythonArgs: ['/opt/linfo-tk/linfo-tk.py']
Traceback:
Traceback (most recent call last):
  File "/opt/linfo-tk/linfo-tk.py", line 1685, in <module>
    app = Window(root)
  File "/opt/linfo-tk/linfo-tk.py", line 1393, in __init__
    txt = function()
  File "/opt/linfo-tk/linfo-tk.py", line 316, in userinfo
    user = os.getlogin()
OSError: [Errno 25] Inappropriate ioctl for device

This usually means that the program does not have a controlling terminal.

The program installs using the Debian package system (.deb) and an
entry is created in the Applications Menu.  The strange thing is
that the crash only occurs when the program is run from the menu.
If I open a terminal and run the program from there, the program
runs fine.

And this supports that.

getlogin is not magic, and can be overused. The Python docs say "Return the name of the user logged in on the controlling terminal of the process." Clearly that will fail.

When you start from a terminal, your command will have that as its controlling terminal unless it has gone out of its way not to. When you start from a menu, usually that menu system will not be associated with a terminal. In this case you need to fall back on other methods of figuring out "who is logged in".

I found a little info on the web about this but it was not clear
whether it is a bug in Linux or a bug in the os module.  I also
found a couple of work-arounds but neither of them will work for
my purposes.

   user = pwd.getpwuid(os.getuid())[0]
   user = getpass.getuser()

I will try to explain...
The program reports system information based on the user's name.
Things such as passwd, groups and shadow info.  However, the
program must have elevated privileges to get the shadow info so
the program has the option to 'restart as root' so the shadow
information will be obtainable.

If the program is restarting as root, the work-arounds report
the user as 'root'.

The "shadow" information is normally concealed for good reason. I appreciate that you're trying to only report that information for the current user, but you should consider whether you should report it at all.

Personally I would be reluctant to write a program that "restarts as root"; it feels like a tool where a bug would lead easily to privilege escalation - that the calling user (not root, and from root's point of view untrustworthy) might get it to perform extra tasks beyond your plan AS ROOT. Risky.

Is there a way to get the actual user name or is there a fix
or a better work-around for the os.getlogin() function?

The standard way is not to "restart as root", but to write a setuid program. It still has all the pitfalls of any program running as root (the change for bugs to let the calling user do something they should not be allowed to do), but you can examine the value from os.getuid(): it will be the _calling_ user, while os.geteuid() will be the effective user (root in your case). Then the workaround will be effective.

You should also _minimise_ the time and work your program does as root. Along the lines of:

 ... program invoked setuid ...
 look up os.getuid() to find the uid of the invoker
 read as little as possible of the privileged info (i.e. shadow) as required
 os.setuid() BACK TO THE ORIGINAL USER SO YOU ARE NO LONGER ROOT
 ... do everything else ...

Part of your problem is that "who is the currently logged in user" is a nebulous idea. Supposing you were to address the lack of controlling terminal by seeing who is logged into the console. That is a little trusting. Supposing _you_ are logged into the console, running X11. And while so, _I_ ssh into your machine and run your program without a controlling terminal. Then your program will _mistakenly_ presume the logged in user is _you_ (because, after all, you're logged in), and report _your_ information to _me_.

For all that setuid programs have their own security issues, at least they _know_ who they were invoked by from os.getuid(), without playing insecure guessing games around "who is logged in". Because the latter is not equivalent to "whose information should I access?"

I hope this points a way forward.

Personally I would usually resist accessing information not available as the user, and avoid the need to run as root at all.

Cheers,
Cameron Simpson <c...@zip.com.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to