What is the XDG_SESSION_COOKIE environment variable for? - linux

I've been fighting with crontab recently because in Intrepid the gconftool uses a dbus backend, and that means that when used from crontab it doesn't work.
To make it work I have had to export the relevant environment variables when I log in so that it finds the dbus session address when the cron comes to run.
Out of curiosity I wondered what environment the cron could see and it turns out all I have is HOME, LOGNAME, PATH, SHELL, CWD and this new one on me, XDG_SESSION_COOKIE. This looks curious and several googlings have thrown up a number of bugs or other feature requests involving it but nothing that tells me what it does.
My instinct is that this variable can be used to find all the stuff that I've had to export to the file that I source before the cron job runs.
My questions, therefore, are a) can I? b) if so, how? and c) what (else) does it do?
Thanks all

This is very interesting. I found out it is the display manager setting a cookie. That one can be used to register processes to belong to a "session" which are managed by a daemon called ConsoleKit. That is to support fast user switching. My KDE4.2.1 system apparently supports it too.
Read this fedora wiki entry.
So this environment variable is like DBUS_SESSION_BUS_ADDRESS to give access to some entity (in the case of XDG_SESSION_COOKIE a login-session managed by ConsoleKit). For example having that environment variable in place, you can ask the manager for your current session:
$ dbus-send --print-reply --system --type=method_call \
--dest=org.freedesktop.ConsoleKit \
/org/freedesktop/ConsoleKit/Manager \
org.freedesktop.ConsoleKit.Manager.GetCurrentSession
method return sender=:1.1 -> dest=:1.34 reply_serial=2
object path "/org/freedesktop/ConsoleKit/Session1"
$
The Manager also supports querying for the session some process belongs to
$ [...].Manager.GetSessionForUnixProcess uint32:4494
method return sender=:1.1 -> dest=:1.42 reply_serial=2
object path "/org/freedesktop/ConsoleKit/Session1"
However, it does not list or somehow contain variables that is related to some cron job. However, documentation of dbus-launch says that libdbus will automatically find the right DBUS bus address. For example, files are stored in /home/js/.dbus/session-bus that contain the correct current dbus session addresses.

Related

Windows Environment Variables - Troubling accessing updated environment variables in program

I have wrote an initialization script that sets user environment variables which are keys that have been hashed and encrypted...Once the keys have been created the key encryption exe is no longer required. I want to launch the main application and remove the init file containing the hashing and key encryption functions.
I am not having any trouble with any of the above...Everything works as should when independent of each other. The problem is that in order for the main application to have access to the newly created environment variables I need the init script to completely exit...
Everything I have tried, Popen with flags, os.system() and others have still left me in a situation where the parent process ends and the main application launches, however, the environment variables have not updated...I close and relaunch main.py and...boom the program sees the updated variables and all is fine.
All I want is the init script to run, spawn a new process that is not linked at all with init.py and then exit so it can be removed. I thought this would be simple but after many hours of head scratching and trying numerous things, I am still no closer.
If I have to I will simply bundle it as two separate .exe files but I wanted it to be a one click install type thing.
I am running windows 10 and this can be platform specific.
Links looked at:
How to stop/terminate a python script from running?
Using a Python subprocess call to invoke a Python script
Starting a separate process
https://docs.python.org/2/library/subprocess.html
Python: Howto launch a full process not a child process and retrieve the PID
And more...
Current closest result
p = Popen(["python","UserInterface.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE,
creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
Create an environment block, set the environment variable using SetEnvironmentVariable, and use CreateProcess to specify this environment block for the created process.
MSDN DOC:
To specify a different environment for a process, create a new
environment block and pass the pointer to it as a parameter to the
CreateProcess function.
...
To programmatically add or modify system environment variables, add
them to the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE
message with lParam set to the string "Environment". This allows
applications, such as the shell, to pick up your updates.

Maintain a session across multiple instances of app when called from same shell

I'm trying to have data (generated by an application only after its launch) persisted across multiple invocations of an application, but only when they're started from the same shell session.
One possible way to do that would be to pass the data back from the application to the calling shell, but since environment variable changes are only passed from parent to child, I don't know how to implement that.
Practical example:
There is job command that create subdirectory with current datetime and does work inside. Sometimes job needs to be killed and restarted, so it need directory where if finished, like job --resume 21Fri_1849/data. I would like to save 21Jan_1849/data so I don't have to check and type it each time I need to resume job. If I created something like .last_job, and wanted to restart job in another session, it could resume wrong (last) job, so files are not solution (AFAIK).
How can this be done?
Since you're only trying to target Linux, there are a fair number of tricks available here. Consider this one:
#!/usr/bin/env bash
current_boot_id=$(</proc/sys/kernel/random/boot_id)
# honor myprog_shell_pid if set and valid, fall back to PPID otherwise
if [[ $myprog_shell_pid ]] && [[ -e /proc/$myprog_shell_pid/stat ]]; then
parent_pid=$myprog_shell_pid
else
parent_pid=$PPID
fi
parent_start_time=$(awk '{print $22}' "/proc/$parent_pid/stat")
mkdir -p "$HOME/.cache/myscript-sessions"
data=$HOME/.cache/myscript-sessions/${current_boot_id}:${parent_pid}:${parent_start_time}
Now, we have a data file name that changes:
When we're rebooted (because current_boot_id is updated)
If we're run from a different shell (because our PPID changes).
If we're run from a different shell with the same PID (because the start time for the parent PID will be different).
...and you can easily delete files with the wrong boot id (because the system rebooted), or with names that refer to PID/start-time combinations that don't exist.
One caveat is that by default, this is sensitive to being called by subshells (output=$(./yourprog) will have a different PPID than ./yourprog will), but if the parent shell runs export myprog_shell_pid=$$, that issue goes away.
You're crossing over to where you need a simple job management engine instead of just shell. Using 'make' and writing Makefiles is the probably the simplest way to set this up. You can write a rule that tells how to turn a stage 1 file into a stage 2 file based on file extension, and then make will know how far things got and how to resume next time you run it.

Gnome online accounts

I successfully installed gnome-online-accounts on my PC, equipped with Debian 9 OS. Everything works fine if I work from the X-terminal, having logged on with the default user. The command:
gio list google-drive://XXXXXXXXXXX#gmail.com/
gives the expected results.
But it doesn't if the same command is given thru crontab, though from the same default user. Here is the message:
gio: google-drive://XXXXXXXXXXX#gmail.com/: Operation not supported
If the problem was caused by an unmounted file system, due to lost of connectivity, the message should be:
gio: google-drive://XXXXXXXXXXX#gmail.com/: The specified location is not mounted
It seems like the command was given by another user.
Anyone has an idea about where is the trick?
As hinted at the end of this page, inside the bash script executed by crontab, before the gio call, it should be added:
declare -x DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/XXXX/bus
The XXXX value must be replaced by the UID value of the user enabled to the goa connection. This value is often "1000".

How to deal with DISPLAY=:0.0

My X program sometimes must be started from console, but by default on Ubuntu the DISPLAY env var is not set. Is it correct to include DISPLAY=:0.0 startmyapp in the startup script, or how to deal with it otherwise? Who and when and how is responsible for setting this display variable properly? Why the environment is not out of the box ready for this once you install X or the desktop that includes X?
The DISPLAY variable controls the X session that the application communicates with. There can be many (or none) of these available at any given moment. You can't just statically set this value and have it necessarily be correct.
It is set correctly inside an X session (through the environment) and you can set it manually outside of that to use that same session (but you have to know which session you want to use for that).
If you know that will always be your session and you know that will always be the session you want to use then yes, you can just set it in the services startup script. Otherwise you need to come up with some other way to figure out which DISPLAY value you need.

hacking whoami to return a fake username

I've created a new whoami command which requires a fake username and have put it in the PATH by adding it to ~/.profile . It is created in a way that whoami is called before actual the actual whoami from Linux.
The main reason to do this is because I am remote accessing a Hadoop cluster and want the copied files to be under the fake username.
This works fine when I call whoami in the shell and even calling $PATH shows the path to my created whoami before everything else. But for some reason, when Hadoop is called, it doesn't pick the created `whoami'.
Can someone help me with how to fix this?
thanks
Most applications do not use whoami to determine a user's username or group. For instance, in bash you can use the command id to find more detailed information about yourself or id [username] (such as id root) to find out more detailed information about other users. Groups can be found with groups as well. Also, different programming languages, such as C, have their own methods of determining user identities such as the getuid() command.
If you really "need" to go as far as faking your user account, you'll need to go down to OS level and create hooks into the kernel/API that handles those methods.
Is it possible that you simply chown the files after they are copied instead?
UPDATE:
It appears that some releases of Hadoop do actually use whoami (my own implementation w/ clustering does not).
In this event, the best (a term loosely used) suggestion would be to move the legitimate whoami executable and create a whoami shell script that goes in it's place. The custom script should validate the current user and if it's "hadoop", return whatever faked username you want - otherwise return valid output. Igor's answer would work in this case.
I suppose that hadoop uses other PATH variable then you have in your shell.
You can tune its PATH and add the directory with fake whoami to its beginning.
When it is impossible,
you can write a small wrapper for whoami (I'm not sure that it is a good idea but you can do this if you want) that will run original whoami except when the script is executed by hadoop:
#!/bin/sh
WHOAMI=/bin/whoami.orig
if [ "$($WHOAMI)" = hadoop ]
then
echo fake
else
exec $WHOAMI "$#"
fi

Resources