707c76b2dfecce74c6e4c701a0d3f4f2dc37be76
[portage.git] / pym / portage_data.py
1 # portage_data.py -- Calculated/Discovered Data Values
2 # Copyright 1998-2004 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Id$
5
6 if not hasattr(__builtins__, "set"):
7         from sets import Set as set
8
9 import os,pwd,grp
10 from portage_util import writemsg
11 from output import green,red
12 from output import create_color_func
13 bad = create_color_func("BAD")
14
15 ostype=os.uname()[0]
16
17 lchown = None
18 if ostype=="Linux" or ostype.lower().endswith("gnu"):
19         userland="GNU"
20         os.environ["XARGS"]="xargs -r"
21 elif ostype == "Darwin":
22         userland="Darwin"
23         os.environ["XARGS"]="xargs"
24         def lchown(*pos_args, **key_args):
25                 pass
26 elif ostype.endswith("BSD") or ostype =="DragonFly":
27         userland="BSD"
28         os.environ["XARGS"]="xargs"
29 else:
30         writemsg(red("Operating system")+" \""+ostype+"\" "+red("currently unsupported. Exiting.")+"\n")
31         sys.exit(1)
32
33 if not lchown:
34         if "lchown" in dir(os):
35                 # Included in python-2.3
36                 lchown = os.lchown
37         else:
38                 try:
39                         import missingos
40                         lchown = missingos.lchown
41                 except ImportError:
42                         def lchown(*pos_args, **key_args):
43                                 writemsg(red("!!!") + " It seems that os.lchown does not" + \
44                                         " exist.  Please rebuild python.\n", noiselevel=-1)
45                         lchown()
46
47 os.environ["USERLAND"]=userland
48
49 def portage_group_warning():
50         warn_prefix = bad("*** WARNING ***  ")
51         mylines = [
52                 "For security reasons, only system administrators should be",
53                 "allowed in the portage group.  Untrusted users or processes",
54                 "can potentially exploit the portage group for attacks such as",
55                 "local privilege escalation."
56         ]
57         for x in mylines:
58                 writemsg(warn_prefix, noiselevel=-1)
59                 writemsg(x, noiselevel=-1)
60                 writemsg("\n", noiselevel=-1)
61         writemsg("\n", noiselevel=-1)
62
63 # Portage has 3 security levels that depend on the uid and gid of the main
64 # process and are assigned according to the following table:
65 #
66 # Privileges  secpass  uid    gid
67 # normal      0        any    any
68 # group       1        any    portage_gid
69 # super       2        0      any
70 #
71 # If the "wheel" group does not exist then wheelgid falls back to 0.
72 # If the "portage" group does not exist then portage_uid falls back to wheelgid.
73
74 secpass=0
75
76 uid=os.getuid()
77 wheelgid=0
78
79 if uid==0:
80         secpass=2
81 try:
82         wheelgid=grp.getgrnam("wheel")[2]
83 except KeyError:
84         writemsg("portage initialization: your system doesn't have a 'wheel' group.\n")
85         writemsg("Please fix this as it is a normal system requirement. 'wheel' is GID 10\n")
86         writemsg("`emerge baselayout` and a config update with dispatch-conf, etc-update\n")
87         writemsg("or cfg-update should remedy this problem.\n")
88         pass
89
90 #Discover the uid and gid of the portage user/group
91 try:
92         portage_uid=pwd.getpwnam("portage")[2]
93         portage_gid=grp.getgrnam("portage")[2]
94         if secpass < 1 and portage_gid in os.getgroups():
95                 secpass=1
96 except KeyError:
97         portage_uid=0
98         portage_gid=0
99         writemsg("\n")
100         writemsg(  red("portage: 'portage' user or group missing. Please update baselayout\n"))
101         writemsg(  red("         and merge portage user(250) and group(250) into your passwd\n"))
102         writemsg(  red("         and group files. Non-root compilation is disabled until then.\n"))
103         writemsg(      "         Also note that non-root/wheel users will need to be added to\n")
104         writemsg(      "         the portage group to do portage commands.\n")
105         writemsg("\n")
106         writemsg(      "         For the defaults, line 1 goes into passwd, and 2 into group.\n")
107         writemsg(green("         portage:x:250:250:portage:/var/tmp/portage:/bin/false\n"))
108         writemsg(green("         portage::250:portage\n"))
109         writemsg("\n")
110         portage_group_warning()
111
112 userpriv_groups = [portage_gid]
113 if secpass >= 2:
114         # Get a list of group IDs for the portage user.  Do not use grp.getgrall()
115         # since it is known to trigger spurious SIGPIPE problems with nss_ldap.
116         from commands import getstatusoutput
117         mystatus, myoutput = getstatusoutput("id -G portage")
118         if mystatus == os.EX_OK:
119                 for x in myoutput.split():
120                         try:
121                                 userpriv_groups.append(int(x))
122                         except ValueError:
123                                 pass
124                         del x
125                 userpriv_groups = list(set(userpriv_groups))
126         del getstatusoutput, mystatus, myoutput