chiark / gitweb /
chpwd, subcommand.py: Only show global options in admin context help.
[chopwood] / chpwd
diff --git a/chpwd b/chpwd
index 65ae8739ea2ac86fb4635658e68c75602191c6d4..07fe830a85b4bc920afebf9692f5dfc0fb6c0b0f 100755 (executable)
--- a/chpwd
+++ b/chpwd
@@ -30,6 +30,7 @@ import optparse as OP
 import os as OS; ENV = OS.environ
 import shlex as SL
 import sys as SYS
+import syslog as L
 
 from auto import HOME, VERSION
 import cgi as CGI
@@ -83,6 +84,19 @@ for short, long, props in [
     'help': "impersonate USER, and default context to `userv'." })]:
   OPTPARSE.add_option(short, long, **props)
 
+def parse_options():
+  """
+  Parse the main command-line options, returning the positional arguments.
+  """
+  global OPTS
+  OPTS, args = OPTPARSE.parse_args()
+  OPTPARSE.show_global_opts = False
+  ## It's tempting to load the configuration here.  Don't do that.  Some
+  ## contexts will want to check that the command line was handled properly
+  ## upstream before believing it for anything, such as executing arbitrary
+  ## Python code.
+  return args
+
 ###--------------------------------------------------------------------------
 ### CGI dispatch.
 
@@ -95,10 +109,9 @@ CGI.SPECIAL['%user'] = None
 ## issuing redirects in the early setup phase fails because we don't know
 ## the script name.  So package the setup here.
 def cgi_setup(ctx = 'cgi-noauth'):
-  global OPTS
   if OPTS: return
   OPTPARSE.context = ctx
-  OPTS, args = OPTPARSE.parse_args()
+  args = parse_options()
   if args: raise U.ExpectedError, (500, 'Unexpected arguments to CGI')
   CONF.loadconfig(OPTS.config)
   D.opendb()
@@ -200,24 +213,30 @@ def cli_errors():
 
 if __name__ == '__main__':
 
+  L.openlog(OS.path.basename(SYS.argv[0]), 0, L.LOG_AUTH)
+
   if 'REQUEST_METHOD' in ENV:
     ## This looks like a CGI request.  The heavy lifting for authentication
     ## over HTTP is done in `dispatch_cgi'.
 
     with OUT.redirect_to(CGI.HTTPOutput()):
-      with CGI.cgi_errors(cgi_setup): dispatch_cgi()
+      with U.Escape() as CGI.HEADER_DONE:
+        with CGI.cgi_errors(cgi_setup):
+          dispatch_cgi()
 
   elif 'USERV_SERVICE' in ENV:
     ## This is a Userv request.  The caller's user name is helpfully in the
     ## `USERV_USER' environment variable.
 
     with cli_errors():
-      OPTS, args = OPTPARSE.parse_args()
+      args = parse_options()
+      if not args or args[0] != 'userv':
+        raise U.ExpectedError, (500, 'missing userv token')
       CONF.loadconfig(OPTS.config)
       try: CU.set_user(ENV['USERV_USER'])
       except KeyError: raise ExpectedError, (500, 'USERV_USER unset')
       with OUT.redirect_to(O.FileOutput()):
-        OPTPARSE.dispatch('userv', [ENV['USERV_SERVICE']] + args)
+        OPTPARSE.dispatch('userv', [ENV['USERV_SERVICE']] + args[1:])
 
   elif 'SSH_ORIGINAL_COMMAND' in ENV:
     ## This looks like an SSH request; but we present two different
@@ -226,8 +245,7 @@ if __name__ == '__main__':
 
     def ssh_setup():
       """Extract and parse the client's request from where SSH left it."""
-      global OPTS
-      OPTS, args = OPTPARSE.parse_args()
+      args = parse_options()
       CONF.loadconfig(OPTS.config)
       cmd = SL.split(ENV['SSH_ORIGINAL_COMMAND'])
       if args: raise U.ExpectedError, (500, 'Unexpected arguments via SSH')
@@ -240,7 +258,6 @@ if __name__ == '__main__':
       with cli_errors():
         cmd = ssh_setup()
         CU.set_user(ENV['CHPWD_SSH_USER'])
-        S.SERVICES['master'].find(CU.USER)
         with OUT.redirect_to(O.FileOutput()):
           OPTPARSE.dispatch('userv', cmd)
 
@@ -273,7 +290,7 @@ if __name__ == '__main__':
     ## as we are.
 
     with cli_errors():
-      OPTS, args = OPTPARSE.parse_args()
+      args = parse_options()
       CONF.loadconfig(OPTS.config)
       CGI.SSLP = OPTS.sslp
       ctx = OPTS.context
@@ -283,7 +300,9 @@ if __name__ == '__main__':
         if ctx is None: ctx = 'userv'
       else:
         D.opendb()
-        if ctx is None: ctx = 'admin'
+        if ctx is None:
+          ctx = 'admin'
+          OPTPARSE.show_global_opts = True
       with OUT.redirect_to(O.FileOutput()):
         OPTPARSE.dispatch(ctx, args)