Use GlobalDir instead of GenerateDir in one place
[mirror/userdir-ldap.git] / ud-mailgate
index f3752ec..30c9514 100755 (executable)
@@ -9,6 +9,7 @@
 
 import userdir_gpg, userdir_ldap, sys, traceback, time, ldap, os, commands
 import pwd, tempfile
+import subprocess
 
 from userdir_gpg import *
 from userdir_ldap import *
@@ -40,12 +41,12 @@ ValidHostNames = [] # will be initialized in later
 SSHFingerprint = re.compile('^(\d+) ([0-9a-f\:]{47}) (.+)$')
 SSHRSA1Match = re.compile('^^(.* )?\d+ \d+ \d+')
 
-GenderTable = {"male": 1,
-              "1": 1,
-              "female": 2,
-              "2": 2,
-              "unspecified": 9,
-              "9": 9,
+GenderTable = {"male": '1',
+              "1": '1',
+              "female": '2',
+              "2": '2',
+              "unspecified": '9',
+              "9": '9',
 };
 
 ArbChanges = {"c": "..",
@@ -505,6 +506,9 @@ def FinishConfirmSudopassword(l, uid, Attrs):
    global SudoPasswd
    result = "\n"
 
+   if len(SudoPasswd) == 0:
+       return None
+
    res = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid="+uid, ['sudoPassword']);
    if len(res) != 1:
       raise UDFormatError, "Not exactly one hit when searching for user"
@@ -568,6 +572,8 @@ def connect_to_ldap_and_check_if_locked(DnRecord):
              or GetAttr(Attrs[0],"userPassword").startswith("!"):
       raise UDNotAllowedError, "This account is locked";
 
+   return l
+
 # Handle an [almost] arbitary change
 def HandleChange(Reply,DnRecord,Key):
    global PlainText;
@@ -611,7 +617,8 @@ def HandleChange(Reply,DnRecord,Key):
    if CommitChanges == 1: # only if we are still good to go
       try:
          Res = FinishConfirmSudopassword(l, GetAttr(DnRecord,"uid"), Attrs)
-         Result = Result + Res + "\n";
+         if not Res is None:
+            Result = Result + Res + "\n";
       except Error, e:
          CommitChanges = 0
          Result = Result + "FinishConfirmSudopassword raised an error (%s) - no changes committed\n"%(e);
@@ -690,6 +697,44 @@ def HandleChPass(Reply,DnRecord,Key):
 
    return Reply;
 
+def HandleChKrbPass(Reply,DnRecord,Key):
+   # Connect to the ldap server, will throw an exception if account locked.
+   l = connect_to_ldap_and_check_if_locked(DnRecord)
+
+   user = GetAttr(DnRecord,"uid")
+   krb_proc = subprocess.Popen( ('ud-krb-reset', user), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+   krb_proc.stdin.close()
+   out = krb_proc.stdout.readlines()
+   krb_proc.wait()
+   exitcode = krb_proc.returncode
+
+   # Use GPG to encrypt it
+   m = "Tried to reset your kerberos principal's password.\n"
+   if exitcode == 0:
+      m += "The exitcode of the reset script was zero, indicating that everything\n"
+      m += "worked.  However, this being software who knows.  Script's output below."
+   else:
+      m += "The exitcode of the reset script was %d, indicating that something\n"%(exitcode)
+      m += "went terribly, terribly wrong.  Please consult the script's output below\n"
+      m += "for more information.  Contact the admins if you have any questions or\n"
+      m += "require assitance."
+
+   m += "\n"+''.join( map(lambda x: "| "+x, out)  )
+
+   Message = GPGEncrypt(m, "0x"+Key[1],Key[4]);
+   if Message == None:
+      raise UDFormatError, "Unable to generate the encrypted reply, gpg failed.";
+
+   Subst = {};
+   Subst["__FROM__"] = ChPassFrom;
+   Subst["__EMAIL__"] = EmailAddress(DnRecord);
+   Subst["__CRYPTTYPE__"] = get_crypttype_preamble(Key)
+   Subst["__PASSWORD__"] = Message;
+   Subst["__ADMIN__"] = ReplyTo;
+   Reply = Reply + TemplateSubst(Subst,open(TemplatesDir+"passwd-changed","r").read());
+
+   return Reply;
+
 # Start of main program
 
 # Drop messages from a mailer daemon.
@@ -787,8 +832,10 @@ try:
    if sys.argv[1] == "ping":
       Reply = HandlePing(Reply,Attrs[0],pgp.key_info);
    elif sys.argv[1] == "chpass":
-      if PlainText.strip().find("Please change my Debian password"):
+      if PlainText.strip().find("Please change my Debian password") >= 0:
          Reply = HandleChPass(Reply,Attrs[0],pgp.key_info);
+      elif PlainText.strip().find("Please change my Kerberos password") >= 0:
+         Reply = HandleChKrbPass(Reply,Attrs[0],pgp.key_info);
       else:
          raise UDFormatError,"Please send a signed message where the first line of text is the string 'Please change my Debian password' or some other string we accept here.";
    elif sys.argv[1] == "change":