From 5eef87b8b039c0f6b32005eb363ba4c9a2c2efaa Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Tue, 2 Sep 2003 15:32:50 +0000 Subject: [PATCH] Added Apple password server support ticket: 1799 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15803 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin/server/ChangeLog | 4 + src/kadmin/server/ovsec_kadmd.c | 11 ++ src/lib/kadm5/srv/ChangeLog | 4 + src/lib/kadm5/srv/svr_principal.c | 145 ++++++++++++++++++ .../MacOSX/Scripts/Kerberos5ServerBuild.jam | 4 +- 5 files changed, 166 insertions(+), 2 deletions(-) diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog index 7c363fbcc..f5f29f644 100644 --- a/src/kadmin/server/ChangeLog +++ b/src/kadmin/server/ChangeLog @@ -1,3 +1,7 @@ +2003-09-02 Alexandra Ellwood + + * ovsec_kadmd.c: Added Apple password server support. + 2003-08-29 Ken Raeburn * Makefile.in (OBJS): Use @LIBOBJS@. diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c index 290af20ee..4510b1bb7 100644 --- a/src/kadmin/server/ovsec_kadmd.c +++ b/src/kadmin/server/ovsec_kadmd.c @@ -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) diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index 5c53f6011..eea698794 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,7 @@ +2003-09-02 Alexandra Ellwood + + * svr_principal.c: Added Apple password server support. + 2003-06-13 Tom Yu * server_kdb.c (kdb_init_hist): Force history principal's key to diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index c1b8bc59c..1255e387b 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 #include +#ifdef USE_PASSWORD_SERVER +#include +#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; diff --git a/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam b/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam index 7e1a33c56..d4a969843 100644 --- a/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam +++ b/src/mac/MacOSX/Scripts/Kerberos5ServerBuild.jam @@ -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) != "" { -- 2.26.2