Added Apple password server support
authorAlexandra Ellwood <lxs@mit.edu>
Tue, 2 Sep 2003 15:32:50 +0000 (15:32 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Tue, 2 Sep 2003 15:32:50 +0000 (15:32 +0000)
ticket: 1799

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15803 dc483132-0cff-0310-8789-dd5450dbe970

src/kadmin/server/ChangeLog
src/kadmin/server/ovsec_kadmd.c
src/lib/kadm5/srv/ChangeLog
src/lib/kadm5/srv/svr_principal.c
src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam

index 7c363fbcc2c154bf8cb4ac96a34504cf63fe369c..f5f29f644a4d6f87892e141580f97f4bcef2627c 100644 (file)
@@ -1,3 +1,7 @@
+2003-09-02  Alexandra Ellwood  <lxs@mit.edu>
+
+       * ovsec_kadmd.c: Added Apple password server support.
+
 2003-08-29  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.in (OBJS): Use @LIBOBJS@.
index 290af20eebbc2774459a4ff51de39f3a58034477..4510b1bb7a8784d14db99bfbccc670b6da2e6ae4 100644 (file)
@@ -113,6 +113,10 @@ void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
 int schpw;
 void do_schpw(int s, kadm5_config_params *params);
 
+#ifdef USE_PASSWORD_SERVER
+void kadm5_set_use_password_server (void);
+#endif
+
 /*
  * Function: usage
  * 
@@ -127,6 +131,9 @@ void do_schpw(int s, kadm5_config_params *params);
 static void usage()
 {
      fprintf(stderr, "Usage: kadmind [-r realm] [-m] [-nofork] "
+#ifdef USE_PASSWORD_SERVER
+             "[-passwordserver] "
+#endif
             "[-port port-number]\n");
      exit(1);
 }
@@ -242,6 +249,10 @@ int main(int argc, char *argv[])
               params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
          } else if (strcmp(*argv, "-nofork") == 0) {
               nofork = 1;
+#ifdef USE_PASSWORD_SERVER
+          } else if (strcmp(*argv, "-passwordserver") == 0) {
+              kadm5_set_use_password_server ();
+#endif              
          } else if(strcmp(*argv, "-port") == 0) {
            argc--; argv++;
            if(!argc)
index 5c53f6011c4036a4311a945275c9c1e42757dc34..eea698794f8715f08b7087e68eed10f15aef2e9f 100644 (file)
@@ -1,3 +1,7 @@
+2003-09-02  Alexandra Ellwood  <lxs@mit.edu>
+
+       * svr_principal.c: Added Apple password server support.
+
 2003-06-13  Tom Yu  <tlyu@mit.edu>
 
        * server_kdb.c (kdb_init_hist): Force history principal's key to
index c1b8bc59c9c4ef014935982a411ff458214167d4..1255e387b6a5fc144405a864fd10824a72333435 100644 (file)
@@ -19,6 +19,9 @@ static char *rcsid = "$Header$";
 #include       "server_internal.h"
 #include       <stdarg.h>
 #include       <stdlib.h>
+#ifdef USE_PASSWORD_SERVER
+#include       <sys/wait.h>
+#endif
 
 extern krb5_principal      master_princ;
 extern krb5_principal      hist_princ;
@@ -1065,6 +1068,112 @@ static kadm5_ret_t add_to_history(krb5_context context,
 }
 #undef KADM_MOD
 
+#ifdef USE_PASSWORD_SERVER
+
+/* FIXME: don't use global variable for this */
+krb5_boolean use_password_server = 0;
+
+static krb5_boolean
+kadm5_use_password_server (void)
+{
+    return use_password_server;
+}
+
+void
+kadm5_set_use_password_server (void)
+{
+    use_password_server = 1;
+}
+
+/*
+ * kadm5_launch_task () runs a program (task_path) to synchronize the 
+ * Apple password server with the Kerberos database.  Password server
+ * programs can receive arguments on the command line (task_argv)
+ * and a block of data via stdin (data_buffer).  On success, they
+ * return one of the result codes listed in success_codes.
+ *
+ * Because a failure to communicate with the tool results in the
+ * password server falling out of sync with the database,
+ * kadm5_launch_task() always fails if it can't talk to the tool.
+ */
+
+static kadm5_ret_t
+kadm5_launch_task (krb5_context context,
+                   const char *task_path, char * const task_argv[],
+                   const char *data_buffer) 
+{
+    kadm5_ret_t ret = 0;
+    int data_pipe[2];
+    
+    if (data_buffer != NULL) {
+        ret = pipe (data_pipe);
+        if (ret) { ret = errno; }
+    }
+
+    if (!ret) {
+        pid_t pid = fork ();
+        if (pid == -1) {
+            ret = errno;
+        } else if (pid == 0) {
+            /* The child: */
+            
+            if (data_buffer != NULL) {
+                if (dup2 (data_pipe[0], STDIN_FILENO) == -1) {
+                    _exit (1);
+                }
+            } else {
+                close (data_pipe[0]);
+            }
+
+            close (data_pipe[1]);
+            
+            execv (task_path, task_argv);
+            
+            _exit (1); /* Fail if execv fails */
+        } else {
+            /* The parent: */
+            
+            if (data_buffer != NULL) {
+                /* Write out the buffer to the child */
+                if (krb5_net_write (context, data_pipe[1],
+                                    data_buffer, strlen (data_buffer)) < 0) {
+                    ret = errno;
+                }
+            }
+
+            close (data_buffer[0]);
+            close (data_buffer[1]);
+
+            if (!ret) {
+                int status = 0;
+
+                waitpid (pid, &status, 0);
+
+                /* fprintf (stderr, "Call \"%s\" returned status %d\n", argv[2],
+                    WEXITSTATUS(status)); */
+
+                if (WIFEXITED (status)) {
+                    /* task finished.  Check return value */
+                    if ((WEXITSTATUS (status) != 0) && (WEXITSTATUS (status) != 252)) {
+                       ret = KRB5KDC_ERR_POLICY; /* password change rejected */
+                    }
+                } else {
+                    /* task crashed or was killed */
+                    ret = KRB5KRB_ERR_GENERIC; /* FIXME: better error */
+                }
+            } else {
+                /* since the password write failed, just try and kill the child
+                 * process in order to clean up (it may already be gone). */
+                kill (pid, SIGKILL);
+            }
+        }
+    }
+
+    return ret;
+}
+
+#endif
+
 kadm5_ret_t
 kadm5_chpass_principal(void *server_handle,
                            krb5_principal principal, char *password)
@@ -1193,6 +1302,42 @@ kadm5_chpass_principal_3(void *server_handle,
        kdb.pw_expiration = 0;
     }
 
+#ifdef USE_PASSWORD_SERVER
+    if (kadm5_use_password_server () &&
+        (krb5_princ_size (handle->context, principal) == 1)) {
+        krb5_data *princ = krb5_princ_component (handle->context, principal, 0);
+        const char *path = "/usr/sbin/mkpassdb";
+        char *argv[] = { "mkpassdb", "-setpassword", NULL, NULL };
+        char *pstring = NULL;
+        char pwbuf[256];
+        int pwlen = strlen (password);
+
+        if (pwlen > 254) pwlen = 254;
+        strncpy (pwbuf, password, pwlen);
+        pwbuf[pwlen] = '\n';
+        pwbuf[pwlen + 1] = '\0';
+
+        if (!ret) {
+            pstring = malloc ((princ->length + 1) * sizeof (char));
+            if (pstring == NULL) { ret = errno; }
+        }
+
+        if (!ret) {
+            memcpy (pstring, princ->data, princ->length);
+            pstring [princ->length] = '\0';
+            argv[2] = pstring;
+
+            ret = kadm5_launch_task (handle->context, path, argv, pwbuf);
+        }
+        
+        if (pstring != NULL)
+            free (pstring);
+        
+        if (ret)
+            goto done;
+    }
+#endif
+
     ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now);
     if (ret)
        goto done;
index 7e1a33c56add5ac66255d00737d60856a3c82021..d4a96984352224f700878a24cc9ef08492e36035 100644 (file)
@@ -8,9 +8,9 @@ Makefile = "$(IntermediateBuild)/Makefile" ;
 MakeStamp = "$(IntermediateBuild)/make.stamp" ;
 
 if $(KerberosCFLAGS) != "" { 
-    KerberosCFLAGS = "CFLAGS=$(CFLAGS) -fno-common -include /usr/include/TargetConditionals.h" ; 
+    KerberosCFLAGS = "CFLAGS=$(CFLAGS) -fno-common -include /usr/include/TargetConditionals.h -DUSE_PASSWORD_SERVER" ; 
 } else {
-    KerberosCFLAGS = "CFLAGS=-fno-common -include /usr/include/TargetConditionals.h" ;
+    KerberosCFLAGS = "CFLAGS=-fno-common -include /usr/include/TargetConditionals.h -DUSE_PASSWORD_SERVER" ;
 }
 
 if $(KerberosLDFLAGS) != "" {