1 # data.py -- Calculated/Discovered Data Values
2 # Copyright 1998-2009 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
6 import os, sys, pwd, grp, platform
7 from portage.const import PORTAGE_GROUPNAME, PORTAGE_USERNAME
10 portage.proxy.lazyimport.lazyimport(globals(),
11 'portage.output:colorize',
12 'portage.util:writemsg',
14 from portage.localization import _
16 ostype=platform.system()
18 if ostype == "DragonFly" or ostype.endswith("BSD"):
23 lchown = getattr(os, "lchown", None)
26 if ostype == "Darwin":
27 def lchown(*pos_args, **key_args):
32 lchown = missingos.lchown
34 def lchown(*pos_args, **key_args):
35 writemsg(colorize("BAD", "!!!") + _(
36 " It seems that os.lchown does not"
37 " exist. Please rebuild python.\n"), noiselevel=-1)
40 lchown = portage._unicode_func_wrapper(lchown)
42 def portage_group_warning():
43 warn_prefix = colorize("BAD", "*** WARNING *** ")
45 "For security reasons, only system administrators should be",
46 "allowed in the portage group. Untrusted users or processes",
47 "can potentially exploit the portage group for attacks such as",
48 "local privilege escalation."
51 writemsg(warn_prefix, noiselevel=-1)
52 writemsg(x, noiselevel=-1)
53 writemsg("\n", noiselevel=-1)
54 writemsg("\n", noiselevel=-1)
56 # Portage has 3 security levels that depend on the uid and gid of the main
57 # process and are assigned according to the following table:
59 # Privileges secpass uid gid
61 # group 1 any portage_gid
64 # If the "wheel" group does not exist then wheelgid falls back to 0.
65 # If the "portage" group does not exist then portage_uid falls back to wheelgid.
75 wheelgid=grp.getgrnam("wheel")[2]
79 #Discover the uid and gid of the portage user/group
81 portage_uid = pwd.getpwnam(PORTAGE_USERNAME)[2]
82 portage_gid = grp.getgrnam(PORTAGE_GROUPNAME)[2]
83 if secpass < 1 and portage_gid in os.getgroups():
88 userpriv_groups = [portage_gid]
89 writemsg(colorize("BAD",
90 _("portage: 'portage' user or group missing.")) + "\n", noiselevel=-1)
92 " For the defaults, line 1 goes into passwd, "
93 "and 2 into group.\n"), noiselevel=-1)
94 writemsg(colorize("GOOD",
95 " portage:x:250:250:portage:/var/tmp/portage:/bin/false") \
96 + "\n", noiselevel=-1)
97 writemsg(colorize("GOOD", " portage::250:portage") + "\n",
99 portage_group_warning()
101 userpriv_groups = [portage_gid]
103 # Get a list of group IDs for the portage user. Do not use
104 # grp.getgrall() since it is known to trigger spurious
105 # SIGPIPE problems with nss_ldap.
107 from subprocess import getstatusoutput
109 from commands import getstatusoutput
110 mystatus, myoutput = getstatusoutput("id -G portage")
111 if mystatus == os.EX_OK:
112 for x in myoutput.split():
114 userpriv_groups.append(int(x))
118 userpriv_groups = list(set(userpriv_groups))
119 del getstatusoutput, mystatus, myoutput