summaryrefslogtreecommitdiffstats
path: root/src/lib/kadm5/srv/svr_principal.c
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2003-09-02 15:32:50 +0000
committerAlexandra Ellwood <lxs@mit.edu>2003-09-02 15:32:50 +0000
commit5eef87b8b039c0f6b32005eb363ba4c9a2c2efaa (patch)
tree5a9da6cf8f5816f90c9d541683e44fded849f4e7 /src/lib/kadm5/srv/svr_principal.c
parent595a11922fbe9db810d164b13c203afe78d73851 (diff)
downloadkrb5-5eef87b8b039c0f6b32005eb363ba4c9a2c2efaa.tar.gz
krb5-5eef87b8b039c0f6b32005eb363ba4c9a2c2efaa.tar.xz
krb5-5eef87b8b039c0f6b32005eb363ba4c9a2c2efaa.zip
Added Apple password server support
ticket: 1799 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15803 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/kadm5/srv/svr_principal.c')
-rw-r--r--src/lib/kadm5/srv/svr_principal.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index c1b8bc59c9..1255e387b6 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -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;