chiark / gitweb /
Automatically add and remove password database records.
[chopwood] / service.py
index aa773884061f04617826de7b48f2fe0e83431f63..ddd28b9a121cadd76617cdc39ddefb460d42fce7 100644 (file)
@@ -40,11 +40,10 @@ import util as U
 ### Protocol.
 ###
 ### A service is a thing for which a user might have an account, with a login
-### name and password.  The service protocol is fairly straightforward: a
-### password can be set to a particular value using `setpasswd' (which
-### handles details of hashing and so on), or cleared (i.e., preventing
-### logins using a password) using `clearpasswd'.  Services also present
-### `friendly' names, used by the user interface.
+### name and password.  The service protocol is fairly straightforward: there
+### are methods corresponding to the various low-level operations which can
+### be performed on services.  Services also present `friendly' names, used
+### by the user interface.
 ###
 ### A service may be local or remote.  Local services are implemented in
 ### terms of a backend and hashing scheme.  Information about a particular
@@ -76,12 +75,18 @@ class IncorrectPassword (Exception):
 class BasicService (object):
   """
   A simple base class for services.
+
+  The `manage_pwent_p' flag indicates whether administration commands should
+  attempt to add or remove password entries in the corresponding database
+  when users are added or removed.
   """
 
-  def __init__(me, friendly, name = None, *args, **kw):
+  def __init__(me, friendly, name = None, manage_pwent_p = True,
+               *args, **kw):
     super(BasicService, me).__init__(*args)
     me.name = name
     me.friendly = friendly
+    me.manage_pwent_p = manage_pwent_p
     me.meta = kw
 
 ###--------------------------------------------------------------------------
@@ -128,6 +133,10 @@ class Account (object):
     me._rec.passwd = passwd
     me._rec.write()
 
+  def remove(me):
+    """Service protocol: remove the user's password entry."""
+    me._rec.remove()
+
 class LocalService (BasicService):
   """
   A local service has immediate knowledge of a hashing scheme and a password
@@ -162,6 +171,15 @@ class LocalService (BasicService):
     """Service protocol: clear USER's password, preventing logins."""
     me.find(user).clearpasswd()
 
+  def mkpwent(me, user, passwd, fields):
+    """Service protocol: create a record for USER."""
+    if me.hash.NULL is not None: passwd = me.hash.NULL
+    me._be.create(user, passwd, fields)
+
+  def rmpwent(me, user):
+    """Service protocol: delete the record for USER."""
+    me.find(user).remove()
+
 CONF.export('LocalService')
 
 ###--------------------------------------------------------------------------
@@ -300,6 +318,14 @@ class SSHRemoteService (BasicRemoteService):
     """Service protocol: clear the USER's password."""
     me._run_noout(['clear', me.name, user])
 
+  def mkpwent(me, user, passwd, fields):
+    """Service protocol: create a record for USER."""
+    me._run_noout(['mkpwent', user, me.name] + fields, passwd + '\n')
+
+  def rmpwent(me, user):
+    """Service protocol: delete the record for USER."""
+    me._run_noout(['rmpwent', user, me.name])
+
 CONF.export('SSHRemoteService')
 
 class CommandRemoteService (BasicRemoteService):
@@ -380,6 +406,14 @@ class CommandRemoteService (BasicRemoteService):
     """Service protocol: clear the USER's password."""
     me._dispatch(me._run_noout, 'clear', [('u', user)])
 
+  def mkpwent(me, user, passwd, fields):
+    """Service protocol: create a record for USER."""
+    me._dispatch(me._run_noout, 'mkpwent', [('u', user)])
+
+  def rmpwent(me, user):
+    """Service protocol: delete the record for USER."""
+    me._dispatch(me._run_noout, 'rmpwent', [('u', user)])
+
 CONF.export('CommandRemoteService')
 
 ###--------------------------------------------------------------------------