From c295f55d571fa6ec34643924efb225d8b153a8f6 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 28 Jun 2009 21:11:51 -0400 Subject: [PATCH] Fix possibly vulnerable ldap code to use better kernel hooks. However, this means you can't test these without a kernel with the scripts AFS patch. Signed-off-by: Edward Z. Yang --- TODO | 3 +++ wizard/command/massmigrate.py | 8 +++++--- wizard/shell.py | 6 ++++-- wizard/tests/util_test.py | 13 ++++++------- wizard/util.py | 23 ++++------------------- 5 files changed, 22 insertions(+), 31 deletions(-) diff --git a/TODO b/TODO index 42f981a..0b67f34 100644 --- a/TODO +++ b/TODO @@ -271,3 +271,6 @@ git tag v1.2.3-scripts * Make 'wizard summary' generate nice pretty graphs of installs by date (more histograms, will need to check actual .scripts-version files.) + +* Update AFS patch to advertise its existence, so we can check for it + here. diff --git a/wizard/command/massmigrate.py b/wizard/command/massmigrate.py index 675003f..f6f4c8a 100644 --- a/wizard/command/massmigrate.py +++ b/wizard/command/massmigrate.py @@ -43,8 +43,8 @@ stat every install to find out if it migrated it yet). if not options.debug: base_args.append("--quiet") # check if we have root - uid = os.getuid() - user = None + my_uid = os.getuid() + uid = None # dry run is purposely omitted if options.no_parallelize: sh = shell.DummyParallelShell(logger=logger) @@ -79,9 +79,11 @@ stat every install to find out if it migrated it yet). logger.error("%s in %s" % (name, d.location)) return (on_success, on_error) on_success, on_error = make_on_pair(d) + if not my_uid: + uid = get_dir_uid(d.location) sh.wait() # wait for a parallel processing slot to be available sh.callAsUser(shell.wizard, "migrate", d.location, *base_args, - user=user, on_success=on_success, on_error=on_error) + uid=uid, on_success=on_success, on_error=on_error) sh.join() for name, deploys in errors.items(): logger.warning("%s from %d installs" % (name, len(deploys))) diff --git a/wizard/shell.py b/wizard/shell.py index 4debb8c..4b1d702 100644 --- a/wizard/shell.py +++ b/wizard/shell.py @@ -70,9 +70,11 @@ class Shell(object): self.logger.debug("STDERR: " + stderr) def callAsUser(self, *args, **kwargs): user = kwargs.pop("user", None) + uid = kwargs.pop("uid", None) kwargs.setdefault("python", is_python(args)) - if not user: return self.call(*args, **kwargs) - return self.call("sudo", "-u", user, *args, **kwargs) + if not user and not uid: return self.call(*args, **kwargs) + if uid: return self.call("sudo", "-u", "#" + uid, *args, **kwargs) + if user: return self.call("sudo", "-u", user, *args, **kwargs) class ParallelShell(Shell): """Commands are queued here, and executed in parallel (with diff --git a/wizard/tests/util_test.py b/wizard/tests/util_test.py index ad77c88..c34abba 100644 --- a/wizard/tests/util_test.py +++ b/wizard/tests/util_test.py @@ -9,14 +9,13 @@ class MyError(Exception): ERROR: Foo """ -def test_get_dir_user(): - assert get_dir_user("/mit/ezyang/web_scripts/test-wiki") == "ezyang" +def test_get_dir_uid(): + if os.getuid(): return # only run if on a scripts server. This is crude + assert get_dir_uid("/mit/ezyang/web_scripts/test-wiki") == 537864399 -def test_get_dir_user_locker(): - assert get_dir_user("/mit/apo/web_scripts/") == "apo" - -def test_get_dir_url(): - assert get_dir_url("/mit/ezyang/web_scripts/foo") == "http://ezyang.scripts.mit.edu/foo" +def test_get_dir_uid_locker(): + if os.getuid(): return + assert get_dir_uid("/mit/apo/web_scripts/") == 536956980 def test_get_exception_name(): try: diff --git a/wizard/util.py b/wizard/util.py index dddbb34..6b348f2 100644 --- a/wizard/util.py +++ b/wizard/util.py @@ -1,5 +1,5 @@ import os.path -import ldap +import os def get_exception_name(output): """Reads the stderr output of another Python command and grabs the @@ -13,22 +13,7 @@ def get_exception_name(output): else: return line -def get_dir_user(dir): - """Finds the username of the person who owns this directory, via LDAP. - Only works for directories under web_scripts""" - dir = os.path.realpath(dir) - homedir, _, _ = dir.partition("/web_scripts") - if homedir == dir: return None - con = ldap.initialize('ldap://scripts.mit.edu') - return con.search_s( - "ou=People,dc=scripts,dc=mit,dc=edu", # base - ldap.SCOPE_SUBTREE, # default - "homeDirectory=" + homedir, # search - ['uid'] # attr - )[0][1]["uid"][0] # unwrap the result - -def get_dir_url(dir): - """Finds the URL a path would correspond to in the filesystem""" - _, _, path = dir.partition("/web_scripts") - return "http://%s.scripts.mit.edu%s" % (get_dir_user(dir), path) +def get_dir_uid(dir): + """Finds the uid of the person who owns this directory.""" + return os.stat(dir).st_uid -- 2.45.2