diff --git a/src/PyKAdminPrincipalObject.c b/src/PyKAdminPrincipalObject.c index 55fe61eaa4535654e4ea8d933362cb4d982ee827..5adbc993e4c13fc1ddcce59f3c7b33755ebd45d5 100644 --- a/src/PyKAdminPrincipalObject.c +++ b/src/PyKAdminPrincipalObject.c @@ -285,9 +285,72 @@ cleanup: return result; } +/* taken from mit-krb5 kadmin.c - why's it in kadmin.c and not libkadm5 + * anyways? */ +/* Construct a tl_data element and add it to the tail of *tl_datap. */ +static int +add_tl_data(krb5_int16 *n_tl_datap, krb5_tl_data **tl_datap, + krb5_int16 tl_type, krb5_ui_2 len, krb5_octet *contents) +{ + krb5_tl_data *tl_data; + krb5_octet *copy; + + copy = malloc(len); + tl_data = calloc(1, sizeof(*tl_data)); + if (copy == NULL || tl_data == NULL) + return ENOMEM; + memcpy(copy, contents, len); + + tl_data->tl_data_type = tl_type; + tl_data->tl_data_length = len; + tl_data->tl_data_contents = copy; + tl_data->tl_data_next = NULL; + + for (; *tl_datap != NULL; tl_datap = &(*tl_datap)->tl_data_next); + *tl_datap = tl_data; + (*n_tl_datap)++; + + return 0; +} + +/* taken from k5-platform.h */ +static inline void +store_32_le (unsigned int val, void *vp) +{ + unsigned char *p = (unsigned char *) vp; + p[3] = (val >> 24) & 0xff; + p[2] = (val >> 16) & 0xff; + p[1] = (val >> 8) & 0xff; + p[0] = (val ) & 0xff; +} static PyObject *PyKAdminPrincipal_unlock(PyKAdminPrincipalObject *self) { - return NULL; + krb5_error_code retval; + krb5_timestamp now; + krb5_octet timebuf[4]; + + /* Zero out the failed auth count. */ + self->entry.fail_auth_count = 0; + self->mask |= KADM5_FAIL_AUTH_COUNT; + + /* Record the timestamp of this unlock operation so that slave KDCs will + * see it, since fail_auth_count is unreplicated. */ + retval = krb5_timeofday(self->kadmin->context, &now); + if (retval) { + PyKAdminError_raise_error(retval, "krb5_timeofday"); + return NULL; + } + store_32_le((krb5_int32)now, timebuf); + retval = add_tl_data(&self->entry.n_tl_data, &self->entry.tl_data, + KRB5_TL_LAST_ADMIN_UNLOCK, 4, timebuf); + if (retval) { + PyKAdminError_raise_error(retval, "add_tl_data"); + return NULL; + } + + self->mask |= KADM5_TL_DATA; + + Py_RETURN_TRUE; }