rda-python-setuid 1.0.4__tar.gz → 1.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rda_python_setuid-1.0.4/src/rda_python_setuid.egg-info → rda_python_setuid-1.0.5}/PKG-INFO +6 -6
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/README.md +5 -5
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/pyproject.toml +1 -1
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/install.py +11 -11
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/install.usg +20 -20
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/pgstart.py +38 -23
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/pywrapper.c +7 -7
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/pywrapper.py +29 -19
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5/src/rda_python_setuid.egg-info}/PKG-INFO +6 -6
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/LICENSE +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/MANIFEST.in +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/setup.cfg +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid/__init__.py +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/SOURCES.txt +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/dependency_links.txt +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/entry_points.txt +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/requires.txt +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/top_level.txt +0 -0
- {rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/tests/test_setuid.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_setuid
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: RDA Python Package to setuid for program executions as an effective or common user
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-setuid
|
|
@@ -52,7 +52,7 @@ prefix:
|
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
`pip install` then places `setuid_dsarch` in the environment's `bin/` directory
|
|
55
|
-
automatically. `pywrapper-install
|
|
55
|
+
automatically. `pywrapper-install -l/--link` locks it down to `chmod 700` so users
|
|
56
56
|
cannot bypass the setuid wrapper by running it directly.
|
|
57
57
|
|
|
58
58
|
## Environment setup
|
|
@@ -91,13 +91,13 @@ pywrapper-install
|
|
|
91
91
|
pip install rda_python_dsarch
|
|
92
92
|
|
|
93
93
|
# 2. Compile pywrapper C binary (once per environment):
|
|
94
|
-
pywrapper-install
|
|
94
|
+
pywrapper-install
|
|
95
95
|
|
|
96
96
|
# 3. Wire up each program as a setuid entry:
|
|
97
|
-
pywrapper-install
|
|
97
|
+
pywrapper-install -l dsarch
|
|
98
98
|
|
|
99
99
|
# 4. Optionally, allow a specialist to run commands as themselves:
|
|
100
|
-
pywrapper-install
|
|
100
|
+
pywrapper-install -p -u zji
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
### Simple install (no sudo required, runs as current user)
|
|
@@ -107,7 +107,7 @@ direct symlink from `dsarch` to `setuid_dsarch`:
|
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
109
|
pip install rda_python_dsarch
|
|
110
|
-
pywrapper-install
|
|
110
|
+
pywrapper-install -l dsarch -s
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
## Runtime flow
|
|
@@ -36,7 +36,7 @@ prefix:
|
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
`pip install` then places `setuid_dsarch` in the environment's `bin/` directory
|
|
39
|
-
automatically. `pywrapper-install
|
|
39
|
+
automatically. `pywrapper-install -l/--link` locks it down to `chmod 700` so users
|
|
40
40
|
cannot bypass the setuid wrapper by running it directly.
|
|
41
41
|
|
|
42
42
|
## Environment setup
|
|
@@ -75,13 +75,13 @@ pywrapper-install
|
|
|
75
75
|
pip install rda_python_dsarch
|
|
76
76
|
|
|
77
77
|
# 2. Compile pywrapper C binary (once per environment):
|
|
78
|
-
pywrapper-install
|
|
78
|
+
pywrapper-install
|
|
79
79
|
|
|
80
80
|
# 3. Wire up each program as a setuid entry:
|
|
81
|
-
pywrapper-install
|
|
81
|
+
pywrapper-install -l dsarch
|
|
82
82
|
|
|
83
83
|
# 4. Optionally, allow a specialist to run commands as themselves:
|
|
84
|
-
pywrapper-install
|
|
84
|
+
pywrapper-install -p -u zji
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
### Simple install (no sudo required, runs as current user)
|
|
@@ -91,7 +91,7 @@ direct symlink from `dsarch` to `setuid_dsarch`:
|
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
pip install rda_python_dsarch
|
|
94
|
-
pywrapper-install
|
|
94
|
+
pywrapper-install -l dsarch -s
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
## Runtime flow
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
#
|
|
13
13
|
# Usage:
|
|
14
14
|
# # 1. Compile and install pywrapper (run once per environment):
|
|
15
|
-
# pywrapper-install
|
|
15
|
+
# pywrapper-install [-u gdexdata] [-e $ENVHOME/bin/]
|
|
16
16
|
#
|
|
17
17
|
# # 2. Create pgstart_USER entry so USER can run commands as themselves:
|
|
18
|
-
# pywrapper-install
|
|
18
|
+
# pywrapper-install -p [-u zji] [-e $ENVHOME/bin/]
|
|
19
19
|
#
|
|
20
20
|
# # 3. Create a symlink so a program runs as CommonUser via pywrapper (setuid):
|
|
21
|
-
# pywrapper-install
|
|
21
|
+
# pywrapper-install -l myprog [-u gdexdata] [-e $ENVHOME/bin/]
|
|
22
22
|
#
|
|
23
23
|
# # 4. Simple install: symlink PROGRAM -> setuid_PROGRAM (no setuid, runs as current user):
|
|
24
|
-
# pywrapper-install
|
|
24
|
+
# pywrapper-install -l myprog -s [-e $ENVHOME/bin/]
|
|
25
25
|
#
|
|
26
26
|
# Convention for wrapped programs:
|
|
27
27
|
# The target package must register its connector entry point with a setuid_ prefix:
|
|
@@ -72,24 +72,24 @@ def main():
|
|
|
72
72
|
description="Compile and install the pywrapper setuid C binary."
|
|
73
73
|
)
|
|
74
74
|
parser.add_argument(
|
|
75
|
-
'--envhome', default=None,
|
|
75
|
+
'-e', '--envhome', default=None,
|
|
76
76
|
help="Path to the venv bin/ directory (default: bin/ dir of the current Python executable)"
|
|
77
77
|
)
|
|
78
78
|
parser.add_argument(
|
|
79
|
-
'--user', default=None,
|
|
80
|
-
help="User name to own the setuid binary (default: current login user for
|
|
79
|
+
'-u', '--user', default=None,
|
|
80
|
+
help="User name to own the setuid binary (default: current login user for -p/--pgstart, gdexdata otherwise)"
|
|
81
81
|
)
|
|
82
82
|
parser.add_argument(
|
|
83
|
-
'--simple', action='store_true',
|
|
84
|
-
help="Simple install: create symlink PROGRAM -> setuid_PROGRAM, skipping setuid (use with
|
|
83
|
+
'-s', '--simple', action='store_true',
|
|
84
|
+
help="Simple install: create symlink PROGRAM -> setuid_PROGRAM, skipping setuid (use with -l/--link)"
|
|
85
85
|
)
|
|
86
86
|
group = parser.add_mutually_exclusive_group()
|
|
87
87
|
group.add_argument(
|
|
88
|
-
'--pgstart', action='store_true',
|
|
88
|
+
'-p', '--pgstart', action='store_true',
|
|
89
89
|
help="Create pgstart_USER for running commands as USER (Mode 2)"
|
|
90
90
|
)
|
|
91
91
|
group.add_argument(
|
|
92
|
-
'--link', metavar='PROGRAM',
|
|
92
|
+
'-l', '--link', metavar='PROGRAM',
|
|
93
93
|
help="Create symlink PROGRAM -> pywrapper for running a fixed program as CommonUser (Mode 1)"
|
|
94
94
|
)
|
|
95
95
|
args = parser.parse_args()
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
that execute Python scripts as a common or effective user via the setuid mechanism.
|
|
3
3
|
Must be run inside the target Python virtual environment.
|
|
4
4
|
|
|
5
|
-
Usage: pywrapper-install
|
|
5
|
+
Usage: pywrapper-install [-u USER] [-e BINDIR] [-p | -l PROGRAM [-s]]
|
|
6
6
|
|
|
7
|
-
- Option --user USER
|
|
7
|
+
- Option -u or --user USER
|
|
8
8
|
The user name to own the setuid binary. For Mode 1 (CommonUser program),
|
|
9
9
|
this is the common user (e.g. gdexdata). For Mode 2 (pgstart), this is
|
|
10
|
-
the specialist user (e.g. zji). Defaults to 'gdexdata' unless
|
|
10
|
+
the specialist user (e.g. zji). Defaults to 'gdexdata' unless -p/--pgstart
|
|
11
11
|
is given, in which case it defaults to the current login user.
|
|
12
12
|
|
|
13
|
-
- Option --envhome BINDIR
|
|
13
|
+
- Option -e or --envhome BINDIR
|
|
14
14
|
Path to the venv bin/ directory. Defaults to the bin/ directory of the
|
|
15
15
|
currently active Python executable. Only needed when installing into an
|
|
16
16
|
environment other than the one currently active.
|
|
17
17
|
|
|
18
|
-
- Option --pgstart
|
|
18
|
+
- Option -p or --pgstart
|
|
19
19
|
Mode 2: copy the compiled pywrapper binary to pgstart_USER (owned by USER,
|
|
20
20
|
chmod 4750). Allows USER to run arbitrary commands as themselves via the
|
|
21
|
-
setuid wrapper. Cannot be combined with
|
|
21
|
+
setuid wrapper. Cannot be combined with -l/--link.
|
|
22
22
|
|
|
23
|
-
- Option --link PROGRAM
|
|
23
|
+
- Option -l or --link PROGRAM
|
|
24
24
|
Mode 1: create a symlink PROGRAM -> pywrapper in the bin/ directory, then
|
|
25
25
|
lock down setuid_PROGRAM (chmod 700, owned by USER) so users cannot bypass
|
|
26
26
|
the setuid wrapper by running setuid_PROGRAM directly. Cannot be combined
|
|
27
|
-
with
|
|
27
|
+
with -p/--pgstart.
|
|
28
28
|
|
|
29
|
-
- Option --simple (use with
|
|
29
|
+
- Option -s or --simple (use with -l/--link)
|
|
30
30
|
Simple install: create a symlink PROGRAM -> setuid_PROGRAM directly,
|
|
31
31
|
skipping the setuid mechanism entirely. The program runs as the current
|
|
32
|
-
user with no privilege change.
|
|
32
|
+
user with no privilege change. -u/--user is not required with this option.
|
|
33
33
|
Useful for users who do not need or cannot set up the setuid wrapper.
|
|
34
34
|
|
|
35
35
|
When run without --pgstart or --link, the default action is to compile pywrapper.c
|
|
@@ -98,13 +98,13 @@
|
|
|
98
98
|
pip install rda_python_dsarch
|
|
99
99
|
|
|
100
100
|
2. Compile pywrapper (once per environment):
|
|
101
|
-
pywrapper-install
|
|
101
|
+
pywrapper-install
|
|
102
102
|
|
|
103
103
|
3. Wire up each program as a setuid entry:
|
|
104
|
-
pywrapper-install
|
|
104
|
+
pywrapper-install -l dsarch
|
|
105
105
|
|
|
106
106
|
4. Optionally, allow a specialist to run commands as themselves:
|
|
107
|
-
pywrapper-install
|
|
107
|
+
pywrapper-install -p
|
|
108
108
|
|
|
109
109
|
Option B - Simple install (no sudo required, runs as current user):
|
|
110
110
|
|
|
@@ -112,21 +112,21 @@
|
|
|
112
112
|
pip install rda_python_dsarch
|
|
113
113
|
|
|
114
114
|
2. Create a direct symlink to the connector script:
|
|
115
|
-
pywrapper-install
|
|
115
|
+
pywrapper-install -l dsarch -s
|
|
116
116
|
|
|
117
117
|
Examples:
|
|
118
118
|
|
|
119
|
-
1. Compile and install pywrapper for common user gdexdata:
|
|
120
|
-
pywrapper-install
|
|
119
|
+
1. Compile and install pywrapper for common user gdexdata (default):
|
|
120
|
+
pywrapper-install
|
|
121
121
|
|
|
122
122
|
2. Same, but targeting a specific environment:
|
|
123
|
-
pywrapper-install
|
|
123
|
+
pywrapper-install -e /glade/u/home/gdexdata/gdexmsenv/bin/
|
|
124
124
|
|
|
125
125
|
3. Wire up dsarch to run as gdexdata via pywrapper:
|
|
126
|
-
pywrapper-install
|
|
126
|
+
pywrapper-install -l dsarch
|
|
127
127
|
|
|
128
128
|
4. Allow specialist zji to run commands as themselves via pgstart:
|
|
129
|
-
pywrapper-install
|
|
129
|
+
pywrapper-install -p -u zji
|
|
130
130
|
|
|
131
131
|
5. Simple install of dsarch for a user who does not need setuid:
|
|
132
|
-
pywrapper-install
|
|
132
|
+
pywrapper-install -l dsarch -s
|
|
@@ -19,26 +19,38 @@ import sys
|
|
|
19
19
|
import re
|
|
20
20
|
import pwd
|
|
21
21
|
import subprocess
|
|
22
|
-
from rda_python_common import PgLOG
|
|
22
|
+
from rda_python_common.pg_log import PgLOG
|
|
23
23
|
|
|
24
|
-
#
|
|
25
|
-
# main function to excecute this script
|
|
26
|
-
#
|
|
27
24
|
def main():
|
|
25
|
+
"""Entry point for pgstart.
|
|
26
|
+
|
|
27
|
+
Checks whether the real user is authorized (must be the effective user or
|
|
28
|
+
the GDEX common user), then executes the supplied command as the effective
|
|
29
|
+
user. Supports foreground/background execution and optional working-directory
|
|
30
|
+
change via command-line options.
|
|
28
31
|
|
|
32
|
+
Options (prefix with '-'):
|
|
33
|
+
bg -- run command in background (non-blocking)
|
|
34
|
+
fg -- run command in foreground (default, no-op flag)
|
|
35
|
+
cwd -- change to the next argument as working directory before running
|
|
36
|
+
env -- print environment variables and exit
|
|
37
|
+
inc -- print sys.path include paths and exit
|
|
38
|
+
plg -- print PGLOG variables and exit
|
|
39
|
+
"""
|
|
40
|
+
pglog = PgLOG()
|
|
29
41
|
permit = False
|
|
30
|
-
|
|
42
|
+
pglog.PGLOG['LOGFILE'] = "pgstart.log"
|
|
31
43
|
aname = PgLOG.get_command()
|
|
32
|
-
bckgrd =
|
|
44
|
+
bckgrd = False
|
|
33
45
|
workdir = None
|
|
34
46
|
argv = sys.argv[1:]
|
|
35
47
|
|
|
36
|
-
ruid =
|
|
37
|
-
euid =
|
|
48
|
+
ruid = pglog.PGLOG['RUID']
|
|
49
|
+
euid = pglog.PGLOG['EUID']
|
|
38
50
|
ruser = pwd.getpwuid(ruid).pw_name
|
|
39
51
|
euser = pwd.getpwuid(euid).pw_name
|
|
40
|
-
if ruser == euser or ruser ==
|
|
41
|
-
|
|
52
|
+
if ruser == euser or ruser == pglog.PGLOG['GDEXUSER']: permit = True
|
|
53
|
+
pglog.set_suid(euid)
|
|
42
54
|
|
|
43
55
|
while argv:
|
|
44
56
|
ms = re.match(r'^-(\w+)$', argv[0])
|
|
@@ -46,40 +58,43 @@ def main():
|
|
|
46
58
|
argv.pop(0)
|
|
47
59
|
opt = ms.group(1)
|
|
48
60
|
if opt == "bg":
|
|
49
|
-
bckgrd =
|
|
61
|
+
bckgrd = True
|
|
50
62
|
elif opt == "cwd":
|
|
51
63
|
if argv: workdir = argv.pop(0)
|
|
52
64
|
elif opt != "fg":
|
|
53
|
-
display_message(opt)
|
|
65
|
+
display_message(pglog, opt)
|
|
54
66
|
|
|
55
67
|
if not (permit and argv):
|
|
56
68
|
print("********************************************************************")
|
|
57
69
|
print("* Your Login Name is {}({}) & Effective User Name is {}({}).".format(ruser, ruid, euser, euid))
|
|
58
|
-
print("* Pass a command or options -(
|
|
70
|
+
print("* Pass a command or options -(bg|fg|cwd|env|inc|plg) to run '{}'.".format(aname))
|
|
59
71
|
if not permit:
|
|
60
|
-
print("* You must be '{}' or '{}' to execute a command as user '{}'.".format(euser,
|
|
72
|
+
print("* You must be '{}' or '{}' to execute a command as user '{}'.".format(euser, pglog.PGLOG['GDEXUSER'], euser))
|
|
61
73
|
print("********************************************************************")
|
|
62
74
|
sys.exit(0)
|
|
63
75
|
|
|
64
|
-
cmd =
|
|
76
|
+
cmd = pglog.argv_to_string(argv)
|
|
65
77
|
|
|
66
|
-
msg = "{}-{}{}-{}".format(
|
|
78
|
+
msg = "{}-{}{}-{}".format(pglog.PGLOG['HOSTNAME'], aname, pglog.current_datetime(), pglog.PGLOG['CURUID'])
|
|
67
79
|
if workdir:
|
|
68
80
|
msg += "-" + workdir
|
|
69
81
|
os.chdir(workdir)
|
|
70
82
|
|
|
71
|
-
|
|
83
|
+
pglog.pglog("{}: {}".format(msg, cmd), PgLOG.MSGLOG)
|
|
72
84
|
if bckgrd:
|
|
73
85
|
subprocess.Popen(argv)
|
|
74
86
|
else:
|
|
75
87
|
subprocess.run(argv)
|
|
76
88
|
sys.exit(0)
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
#
|
|
81
|
-
def display_message(option):
|
|
90
|
+
def display_message(pglog, option):
|
|
91
|
+
"""Print diagnostic information for the given option and exit.
|
|
82
92
|
|
|
93
|
+
Args:
|
|
94
|
+
pglog (PgLOG): Initialized PgLOG instance.
|
|
95
|
+
option (str): One of 'env' (environment variables), 'inc' (sys.path),
|
|
96
|
+
or 'plg' (PGLOG dict). Prints an error for unknown values.
|
|
97
|
+
"""
|
|
83
98
|
if option == "env":
|
|
84
99
|
print("Environment Variables:")
|
|
85
100
|
for ename in sorted(os.environ):
|
|
@@ -90,8 +105,8 @@ def display_message(option):
|
|
|
90
105
|
print(pname)
|
|
91
106
|
elif option == "plg":
|
|
92
107
|
print("PGLOG variables:")
|
|
93
|
-
for vname in sorted(
|
|
94
|
-
print("{}: {}".format(vname,
|
|
108
|
+
for vname in sorted(pglog.PGLOG):
|
|
109
|
+
print("{}: {}".format(vname, pglog.PGLOG[vname]))
|
|
95
110
|
else:
|
|
96
111
|
print("* {}: Unknown option".format(option))
|
|
97
112
|
|
|
@@ -10,22 +10,22 @@
|
|
|
10
10
|
* python -m pip install rda_python_setuid
|
|
11
11
|
*
|
|
12
12
|
* # Compile pywrapper and set setuid bit (owned by CommonUser):
|
|
13
|
-
* pywrapper-install
|
|
13
|
+
* pywrapper-install [-u CommonUser] [-e $ENVHOME/bin]
|
|
14
14
|
*
|
|
15
|
-
* # For an existing python program, $ENVHOME/bin/
|
|
15
|
+
* # For an existing python program, $ENVHOME/bin/setuid_CommonProgram, to execute it
|
|
16
16
|
* # as the common user (Mode 1 - symlink):
|
|
17
|
-
* pywrapper-install
|
|
17
|
+
* pywrapper-install -l CommonProgram [-u CommonUser] [-e $ENVHOME/bin]
|
|
18
18
|
* CommonProgram [options]
|
|
19
19
|
*
|
|
20
20
|
* # For a specialist to run commands as themselves via pgstart (Mode 2):
|
|
21
|
-
* pywrapper-install
|
|
21
|
+
* pywrapper-install -p [-u EffectUser] [-e $ENVHOME/bin]
|
|
22
22
|
* pgstart_EffectUser EffectProgram [options]
|
|
23
23
|
*
|
|
24
24
|
* N: python 3 release number, it is 10 for Python 3.10.12
|
|
25
25
|
* CommonUser: a common user login name, such as gdexdata, for GDEXMS configuration
|
|
26
26
|
* EffectUser: any user login name in the same group of the common user
|
|
27
|
-
* $ENVHOME: /glade/u/home/gdexdata/
|
|
28
|
-
* /glade/work/gdexdata/conda-envs/pg-
|
|
27
|
+
* $ENVHOME: /glade/u/home/gdexdata/gdexmsenv (venv) on DECS machines, and
|
|
28
|
+
* /glade/work/gdexdata/conda-envs/pg-gdex (conda) on DAV
|
|
29
29
|
*
|
|
30
30
|
* Convention:
|
|
31
31
|
* Any Python package whose program is to be run via pywrapper must register
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* "setuid_dsarch" = "rda_python_dsarch.dsarch:main"
|
|
35
35
|
* pip install places setuid_dsarch in $ENVHOME/bin/. pywrapper locates it by
|
|
36
36
|
* prepending setuid_ to the invoked program name. No manual script creation needed.
|
|
37
|
-
* pywrapper-install
|
|
37
|
+
* pywrapper-install -l/--link will chown setuid_dsarch to CommonUser and chmod 700,
|
|
38
38
|
* preventing direct execution by other users while still allowing pywrapper
|
|
39
39
|
* (which runs with EUID=CommonUser via the setuid bit) to execv it.
|
|
40
40
|
*
|
|
@@ -17,15 +17,23 @@
|
|
|
17
17
|
import os
|
|
18
18
|
import sys
|
|
19
19
|
import pwd
|
|
20
|
-
from rda_python_common import PgLOG
|
|
20
|
+
from rda_python_common.pg_log import PgLOG
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
# main function to excecute this script
|
|
24
|
-
#
|
|
25
22
|
def main():
|
|
23
|
+
"""Entry point for setuid_pywrapper (the default pywrapper.c fallback target).
|
|
24
|
+
|
|
25
|
+
When pywrapper.c cannot find a matching setuid_<program> entry point, it
|
|
26
|
+
falls back to executing this script. Prints UID information and setup
|
|
27
|
+
instructions, or dumps diagnostic information when a flag is supplied.
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
Options:
|
|
30
|
+
-env -- print environment variables and exit
|
|
31
|
+
-inc -- print sys.path include paths and exit
|
|
32
|
+
-plg -- print PGLOG variables and exit
|
|
33
|
+
"""
|
|
34
|
+
pglog = PgLOG()
|
|
35
|
+
pglog.set_suid(pglog.PGLOG['EUID'])
|
|
36
|
+
inc = True
|
|
29
37
|
print("********************************************************************")
|
|
30
38
|
argv = sys.argv[1:]
|
|
31
39
|
if argv:
|
|
@@ -33,35 +41,37 @@ def main():
|
|
|
33
41
|
print("Environment Variables:")
|
|
34
42
|
for ename in sorted(os.environ):
|
|
35
43
|
print("{}: {}".format(ename, os.environ[ename]))
|
|
36
|
-
inc =
|
|
44
|
+
inc = False
|
|
37
45
|
elif argv[0] == "-inc":
|
|
38
46
|
print("Including Paths:")
|
|
39
47
|
for pname in sorted(sys.path):
|
|
40
48
|
print(pname)
|
|
41
|
-
inc =
|
|
49
|
+
inc = False
|
|
42
50
|
elif argv[0] == "-plg":
|
|
43
51
|
print("PGLOG variables:")
|
|
44
|
-
for vname in sorted(
|
|
45
|
-
print("{}: {}".format(vname,
|
|
46
|
-
inc =
|
|
52
|
+
for vname in sorted(pglog.PGLOG):
|
|
53
|
+
print("{}: {}".format(vname, pglog.PGLOG[vname]))
|
|
54
|
+
inc = False
|
|
47
55
|
else:
|
|
48
56
|
print("* {}: Unknown option".format(argv[0]))
|
|
49
57
|
else:
|
|
50
|
-
ruid =
|
|
51
|
-
euid =
|
|
58
|
+
ruid = pglog.PGLOG['RUID']
|
|
59
|
+
euid = pglog.PGLOG['EUID']
|
|
52
60
|
ruser = pwd.getpwuid(ruid).pw_name
|
|
53
61
|
euser = pwd.getpwuid(euid).pw_name
|
|
54
|
-
print("* Your Login Name is {}({}) & Effective User Name is {}({}).".format(ruser, ruid, euser,euid))
|
|
55
|
-
print("* To wrap
|
|
56
|
-
print("*
|
|
57
|
-
print("*
|
|
62
|
+
print("* Your Login Name is {}({}) & Effective User Name is {}({}).".format(ruser, ruid, euser, euid))
|
|
63
|
+
print("* To wrap a Python program 'yourscript', register its entry point")
|
|
64
|
+
print("* with a setuid_ prefix in pyproject.toml:")
|
|
65
|
+
print("* [project.scripts]")
|
|
66
|
+
print("* \"setuid_yourscript\" = \"your_package.module:main\"")
|
|
67
|
+
print("* Then run: pywrapper-install -l yourscript")
|
|
58
68
|
if inc:
|
|
59
69
|
print("* Include -env to show environment variables")
|
|
60
70
|
print("* Include -inc to show included paths")
|
|
61
71
|
print("* Include -plg to show PGLOG variables")
|
|
62
|
-
|
|
72
|
+
|
|
63
73
|
print("********************************************************************\n")
|
|
64
|
-
|
|
74
|
+
|
|
65
75
|
sys.exit(0)
|
|
66
76
|
|
|
67
77
|
#
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_setuid
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: RDA Python Package to setuid for program executions as an effective or common user
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-setuid
|
|
@@ -52,7 +52,7 @@ prefix:
|
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
`pip install` then places `setuid_dsarch` in the environment's `bin/` directory
|
|
55
|
-
automatically. `pywrapper-install
|
|
55
|
+
automatically. `pywrapper-install -l/--link` locks it down to `chmod 700` so users
|
|
56
56
|
cannot bypass the setuid wrapper by running it directly.
|
|
57
57
|
|
|
58
58
|
## Environment setup
|
|
@@ -91,13 +91,13 @@ pywrapper-install
|
|
|
91
91
|
pip install rda_python_dsarch
|
|
92
92
|
|
|
93
93
|
# 2. Compile pywrapper C binary (once per environment):
|
|
94
|
-
pywrapper-install
|
|
94
|
+
pywrapper-install
|
|
95
95
|
|
|
96
96
|
# 3. Wire up each program as a setuid entry:
|
|
97
|
-
pywrapper-install
|
|
97
|
+
pywrapper-install -l dsarch
|
|
98
98
|
|
|
99
99
|
# 4. Optionally, allow a specialist to run commands as themselves:
|
|
100
|
-
pywrapper-install
|
|
100
|
+
pywrapper-install -p -u zji
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
### Simple install (no sudo required, runs as current user)
|
|
@@ -107,7 +107,7 @@ direct symlink from `dsarch` to `setuid_dsarch`:
|
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
109
|
pip install rda_python_dsarch
|
|
110
|
-
pywrapper-install
|
|
110
|
+
pywrapper-install -l dsarch -s
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
## Runtime flow
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/requires.txt
RENAMED
|
File without changes
|
{rda_python_setuid-1.0.4 → rda_python_setuid-1.0.5}/src/rda_python_setuid.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|