Summary: | Functionality of /etc/profile.d and possible /etc/bashrc.d | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | Joakim Lindblad <joakim> |
Component: | [OLD] baselayout | Assignee: | Gentoo's Team for Core System packages <base-system> |
Status: | RESOLVED FIXED | ||
Severity: | minor | CC: | axxo, azarah, blaisorblade_spam, bugs-gentoo.org, converter42, dberkholz, drobbins, gentoo, grobian, jnelson, pacho, sbriesen, StormByte, yamadharma |
Priority: | High | ||
Version: | 1.1a | ||
Hardware: | All | ||
OS: | All | ||
Whiteboard: | |||
Package list: | Runtime testing required: | --- | |
Bug Depends on: | |||
Bug Blocks: | 5807, 71611 |
Description
Joakim Lindblad
2002-07-11 06:01:50 UTC
An additional issue would of course then be where to put things which optionally could be run at startup, to be sourced on a per user basis from their .bashrc or .bash_profile. Like the bash_completion stuff e.g. (if not all users want it). I am not in favour of just adding stuff to startup without the user knowing about it. This could be a serious security risk, and should be up to, and only up to the admin, or the user (he can add to .bash_profile or whatever). As a reply to Martins comment: No, I am not talking about letting users add stuff to /etc/profile.d and /etc/bashrc.d. I am talking about a place for root and root only to place startup routines. I am missing this functionality at the moment. Individual users should put their startup things in ~/.bash_profile and ~/.bashrc. We did discuss this, and currently it seems the general feeling is that we do not support this officially. You can still add this yourself, and as your /etc/profile will not be overwritten, you wont have to worry. I will take it to the other developers again for discussion, but like I said, many voted against last time due to not wanting to create such an meganism, as ebuilds could then just drop stuff there, and generally cause a security risk. > due to not wanting to create such an meganism, as ebuilds could then
> just drop stuff there, and generally cause a security risk.
Pardon my ignorance, but how in the world can this be a security risk?
You (as the user) are already running on a machine controlled by the root
user, who has COMPLETE control of the kernel and *anything* running on the
macihne, for $DEITY's sake. As only the root user can install things in
/etc/profile.d (or whatever), security cannot be compromised.
If you're arguing that scripts added to /etc/profile.d could add scripts with
unsafe content, say a script containing the following
export PATH=$PATH:/home/luser/bin
where luser isn't you (or some such), then I would argue that /etc/env.d
poses just as great a security risk since any random package could do the
exact same thing with an /etc/env.d "script". In either case, it's the
*packager's* job to ensure that nothing dangerous gets added to /etc/profile.d
or /etc/env.d, just as it is the packager's job to ensure (sort of) the
package does add backdoors/etc. to the system.
Security aside, I (as a regular user) *would* want to be able to choose which
profile scripts were run for me automatically startup, so why not just do
something like:
/etc/profile:
...yadayada...
PROFILES=$HOME/.my_profiles
if [ -f $PROFILES ]; do
cat $PROFILES | while read PROFILE do
source /etc/profile.d/$PROFILE.sh
done;
fi
...yaddayadda...
(sorry if the formatting didn't come out right). Of course, to accompany this
one would want an "add-profile" and a "del-profile" script, which would
add/remove appropriate lines to $HOME/.my_profiles. This way, the user has
complete control over which profiles are added to his/her startup. Also the
script should perhaps be a bit more robust (ie. check if
/etc/profile.d/$PROFILE.sh exists before trying to source it, etc.), but it's
not rocket science.
Any *good* arguments against this? Btw, I do not consider the fact that
packages can drop random stuff in /etc/profile.d a good argument. Packages
could just as easily drop random stuff in /etc, /usr/bin, /usr/lib or anywhere
in the filesystem. Again, it's the package maintainers responsibility that
this does not happen.
(Sorry if this comes off as a flame, it's not meant to be, but I just got
tired of hearing this argument.)
> *packager's* job to ensure that nothing dangerous gets added to
> /etc/profile.d or /etc/env.d, just as it is the packager's job
> to ensure (sort of) the package does add backdoors/etc. to the
> system.
Sorry, that should of course say:
[...] the package DOESN'T add backdoors/etc. [...]
:)
Thank you Bardur! At least someone got it right. Let's hope that people drop
that stupid security argument now.
> Security aside, I (as a regular user) *would* want to be able to choose which
> profile scripts were run for me automatically startup, so why not just do
> something like: ...
Quite ok idea, but I am not really in for that solution, it seems a bit overkill
for the single user, but maybe not. (Why not just add the /etc/profile.x/stuff
directly to your ~/.bash_profile instead of hiding the functionality and going
over /etc/profile?)
Ok, trying to make my point clearer:
There is a need for *two* ways to run scripts,
a) by root, installed by root, for *all* users (yes I think anyone beeing root
for say 100's of users wants this).
b) by individual users, added by individual users.
What I was looking for was to standardize the type (a) and my suggestion was to
follow the Red Hat and derivates (no I don't know how SUSE etc does this) and
have an /etc/profile.d where everything in it gets run.
Additionally and messing up with this is the need for type (b), which of course
also must exist so let us think about that one too. For the local user there
must be a common place where scripts reside (root writeable only!!!) that people
can link to or directly run from. As things here are optional, why not do
something like the /etc/init.d and /etc/runlevel linkage thing here.
Wrapping this up a bit, I think we should have:
i) a place to put startup scripts (by the emerge install) say
/etc/startup_scripts or whatever (*please* don't name this /etc/profile.d as
this breaks name convention for all users comming from the Red Hat / Mandrake
world).
ii) a place where root (*only*) can put links to /etc/startup_scripts for the
things that *all* users should run on login, I'd call this /etc/profile.d, but
you may argue with that.
iii) if we really wan't to tell the local user how to do things (this is
optional in my opinon) we could urge (i.e. put in /etc/skel) a local directory
$HOME/.etc/profile.d or something which contains links to /etc/startup_scripts
and is sourced by $HOME/.bash_profile or similar. (Or your solution Bardur.)
Extending the idea one could of course also have /etc/shutdown_scripts and
machinery to add things automagically. In brief, learn from /etc/init.d et al.
The *important* issue here: If we don't standardize this early, every root and
every user out there will build it's own solution, and I don't think that is a
good thing (it will certainly give trouble for people putting together ebuilds).
/Joakim
> it seems a bit overkill for the single user, but maybe not. > (Why not just add the /etc/profile.x/stuff directly to your > ~/.bash_profile instead of hiding the functionality and going > over /etc/profile?) In the case of a single user, we *are* talking overkill, but I have co-managed a network of about 50-100 workstations (with ~400 users in total), and the fact that almost every single person has a different ~/.bash_profile (or ~/.tcshrc since tcsh seems to be preferred here) can be a royal PITA and can lead to all sorts of strange behaviour. Just think how much easier things would be -- both for the users and the system administrators -- if we could do away with the user's need to modify ~/.bash_profile himself/herself and just tell them to run env-add package (s/env-add/yourpreferrednamehere/) to get all the needed environment (and shell functions/aliases/etc.) changes for a given package. I cannot really see any drawbacks to this, but maybe someone would care to enlighten me? That said, it wood be a good thing if there were at least a standard *location* for putting these package-dependent "environment scripts", so that users could just add, e.g. . /etc/profile.d/packagename.sh to his/her ~/.bash_profile. This still leaves something to be desired, but the fact that the *location* is standard means that these sorts of things don't just get scattered in random subdirectories in the packages' docdirs (which might even vary with version numbers). Btw, my main motivation for this functionality is an ebuild for the Aegis package (see bug #5807 for details). If some of the "official" Gentoo people would comment on their preferred solution, I could very likely be convinced to code up the necessary scripts to implement it. (I realize that this will not require massive coding, but if the problem is really just the lack of time to actually implement something, then consider me voluteered :)) > and the fact that almost every single person has a different ~/.bash_profile > (or ~/.tcshrc since tcsh seems to be preferred here) can be a royal PITA You'r totaly right there, esp. when some users run tcsh, some run bash and some run zsh, each with it's own little quirks. (Note that tcsh equiv. of .bash_profile is .login) > I cannot really see any drawbacks to this, but maybe someone would care to > enlighten me? The only thing I am afraid of is loosing control as an individual user, but if care is taken so that the mechanism stays simple and clear I don't see any problems. But I *do* want to keep it simple and not hidden under loads of layers of scripts and GUIs etc., there is a reason I am running Gentoo and not Mandrake anymore. The more I think about it, the more I realize that the rc scripts of /etc/init.d et al. is the way to go. Just do something similar for the login environment and the shells in use. a) enforced by root and b) for the individual user. Care must be taken not to mess up with the different kinds of shells on the market though. <joke> Ok, guess I should respond again and try and say something stunning </joke> I thought about this some more, and yes, why it is not implemented is due to many reasons. Some have been mentioned, others not. Main thing .. I do not want to dictate something to everybody; simplicity; security (please do not argue this one for now, as not entirely my point). But I must agree .. we need to either: 1) Get a standard going 2) Or just plain refuse As I do not think you should entirely throw away user input (except maybe if explicitly to make things easier [ and usually more annoying for guru ] for newbies .... we are not a newbie distro after all ... ), I think we are past the "try to ignore and hope it goes away stage" :P It have not, and there has been valid points as to why, so here goes .... I am going to *suggest* an easy simple way to do this, and want some comments. Please keep it simple, secure (yeah, some will moan if too automated), and practical. I will then leave you guys to comment for the next few days, and if you so wish, call me a "arogant bastard", "selfish pig" or the like if you so wish =) *g* --------------------------cut------------------------------------------- # Global (enabled by sys admin) for x in /etc/profile.d/* do # sys admin must set it executeble to be used if [ -x $x -a -f $x ] ; then # if .sh, then it should be sourced if [ "${x##*.}" == "sh.env" ] ; then source $x elif [ "${x##*.}" == "sh" ] ; then # else execute it exec $x fi fi done # Private (enabled by user) for x in $HOME/.profile.d/* do local realx="$x" if [ -L $x ] ; then realx="`readlink $x`" if # only use it if not enabled globally by sys admin # also, if the user have it in his ~/.profile.d/, we presume # he put it there, and not a ebuild if [ "${realx%/*}" == "/etc/profile.d" -a ! -x $realx -a -f $realx ] || \ [ "${realx%/*}" != "/etc/profile.d" -a -f $realx ] ; then # source it if [ "${x##*.}" == "sh.env" ] ; then source $realx # execute it elif [ "${x##*.}" == "sh" ] ; then exec $realx fi fi done --------------------------cut------------------------------------------- This should go (my opinion) into ~/.bash_profile, as you mostly only want it if the user login ... or at least the global stuff, commented by default. The sys admin can then enable it at system install by editing the /etc/skel/.* files if he so wish, or the user can do afterwards. I also think a README in /etc/profile.d/ explaining the whole mess should work =) We use .sh for script that should be executed, then the zsh/tcsh guys can add thier own .csh* or whatever. .sh.env is for stuff that should be sourced. A global script can only be "enabled" if it is executable, else ignored. If in ~/.profile.d/ it *should* be added by the user, thus we alway use them if not used by global. Adding scripts can be added if really needed, but then should follow rc-update and co behaviour and output preferred. This is a quick job of putting my thoughts into code, so may have some syntax/logic errors ;-) A few quick comments:
1) The script logic is basically sound, but I cannot see any need to "exec"
anything. The exec'd program/script isn't going to be able to anything to the
user's environment (variables+aliases+...) anyway, is it? Of course, it could
create files (for the user) or do something of that nature, but so could any
script that were sourced. I really cannot see any good uses for this, so in
the name of simplicity it should probably be left out.
2) Just a question of style I guess, but I would probably go for a
for x in /etc/profile.d/*.sh
loop instead of a
for x in /etc/profile.d/*
and checking each file name individually.
3) There is still a question of the ordering of the "sourcing". If a normal
shell glob is used, the files would be processed in lexicographical order,
meaining that specific priorities could be given through using names of the
form "NNsomepackage.sh", "NNotherpackage.sh", etc. This should probably be
sufficient, but it should probably decided - as a matter of policy - if
"NNpackage.sh" names are to be used (as in /etc/env.d), or plain "package.sh"
names should be used.
4) I do take issue with the following:
> This should go (my opinion) into ~/.bash_profile, as you mostly only
> want it if the user login [...] The sys admin can then enable it at
> system install by editing the /etc/skel/.* files if he so wish, or
> the user can do afterwards.
The problem with this approach is, that it is exactly what we are trying to
avoid. I touched on a couple of issues with it in my previous post, but
basically it will create a MESS of the user's ~/.xxx_profile files:
*) Different versions of these scripts will be copied to users which are
created at different times
*) The profile.d feature CANNOT be enabled this retroactively
(ie. for users that have already been created). It would require
manual/automatic editing of each and every user that has been
created. This is a laborious/dangerous undertaking at best.
*) Changes to these scripts WILL NOT and CANNOT be propagated to users'
~/.xxx_profile files automatically. This would mean, that if Gentoo
policy regarding the /etc/profile.d directory were to change, there would be
NO GOING BACK.
[Can you tell, that I administer lots of users...? :) I've been through
similar stuff before, and let me tell you: it wasn't fun.]
Therefore these scripts absolutely *MUST* go in /etc/profile (bash's global
profile). If it is commented out by default, that's fine. The main point is
not whether /etc/profile.d/ scripts get run by default after a system
install, but whether there *is* a standard mechanism, that the system
administrator can enable if necessary.
More comments: Ok. Basically what Martin suggests is what I had in mind at the first place. I do see a problem with this one though, which Bardur touches, and that is that it does not contain any place where to put scripts which are *not* to be sourced. If we are to leave things up to individual users to source foo.sh there must be a place where the packager can put foo.sh once and for all when root does the ebuild, regardless if we wish to use it or not, just that it is installed. So, (sorry for repeating myself, flame me for this,) my suggestion is to have three places to put things. 1. A place where the ebuild put the script, say /etc/scripts.d (root write only), which do nothing but lay around. 2. A place where things are sourced at login from /etc/profile, say /etc/profile.d which contains links to the directory /etc/scripts.d (think /etc/init.d and /etc/runlevels/foo here). This is where root put links for the scripts that everybody is to run at login. 3. A place for the common user (enforced or not, I don't really care personally) to put links to /etc/scripts.d, say $HOME/.profile.d sourced from $HOME/.profile (or optionally from /etc/profile, but I do prefer the first one). The first place is the most important one to standardize, as it is to be used by the packager. The second place is important to standardize only if we wish to standardize /etc/profile in some sence. I think it is a good thing though. The third place I cannot really see why it needs to be enforced by the distro, if we have the other two, it is easy for the local maintainer to set it up anyway he/she likes it. Bardur takes this, as I see it, one step further and asks for machinery to automize the putting of things (i.e. links to the first place) in the third place (and probably the second also). Sure, why not, as long as I am not forced to use it if I don't want to. (I am not forced to use rc-update add blaha neither if I don't want to, but, the point is, it is quite nice to have.) As the rc-scripts already exist, doing basically the same thing, this shouldn't be too hard to put together should it? And if the rc-scripts are to be used, then we can go all the way and get the same dependency system as in the /etc/init.d scripts, which in my eyes would be a really nice thing. (Much more flexible than the priority thing of /etc/env.d) Ok, I havent forgotten about this, just been a bit busy .. will try to respond in the next week or so. *** Bug 14368 has been marked as a duplicate of this bug. *** Azarah, would you like me to look at this? Give me the ticket if so. *** Bug 71611 has been marked as a duplicate of this bug. *** *** Bug 76304 has been marked as a duplicate of this bug. *** Ok, just to add my submisssion also here (copied from my Bug): I would suggest to add the following extention for /etc/profile: # Source profile extensions for certain packages # if [ -d /etc/profile.d ] ; then for s in /etc/profile.d/*.sh ; do [ -x "$s" ] && . "$s" done unset s fi with the "test -x" it is possible to enable/disable single scripts w/o deleting them (just set or unset the X-flag). It's not needed otherwise. *** Bug 38381 has been marked as a duplicate of this bug. *** I think this "bug" is a little dead here... why? It was started 3 years ago!!! There must be something happening here. Why Gentoo did not have some place to super user's put global customization settings that are untouchable to Gentoo's distribution system and cannot be replaced during a etc-update? FI, ebuilds for tcsh and xorg-x11 both dump stuff in /etc/profile.d If /etc/profile.d directory is to be populated by the owner rather than Gentoo, these will need to be modified. Last I checked, xorg-x11 at least do not.
To followup .. from -dev ML:
-----
On Fri, 2005-07-15 at 19:02 -0400, Mike Frysinger wrote:
> On Friday 15 July 2005 06:56 pm, Herbert Fischer wrote:
> > Thanks... I saw that "bug" and saw that it is very old (from 2002) and
> > nothing was done. Did you know why?
>
> hmm, us baselayout guys have discussed it before, but i guess we've never
> posted to the bug
>
> the only thing we really have against it is the potential of developer
> abuse ... that is, we feel that ebuild authors should *never* install a file
> there, it should only ever contain files created by the user
I the the resolution was pretty much that it is not that much of a
schlep to maintain those lines of code in /etc/profile if the user/admin
really wants it.
--
Martin Schlemmer
Reply to comment 22: This does not address the issue of packages which actually require installation and sourcing of scripts to function as the authors intended. Cook from 'dev-util' is/was one such package. Long story, but all the 'short versions' of commands were aliases expanding to very long command invocations. Without sourcing a file containing those aliases it was basically unusable. I don't use cook anymore so I don't particularly care about it, but there are bound to be similar packages. Telling the *users* that they need to add custom code to /etc/profile (and profiles of whatever other shells the other users on the system use) just to get a package working is hardly optimal. Also, what kind of 'developer abuse' are you talking about? I can't think of any kind of 'developer abuse' which isn't already possible through other mechanisms anyway. In short, I don't see why adding a short snippet similar to comment 18 is a bad idea. Please explain it to me. Why trying to be too smart? Wouldn't the following line at the end of /etc/profile suffice? test ! -x /etc/profile.local || . /etc/profile.local Not really. Sacrificing the flexibility, ease of updates, etc. of a directory-based approach to save 5 lines in /etc/profile is not a good tradeoff. Sorry, my comment 24 was regarding comment 3 and comment 20. To elaborate further: For user/admin maintained files the hook from comment 24 would be enough. For more complex setups the user/admin could put a snippet similar to that from comment 18 in /etc/profile.local. Um, ok, but regarding comment 20: Maybe I'm missing something, but I don't really see what the desire to have a file/directory which is protected from portage/etc-update has to do with this "bug". Surely an "exclude these files/directories" feature would something one would add to portage/etc-update -- and as such a request for such features belongs in a separate bug report. Glad too see that some activity has arisen around this one again. It's been dead for too long. First, regarding comment 20. The issue here is not (as correctly pointed out in comment 27) a place untouched by emerge. This is already facilitated by CONFIG_PROTECT_MASK. Read man pages of env-update: --snip-- etc-update will check all directories in the CONFIG_PROTECT variable. All config files found in CONFIG_PROTECT_MASK will automatically be updated for you by etc-update. See make.conf(5) for more information. --snap-- The issue is still: To have a standardized place where ebuilds (or whatever and whoever with root permission) can drop scripts which are to be run at login time (as opposed from scripts in init.d which are run at boot time). Preferably with options to enable/disable the execution of the scripts. From a personal point of view, adding a small script as the one in comment 18 is perfect. That's what I've been using for the 3 years since this thread was opened. The desire, however, is to have something standardized(!) So that a developer/packager/... can know the behaviour when putting something in /etc/profile.d. If it's not a standard, then it's useless from a packagers point of view. Yes, some of this functionality is in /etc/env.d but significantly less powerful. Similar, very well functioning is the rc-* pile of scripts for handling /etc/init.d and runlevels. This would be great to have at login-level also, but if people feel that's too heavy machinery, comment 18 is the way to go. Only thing needed is to elevate it to a standard. ok, once again my thoughts: /etc/profile.d is a well known and established standard in many other distros. The code fragment I posted in comment 18 is more or less "stolen" from SuSE. So why do we need something special? Many packages (ie. xorg-x11) are placing files in this directory (if not removed by the package maintainer), because many other distros sources /etc/profile.d/*.sh by default. Ok, we have /etc/env.d, and this is good for most static environment settings. But for dynamic settings, /etc/profile.d is the way to go. Just my 2 euro cents. Ok. Forgive me if I missed something here in the many lenghty replies above. For tcsh I put some files into /etc/profile.d, in the latest ebuild such that only those which have a .csh suffix are being sourced. This sourcing will probably be made conditional on having an interactive shell or not as per bug #104763. So, since tcsh is blocking this bug now, where do I have to place my files instead? whats wrong with just using say /etc/tcsh.d/ for tcsh-specific scripts ? imo, only POSIX sh compatible scripts should ever be placed into /etc/profile.d That's completely fine with me. However, it leaves us with the question why we do it different from other distros. Fedora/RedHat places them also in /etc/profile.d. Debian doesn't have such directory. I think SuSE does also use /etc/profile.d, but I cannot check that. Again, simply moving the location works fine for me, but doesn't solve the security risk imposed by it as written down here. Perhaps it might then be better to merge everything into csh.cshrc and csh.login instead and put the scripts that I disabled as examples somewhere in the same location as the docs? we could go with the requirement that all files in profile.d be named with .sh and have bash only source those files (which is what redhat does) which means nothing needs to be changed in tcsh, correct ? tcsh only sources .csh files, so pretty much everything is happily ignored by tcsh. In older versions only 4 named files are also being sourced from /etc/profile.d: tcsh-aliases, tcsh-bindkey, tcsh-complete and tcsh-settings, which have no suffix. This behaviour is removed in the latest version which should still be stabled. tcsh would indeed not need any modifications as it ignores more or less anything which doesn't end with .csh from /etc/profile.d currently and in the future. added /etc/profild.d/*.sh to svn, thanks Fabian |