diff --git a/kpasswd/kpasswdd.c b/kpasswd/kpasswdd.c index 967bf93..23dd359 100644 --- a/kpasswd/kpasswdd.c +++ b/kpasswd/kpasswdd.c @@ -41,6 +41,8 @@ RCSID("$Id$"); #include #include +#include + static krb5_context context; static krb5_log_facility *log_facility; @@ -49,6 +51,9 @@ krb5_addresses explicit_addresses; static sig_atomic_t exit_flag = 0; +static PyObject *lib_password = NULL; +static PyObject *lib_password_change = NULL; + static void add_one_address (const char *str, int first) { @@ -253,6 +258,10 @@ change (krb5_auth_context auth_context, krb5_data *pwd_data = NULL; char *tmp; ChangePasswdDataMS chpw; + int ucs_error = -1; + + PyObject *args = NULL, *call = NULL; + PyObject *errobj = NULL, *errdata = NULL, *errtraceback = NULL, *pystring = NULL, *pystring2 = NULL; memset (&conf, 0, sizeof(conf)); memset(&chpw, 0, sizeof(chpw)); @@ -407,6 +416,80 @@ change (krb5_auth_context auth_context, tmp = pwd_data->data; tmp[pwd_data->length - 1] = '\0'; + // Sync password to UCS LDAP + + // lib_password = PyImport_ImportModule("univention.lib.password"); + if (!lib_password) + goto ucs_done; + + // lib_password_change = PyObject_GetAttrString(lib_password, "change"); + if (!lib_password_change) + goto ucs_done; + + tmp = pwd_data->data; + tmp[pwd_data->length - 1] = '\0'; + + args = Py_BuildValue("ss", client, tmp); + if (!args) + goto ucs_done; + + call = PyEval_CallObject(lib_password_change, args); + + if (call == NULL) { + PyErr_Fetch(&errobj, &errdata, &errtraceback); + pystring = PyObject_Str(errobj); + if ( PyString_Check(pystring) ) { + const char *err = PyString_AsString(pystring); + ucs_error = 1; + + if( !strcmp(err, "")) { + krb5_warnx (context, "%s", err); + reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, "Password already used"); + } else if( !strcmp(err, "")) { + krb5_warnx (context,"%s", err); + reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, "Password is too short"); + } else if( !strcmp(err, "")) { + krb5_warnx (context, "%s", err); + pystring2 = PyObject_Str(errdata); + if ( PyString_Check(pystring2) ) { + const char *msg = PyString_AsString(pystring2); + reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, msg); + } else { + reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, "The passwort didn't pass quality check"); + } + } else { + /* + * Ignore all other errors, for example the user is not + * a valid UCS user. + */ + ucs_error = -1; + } + } + } else { + ucs_error = 0; + } + +ucs_done: + Py_XDECREF(errobj); + Py_XDECREF(errdata); + Py_XDECREF(errtraceback); + Py_XDECREF(pystring); + Py_XDECREF(pystring2); + Py_XDECREF(args); + Py_XDECREF(call); + + if ( ucs_error == 0) { + /* change was successful */ + reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SUCCESS, "Password changed"); + krb5_free_data (context, pwd_data); + pwd_data = NULL; + goto out; + } else if ( ucs_error == 1 ) { + /* failed to change the password pwToShort, pwalreadyused or pwQuality */ + krb5_free_data (context, pwd_data); + pwd_data = NULL; + goto out; + } /* else continue the kpasswdd pwd change */ + ret = kadm5_s_chpass_principal_cond (kadm5_handle, principal, 1, tmp); krb5_free_data (context, pwd_data); pwd_data = NULL; @@ -696,6 +773,11 @@ doit(krb5_keytab keytab, int port) struct sockaddr_storage __ss; struct sockaddr *sa = (struct sockaddr *)&__ss; + Py_Initialize(); + lib_password = PyImport_ImportModule("univention.lib.password"); + if (lib_password) + lib_password_change = PyObject_GetAttrString(lib_password, "change"); + if (explicit_addresses.len) { addrs = explicit_addresses; } else { @@ -777,6 +859,11 @@ doit(krb5_keytab keytab, int port) krb5_free_addresses(context, &addrs); krb5_free_context(context); + + Py_XDECREF(lib_password); + Py_XDECREF(lib_password_change); + Py_Finalize(); + return 0; } diff --git a/kpasswd/Makefile.am b/kpasswd/Makefile.am index 7b85dfc..69ef613 100644 --- a/kpasswd/Makefile.am +++ b/kpasswd/Makefile.am @@ -18,6 +18,7 @@ kpasswdd_LDADD = \ $(top_builddir)/lib/kadm5/libkadm5srv.la \ $(top_builddir)/lib/hdb/libhdb.la \ $(LDADD) \ + -lpython2.7 $(LIB_pidfile) \ $(LIB_dlopen) \ $(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)