#!/bin/sh # # Script to activate profiles (i.e. conditional extra stuff) for the various # desktop environments in Debian based on the data in the *.listing files in # the /etc/desktop-profiles directory. Sourced by /etc/X11/Xsession. # # See the desktop-profiles(7) man page for an overview of how this works # # Code in this file has a couple of debian-specific parts: # - use of tempfile from debian-utils # (at start of execution, and in sort_profiles & activate_gnome functions) # - hardcoded default values for the different GNUSTEP_*_ROOT env variables # (in activate_gnustep function below) # # (c) 2004-2005 Bart Cornelis ############################################################################### ######################################################## # get utility functions for working with .listing files ######################################################## LIB=/usr/share/desktop-profiles/listingmodule; if (test -r $LIB); then . $LIB; INSTALLED=true; else # test for shell-library if absent then either: # - the package installation is corrupt # - the package is removed (this file is left as it's in /etc/ and # thus treated as a conffile # We'll assume the latter. echo "Shell library $LIB is missing -> assuming desktop-profiles is removed (but not purged)" >> $ERRFILE; INSTALLED=false fi; general_trap () { rm -f "$GCONF_FILE"; exit; } sort_profiles_trap () { rm -f "$GCONF_FILE"; rm -f "$PROFILES"; exit; } ######################################################################### # Sort all profiles that have their requirements met by kind # (result for each $KIND is saved in the corresponding env variable # except for gnome which is saved in $GNOME_FILE, which is a tempfile) ######################################################################### sort_profiles(){ #make sure we start with empty variables KDEDIRS_NEW='';XDG_CONFIG_DIRS_NEW='';XDG_DATA_DIRS_NEW='';CHOICESPATH_NEW='';GNUSTEP_PATHLIST_NEW='';UDEDIRS_NEW='';PROFILES_NEW=''; # adjust trap to ensure we don't leave any tempfiles behind trap sort_profiles_trap HUP INT TERM; # get profiles that are have fulfilled requirements, and save result on file descriptor 3 PROFILES=`tempfile`; exec 3<> $PROFILES; (#reset trap as we're now in a subshell trap sort_profiles_trap HUP INT TERM; # get profiles that are have fulfilled requirements cat $(list_listings) | grep -v -e "^[[:space:]]*#" -e "^[[:space:]]*$" | while read PROFILE; do if (test_profile_requirements "$PROFILE"); then echo $PROFILE; fi; done; #and sort them by preference ) | sort --reverse --general-numeric-sort --field-separator=";" --key 4 > $PROFILES; # read from file descriptor 3 (not using pipe, because then the variables being # changed are in a subshell, which means they're unchanged outside the while loop) while read PROFILE <&3; do # sort per profile kind KIND=`echo "$PROFILE" | cut --fields 2 --delimiter ";"`; if (test "$KIND" = "KDE"); then KDEDIRS_NEW="$KDEDIRS_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "XDG_CONFIG"); then XDG_CONFIG_DIRS_NEW="$XDG_CONFIG_DIRS_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "XDG_DATA"); then XDG_DATA_DIRS_NEW="$XDG_DATA_DIRS_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "ROX"); then CHOICESPATH_NEW="$CHOICESPATH_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "GNUSTEP"); then GNUSTEP_PATHLIST_NEW="$GNUSTEP_PATHLIST_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "UDE"); then UDEDIRS_NEW="$UDEDIRS_NEW $(echo "$PROFILE" | cut --fields 3 --delimiter ";")"; elif (test "$KIND" = "GCONF"); then echo "`echo "$PROFILE" | cut --fields 3 --delimiter ";"` " >> $GCONF_FILE; fi; done; # close filedescriptor, delete tempfile, readjust trap exec 3>&- ; rm -f $PROFILES; trap general_trap HUP INT TERM; } ########################################################## # Functions for activating the different kinds of profile ########################################################## activate_KDE () { KDEDIRS_NEW=`echo "$KDEDIRS_NEW" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"` if (test "$KDEDIRS_NEW"x != x) && (test "$KDEDIRS_NEW" != "$(cat $DEFAULT_LISTING | grep "^kde-prefix" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"); then # set KDEDIRS, handle current value based on active personality if (test "$KDEDIRS"x = x); then KDEDIRS=$(sh -c "echo $KDEDIRS_NEW");# FORCE expansion of variables in KDEDIRS_NEW if any else # we need to check what to do with already set value case "$PERSONALITY" in autocrat) KDEDIRS=$(sh -c "echo $KDEDIRS_NEW") ;; rude) KDEDIRS=$(sh -c "echo $KDEDIRS_NEW"):$KDEDIRS ;; polite | *) KDEDIRS=$KDEDIRS:$(sh -c "echo $KDEDIRS_NEW") ;; esac; fi; export KDEDIRS; #desktop-profiles is not setting the variable so if we're autcratic enforce that view elif (test "$PERSONALITY" = autocrat); then unset KDEDIRS; fi; } activate_XDG_CONFIG () { XDG_CONFIG_DIRS_NEW=`echo "$XDG_CONFIG_DIRS_NEW" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"` if (test "$XDG_CONFIG_DIRS_NEW"x != x) && (test "$XDG_CONFIG_DIRS_NEW" != "$(cat $DEFAULT_LISTING | grep "^default-xdg_config_dirs" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"); then # set XDG_CONFIG_DIRS, handle current value based on active personality if (test "$XDG_CONFIG_DIRS"x = x); then XDG_CONFIG_DIRS=$(sh -c "echo $XDG_CONFIG_DIRS_NEW");# FORCE expansion of variables in XDG_CONFIG_DIRS_NEW if any else case "$PERSONALITY" in autocrat) XDG_CONFIG_DIRS=$(sh -c "echo $XDG_CONFIG_DIRS_NEW") ;; rude) XDG_CONFIG_DIRS=$(sh -c "echo $XDG_CONFIG_DIRS_NEW"):$XDG_CONFIG_DIRS ;; polite | *) XDG_CONFIG_DIRS=$XDG_CONFIG_DIRS:$(sh -c "echo $XDG_CONFIG_DIRS_NEW") ;; esac; fi; export XDG_CONFIG_DIRS; #desktop-profiles is not setting the variable so if we're autcratic enforce that view elif (test "$PERSONALITY" = autocrat); then unset XDG_CONFIG_DIRS; fi; } activate_XDG_DATA () { XDG_DATA_DIRS_NEW=`echo "$XDG_DATA_DIRS_NEW" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"` if (test "$XDG_DATA_DIRS_NEW"x != x) && (test "$XDG_DATA_DIRS_NEW" != "$(cat $DEFAULT_LISTING | grep "^default-xdg_data_dirs" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"); then # set XDG_DATA_DIRS, handle current value based on active personality if (test "$XDG_DATA_DIRS"x = x); then XDG_DATA_DIRS=$(sh -c "echo $XDG_DATA_DIRS_NEW");# FORCE expansion of variables in XDG_DATA_DIRS_NEW if any else case "$PERSONALITY" in autocrat) XDG_DATA_DIRS=$(sh -c "echo $XDG_DATA_DIRS_NEW") ;; rude) XDG_DATA_DIRS=$(sh -c "echo $XDG_DATA_DIRS_NEW"):$XDG_DATA_DIRS ;; polite | *) XDG_DATA_DIRS=$XDG_DATA_DIRS:$(sh -c "echo $XDG_DATA_DIRS_NEW") ;; esac; fi; export XDG_DATA_DIRS; #desktop-profiles is not setting the variable so if we're autcratic enforce that view elif (test "$PERSONALITY" = autocrat); then unset XDG_DATA_DIRS; fi; } activate_ROX () { CHOICESPATH_NEW=`echo "$CHOICESPATH_NEW" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"` DEFAULT_CHOICES=$(cat $DEFAULT_LISTING | grep '^default-rox-system;' | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g") DEFAULT_CHOICES="$(cat $DEFAULT_LISTING | grep '^default-rox-user;' | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"):$DEFAULT_CHOICES" if (test "$CHOICESPATH_NEW"x != x) && (test "$CHOICESPATH_NEW" != "$DEFAULT_CHOICES"); then # set CHOICESPATH, handle current value based on active personality if (test "$CHOICESPATH"x = x); then CHOICESPATH=$(sh -c "echo $CHOICESPATH_NEW");# FORCE expansion of variables in CHOICESPATH_NEW if any else case "$PERSONALITY" in autocrat) CHOICESPATH=$(sh -c "echo $CHOICESPATH_NEW") ;; rude) CHOICESPATH=$(sh -c "echo $CHOICESPATH_NEW"):$CHOICESPATH ;; polite | *) CHOICESPATH=$CHOICESPATH:$(sh -c "echo $CHOICESPATH_NEW") ;; esac; fi; export CHOICESPATH; #desktop-profiles is not setting the variable so if we're autcratic enforce that view elif (test "$PERSONALITY" = autocrat); then unset CHOICESPATH; fi; } activate_UDE () { # don't s/ /:g/ in next line, UDE doesn't currently support combining profile dirs UDEDIRS_NEW=`echo "$UDEDIRS_NEW" | sed -e "s/^ *//" -e "s/ *$//"` if (test "$UDEDIRS_NEW"x != x) && (test "$UDEDIRS_NEW" != "$(cat $DEFAULT_LISTING | grep "^ude-install-dir" | cut --fields 3 --delimiter ";")"); then # UDE currently only supports one dir, so we use the current setting unless # - we're in autocratic or rude mode or # - UDEdir wasn't set up yet and we're in polite mode if ( (test "$PERSONALITY" = autocrat) || (test "$PERSONALITY" = rude) || \ ( (test "$PERSONALITY" = polite) && (test "$UDEdir"x = x) ) );then for dir in $UDEDIRS_NEW; do UDEdir=$dir; break; done; export UDEdir=$(sh -c "echo $UDEdir");# FORCE expansion of variables in UDEdir if any fi; #desktop-profiles is not setting the variable so if we're autcratic enforce that view elif (test "$PERSONALITY" = autocrat); then unset UDEdir; fi; } activate_GNUSTEP () { # default values as set in /usr/lib/GNUstep/System/Library/Makefiles/GNUstep.sh (On Debian) export GNUSTEP_USER_ROOT=${GNUSTEP_USER_ROOT:-`/usr/lib/GNUstep/System/Library/Makefiles/user_home user 2> /dev/null`}; export GNUSTEP_LOCAL_ROOT=${GNUSTEP_LOCAL_ROOT:-/usr/local/lib/GNUstep/Local}; export GNUSTEP_NETWORK_ROOT=${GNUSTEP_NETWORK_ROOT:-/usr/local/lib/GNUstep/Network}; export GNUSTEP_SYSTEM_ROOT=${GNUSTEP_SYSTEM_ROOT:-/usr/lib/GNUstep/System}; #should be in GNUSTEP_PATHLIST_NEW (see /usr/lib/GNUstep/System/Library/Makefiles/GNUstep.sh) GNUSTEP_PATHLIST_NEW=`echo "$GNUSTEP_PATHLIST_NEW" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"` # get default domains DEFAULT_DOMAINS=$(cat $DEFAULT_LISTING | grep "^gnustep-user-domain" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g") DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-local-domain" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")" DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-network-domain" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")" DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-system-domain" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")" if (test "$GNUSTEP_PATHLIST_NEW"x != x) && (test "$GNUSTEP_PATHLIST_NEW" != "$DEFAULT_DOMAINS"); then # set GNUSTEP_PATHLIST, handle current value based on active personality if (test "$GNUSTEP_PATHLIST"x = x); then export GNUSTEP_PATHLIST=$(sh -c "echo $GNUSTEP_PATHLIST_NEW");# FORCE expansion of variables in GNUSTEP_PATHLIST_NEW if any else case "$PERSONALITY" in autocrat) export GNUSTEP_PATHLIST=$(sh -c "echo $GNUSTEP_PATHLIST_NEW") ;; rude) export GNUSTEP_PATHLIST=$(sh -c "echo $GNUSTEP_PATHLIST_NEW"):$GNUSTEP_PATHLIST ;; polite | *) export GNUSTEP_PATHLIST=$GNUSTEP_PATHLIST:$(sh -c "echo $GNUSTEP_PATHLIST_NEW") ;; esac; fi; else #desktop-profiles is not setting the variable so if we're autcratic enforce that view if (test "$PERSONALITY" = autocrat); then unset GNUSTEP_PATHLIST; fi; # if we're not setting things, then make sure we've not added to the environment if (test "$GNUSTEP_USER_ROOT" = "$(/usr/lib/GNUstep/System/Library/Makefiles/user_home user 2> /dev/null)"); then unset GNUSTEP_USER_ROOT; fi if (test "$GNUSTEP_LOCAL_ROOT" = "/usr/local/lib/GNUstep/Local"); then unset GNUSTEP_LOCAL_ROOT; fi if (test "$GNUSTEP_NETWORK_ROOT" = "/usr/local/lib/GNUstep/Network"); then unset GNUSTEP_NETWORK_ROOT; fi if (test "$GNUSTEP_SYSTEM_ROOT" = "/usr/lib/GNUstep/System"); then unset GNUSTEP_SYSTEM_ROOT; fi fi; } activate_GCONF () { # HACK WARNING: # # While GCONF allows multiple "configuration sources", there seems to be no clean way to # make the used "configuration sources" dependend on a condition (such as group membership). # One dirty way to get this ability is to generate a path file at login which will include # directives activating the profiles that have their requirements met. # # NOTE: this alone isn't enough, the system-wide path file (/etc/gconf//path) # needs to contain a include directive for this generated file. (preferably it should # contain _only_ that include directive setting everything else up through profiles) # $XDG_CACHE_HOME is not supposed to contain anything that can't be deleted # so we can savely do this to avoid leaving old generated files from # previous logins laying around XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}; rm -f $(grep -sl '^# Generated by desktop-profiles package$' $XDG_CACHE_HOME/* | cut --delimiter ':' --fields 1); # only generate path files for user if they will be included if (grep 'include *\$(ENV_MANDATORY_PATH)' /etc/gconf/2/path > /dev/null 2>&1 ) || (grep 'include *\$(ENV_DEFAULTS_PATH)' /etc/gconf/2/path > /dev/null 2>&1 ) || (grep 'include *\$(ENV_MANDATORY_PATH)' /etc/gconf/1/path > /dev/null 2>&1 ) || (grep 'include *\$(ENV_DEFAULTS_PATH)' /etc/gconf/1/path > /dev/null 2>&1 ); then # used to keep track if we passed from mandatory to default configuration sources yet INCLUDED_HOME=false; # create tempfile, while ensuring that cachedir exists # We're using tempfile since it ensures we have a new file with # a random filename, which is necessary for security: # - if (generated) path file isn't there all is fine # - if (generated) path file is there and the permissions on it allow $USER to write all is fine # (as it's regenerated on login) # - if (generated) path file is there (possibly changed by attacker) and the permissions on it do # not allow $USER to write things are not fine (as regeneration fails, and configuration sources # by attacker will be used). # Attacker can be $USER hirself (to avoid mandatory settings from sysadmin), or if file is in a # directory that's writeable by someone else a third party mkdir -p $XDG_CACHE_HOME; export MANDATORY_PATH=$(tempfile --directory $XDG_CACHE_HOME); export DEFAULTS_PATH=$(tempfile --directory $XDG_CACHE_HOME); # add marker to generated files, both so we can find it again later, and to indicate origin echo "# Generated by desktop-profiles package" > "$MANDATORY_PATH"; echo "# Generated by desktop-profiles package" > "$DEFAULTS_PATH"; # see if there's actually anyting to add, if so create pathfiles and fill them cat $GCONF_FILE | while read LINE; do # user gconf source should be included by system-wide path already if (test "$LINE" != 'xml:readwrite:$(HOME)/.gconf'); then if (test $INCLUDED_HOME = false); then # add configuration source echo $LINE >> "$MANDATORY_PATH"; else # add configuration source echo $LINE >> "$DEFAULTS_PATH"; fi; else INCLUDED_HOME=true; fi done; # get rid of temp files and variables if we don't use them if (test "$(cat $MANDATORY_PATH | wc -l)" -eq 1); then rm -f $MANDATORY_PATH; unset MANDATORY_PATH; fi; if (test "$(cat $DEFAULTS_PATH | wc -l)" -eq 1); then rm -f $DEFAULTS_PATH; unset DEFAULTS_PATH; fi; fi; # end generated path files will be included # cleanup tempfile rm -f $GCONF_FILE; } ##################### # Start of execution ##################### # Check is needed, as this file is a conffile and thus left after package # deinstallation, yet it shouldn't do anything when the package is deinstalled if (test $INSTALLED = true); then ################################# # Check if user set any defaults ################################# if (test -r /etc/default/desktop-profiles); then . /etc/default/desktop-profiles; fi; # sheep don't form an opintion, they just follow along # so skip everything if personality is set to sheep if (test "$PERSONALITY" != sheep); then ################################################# # Make sure the variables we need are initialized ################################################# LISTINGS_DIRS=${LISTINGS_DIRS:-'/etc/desktop-profiles'} CACHE_DIR=${CACHE_DIR:-'/var/cache/desktop-profiles'} CACHE_FILE="$CACHE_DIR/activated_profiles" ACTIVE_PROFILE_KINDS=${ACTIVE_PROFILE_KINDS:-''} DEFAULT_LISTING=/etc/desktop-profiles/desktop-profiles.listing PROFILE_PATH_FILES_DIR=${PROFILE_PATH_FILES_DIR:-'/var/cache/desktop-profiles/'} ############################################################ # Actual activation of profiles ############################################################ # if we have a cache and it's up-to-date -> use it if (test -r "$CACHE_FILE") && (test $(ls -t -1 /etc/desktop-profiles/*.listing \ /etc/default/desktop-profiles \ "$CACHE_FILE" 2> /dev/null | \ head -1) = "$CACHE_FILE"); then # export the variable settings in the cache file after replacing # the placeholders for the current variable values with said values # (the location of placeholders is based on the active personalitytype) export $(cat "$CACHE_FILE" | sed -e "s|\\\$KDEDIRS|$KDEDIRS|" \ -e "s|\\\$XDG_CONFIG_DIRS|$XDG_CONFIG_DIRS|" \ -e "s|\\\$XDG_DATA_DIRS|$XDG_DATA_DIRS|" \ -e "s|\\\$CHOICESPATH|$CHOICESPATH|" \ -e "s|\\\$GNUSTEP_PATHLIST|$GNUSTEP_PATHLIST|" \ -e "s|\\\$UDEdir|$UDEdir|" ); # UDEdir only holds 1 dir, so drop every dir except the first nonempty one export UDEdir=$(echo $UDEdir | sed 's|^:||' | cut --fields 1 --delimiter ":"); # else if we have any profile kinds we're interested in, then go # calculate the profile assignments elif (test "$ACTIVE_PROFILE_KINDS"x != "x"); then # add trap to ensure we don't leave any tempfiles behind trap general_trap HUP INT TERM; # get temp file GCONF_FILE=`tempfile`; # sort the profiles, whose requirements are met into: # - the appropriate environment variables # - $GCONF_FILE sort_profiles; # activate the profiles of the active kinds for KIND in $ACTIVE_PROFILE_KINDS; do # || true is to avoid hanging x-startup when trying a non-existing KIND # which can happen e.g. due to typo's in the config file. activate_$KIND || true; done; fi; # end dynamic profile assignment fi;# end !sheep fi;