From 7f05a4a3440ef9f75bfc935483977f97dd1c422e Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 8 Jul 2014 13:34:15 -0400 Subject: [PATCH 01/25] prep for policy additions, added compare function to common --- PyKAdminCommon.c | 18 ++++++++++++++++++ PyKAdminCommon.h | 2 +- PyKAdminPolicyObject.c | 3 ++- PyKAdminPolicyObject.h | 22 +++++++++++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index 638a508..c038eba 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -354,6 +354,24 @@ int pykadmin_principal_ent_rec_compare(krb5_context ctx, kadm5_principal_ent_rec return result; } +int pykadmin_policy_ent_rec_compare(krb5_context ctx, kadm5_policy_ent_rec *a, kadm5_policy_ent_rec *b) { + + int result = 1; + + result &= (strcmp(a->policy, b->policy) == 0); + + result &= (a->pw_min_life == b->pw_min_life); + result &= (a->pw_max_life == b->pw_max_life); + result &= (a->pw_min_length == b->pw_min_length); + result &= (a->pw_min_classes == b->pw_min_classes); + result &= (a->pw_history_num == b->pw_history_num); + result &= (a->policy_refcnt == b->policy_refcnt); + result &= (a->pw_max_fail == b->pw_max_fail); + result &= (a->pw_failcnt_interval == b->pw_failcnt_interval); + result &= (a->pw_lockout_duration == b->pw_lockout_duration); + + return result; +} /* krb5_error_code pykadmin_copy_kadm_ent_rec(PyKAdminObject *kadmin, kadm5_principal_ent_rec *src, kadm5_principal_ent_rec *dst) { diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index 35dd6d9..c8d45d7 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -14,7 +14,7 @@ krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); int pykadmin_principal_ent_rec_compare(krb5_context ctx, kadm5_principal_ent_rec *a, kadm5_principal_ent_rec *b); - +int pykadmin_policy_ent_rec_compare(krb5_context ctx, kadm5_policy_ent_rec *a, kadm5_policy_ent_rec *b); // TODO //krb5_error_code pykadmin_copy_kadm_ent_rec(PyKAdminObject *kadmin, kadm5_principal_ent_rec *src, kadm5_principal_ent_rec *dst); diff --git a/PyKAdminPolicyObject.c b/PyKAdminPolicyObject.c index 7dce287..586896e 100644 --- a/PyKAdminPolicyObject.c +++ b/PyKAdminPolicyObject.c @@ -16,7 +16,8 @@ static PyObject *PyKAdminPolicyObject_new(PyTypeObject *type, PyObject *args, Py self = (PyKAdminPolicyObject *)type->tp_alloc(type, 0); - if (self != NULL) { + if (self) { + } return (PyObject *)self; diff --git a/PyKAdminPolicyObject.h b/PyKAdminPolicyObject.h index 18611cf..e8b61de 100644 --- a/PyKAdminPolicyObject.h +++ b/PyKAdminPolicyObject.h @@ -11,6 +11,24 @@ extern time_t get_date(char *); +/* +typedef struct _kadm5_policy_ent_t { + char *policy; + long pw_min_life; + long pw_max_life; + long pw_min_length; + long pw_min_classes; + long pw_history_num; + long policy_refcnt; + + // version 3 fields + int32 krb5_kvno pw_max_fail; + int32 krb5_deltat pw_failcnt_interval; + int32 krb5_deltat pw_lockout_duration; +} kadm5_policy_ent_rec, *kadm5_policy_ent_t; +*/ + + typedef struct { PyObject_HEAD PyKAdminObject *kadmin; @@ -19,7 +37,9 @@ typedef struct { PyTypeObject PyKAdminPolicyObject_Type; -PyKAdminPolicyObject *PyKAdminPolicyObject_create(PyKAdminObject *kadmin, char *name); +PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name); + +//PyKAdminPolicyObject *PyKAdminPolicyObject_create(PyKAdminObject *kadmin, char *name); void PyKAdminPolicyObject_destroy(PyKAdminPolicyObject *self); #endif From c81c182b31f431c59b5c0430692f43d8096d566a Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 8 Jul 2014 14:05:21 -0400 Subject: [PATCH 02/25] policy iteration and unpacking via common --- PyKAdminCommon.c | 62 ++++++++++++++++++++++++++++++++ PyKAdminCommon.h | 2 ++ PyKAdminObject.c | 60 ++++++++++++++++++++++++++++++- PyKAdminPolicyObject.c | 81 ++++++++++++++++++++++++++++++++++++++---- PyKAdminPolicyObject.h | 24 +++---------- 5 files changed, 202 insertions(+), 27 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index c038eba..a684883 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -265,6 +265,68 @@ krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kd } + +/* +typedef struct _kadm5_policy_ent_t { + char *policy; + long pw_min_life; + long pw_max_life; + long ; + long ; + long ; + long ; + + // version 3 fields + int32 krb5_kvno pw_max_fail; + int32 krb5_deltat pw_failcnt_interval; + int32 krb5_deltat pw_lockout_duration; +} kadm5_policy_ent_rec, *kadm5_policy_ent_t; + +typedef struct _osa_policy_ent_t { + int version; + char *name; + krb5_ui_4 pw_min_life; + krb5_ui_4 pw_max_life; + krb5_ui_4 pw_min_length; + krb5_ui_4 pw_min_classes; + krb5_ui_4 pw_history_num; + krb5_ui_4 policy_refcnt; + + // Only valid if version > 1 + krb5_ui_4 pw_max_fail; // pwdMaxFailure + krb5_ui_4 pw_failcnt_interval; // pwdFailureCountInterval + krb5_ui_4 pw_lockout_duration; // pwdLockoutDuration +} osa_policy_ent_rec, *osa_policy_ent_t; + + +*/ + + +krb5_error_code pykadmin_policy_kadm_from_osa(krb5_context ctx, osa_policy_ent_rec *osa, kadm5_policy_ent_rec *entry, long mask) { + + krb5_error_code retval = 0; + + memset(entry, 0, sizeof(kadm5_policy_ent_rec)); + + entry->policy = strdup(osa->name); + entry->pw_min_life = osa->pw_min_life; + entry->pw_max_life = osa->pw_max_life; + entry->pw_min_length = osa->pw_min_length; + entry->pw_min_classes = osa->pw_min_classes; + entry->pw_history_num = osa->pw_history_num; + entry->policy_refcnt = osa->policy_refcnt; + + if (osa->version > 1) { + entry->pw_max_fail = osa->pw_max_fail; + entry->pw_failcnt_interval = osa->pw_failcnt_interval; + entry->pw_lockout_duration = osa->pw_lockout_duration; + } + + return retval; +} + + + int pykadmin_compare_tl_data(krb5_context ctx, krb5_tl_data *a, krb5_tl_data *b) { int result = 1; diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index c8d45d7..be4d5cb 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -13,6 +13,8 @@ krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); +krb5_error_code pykadmin_policy_kadm_from_osa(krb5_context ctx, osa_policy_ent_rec *osa, kadm5_policy_ent_rec *entry, long mask); + int pykadmin_principal_ent_rec_compare(krb5_context ctx, kadm5_principal_ent_rec *a, kadm5_principal_ent_rec *b); int pykadmin_policy_ent_rec_compare(krb5_context ctx, kadm5_policy_ent_rec *a, kadm5_policy_ent_rec *b); diff --git a/PyKAdminObject.c b/PyKAdminObject.c index a531a62..5b06e1d 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -260,15 +260,72 @@ static void kdb_iter_pols(void *data, osa_policy_ent_rec *entry) { PyKAdminObject *self = (PyKAdminObject *)data; + PyObject *result = NULL; + + PyKAdminPolicyObject *policy = PyKAdminPolicyObject_policy_with_osa_entry(self, entry); + + if (policy) { + + if (self->each_policy.callback) { + + result = PyObject_CallFunctionObjArgs(self->each_policy.callback, policy, self->each_policy.data, NULL); + + if (!result) { + // use self to hold exception + } + + } + PyKAdminPolicyObject_destroy(policy); + } } static PyObject *PyKAdminObject_each_policy(PyKAdminObject *self, PyObject *args, PyObject *kwds) { - return NULL; + + char *match = NULL; + krb5_error_code retval = 0; + kadm5_ret_t lock = 0; + + static char *kwlist[] = {"", "data", "match", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oz", kwlist, &PyFunction_Type, &self->each_policy.callback, &self->each_policy.data, &match)) + return NULL; + + if (!self->each_policy.data) + self->each_policy.data = Py_None; + + Py_XINCREF(self->each_policy.callback); + Py_XINCREF(self->each_policy.data); + + lock = kadm5_lock(self->server_handle); + + if (!lock || (lock == KRB5_PLUGIN_OP_NOTSUPP)) { + + krb5_clear_error_message(self->context); + + retval = krb5_db_iter_policy(self->context, match, kdb_iter_pols, (void *)self); + + if (lock != KRB5_PLUGIN_OP_NOTSUPP) { + lock = kadm5_unlock(self->server_handle); + } + } + + Py_XDECREF(self->each_policy.callback); + Py_XDECREF(self->each_policy.data); + + if (retval) { + // TODO raise proper exception + return NULL; + } + + Py_RETURN_TRUE; + } static PyKAdminPrincipalObject *PyKAdminObject_list_principals(PyKAdminObject *self, PyObject *args, PyObject *kwds) { + + return NULL; } @@ -284,6 +341,7 @@ static PyMethodDef PyKAdminObject_methods[] = { {"create_princ", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, {"create_principal", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, {"list_principals", (PyCFunction)PyKAdminObject_list_principals, METH_VARARGS, ""}, + {"principals", (PyCFunction)PyKAdminObject_principal_iter, (METH_VARARGS | METH_KEYWORDS), ""}, {"policies", (PyCFunction)PyKAdminObject_policy_iter, (METH_VARARGS | METH_KEYWORDS), ""}, diff --git a/PyKAdminPolicyObject.c b/PyKAdminPolicyObject.c index 586896e..efd6cc5 100644 --- a/PyKAdminPolicyObject.c +++ b/PyKAdminPolicyObject.c @@ -17,7 +17,7 @@ static PyObject *PyKAdminPolicyObject_new(PyTypeObject *type, PyObject *args, Py self = (PyKAdminPolicyObject *)type->tp_alloc(type, 0); if (self) { - + } return (PyObject *)self; @@ -33,6 +33,55 @@ static PyMethodDef PyKAdminPolicyObject_methods[] = { {NULL, NULL, 0, NULL} }; +/* +Policy: test_policy +Maximum password life: 0 +Minimum password life: 864000 +Minimum password length: 1 +Minimum number of password character classes: 1 +Number of old keys kept: 1 +Reference count: 0 +Maximum password failures before lockout: 10 +Password failure count reset interval: 0 days 00:00:00 +Password lockout duration: 0 days 00:00:00 +*/ + +static int KAdminPolicyObject_print(PyKAdminPolicyObject *self, FILE *file, int flags){ + // TODO + + return 0; +} + + +PyObject *PyKAdminPolicy_RichCompare(PyObject *o1, PyObject *o2, int opid) { + + PyKAdminPolicyObject *a = (PyKAdminPolicyObject *)o1; + PyKAdminPolicyObject *b = (PyKAdminPolicyObject *)o2; + + PyObject *result = NULL; + + int equal = pykadmin_policy_ent_rec_compare(a->kadmin->context, &a->entry, &b->entry); + + switch (opid) { + + case Py_EQ: + result = ((a == b) || equal) ? Py_True : Py_False; + break; + case Py_NE: + result = ((a != b) && !equal) ? Py_True : Py_False; + break; + case Py_LT: + case Py_LE: + case Py_GT: + case Py_GE: + default: + result = Py_NotImplemented; + } + + Py_XINCREF(result); + return result; +} + PyTypeObject PyKAdminPolicyObject_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ @@ -55,10 +104,10 @@ PyTypeObject PyKAdminPolicyObject_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "KAdmin objects", /* tp_doc */ + "Python KAdmin Policy Object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - 0, /* tp_richcompare */ + PyKAdminPolicy_RichCompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ @@ -75,25 +124,45 @@ PyTypeObject PyKAdminPolicyObject_Type = { PyKAdminPolicyObject_new, /* tp_new */ }; +PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name) { + PyKAdminPolicyObject *policy = NULL; -PyKAdminPolicyObject *PyKAdminPolicyObject_create(PyKAdminObject *kadmin, char *name) { + policy = (PyKAdminPolicyObject *)PyKAdminPolicyObject_new(&PyKAdminPolicyObject_Type, NULL, NULL); + + if (policy) { + Py_XINCREF(kadmin); + policy->kadmin = kadmin; + } + + return policy; +} +PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_osa_entry(PyKAdminObject *kadmin, osa_policy_ent_rec *entry) { + PyKAdminPolicyObject *policy = NULL; + krb5_error_code retval = 0; + policy = (PyKAdminPolicyObject *)PyKAdminPolicyObject_new(&PyKAdminPolicyObject_Type, NULL, NULL); if (policy) { Py_XINCREF(kadmin); policy->kadmin = kadmin; - } - //_KAdminPolicy_load_principal(policy, client_name); + retval = pykadmin_policy_kadm_from_osa(kadmin->context, entry, &policy->entry, 0); + + if (retval) { + // this will never happen for while the above is called. + } + } return policy; } + + void PyKAdminPolicyObject_destroy(PyKAdminPolicyObject *self) { PyKAdminPolicyObject_dealloc(self); } diff --git a/PyKAdminPolicyObject.h b/PyKAdminPolicyObject.h index e8b61de..602217b 100644 --- a/PyKAdminPolicyObject.h +++ b/PyKAdminPolicyObject.h @@ -9,37 +9,21 @@ #include #include -extern time_t get_date(char *); - -/* -typedef struct _kadm5_policy_ent_t { - char *policy; - long pw_min_life; - long pw_max_life; - long pw_min_length; - long pw_min_classes; - long pw_history_num; - long policy_refcnt; - - // version 3 fields - int32 krb5_kvno pw_max_fail; - int32 krb5_deltat pw_failcnt_interval; - int32 krb5_deltat pw_lockout_duration; -} kadm5_policy_ent_rec, *kadm5_policy_ent_t; -*/ +#include "PyKadminCommon.h" +extern time_t get_date(char *); typedef struct { PyObject_HEAD PyKAdminObject *kadmin; - kadm5_policy_ent_rec policy; + kadm5_policy_ent_rec entry; } PyKAdminPolicyObject; PyTypeObject PyKAdminPolicyObject_Type; PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name); +PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_osa_entry(PyKAdminObject *kadmin, osa_policy_ent_rec *entry); -//PyKAdminPolicyObject *PyKAdminPolicyObject_create(PyKAdminObject *kadmin, char *name); void PyKAdminPolicyObject_destroy(PyKAdminPolicyObject *self); #endif From f3f0b2361601976b2256884815c9fb0dde4170cd Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 8 Jul 2014 15:10:56 -0400 Subject: [PATCH 03/25] working on policy, tp_alloc,tp_free not being set properly --- PyKAdminObject.c | 18 ++++++++++++++++++ PyKAdminPolicyObject.c | 38 +++++++++++++++++++++++++++++++++----- PyKAdminPolicyObject.h | 1 + PyKAdminPrincipalObject.c | 13 +++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index 5b06e1d..82d05ef 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -153,6 +153,21 @@ static PyKAdminPrincipalObject *PyKAdminObject_get_principal(PyKAdminObject *sel return principal; } +static PyKAdminPolicyObject *PyKAdminObject_get_policy(PyKAdminObject *self, PyObject *args, PyObject *kwds) { + + PyKAdminPolicyObject *policy = NULL; + char *policy_name = NULL; + + if (!PyArg_ParseTuple(args, "s", &policy_name)) + return NULL; + + if (self->server_handle) { + policy = PyKAdminPolicyObject_policy_with_name(self, policy_name); + } + + return policy; +} + static PyKAdminIterator *PyKAdminObject_principal_iter(PyKAdminObject *self, PyObject *args, PyObject *kwds) { @@ -333,6 +348,9 @@ static PyKAdminPrincipalObject *PyKAdminObject_list_principals(PyKAdminObject *s static PyMethodDef PyKAdminObject_methods[] = { {"getprinc", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, {"get_principal", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, + + {"getpol", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, + {"get_policy", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, {"delprinc", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, {"delete_principal", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, diff --git a/PyKAdminPolicyObject.c b/PyKAdminPolicyObject.c index efd6cc5..a622e92 100644 --- a/PyKAdminPolicyObject.c +++ b/PyKAdminPolicyObject.c @@ -3,11 +3,19 @@ #include "PyKAdminErrors.h" #include "PyKAdminIterator.h" #include "PyKAdminPrincipalObject.h" + #include "PyKAdminPolicyObject.h" static void PyKAdminPolicyObject_dealloc(PyKAdminPolicyObject *self) { - self->ob_type->tp_free((PyObject*)self); + if (self) { + kadm5_free_policy_ent(self->kadmin->server_handle, &self->entry); + + Py_XDECREF(self->kadmin); + + + self->ob_type->tp_free((PyObject*)self); + } } static PyObject *PyKAdminPolicyObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -16,14 +24,26 @@ static PyObject *PyKAdminPolicyObject_new(PyTypeObject *type, PyObject *args, Py self = (PyKAdminPolicyObject *)type->tp_alloc(type, 0); - if (self) { + if (!self) + return NULL; - } + memset(&self->entry, 0, sizeof(kadm5_policy_ent_rec)); return (PyObject *)self; } +static kadm5_ret_t _PyKAdminPolicyObject_load(PyKAdminPolicyObject *self, char *policy_name) { + + kadm5_ret_t retval = 0; + + retval = kadm5_get_policy(self->kadmin->server_handle, policy_name, &self->entry); + + return retval; +} + + + static int PyKAdminPolicyObject_init(PyKAdminPolicyObject *self, PyObject *args, PyObject *kwds) { return 0; } @@ -83,8 +103,8 @@ PyObject *PyKAdminPolicy_RichCompare(PyObject *o1, PyObject *o2, int opid) { } PyTypeObject PyKAdminPolicyObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) +// 0, /*ob_size*/ "kadmin.KAdminPolicy", /*tp_name*/ sizeof(PyKAdminPolicyObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -126,6 +146,7 @@ PyTypeObject PyKAdminPolicyObject_Type = { PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name) { + kadm5_ret_t retval = 0; PyKAdminPolicyObject *policy = NULL; policy = (PyKAdminPolicyObject *)PyKAdminPolicyObject_new(&PyKAdminPolicyObject_Type, NULL, NULL); @@ -133,6 +154,13 @@ PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadm if (policy) { Py_XINCREF(kadmin); policy->kadmin = kadmin; + + retval = _PyKAdminPolicyObject_load(policy, name); + + if (retval) { + PyKAdminPolicyObject_dealloc(policy); + } + } return policy; diff --git a/PyKAdminPolicyObject.h b/PyKAdminPolicyObject.h index 602217b..d819823 100644 --- a/PyKAdminPolicyObject.h +++ b/PyKAdminPolicyObject.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index bcaed3a..26fc68a 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -302,6 +302,19 @@ static PyMethodDef KAdminPrincipal_methods[] = { {NULL, NULL, 0, NULL} }; +/* +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + char *name; /* attribute name * / + getter get; /* C function to get the attribute * / + setter set; /* C function to set the attribute * / + char *doc; /* optional doc string * / + void *closure; /* optional additional data for getter and setter * / +} PyGetSetDef; +*/ + PyTypeObject PyKAdminPrincipalObject_Type = { PyObject_HEAD_INIT(NULL) From 55f42439b8c4debc8ab7b72bd880a0269e13b561 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 8 Jul 2014 15:15:44 -0400 Subject: [PATCH 04/25] manually setting tp_alloc and tp_free for policy objects - investigate --- PyKAdminPolicyObject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PyKAdminPolicyObject.c b/PyKAdminPolicyObject.c index a622e92..72dcd22 100644 --- a/PyKAdminPolicyObject.c +++ b/PyKAdminPolicyObject.c @@ -13,8 +13,9 @@ static void PyKAdminPolicyObject_dealloc(PyKAdminPolicyObject *self) { Py_XDECREF(self->kadmin); + PyObject_Del((PyObject*)self); - self->ob_type->tp_free((PyObject*)self); + //self->ob_type->tp_free((PyObject*)self); } } @@ -140,7 +141,7 @@ PyTypeObject PyKAdminPolicyObject_Type = { 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyKAdminPolicyObject_init, /* tp_init */ - 0, /* tp_alloc */ + PyType_GenericAlloc, /* tp_alloc */ PyKAdminPolicyObject_new, /* tp_new */ }; From 245762be767652a7b7d197f22009e8f63153e0ed Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 11:10:59 -0400 Subject: [PATCH 05/25] logging on unit tests --- PyKAdminCommon.h | 2 +- test/unittests.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index be4d5cb..44e6c4e 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -8,7 +8,7 @@ #include #include -#include "PyKadminXDR.h" +#include "PyKAdminXDR.h" #include "PyKAdminObject.h" krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); diff --git a/test/unittests.py b/test/unittests.py index 040c856..8f40ab1 100644 --- a/test/unittests.py +++ b/test/unittests.py @@ -86,6 +86,8 @@ def setUp(self): self.kadm = kadm + self.logger = logging.getLogger('python-kadmin') + def test_init_with_keytab(self): try: @@ -261,6 +263,8 @@ def setUp(self): self.stop() self.kadm = kadm + + self.logger = logging.getLogger('python-kadmin') def test_local(self): @@ -388,13 +392,23 @@ def test_each_iteration(self): kadm = self.kadm count = [0] + delta = 0 + size = database_size() + start = time.time() + def fxn(princ, data): data[0] += 1 kadm.each_principal(fxn, count) + end = time.time() + + delta = end - start + + self.logger.info("each iteration {0} principals in {1} seconds. [{2} principals/second]".format(count[0], delta, (count[0]/delta))) + self.assertEqual(count[0], size) def test_not_exists(self): From 1436edeb29e074832cddcec659e50c74ad8f387e Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 13:32:00 -0400 Subject: [PATCH 06/25] updates to getters/setters for principals --- PyKAdminCommon.c | 1 - PyKAdminCommon.h | 1 + PyKAdminErrors.c | 10 +-- PyKAdminPolicyObject.h | 2 + PyKAdminPrincipalObject.c | 171 ++++++++++++++++++++++---------------- PyKAdminPrincipalObject.h | 9 +- 6 files changed, 115 insertions(+), 79 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index a684883..0190969 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -101,7 +101,6 @@ static krb5_tl_data *dup_tl_data(krb5_tl_data *tl) return n; } - krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask) { krb5_error_code retval = 0; diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index 44e6c4e..6e801c6 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -18,6 +18,7 @@ krb5_error_code pykadmin_policy_kadm_from_osa(krb5_context ctx, osa_policy_ent_r int pykadmin_principal_ent_rec_compare(krb5_context ctx, kadm5_principal_ent_rec *a, kadm5_principal_ent_rec *b); int pykadmin_policy_ent_rec_compare(krb5_context ctx, kadm5_policy_ent_rec *a, kadm5_policy_ent_rec *b); + // TODO //krb5_error_code pykadmin_copy_kadm_ent_rec(PyKAdminObject *kadmin, kadm5_principal_ent_rec *src, kadm5_principal_ent_rec *dst); diff --git a/PyKAdminErrors.c b/PyKAdminErrors.c index 6fef596..39dbaaa 100644 --- a/PyKAdminErrors.c +++ b/PyKAdminErrors.c @@ -3,12 +3,12 @@ void PyKAdminError_insert(PyObject *module, kadm5_ret_t retval, char *error_name, char *error_string) { - PyObject *error_number = PyLong_FromUnsignedLong(retval); - PyObject *exception = NULL; - PyObject *error_tuple = NULL; - uint32_t length = strlen(error_name) + 0xF; + PyObject *error_number = PyLong_FromUnsignedLong(retval); + PyObject *exception = NULL; + PyObject *error_tuple = NULL; + uint32_t length = strlen(error_name) + 0xF; - char *real_name = malloc(length); + char *real_name = malloc(length); snprintf(real_name, length, "kadmin.%s", error_name); diff --git a/PyKAdminPolicyObject.h b/PyKAdminPolicyObject.h index d819823..031d985 100644 --- a/PyKAdminPolicyObject.h +++ b/PyKAdminPolicyObject.h @@ -22,6 +22,8 @@ typedef struct { PyTypeObject PyKAdminPolicyObject_Type; +#define PyKAdminPolicy_Check(policy) PyObject_TypeCheck(policy, &PyKAdminPolicyObject_Type) + PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name); PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_osa_entry(PyKAdminObject *kadmin, osa_policy_ent_rec *entry); diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 26fc68a..c668ea3 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -7,8 +7,6 @@ #include "PyKAdminCommon.h" -#define Principal_Check(princ) PyObject_TypeCheck(princ, &PyKAdminPrincipalObject_Type) - static void KAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { kadm5_free_principal_ent(self->kadmin->server_handle, &self->entry); @@ -35,19 +33,32 @@ static int KAdminPrincipal_init(PyKAdminPrincipalObject *self, PyObject *args, P return 0; } + + static int KAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int flags){ - krb5_error_code retval = 0; - char *client_name = NULL; + static const char *kPRINT_FORMAT = "%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s"; - if (self->kadmin) { - - retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - /*if (retval) { - printf("%d\n", retval); - }*/ + krb5_error_code errno; + char *client_name = NULL; - printf(" %s", client_name); + if (self && self->kadmin) { + + errno = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); + + fprintf(file, kPRINT_FORMAT, + "Principal", client_name, + "Expiration date", NULL, + "Last password change", NULL, + "Password expiration date", NULL, + "Maximum ticket life", NULL, + "Maximum renewable life", NULL, + "Last modified", NULL, + "Last successful authentication", NULL, + "Last failed authentication", NULL, + "Failed password attempts", NULL, + "Number of keys", NULL + ); } if (client_name) @@ -81,78 +92,62 @@ static PyMemberDef KAdminPrincipal_members[] = { }; -static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, void *closure) { - - char *client_name = NULL; - - krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - - PyObject *principal = Py_BuildValue("s", client_name); - - free(client_name); - - return principal; -} static PyObject *KAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval; - time_t date = 0; - char *expire = NULL; + kadm5_ret_t retval = KADM5_OK; + time_t date = 0; + char *expire = NULL; if (!PyArg_ParseTuple(args, "s", &expire)) return NULL; date = get_date(expire); + if (date == (time_t)-1 ) { + // todo raise exception + return NULL; + } self->entry.princ_expire_time = date; retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_PRINC_EXPIRE_TIME); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } Py_RETURN_TRUE; } static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval; - char *policy = NULL; + kadm5_ret_t retval = KADM5_OK; + //char *policy = NULL; - if (!PyArg_ParseTuple(args, "s", &policy)) + if (!PyArg_ParseTuple(args, "s", &self->entry.policy)) return NULL; - - strcpy(self->entry.policy, policy); + + //strcpy(self->entry.policy, policy); retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } Py_RETURN_TRUE; } static PyObject *KAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval; + kadm5_ret_t retval = KADM5_OK; retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY_CLR); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } Py_RETURN_TRUE; } -static PyGetSetDef KAdminPrincipal_getters_setters[] = { - // {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, "Kerberos Policy"}, - // {"principal", (getter)PyKAdminPrincipal_get_principal, (setter)PyKAdminPrincipal_set_principal, "Kerberos Principal"}, - // {"policy", (getter)PyKAdminPrincipal_get_policy, NULL, "Kerberos Policy"}, - - {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal"}, - {NULL} -}; static PyObject *_KAdminPrincipal_load_principal(PyKAdminPrincipalObject *self, char *client_name) { - kadm5_ret_t retval; + kadm5_ret_t retval = KADM5_OK; krb5_error_code errno; krb5_principal parsed_name; @@ -180,10 +175,10 @@ static PyObject *_KAdminPrincipal_load_principal(PyKAdminPrincipalObject *self, static PyObject *_KAdminPrincipal_refresh_principal(PyKAdminPrincipalObject *self) { - kadm5_ret_t retval; + kadm5_ret_t retval = KADM5_OK; retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } Py_RETURN_NONE; @@ -191,9 +186,9 @@ static PyObject *_KAdminPrincipal_refresh_principal(PyKAdminPrincipalObject *sel static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval; - char *password = NULL; - char *canon = NULL; + kadm5_ret_t retval = KADM5_OK; + char *password = NULL; + char *canon = NULL; if (!PyArg_ParseTuple(args, "s", &password)) return NULL; @@ -220,31 +215,32 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval; + kadm5_ret_t retval = KADM5_OK; char *canon = NULL; retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &canon); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "krb5_unparse_name"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "krb5_unparse_name"); return NULL; } retval = kadm5_randkey_principal(self->kadmin->server_handle, self->entry.principal, NULL, NULL); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_randkey_principal"); return NULL; } + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_randkey_principal"); return NULL; } _KAdminPrincipal_refresh_principal(self); - Py_XINCREF(Py_True); - return Py_True; + Py_RETURN_TRUE; + } +/* static PyObject *KAdminPrincipal_get_name(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - krb5_error_code retval = 0; + kadm5_ret_t retval = KADM5_OK; char *client_name = NULL; PyObject *name = NULL; if (self->kadmin) { retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - if (retval) {} + if (retval != KADM5_OK) {} name = Py_BuildValue("z", client_name); @@ -252,10 +248,9 @@ static PyObject *KAdminPrincipal_get_name(PyKAdminPrincipalObject *self, PyObjec return name; } - +*/ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { -//int PyKAdminPrincipal_compare(PyObject *o1, PyObject *o2) { PyKAdminPrincipalObject *a = (PyKAdminPrincipalObject *)o1; PyKAdminPrincipalObject *b = (PyKAdminPrincipalObject *)o2; @@ -297,24 +292,60 @@ static PyMethodDef KAdminPrincipal_methods[] = { {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_VARARGS, ""}, - {"name", (PyCFunction)KAdminPrincipal_get_name, METH_VARARGS, ""}, + //{"name", (PyCFunction)KAdminPrincipal_get_name, METH_VARARGS, ""}, {NULL, NULL, 0, NULL} }; + + +static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, void *closure) { + + char *client_name = NULL; + + krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); + + PyObject *principal = Py_BuildValue("s", client_name); + + free(client_name); + + return principal; +} + /* -typedef PyObject *(*getter)(PyObject *, void *); -typedef int (*setter)(PyObject *, PyObject *, void *); - -typedef struct PyGetSetDef { - char *name; /* attribute name * / - getter get; /* C function to get the attribute * / - setter set; /* C function to set the attribute * / - char *doc; /* optional doc string * / - void *closure; /* optional additional data for getter and setter * / -} PyGetSetDef; +static PyObject *PyKAdminPrincipal_get_policy(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *result = Py_None; + + if (self && self->entry.policy) { + result = PyString_FromString(self->entry.policy); + if (!result) { + result = Py_None; + } + } + + Py_INCREF(result); + return result; +} */ +static PyGetSetDef KAdminPrincipal_getters_setters[] = { + + // {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, "Kerberos Policy"}, + // {"principal", (getter)PyKAdminPrincipal_get_principal, (setter)PyKAdminPrincipal_set_principal, "Kerberos Principal"}, + // {"policy", (getter)PyKAdminPrincipal_get_policy, NULL, "Kerberos Policy"}, + + // {(char *)name, (getter) get, (setter) set, (char *) doc, (void *) closure}, + + {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, + {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, + + //{"policy", (getter)PyKAdminPrincipal_get_policy, NULL, "principal policy", NULL}, + + {NULL, NULL, NULL, NULL, NULL} +}; + + PyTypeObject PyKAdminPrincipalObject_Type = { PyObject_HEAD_INIT(NULL) @@ -385,7 +416,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj PyKAdminPrincipalObject *PyKadminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb) { - krb5_error_code retval; + kadm5_ret_t retval = KADM5_OK; PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)KAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); diff --git a/PyKAdminPrincipalObject.h b/PyKAdminPrincipalObject.h index df172af..056adfa 100644 --- a/PyKAdminPrincipalObject.h +++ b/PyKAdminPrincipalObject.h @@ -17,13 +17,16 @@ typedef struct { kadm5_principal_ent_rec entry; } PyKAdminPrincipalObject; +#define PyKAdminPrincipalObject_Check(principal) PyObject_TypeCheck(principal, &PyKAdminPrincipalObject_Type) + PyTypeObject PyKAdminPrincipalObject_Type; PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name); -PyKAdminPrincipalObject *PyKadminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb); -PyKAdminPrincipalObject *PyKadminPrincipalObject_principal_with_kadm_entry(PyKAdminObject *kadmin, kadm5_principal_ent_rec *entry); +PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb); +PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_kadm_entry(PyKAdminObject *kadmin, kadm5_principal_ent_rec *entry); // create will be replaced with load_princ_w_name -PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name); +//PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name); + void KAdminPrincipal_destroy(PyKAdminPrincipalObject *self); From 99bbb898fbf860d0760243578f984ba022e85ac8 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 13:41:18 -0400 Subject: [PATCH 07/25] principal reload --- PyKAdminPrincipalObject.c | 62 ++++++++++----------------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index c668ea3..125a034 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -213,12 +213,12 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, } } -static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; - char *canon = NULL; + char *client_name = NULL; - retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &canon); + retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "krb5_unparse_name"); return NULL; } retval = kadm5_randkey_principal(self->kadmin->server_handle, self->entry.principal, NULL, NULL); @@ -230,25 +230,17 @@ static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self, Py } -/* -static PyObject *KAdminPrincipal_get_name(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static PyObject *KAdminPrincipal_reload(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; - char *client_name = NULL; - PyObject *name = NULL; - - if (self->kadmin) { - - retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - if (retval != KADM5_OK) {} - - name = Py_BuildValue("z", client_name); + if (self) { + retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } } - - return name; + + Py_RETURN_TRUE; } -*/ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { @@ -285,14 +277,14 @@ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { static PyMethodDef KAdminPrincipal_methods[] = { {"cpw", (PyCFunction)KAdminPrincipal_change_password, METH_VARARGS, ""}, {"change_password", (PyCFunction)KAdminPrincipal_change_password, METH_VARARGS, ""}, - {"randkey", (PyCFunction)KAdminPrincipal_randomize_key, METH_VARARGS, ""}, - {"randomize_key", (PyCFunction)KAdminPrincipal_randomize_key, METH_VARARGS, ""}, + {"randkey", (PyCFunction)KAdminPrincipal_randomize_key, METH_NOARGS, ""}, + {"randomize_key", (PyCFunction)KAdminPrincipal_randomize_key, METH_NOARGS, ""}, - {"expire", (PyCFunction)KAdminPrincipal_set_expire, METH_VARARGS, ""}, - {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, - {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_VARARGS, ""}, + {"expire", (PyCFunction)KAdminPrincipal_set_expire, METH_VARARGS, ""}, + {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, + {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_VARARGS, ""}, - //{"name", (PyCFunction)KAdminPrincipal_get_name, METH_VARARGS, ""}, + {"reload", (PyCFunction)KAdminPrincipal_reload, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} }; @@ -312,36 +304,12 @@ static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, return principal; } -/* -static PyObject *PyKAdminPrincipal_get_policy(PyKAdminPrincipalObject *self, void *closure) { - - PyObject *result = Py_None; - - if (self && self->entry.policy) { - result = PyString_FromString(self->entry.policy); - if (!result) { - result = Py_None; - } - } - - Py_INCREF(result); - return result; -} -*/ static PyGetSetDef KAdminPrincipal_getters_setters[] = { - // {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, "Kerberos Policy"}, - // {"principal", (getter)PyKAdminPrincipal_get_principal, (setter)PyKAdminPrincipal_set_principal, "Kerberos Principal"}, - // {"policy", (getter)PyKAdminPrincipal_get_policy, NULL, "Kerberos Policy"}, - - // {(char *)name, (getter) get, (setter) set, (char *) doc, (void *) closure}, - {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, - //{"policy", (getter)PyKAdminPrincipal_get_policy, NULL, "principal policy", NULL}, - {NULL, NULL, NULL, NULL, NULL} }; From 274222db78e676bae25be7241e07e38e4e27a913 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:25:54 -0400 Subject: [PATCH 08/25] update principal api to mirror the kadmin cli tool --- PyKAdminObject.c | 20 ++++++++++++++++---- PyKAdminObject.h | 1 + PyKAdminPrincipalObject.c | 34 +++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index 82d05ef..a4a9c73 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -203,15 +203,21 @@ static int kdb_iter_princs(void *data, krb5_db_entry *kdb) { PyKAdminObject *self = (PyKAdminObject *)data; PyObject *result = NULL; + //PyObject *args = NULL; - PyKAdminPrincipalObject *principal = PyKadminPrincipalObject_principal_with_db_entry(self, kdb); + PyKAdminPrincipalObject *principal = PyKAdminPrincipalObject_principal_with_db_entry(self, kdb); if (principal) { if (self->each_principal.callback) { + + //args = PyTuple_Pack(2, principal, self->each_principal.data); + //result = PyObject_Call(self->each_principal.callback, args, NULL); result = PyObject_CallFunctionObjArgs(self->each_principal.callback, principal, self->each_principal.data, NULL); + //Py_DECREF(args); + if (!result) { // use self to hold exception } @@ -235,15 +241,19 @@ static PyObject *PyKAdminObject_each_principal(PyKAdminObject *self, PyObject *a static char *kwlist[] = {"", "data", "match", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oz", kwlist, &PyFunction_Type, &self->each_principal.callback, &self->each_principal.data, &match)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oz", kwlist, /*&PyFunction_Type,*/ &self->each_principal.callback, &self->each_principal.data, &match)) return NULL; if (!self->each_principal.data) self->each_principal.data = Py_None; + + Py_XINCREF(self->each_principal.callback); Py_XINCREF(self->each_principal.data); + + lock = kadm5_lock(self->server_handle); if (!lock || (lock == KRB5_PLUGIN_OP_NOTSUPP)) { @@ -346,6 +356,7 @@ static PyKAdminPrincipalObject *PyKAdminObject_list_principals(PyKAdminObject *s static PyMethodDef PyKAdminObject_methods[] = { + {"getprinc", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, {"get_principal", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, @@ -356,8 +367,9 @@ static PyMethodDef PyKAdminObject_methods[] = { {"delete_principal", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, {"ank", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, - {"create_princ", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, - {"create_principal", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"addprinc", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"add_principal", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"list_principals", (PyCFunction)PyKAdminObject_list_principals, METH_VARARGS, ""}, {"principals", (PyCFunction)PyKAdminObject_principal_iter, (METH_VARARGS | METH_KEYWORDS), ""}, diff --git a/PyKAdminObject.h b/PyKAdminObject.h index b548fe0..cefe13e 100644 --- a/PyKAdminObject.h +++ b/PyKAdminObject.h @@ -27,6 +27,7 @@ typedef struct { } PyKAdminObject; PyTypeObject PyKAdminObject_Type; + PyKAdminObject *PyKAdminObject_create(void); void PyKAdminObject_destroy(PyKAdminObject *self); diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 125a034..c61871f 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -173,6 +173,21 @@ static PyObject *_KAdminPrincipal_load_principal(PyKAdminPrincipalObject *self, //Py_RETURN_FALSE; } + +static PyObject *KAdminPrincipal_reload(PyKAdminPrincipalObject *self) { + + kadm5_ret_t retval = KADM5_OK; + + if (self) { + retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } + } + + Py_RETURN_TRUE; +} + + +/* static PyObject *_KAdminPrincipal_refresh_principal(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; @@ -183,6 +198,7 @@ static PyObject *_KAdminPrincipal_refresh_principal(PyKAdminPrincipalObject *sel Py_RETURN_NONE; } +*/ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { @@ -204,7 +220,7 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, retval = kadm5_chpass_principal(self->kadmin->server_handle, self->entry.principal, password); if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_chpass_principal"); return NULL; } - _KAdminPrincipal_refresh_principal(self); + KAdminPrincipal_reload(self); Py_RETURN_TRUE; @@ -224,24 +240,12 @@ static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { retval = kadm5_randkey_principal(self->kadmin->server_handle, self->entry.principal, NULL, NULL); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_randkey_principal"); return NULL; } - _KAdminPrincipal_refresh_principal(self); + KAdminPrincipal_reload(self); Py_RETURN_TRUE; } -static PyObject *KAdminPrincipal_reload(PyKAdminPrincipalObject *self) { - - kadm5_ret_t retval = KADM5_OK; - - if (self) { - retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } - } - - Py_RETURN_TRUE; -} - PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { PyKAdminPrincipalObject *a = (PyKAdminPrincipalObject *)o1; @@ -382,7 +386,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj return principal; } -PyKAdminPrincipalObject *PyKadminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb) { +PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb) { kadm5_ret_t retval = KADM5_OK; From 971934cc93bcbd6f2d32c9371e222c0ed3344888 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:28:46 -0400 Subject: [PATCH 09/25] get rid of list principals (use iterators) --- PyKAdminObject.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index a4a9c73..751f164 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -348,29 +348,24 @@ static PyObject *PyKAdminObject_each_policy(PyKAdminObject *self, PyObject *args } -static PyKAdminPrincipalObject *PyKAdminObject_list_principals(PyKAdminObject *self, PyObject *args, PyObject *kwds) { - +static PyMethodDef PyKAdminObject_methods[] = { - return NULL; -} + {"ank", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"addprinc", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"add_principal", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, + {"delprinc", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, + {"delete_principal", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, -static PyMethodDef PyKAdminObject_methods[] = { + // kadmin modify princ, rename princ {"getprinc", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, {"get_principal", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""}, - - {"getpol", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, - {"get_policy", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, - {"delprinc", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, - {"delete_principal", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""}, - {"ank", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, - {"addprinc", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, - {"add_principal", (PyCFunction)PyKAdminObject_create_principal, METH_VARARGS, ""}, - {"list_principals", (PyCFunction)PyKAdminObject_list_principals, METH_VARARGS, ""}, + {"getpol", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, + {"get_policy", (PyCFunction)PyKAdminObject_get_policy, METH_VARARGS, ""}, {"principals", (PyCFunction)PyKAdminObject_principal_iter, (METH_VARARGS | METH_KEYWORDS), ""}, {"policies", (PyCFunction)PyKAdminObject_policy_iter, (METH_VARARGS | METH_KEYWORDS), ""}, From cd55efa1372b2d19eab3a4ab59e7feca91c947ce Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:30:25 -0400 Subject: [PATCH 10/25] stubs for lock and unlock --- PyKAdminObject.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index 751f164..e3f55bc 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -369,6 +369,12 @@ static PyMethodDef PyKAdminObject_methods[] = { {"principals", (PyCFunction)PyKAdminObject_principal_iter, (METH_VARARGS | METH_KEYWORDS), ""}, {"policies", (PyCFunction)PyKAdminObject_policy_iter, (METH_VARARGS | METH_KEYWORDS), ""}, + + // todo implement + {"lock", (PyCFunction)NULL, METH_NOARGS, ""}, + {"unlock", (PyCFunction)NULL, METH_NOARGS, ""}, + + #ifdef KADMIN_LOCAL /* From fc07921b63b4f3ba2c2a48dfded6f90fa7965abe Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:37:30 -0400 Subject: [PATCH 11/25] set_policy(None) will clear policy --- PyKAdminObject.c | 2 -- PyKAdminPrincipalObject.c | 27 +++++++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index e3f55bc..bda8800 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -374,8 +374,6 @@ static PyMethodDef PyKAdminObject_methods[] = { {"lock", (PyCFunction)NULL, METH_NOARGS, ""}, {"unlock", (PyCFunction)NULL, METH_NOARGS, ""}, - - #ifdef KADMIN_LOCAL /* due to the nature of how the kadm5clnt library interfaces with the kerberos database over the rpc layer diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index c61871f..eea6bb5 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -116,28 +116,31 @@ static PyObject *KAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObj Py_RETURN_TRUE; } -static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + +static PyObject *KAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; - //char *policy = NULL; - - if (!PyArg_ParseTuple(args, "s", &self->entry.policy)) - return NULL; - //strcpy(self->entry.policy, policy); - - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY); + retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY_CLR); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } Py_RETURN_TRUE; } -static PyObject *KAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + +static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY_CLR); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + if (!PyArg_ParseTuple(args, "|z", &self->entry.policy)) + return NULL; + + if (self->entry.policy == NULL) { + KAdminPrincipal_clear_policy(self); + } else { + retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + } Py_RETURN_TRUE; } @@ -286,7 +289,7 @@ static PyMethodDef KAdminPrincipal_methods[] = { {"expire", (PyCFunction)KAdminPrincipal_set_expire, METH_VARARGS, ""}, {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, - {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_VARARGS, ""}, + {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_NOARGS, ""}, {"reload", (PyCFunction)KAdminPrincipal_reload, METH_NOARGS, ""}, From 44052ea06b54c282df6c683fa6eec6ce8a4081e4 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:39:37 -0400 Subject: [PATCH 12/25] cpw/randkey do not force reload of the entry (could slow iteration) --- PyKAdminPrincipalObject.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index eea6bb5..528564e 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -147,7 +147,6 @@ static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObj - static PyObject *_KAdminPrincipal_load_principal(PyKAdminPrincipalObject *self, char *client_name) { kadm5_ret_t retval = KADM5_OK; @@ -189,20 +188,6 @@ static PyObject *KAdminPrincipal_reload(PyKAdminPrincipalObject *self) { Py_RETURN_TRUE; } - -/* -static PyObject *_KAdminPrincipal_refresh_principal(PyKAdminPrincipalObject *self) { - - kadm5_ret_t retval = KADM5_OK; - - retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } - - Py_RETURN_NONE; - -} -*/ - static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; @@ -222,9 +207,7 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, retval = kadm5_chpass_principal(self->kadmin->server_handle, self->entry.principal, password); if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_chpass_principal"); return NULL; } - - KAdminPrincipal_reload(self); - + Py_RETURN_TRUE; } else { @@ -243,8 +226,6 @@ static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { retval = kadm5_randkey_principal(self->kadmin->server_handle, self->entry.principal, NULL, NULL); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_randkey_principal"); return NULL; } - KAdminPrincipal_reload(self); - Py_RETURN_TRUE; } From 08da650cd8dc2bc5160edd8a52385b413df23fc9 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:40:41 -0400 Subject: [PATCH 13/25] randkey doesnt need to unparse client_name --- PyKAdminPrincipalObject.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 528564e..8111d49 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -218,16 +218,11 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; - char *client_name = NULL; - - retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "krb5_unparse_name"); return NULL; } retval = kadm5_randkey_principal(self->kadmin->server_handle, self->entry.principal, NULL, NULL); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_randkey_principal"); return NULL; } Py_RETURN_TRUE; - } PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { From 4364d70d4e3be26b49342196b3bc28a2a064b8f4 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Mon, 14 Jul 2014 15:43:50 -0400 Subject: [PATCH 14/25] cpw doesn't need to unparse name or check for null pointer --- PyKAdminPrincipalObject.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 8111d49..60daf44 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -192,27 +192,14 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, kadm5_ret_t retval = KADM5_OK; char *password = NULL; - char *canon = NULL; if (!PyArg_ParseTuple(args, "s", &password)) return NULL; - if (password) { + retval = kadm5_chpass_principal(self->kadmin->server_handle, self->entry.principal, password); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_chpass_principal"); return NULL; } - retval = krb5_unparse_name(self->kadmin->context, self->entry.principal, &canon); - - if (retval) { - printf("krb5_unparse_name failure: %ld\n", retval); - } - - retval = kadm5_chpass_principal(self->kadmin->server_handle, self->entry.principal, password); - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_chpass_principal"); return NULL; } - - Py_RETURN_TRUE; - - } else { - Py_RETURN_FALSE; - } + Py_RETURN_TRUE; } static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { From d9956d73b518eedf2b151f3674d19ccf2bcc7ce7 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 10:38:44 -0400 Subject: [PATCH 15/25] extract members and convert timestamps to datetime.datetime objects [pystdlib] --- PyKAdminCommon.c | 20 ++++ PyKAdminCommon.h | 4 + PyKAdminObject.c | 4 + PyKAdminObject.h | 2 + PyKAdminPrincipalObject.c | 206 +++++++++++++++++++++++++++++++++++--- PyKAdminPrincipalObject.h | 1 + 6 files changed, 223 insertions(+), 14 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index 0190969..4da84eb 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -11,6 +11,26 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, */ #include "PyKAdminCommon.h" +#include + + +PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { + + PyDateTime_IMPORT; + + PyObject *datetime = NULL; + PyObject *args = NULL; + + args = Py_BuildValue("(i)", timestamp); + + if (args) { + datetime = PyDateTime_FromTimestamp(args); + Py_DECREF(args); + } + + return datetime; + +} krb5_error_code pykadmin_unpack_xdr_osa_princ_ent_rec(PyKAdminObject *kadmin, krb5_db_entry *kdb, osa_princ_ent_rec *adb) { diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index 6e801c6..0a16bed 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -3,6 +3,7 @@ #define PYKADMINCOMMON_H #include + #include #include #include @@ -11,6 +12,9 @@ #include "PyKAdminXDR.h" #include "PyKAdminObject.h" +PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp); + + krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); krb5_error_code pykadmin_policy_kadm_from_osa(krb5_context ctx, osa_policy_ent_rec *osa, kadm5_policy_ent_rec *entry, long mask); diff --git a/PyKAdminObject.c b/PyKAdminObject.c index bda8800..a56916b 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -58,6 +58,10 @@ static PyObject *PyKAdminObject_new(PyTypeObject *type, PyObject *args, PyObject //if (!self->realm) { // // todo : fail //} + + self->_storage = PyDict_New(); + + } return (PyObject *)self; diff --git a/PyKAdminObject.h b/PyKAdminObject.h index cefe13e..2c724d5 100644 --- a/PyKAdminObject.h +++ b/PyKAdminObject.h @@ -23,6 +23,8 @@ typedef struct { each_iteration_t each_principal; each_iteration_t each_policy; + + PyObject *_storage; } PyKAdminObject; diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 60daf44..d8a744a 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -7,6 +7,54 @@ #include "PyKAdminCommon.h" +#include + +/* +kadm_principal_ent_rec reference + +typedef struct _kadm5_principal_ent_t { + + // done + krb5_principal principal; + krb5_principal mod_name; + + // how to expose timestamps? + krb5_timestamp princ_expire_time; + krb5_timestamp last_pwd_change; + krb5_timestamp pw_expiration; + krb5_timestamp mod_date; + + krb5_deltat max_life; + + krb5_kvno kvno; + krb5_kvno mkvno; + + char *policy; + + krb5_flags attributes; + long aux_attributes; + + // version 2 fields + + krb5_timestamp last_success; + krb5_timestamp last_failed; + + krb5_deltat max_renewable_life; + + krb5_kvno fail_auth_count; + + // these should not be accessed or modified directly by python. + krb5_int16 n_key_data; + krb5_int16 n_tl_data; + krb5_tl_data *tl_data; + krb5_key_data *key_data; + +} kadm5_principal_ent_rec, *kadm5_principal_ent_t; +*/ + + + + static void KAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { kadm5_free_principal_ent(self->kadmin->server_handle, &self->entry); @@ -26,10 +74,12 @@ static PyObject *KAdminPrincipal_new(PyTypeObject *type, PyObject *args, PyObjec return NULL; memset(&self->entry, 0, sizeof(kadm5_principal_ent_rec)); - return (PyObject *)self; + return (PyObject *)self; + } static int KAdminPrincipal_init(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + return 0; } @@ -72,17 +122,16 @@ static int KAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int static PyMemberDef KAdminPrincipal_members[] = { - {"last_password_change", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_pwd_change), READONLY, ""}, - {"expire_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, princ_expire_time), READONLY, ""}, - {"password_expiration", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, pw_expiration), READONLY, ""}, - {"modified_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mod_date), READONLY, ""}, - {"max_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_life), READONLY, ""}, + //{"last_password_change", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_pwd_change), READONLY, ""}, + //{"expire_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, princ_expire_time), READONLY, ""}, + //{"password_expiration", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, pw_expiration), READONLY, ""}, + //{"modified_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mod_date), READONLY, ""}, + //{"max_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_life), READONLY, ""}, + //{"max_renewable_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_renewable_life), READONLY, ""}, + //{"last_success", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_success), READONLY, ""}, + //{"last_failed", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_failed), READONLY, ""}, - {"max_renewable_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_renewable_life), READONLY, ""}, - {"last_success", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_success), READONLY, ""}, - {"last_failed", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_failed), READONLY, ""}, {"failed_auth_count", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, - {"key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, {"master_key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, ""}, @@ -132,6 +181,8 @@ static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObj kadm5_ret_t retval = KADM5_OK; + // todo: parse as a pyobject, if we pass in a PolicyObject we need to accept that too. + if (!PyArg_ParseTuple(args, "|z", &self->entry.policy)) return NULL; @@ -263,22 +314,149 @@ static PyMethodDef KAdminPrincipal_methods[] = { static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, void *closure) { - char *client_name = NULL; + krb5_error_code ret = 0; + PyObject *principal = NULL; + char *client_name = NULL; - krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); + // todo: handle error + ret = krb5_unparse_name(self->kadmin->context, self->entry.principal, &client_name); - PyObject *principal = Py_BuildValue("s", client_name); + if (client_name) { + principal = PyString_FromString(client_name); + free(client_name); + } + + return principal; +} - free(client_name); + +static PyObject *PyKAdminPrincipal_get_mod_name(PyKAdminPrincipalObject *self, void *closure) { + + krb5_error_code ret = 0; + PyObject *principal = NULL; + char *client_name = NULL; + + // todo: handle error + ret = krb5_unparse_name(self->kadmin->context, self->entry.mod_name, &client_name); + + if (client_name) { + principal = PyString_FromString(client_name); + free(client_name); + } return principal; } +static PyObject *PyKAdminPrincipal_get_last_pwd_change(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.last_pwd_change); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_princ_expire_time(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.princ_expire_time); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_pw_expiration(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.pw_expiration); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_mod_date(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.mod_date); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_last_success(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.last_success); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_last_failed(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *value = NULL; + + value = pykadmin_pydatetime_from_timestamp(self->entry.last_failed); + + if (!value) { + // todo: raise exception + } + + return value; +} + +static PyObject *PyKAdminPrincipal_get_max_renewable_life(PyKAdminPrincipalObject *self, void *closure) { + + PyDateTime_IMPORT; + + PyObject *value = NULL; + + value = PyDelta_FromDSU(0, self->entry.max_renewable_life, 0); + + if (!value) { + // todo: raise exception + } + + return value; +} + + + static PyGetSetDef KAdminPrincipal_getters_setters[] = { {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, + {"mod_name", (getter)PyKAdminPrincipal_get_mod_name, NULL, "Kerberos Principal", NULL}, + + {"last_password_change", (getter)PyKAdminPrincipal_get_last_pwd_change, NULL, "Kerberos Principal", NULL}, + {"expire_time", (getter)PyKAdminPrincipal_get_princ_expire_time, NULL, "Kerberos Principal", NULL}, + {"password_expiration", (getter)PyKAdminPrincipal_get_pw_expiration, NULL, "Kerberos Principal", NULL}, + {"mod_date", (getter)PyKAdminPrincipal_get_mod_date, NULL, "Kerberos Principal", NULL}, + {"last_success", (getter)PyKAdminPrincipal_get_last_success, NULL, "Kerberos Principal", NULL}, + {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, "Kerberos Principal", NULL}, + + {"max_renewable_life", (getter)PyKAdminPrincipal_get_max_renewable_life, NULL, "Kerberos Principal", NULL}, {NULL, NULL, NULL, NULL, NULL} }; diff --git a/PyKAdminPrincipalObject.h b/PyKAdminPrincipalObject.h index 056adfa..d41791e 100644 --- a/PyKAdminPrincipalObject.h +++ b/PyKAdminPrincipalObject.h @@ -3,6 +3,7 @@ #define PYKADMINPRINCIPALOBJECT_H #include + #include #include #include From dd02adec4f2df62f767e518c7499fccade5fb3e2 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 10:46:54 -0400 Subject: [PATCH 16/25] last stubs for setting principal values --- PyKAdminPrincipalObject.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index d8a744a..03ded10 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -305,6 +305,10 @@ static PyMethodDef KAdminPrincipal_methods[] = { {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_NOARGS, ""}, + // TODO + //{"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, + //{"password_expire", (PyCFunction)NULL, METH_NOARGS, ""}, + {"reload", (PyCFunction)KAdminPrincipal_reload, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} From 0a795642f32bbc598544c8d155a759c309527f6b Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 10:50:28 -0400 Subject: [PATCH 17/25] clean up commented out blocks --- PyKAdminPrincipalObject.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 03ded10..e8b4ec7 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -120,17 +120,7 @@ static int KAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int static PyMemberDef KAdminPrincipal_members[] = { - - - //{"last_password_change", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_pwd_change), READONLY, ""}, - //{"expire_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, princ_expire_time), READONLY, ""}, - //{"password_expiration", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, pw_expiration), READONLY, ""}, - //{"modified_time", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mod_date), READONLY, ""}, - //{"max_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_life), READONLY, ""}, - //{"max_renewable_life", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, max_renewable_life), READONLY, ""}, - //{"last_success", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_success), READONLY, ""}, - //{"last_failed", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, last_failed), READONLY, ""}, - + {"failed_auth_count", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, {"key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, {"master_key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, ""}, From 721ef5a2458f9e82ef646327a7d1dd93cb4e683a Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 12:49:15 -0400 Subject: [PATCH 18/25] get rid of the principal load function as it can simply be included in principal_with_name --- PyKAdminObject.c | 4 +++ PyKAdminPrincipalObject.c | 73 +++++++++++++-------------------------- 2 files changed, 28 insertions(+), 49 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index a56916b..d41858b 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -202,6 +202,9 @@ static PyKAdminIterator *PyKAdminObject_policy_iter(PyKAdminObject *self, PyObje return PyKAdminIterator_create(self, mode, match); } + +#ifdef KADMIN_LOCAL + static int kdb_iter_princs(void *data, krb5_db_entry *kdb) { PyKAdminObject *self = (PyKAdminObject *)data; @@ -350,6 +353,7 @@ static PyObject *PyKAdminObject_each_policy(PyKAdminObject *self, PyObject *args Py_RETURN_TRUE; } +#endif static PyMethodDef PyKAdminObject_methods[] = { diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index e8b4ec7..898b29f 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -55,7 +55,7 @@ typedef struct _kadm5_principal_ent_t { -static void KAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { +static void PyKAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { kadm5_free_principal_ent(self->kadmin->server_handle, &self->entry); @@ -186,38 +186,7 @@ static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObj Py_RETURN_TRUE; } - - -static PyObject *_KAdminPrincipal_load_principal(PyKAdminPrincipalObject *self, char *client_name) { - - kadm5_ret_t retval = KADM5_OK; - krb5_error_code errno; - krb5_principal parsed_name; - - if (client_name) { - - errno = krb5_parse_name(self->kadmin->context, client_name, &parsed_name); - - if (errno) { - printf("Failed to parse princ name %d\n", errno); - } - - retval = kadm5_get_principal(self->kadmin->server_handle, parsed_name, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); - - krb5_free_principal(self->kadmin->context, parsed_name); - - if (retval != 0x0) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } - - Py_RETURN_TRUE; - } - - // TODO: raise exception - return NULL; - //Py_RETURN_FALSE; -} - - -static PyObject *KAdminPrincipal_reload(PyKAdminPrincipalObject *self) { +static PyObject *PyKAdminPrincipal_reload(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; @@ -299,7 +268,7 @@ static PyMethodDef KAdminPrincipal_methods[] = { //{"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, //{"password_expire", (PyCFunction)NULL, METH_NOARGS, ""}, - {"reload", (PyCFunction)KAdminPrincipal_reload, METH_NOARGS, ""}, + {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} }; @@ -463,7 +432,7 @@ PyTypeObject PyKAdminPrincipalObject_Type = { "kadmin.Principal", /*tp_name*/ sizeof(PyKAdminPrincipalObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)KAdminPrincipal_dealloc, /*tp_dealloc*/ + (destructor)PyKAdminPrincipal_dealloc, /*tp_dealloc*/ (printfunc)KAdminPrincipal_print, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -501,24 +470,30 @@ PyTypeObject PyKAdminPrincipalObject_Type = { PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name) { + + krb5_error_code errno; - PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)KAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); + PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)Py_None; - if (principal) { + if (client_name) { - Py_XINCREF(kadmin); - principal->kadmin = kadmin; + principal = (PyKAdminPrincipalObject *)KAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); - /* todo : fetch kadmin entry */ - PyObject *result = _KAdminPrincipal_load_principal(principal, client_name); + if (principal) { - if (!result) { - //Py_XDECREF(kadmin); // this is redundant as dealloc decrementes the reference for us - Py_XINCREF(Py_None); - KAdminPrincipal_dealloc(principal); - principal = (PyKAdminPrincipalObject *)Py_None; - } + Py_INCREF(kadmin); + principal->kadmin = kadmin; + errno = krb5_parse_name(kadmin->context, client_name, &principal->entry.principal); + PyObject *result = PyKAdminPrincipal_reload(principal); + + if (!result || errno) { + Py_INCREF(Py_None); + PyKAdminPrincipal_dealloc(principal); + principal = (PyKAdminPrincipalObject *)Py_None; + } + + } } return principal; @@ -539,7 +514,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdmi if (retval) { - KAdminPrincipal_dealloc(principal); + PyKAdminPrincipal_dealloc(principal); // todo: set exception principal = NULL; @@ -551,7 +526,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdmi } void KAdminPrincipal_destroy(PyKAdminPrincipalObject *self) { - KAdminPrincipal_dealloc(self); + PyKAdminPrincipal_dealloc(self); } From 93025b7fb775718f2d0fe7184cdc9ba8e6ac3c73 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 12:54:19 -0400 Subject: [PATCH 19/25] clean up naming convention PyKAdmin prefix should be used everywhere Object suffix should be used extern and should be dropped for static functions --- PyKAdminPrincipalObject.c | 54 +++++++++++++++++++-------------------- PyKAdminPrincipalObject.h | 5 +--- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 898b29f..f4664d2 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -64,7 +64,7 @@ static void PyKAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { self->ob_type->tp_free((PyObject*)self); } -static PyObject *KAdminPrincipal_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { +static PyObject *PyKAdminPrincipal_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyKAdminPrincipalObject *self; @@ -78,14 +78,14 @@ static PyObject *KAdminPrincipal_new(PyTypeObject *type, PyObject *args, PyObjec } -static int KAdminPrincipal_init(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static int PyKAdminPrincipal_init(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { return 0; } -static int KAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int flags){ +static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int flags){ static const char *kPRINT_FORMAT = "%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s"; @@ -119,7 +119,7 @@ static int KAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int -static PyMemberDef KAdminPrincipal_members[] = { +static PyMemberDef PyKAdminPrincipal_members[] = { {"failed_auth_count", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, {"key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, @@ -132,7 +132,7 @@ static PyMemberDef KAdminPrincipal_members[] = { -static PyObject *KAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static PyObject *PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; time_t date = 0; @@ -156,7 +156,7 @@ static PyObject *KAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObj } -static PyObject *KAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self) { +static PyObject *PyKAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; @@ -167,7 +167,7 @@ static PyObject *KAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self) { } -static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static PyObject *PyKAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; @@ -177,7 +177,7 @@ static PyObject *KAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObj return NULL; if (self->entry.policy == NULL) { - KAdminPrincipal_clear_policy(self); + PyKAdminPrincipal_clear_policy(self); } else { retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY); if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } @@ -198,7 +198,7 @@ static PyObject *PyKAdminPrincipal_reload(PyKAdminPrincipalObject *self) { Py_RETURN_TRUE; } -static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { +static PyObject *PyKAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; char *password = NULL; @@ -212,7 +212,7 @@ static PyObject *KAdminPrincipal_change_password(PyKAdminPrincipalObject *self, Py_RETURN_TRUE; } -static PyObject *KAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { +static PyObject *PyKAdminPrincipal_randomize_key(PyKAdminPrincipalObject *self) { kadm5_ret_t retval = KADM5_OK; @@ -254,15 +254,15 @@ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { return result; } -static PyMethodDef KAdminPrincipal_methods[] = { - {"cpw", (PyCFunction)KAdminPrincipal_change_password, METH_VARARGS, ""}, - {"change_password", (PyCFunction)KAdminPrincipal_change_password, METH_VARARGS, ""}, - {"randkey", (PyCFunction)KAdminPrincipal_randomize_key, METH_NOARGS, ""}, - {"randomize_key", (PyCFunction)KAdminPrincipal_randomize_key, METH_NOARGS, ""}, +static PyMethodDef PyKAdminPrincipal_methods[] = { + {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, + {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, + {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, + {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, - {"expire", (PyCFunction)KAdminPrincipal_set_expire, METH_VARARGS, ""}, - {"set_policy", (PyCFunction)KAdminPrincipal_set_policy, METH_VARARGS, ""}, - {"clear_policy", (PyCFunction)KAdminPrincipal_clear_policy, METH_NOARGS, ""}, + {"expire", (PyCFunction)PyKAdminPrincipal_set_expire, METH_VARARGS, ""}, + {"set_policy", (PyCFunction)PyKAdminPrincipal_set_policy, METH_VARARGS, ""}, + {"clear_policy", (PyCFunction)PyKAdminPrincipal_clear_policy, METH_NOARGS, ""}, // TODO //{"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, @@ -406,7 +406,7 @@ static PyObject *PyKAdminPrincipal_get_max_renewable_life(PyKAdminPrincipalObjec -static PyGetSetDef KAdminPrincipal_getters_setters[] = { +static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, @@ -433,7 +433,7 @@ PyTypeObject PyKAdminPrincipalObject_Type = { sizeof(PyKAdminPrincipalObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyKAdminPrincipal_dealloc, /*tp_dealloc*/ - (printfunc)KAdminPrincipal_print, /*tp_print*/ + (printfunc)PyKAdminPrincipal_print, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -455,17 +455,17 @@ PyTypeObject PyKAdminPrincipalObject_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - KAdminPrincipal_methods, /* tp_methods */ - KAdminPrincipal_members, /* tp_members */ - KAdminPrincipal_getters_setters, /* tp_getset */ + PyKAdminPrincipal_methods, /* tp_methods */ + PyKAdminPrincipal_members, /* tp_members */ + PyKAdminPrincipal_getters_setters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)KAdminPrincipal_init, /* tp_init */ + (initproc)PyKAdminPrincipal_init, /* tp_init */ 0, /* tp_alloc */ - KAdminPrincipal_new, /* tp_new */ + PyKAdminPrincipal_new, /* tp_new */ }; @@ -477,7 +477,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj if (client_name) { - principal = (PyKAdminPrincipalObject *)KAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); + principal = (PyKAdminPrincipalObject *)PyKAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); if (principal) { @@ -503,7 +503,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdmi kadm5_ret_t retval = KADM5_OK; - PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)KAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); + PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)PyKAdminPrincipal_new(&PyKAdminPrincipalObject_Type, NULL, NULL); if (kdb) { diff --git a/PyKAdminPrincipalObject.h b/PyKAdminPrincipalObject.h index d41791e..3648b4d 100644 --- a/PyKAdminPrincipalObject.h +++ b/PyKAdminPrincipalObject.h @@ -25,10 +25,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb); PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_kadm_entry(PyKAdminObject *kadmin, kadm5_principal_ent_rec *entry); -// create will be replaced with load_princ_w_name -//PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name); - -void KAdminPrincipal_destroy(PyKAdminPrincipalObject *self); +void PyKAdminPrincipalObject_destroy(PyKAdminPrincipalObject *self); #endif \ No newline at end of file From 99e49bb08a1437dd2408e4a3008dbd3032f121e4 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 12:54:37 -0400 Subject: [PATCH 20/25] clean up naming convention PyKAdmin prefix should be used everywhere Object suffix should be used extern and should be dropped for static functions --- PyKAdminObject.c | 2 +- PyKAdminPrincipalObject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index d41858b..16a1eb0 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -230,7 +230,7 @@ static int kdb_iter_princs(void *data, krb5_db_entry *kdb) { } } - KAdminPrincipal_destroy(principal); + PyKAdminPrincipalObject_destroy(principal); } return 0; diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index f4664d2..b6f7413 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -525,7 +525,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdmi return principal; } -void KAdminPrincipal_destroy(PyKAdminPrincipalObject *self) { +void PyKAdminPrincipalObject_destroy(PyKAdminPrincipalObject *self) { PyKAdminPrincipal_dealloc(self); } From d531610ea50d05960db28e4d05486e7526874551 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 12:56:42 -0400 Subject: [PATCH 21/25] inline datetime converter --- PyKAdminCommon.c | 2 +- PyKAdminCommon.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index 4da84eb..4cfc896 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -14,7 +14,7 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, #include -PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { +inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { PyDateTime_IMPORT; diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index 0a16bed..d5d5526 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -12,7 +12,7 @@ #include "PyKAdminXDR.h" #include "PyKAdminObject.h" -PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp); +inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp); krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); From ae5dd5c481260dc168bc8a68ac2f5fd75e0ef7bc Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Tue, 15 Jul 2014 15:42:50 -0400 Subject: [PATCH 22/25] working towards attributes --- PyKAdminCommon.c | 21 ++-- PyKAdminPrincipalObject.c | 208 ++++++++++++++++++++++---------------- kadmin.c | 47 +++++++++ test/unittests.py | 2 +- 4 files changed, 181 insertions(+), 97 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index 4cfc896..feebecd 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -18,18 +18,21 @@ inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { PyDateTime_IMPORT; - PyObject *datetime = NULL; - PyObject *args = NULL; + if (timestamp) { + PyObject *datetime = NULL; + PyObject *args = NULL; - args = Py_BuildValue("(i)", timestamp); + args = Py_BuildValue("(i)", timestamp); - if (args) { - datetime = PyDateTime_FromTimestamp(args); - Py_DECREF(args); - } - - return datetime; + if (args) { + datetime = PyDateTime_FromTimestamp(args); + Py_DECREF(args); + } + return datetime; + } else { + Py_RETURN_NONE; + } } krb5_error_code pykadmin_unpack_xdr_osa_princ_ent_rec(PyKAdminObject *kadmin, krb5_db_entry *kdb, osa_princ_ent_rec *adb) { diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index b6f7413..c7f5eb3 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -9,50 +9,8 @@ #include -/* -kadm_principal_ent_rec reference - -typedef struct _kadm5_principal_ent_t { - - // done - krb5_principal principal; - krb5_principal mod_name; - - // how to expose timestamps? - krb5_timestamp princ_expire_time; - krb5_timestamp last_pwd_change; - krb5_timestamp pw_expiration; - krb5_timestamp mod_date; - - krb5_deltat max_life; - - krb5_kvno kvno; - krb5_kvno mkvno; - - char *policy; - - krb5_flags attributes; - long aux_attributes; - - // version 2 fields - - krb5_timestamp last_success; - krb5_timestamp last_failed; - - krb5_deltat max_renewable_life; - - krb5_kvno fail_auth_count; - - // these should not be accessed or modified directly by python. - krb5_int16 n_key_data; - krb5_int16 n_tl_data; - krb5_tl_data *tl_data; - krb5_key_data *key_data; - -} kadm5_principal_ent_rec, *kadm5_principal_ent_t; -*/ - +static const unsigned int kFLAG_MAX = (KRB5_KDB_DISALLOW_POSTDATED | KRB5_KDB_DISALLOW_FORWARDABLE | KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_DISALLOW_RENEWABLE | KRB5_KDB_DISALLOW_PROXIABLE | KRB5_KDB_DISALLOW_DUP_SKEY | KRB5_KDB_DISALLOW_ALL_TIX | KRB5_KDB_REQUIRES_PRE_AUTH | KRB5_KDB_REQUIRES_HW_AUTH | KRB5_KDB_REQUIRES_PWCHANGE | KRB5_KDB_DISALLOW_SVR | KRB5_KDB_PWCHANGE_SERVICE | KRB5_KDB_SUPPORT_DESMD5 | KRB5_KDB_NEW_PRINC | KRB5_KDB_OK_AS_DELEGATE | KRB5_KDB_OK_TO_AUTH_AS_DELEGATE | KRB5_KDB_NO_AUTH_DATA_REQUIRED); static void PyKAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { @@ -70,21 +28,18 @@ static PyObject *PyKAdminPrincipal_new(PyTypeObject *type, PyObject *args, PyObj self = (PyKAdminPrincipalObject *)type->tp_alloc(type, 0); - if (!self) - return NULL; - - memset(&self->entry, 0, sizeof(kadm5_principal_ent_rec)); + if (self) { + memset(&self->entry, 0, sizeof(kadm5_principal_ent_rec)); + } + return (PyObject *)self; } static int PyKAdminPrincipal_init(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - return 0; } - - static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int flags){ static const char *kPRINT_FORMAT = "%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s\n%s: %s"; @@ -118,20 +73,6 @@ static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, in } - -static PyMemberDef PyKAdminPrincipal_members[] = { - - {"failed_auth_count", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, - {"key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, - {"master_key_version_number", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, ""}, - - {"policy", T_STRING, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, policy), READONLY, ""}, - - {NULL} -}; - - - static PyObject *PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; @@ -186,13 +127,70 @@ static PyObject *PyKAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyO Py_RETURN_TRUE; } + +static PyObject *PyKAdminPrincipal_set_flags(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + + kadm5_ret_t retval = KADM5_OK; + unsigned int flag = 0; + + if (!PyArg_ParseTuple(args, "i", &flag)) + return NULL; + + if (flag <= kFLAG_MAX) { + + self->entry.attributes |= flag; + + retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + } + + Py_RETURN_TRUE; +} + +static PyObject *PyKAdminPrincipal_clear_flags(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + + kadm5_ret_t retval = KADM5_OK; + unsigned int flag = 0; + + if (!PyArg_ParseTuple(args, "(i)", &flag)) + return NULL; + + if (flag <= kFLAG_MAX) { + + self->entry.attributes &= ~flag; + + retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + } + + Py_RETURN_TRUE; +} + + static PyObject *PyKAdminPrincipal_reload(PyKAdminPrincipalObject *self) { + krb5_error_code ret = 0; kadm5_ret_t retval = KADM5_OK; + krb5_principal temp = NULL; + if (self) { - retval = kadm5_get_principal(self->kadmin->server_handle, self->entry.principal, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); return NULL; } + + // we need to free prior to fetching otherwise we leak memory since principal and policy are pointers, alternitively we could manually free those + ret = krb5_copy_principal(self->kadmin->context, self->entry.principal, &temp); + if (ret) {} + + retval = kadm5_free_principal_ent(self->kadmin->server_handle, &self->entry); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_free_principal_ent"); } + + if (retval == KADM5_OK) { + retval = kadm5_get_principal(self->kadmin->server_handle, temp, &self->entry, KADM5_PRINCIPAL_NORMAL_MASK); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_get_principal"); } + } + + krb5_free_principal(self->kadmin->context, temp); + + if (retval != KADM5_OK) { return NULL; } } Py_RETURN_TRUE; @@ -254,27 +252,6 @@ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { return result; } -static PyMethodDef PyKAdminPrincipal_methods[] = { - {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, - {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, - {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, - {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, - - {"expire", (PyCFunction)PyKAdminPrincipal_set_expire, METH_VARARGS, ""}, - {"set_policy", (PyCFunction)PyKAdminPrincipal_set_policy, METH_VARARGS, ""}, - {"clear_policy", (PyCFunction)PyKAdminPrincipal_clear_policy, METH_NOARGS, ""}, - - // TODO - //{"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, - //{"password_expire", (PyCFunction)NULL, METH_NOARGS, ""}, - - {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, ""}, - - {NULL, NULL, 0, NULL} -}; - - - static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, void *closure) { krb5_error_code ret = 0; @@ -403,7 +380,50 @@ static PyObject *PyKAdminPrincipal_get_max_renewable_life(PyKAdminPrincipalObjec return value; } +static PyObject *PyKAdminPrincipal_get_attributes(PyKAdminPrincipalObject *self, void *closure) { + + + unsigned int mask = 1; + PyObject *attrs = PyList_New(0); + + while (mask < kFLAG_MAX) { + + if (mask & self->entry.attributes) { + PyList_Append(attrs, PyInt_FromLong(mask)); + } + + mask = mask << 1; + } + + return attrs; + +} + + + +static PyMethodDef PyKAdminPrincipal_methods[] = { + + {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, + {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, + {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, + {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, + + {"expire", (PyCFunction)PyKAdminPrincipal_set_expire, METH_VARARGS, ""}, + {"set_policy", (PyCFunction)PyKAdminPrincipal_set_policy, METH_VARARGS, ""}, + {"clear_policy", (PyCFunction)PyKAdminPrincipal_clear_policy, METH_NOARGS, ""}, + + // TODO + {"set_flags", (PyCFunction)PyKAdminPrincipal_set_flags, METH_VARARGS, ""}, + {"clear_flags", (PyCFunction)PyKAdminPrincipal_clear_flags, METH_VARARGS, ""}, + + // TODO + // {"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, + // {"password_expire", (PyCFunction)NULL, METH_NOARGS, ""}, + {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, ""}, + + {NULL, NULL, 0, NULL} +}; static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { @@ -420,11 +440,25 @@ static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, "Kerberos Principal", NULL}, {"max_renewable_life", (getter)PyKAdminPrincipal_get_max_renewable_life, NULL, "Kerberos Principal", NULL}, + {"attributes", (getter)PyKAdminPrincipal_get_attributes, NULL, "Kerberos Principal", NULL}, {NULL, NULL, NULL, NULL, NULL} }; +static PyMemberDef PyKAdminPrincipal_members[] = { + + {"failures", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, + {"kvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, + {"mkvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, ""}, + + //{"attributes", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, attributes), READONLY, ""}, + + {"policy", T_STRING, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, policy), READONLY, ""}, + + {NULL} +}; + PyTypeObject PyKAdminPrincipalObject_Type = { PyObject_HEAD_INIT(NULL) diff --git a/kadmin.c b/kadmin.c index 9b71ed1..553e64e 100644 --- a/kadmin.c +++ b/kadmin.c @@ -41,6 +41,52 @@ static struct PyMethodDef module_methods[] = { {NULL, NULL, 0, NULL} }; +/* +#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001 +#define KRB5_KDB_DISALLOW_FORWARDABLE 0x00000002 +#define KRB5_KDB_DISALLOW_TGT_BASED 0x00000004 +#define KRB5_KDB_DISALLOW_RENEWABLE 0x00000008 +#define KRB5_KDB_DISALLOW_PROXIABLE 0x00000010 +#define KRB5_KDB_DISALLOW_DUP_SKEY 0x00000020 +#define KRB5_KDB_DISALLOW_ALL_TIX 0x00000040 +#define KRB5_KDB_REQUIRES_PRE_AUTH 0x00000080 +#define KRB5_KDB_REQUIRES_HW_AUTH 0x00000100 +#define KRB5_KDB_REQUIRES_PWCHANGE 0x00000200 +#define KRB5_KDB_DISALLOW_SVR 0x00001000 +#define KRB5_KDB_PWCHANGE_SERVICE 0x00002000 +#define KRB5_KDB_SUPPORT_DESMD5 0x00004000 +#define KRB5_KDB_NEW_PRINC 0x00008000 +#define KRB5_KDB_OK_AS_DELEGATE 0x00100000 +#define KRB5_KDB_OK_TO_AUTH_AS_DELEGATE 0x00200000 +#define KRB5_KDB_NO_AUTH_DATA_REQUIRED 0x00400000 + + +*/ + +void PyKAdminConstant_init(PyObject *module) { + + PyModule_AddIntConstant(module, "DISALLOW_POSTDATED", KRB5_KDB_DISALLOW_POSTDATED); + PyModule_AddIntConstant(module, "DISALLOW_FORWARDABLE", KRB5_KDB_DISALLOW_FORWARDABLE); + PyModule_AddIntConstant(module, "DISALLOW_TGT_BASED", KRB5_KDB_DISALLOW_TGT_BASED); + PyModule_AddIntConstant(module, "DISALLOW_RENEWABLE", KRB5_KDB_DISALLOW_RENEWABLE); + PyModule_AddIntConstant(module, "DISALLOW_PROXIABLE", KRB5_KDB_DISALLOW_PROXIABLE); + PyModule_AddIntConstant(module, "DISALLOW_DUP_SKEY", KRB5_KDB_DISALLOW_DUP_SKEY); + PyModule_AddIntConstant(module, "DISALLOW_ALL_TIX", KRB5_KDB_DISALLOW_ALL_TIX); + PyModule_AddIntConstant(module, "REQUIRES_PRE_AUTH", KRB5_KDB_REQUIRES_PRE_AUTH); + PyModule_AddIntConstant(module, "REQUIRES_HW_AUTH", KRB5_KDB_REQUIRES_HW_AUTH); + PyModule_AddIntConstant(module, "REQUIRES_PWCHANGE", KRB5_KDB_REQUIRES_PWCHANGE); + PyModule_AddIntConstant(module, "DISALLOW_SVR", KRB5_KDB_DISALLOW_SVR); + PyModule_AddIntConstant(module, "PWCHANGE_SERVICE", KRB5_KDB_PWCHANGE_SERVICE); + PyModule_AddIntConstant(module, "SUPPORT_DESMD5", KRB5_KDB_SUPPORT_DESMD5); + PyModule_AddIntConstant(module, "NEW_PRINC", KRB5_KDB_NEW_PRINC); + PyModule_AddIntConstant(module, "OK_AS_DELEGATE", KRB5_KDB_OK_AS_DELEGATE); + PyModule_AddIntConstant(module, "OK_TO_AUTH_AS_DELEGATE", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE); + PyModule_AddIntConstant(module, "NO_AUTH_DATA_REQUIRED", KRB5_KDB_NO_AUTH_DATA_REQUIRED); + +} + + + PyMODINIT_FUNC #ifdef KADMIN_LOCAL initkadmin_local(void) @@ -78,6 +124,7 @@ PyMODINIT_FUNC PyModule_AddObject(module, "KAdminError", KAdminError); PyKAdminError_init(module); + PyKAdminConstant_init(module); } diff --git a/test/unittests.py b/test/unittests.py index 8f40ab1..13a616a 100644 --- a/test/unittests.py +++ b/test/unittests.py @@ -66,7 +66,7 @@ def database_size(): return stdoutdata.count('\n') - 2 -class KAdminUnitTests(unittest.TestCase): +class KAdminUnitTests(): ''' Missing in 2.6 ''' def assertIsNotNone(self, expr, msg=None): From 71d26c8f9aa751311a54a2506e79bb9f520a486f Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Wed, 16 Jul 2014 20:12:25 -0400 Subject: [PATCH 23/25] getters/setters for principals --- PyKAdminCommon.c | 62 +++++ PyKAdminCommon.h | 11 + PyKAdminPolicyObject.c | 10 + PyKAdminPolicyObject.h | 7 +- PyKAdminPrincipalObject.c | 494 ++++++++++++++++++++++++++------------ PyKAdminPrincipalObject.h | 9 +- 6 files changed, 436 insertions(+), 157 deletions(-) diff --git a/PyKAdminCommon.c b/PyKAdminCommon.c index feebecd..b0f8a53 100644 --- a/PyKAdminCommon.c +++ b/PyKAdminCommon.c @@ -13,6 +13,20 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, #include "PyKAdminCommon.h" #include +#define TIME_NONE ((time_t) -1) + +int pykadmin_policy_exists(void *server_handle, char *name) { + + kadm5_ret_t retval = KADM5_OK; + kadm5_policy_ent_rec *policy = NULL; + + retval = kadm5_get_policy(server_handle, name, policy); + if (retval == KADM5_OK) + kadm5_free_policy_ent(server_handle, policy); + + return (retval == KADM5_OK); +} + inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { @@ -29,12 +43,60 @@ inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp) { Py_DECREF(args); } + if (!datetime) + PyErr_SetString(PyExc_AttributeError, NULL); + return datetime; } else { Py_RETURN_NONE; } } +int pykadmin_timestamp_from_pydatetime(PyObject *datetime) { + + PyDateTime_IMPORT; + + time_t timestamp = 0; + struct tm *timeinfo; + + if (datetime) { + + timeinfo = localtime ( ×tamp ); + + timeinfo->tm_year = PyDateTime_GET_YEAR(datetime) - 1900; + timeinfo->tm_mon = PyDateTime_GET_MONTH(datetime) - 1; + timeinfo->tm_mday = PyDateTime_GET_DAY(datetime); + + if (PyDateTime_Check(datetime)) { + timeinfo->tm_hour = PyDateTime_DATE_GET_HOUR(datetime) - 1 ; + timeinfo->tm_min = PyDateTime_DATE_GET_MINUTE(datetime); + timeinfo->tm_sec = PyDateTime_DATE_GET_SECOND(datetime); + } + + timestamp = mktime(timeinfo); + } else { + timestamp = TIME_NONE; + } + + return timestamp; +} + +int pykadmin_seconds_from_pydatetime(PyObject *delta) { + + PyDateTime_IMPORT; + + time_t seconds = 0; + + if (delta) { + seconds += PyDateTime_DELTA_GET_SECONDS(delta); + seconds += PyDateTime_DELTA_GET_DAYS(delta) * 24 * 3600; + } + + return seconds; + +} + + krb5_error_code pykadmin_unpack_xdr_osa_princ_ent_rec(PyKAdminObject *kadmin, krb5_db_entry *kdb, osa_princ_ent_rec *adb) { krb5_error_code retval = 0; diff --git a/PyKAdminCommon.h b/PyKAdminCommon.h index d5d5526..6071851 100644 --- a/PyKAdminCommon.h +++ b/PyKAdminCommon.h @@ -12,8 +12,19 @@ #include "PyKAdminXDR.h" #include "PyKAdminObject.h" + +#ifndef PYTHON3 +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) +#endif + +int pykadmin_policy_exists(void *server_handle, char *name); + inline PyObject *pykadmin_pydatetime_from_timestamp(time_t timestamp); +int pykadmin_timestamp_from_pydatetime(PyObject *datetime); +int pykadmin_seconds_from_pydatetime(PyObject *delta); krb5_error_code pykadmin_kadm_from_kdb(PyKAdminObject *kadmin, krb5_db_entry *kdb, kadm5_principal_ent_rec *entry, long mask); diff --git a/PyKAdminPolicyObject.c b/PyKAdminPolicyObject.c index 72dcd22..5b3e04f 100644 --- a/PyKAdminPolicyObject.c +++ b/PyKAdminPolicyObject.c @@ -103,6 +103,16 @@ PyObject *PyKAdminPolicy_RichCompare(PyObject *o1, PyObject *o2, int opid) { return result; } +char *PyKAdminPolicyObject_policy_name(PyKAdminPolicyObject *self) { + + char *name = NULL; + + if (self) + name = self->entry.policy; + + return name; +} + PyTypeObject PyKAdminPolicyObject_Type = { PyVarObject_HEAD_INIT(NULL, 0) // 0, /*ob_size*/ diff --git a/PyKAdminPolicyObject.h b/PyKAdminPolicyObject.h index 031d985..00d19a1 100644 --- a/PyKAdminPolicyObject.h +++ b/PyKAdminPolicyObject.h @@ -10,7 +10,7 @@ #include #include -#include "PyKadminCommon.h" +#include "PyKAdminCommon.h" extern time_t get_date(char *); @@ -22,7 +22,10 @@ typedef struct { PyTypeObject PyKAdminPolicyObject_Type; -#define PyKAdminPolicy_Check(policy) PyObject_TypeCheck(policy, &PyKAdminPolicyObject_Type) +//#define PyKAdminPolicy_Check(policy) PyObject_TypeCheck(policy, &PyKAdminPolicyObject_Type) +#define PyKAdminPolicyObject_CheckExact(obj) (Py_TYPE(obj) == &PyKAdminPolicyObject_Type) + +char *PyKAdminPolicyObject_policy_name(PyKAdminPolicyObject *self); PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_name(PyKAdminObject *kadmin, char *name); PyKAdminPolicyObject *PyKAdminPolicyObject_policy_with_osa_entry(PyKAdminObject *kadmin, osa_policy_ent_rec *entry); diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index c7f5eb3..9e7ccaa 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -9,8 +9,26 @@ #include - -static const unsigned int kFLAG_MAX = (KRB5_KDB_DISALLOW_POSTDATED | KRB5_KDB_DISALLOW_FORWARDABLE | KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_DISALLOW_RENEWABLE | KRB5_KDB_DISALLOW_PROXIABLE | KRB5_KDB_DISALLOW_DUP_SKEY | KRB5_KDB_DISALLOW_ALL_TIX | KRB5_KDB_REQUIRES_PRE_AUTH | KRB5_KDB_REQUIRES_HW_AUTH | KRB5_KDB_REQUIRES_PWCHANGE | KRB5_KDB_DISALLOW_SVR | KRB5_KDB_PWCHANGE_SERVICE | KRB5_KDB_SUPPORT_DESMD5 | KRB5_KDB_NEW_PRINC | KRB5_KDB_OK_AS_DELEGATE | KRB5_KDB_OK_TO_AUTH_AS_DELEGATE | KRB5_KDB_NO_AUTH_DATA_REQUIRED); +#define TIME_NONE ((time_t) -1) + +static const unsigned int kFLAG_MAX = + ( KRB5_KDB_DISALLOW_POSTDATED + | KRB5_KDB_DISALLOW_FORWARDABLE + | KRB5_KDB_DISALLOW_TGT_BASED + | KRB5_KDB_DISALLOW_RENEWABLE + | KRB5_KDB_DISALLOW_PROXIABLE + | KRB5_KDB_DISALLOW_DUP_SKEY + | KRB5_KDB_DISALLOW_ALL_TIX + | KRB5_KDB_REQUIRES_PRE_AUTH + | KRB5_KDB_REQUIRES_HW_AUTH + | KRB5_KDB_REQUIRES_PWCHANGE + | KRB5_KDB_DISALLOW_SVR + | KRB5_KDB_PWCHANGE_SERVICE + | KRB5_KDB_SUPPORT_DESMD5 + | KRB5_KDB_NEW_PRINC + | KRB5_KDB_OK_AS_DELEGATE + | KRB5_KDB_OK_TO_AUTH_AS_DELEGATE + | KRB5_KDB_NO_AUTH_DATA_REQUIRED ); static void PyKAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { @@ -73,100 +91,65 @@ static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, in } -static PyObject *PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - - kadm5_ret_t retval = KADM5_OK; - time_t date = 0; - char *expire = NULL; - if (!PyArg_ParseTuple(args, "s", &expire)) - return NULL; - - date = get_date(expire); - if (date == (time_t)-1 ) { - // todo raise exception - return NULL; - } - self->entry.princ_expire_time = date; - - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_PRINC_EXPIRE_TIME); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } - - Py_RETURN_TRUE; -} - - -static PyObject *PyKAdminPrincipal_clear_policy(PyKAdminPrincipalObject *self) { - - kadm5_ret_t retval = KADM5_OK; - - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY_CLR); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } - - Py_RETURN_TRUE; -} +static PyObject *PyKAdminPrincipal_set_attributes(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { + //kadm5_ret_t retval = KADM5_OK; + unsigned int flag = 0; -static PyObject *PyKAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - - kadm5_ret_t retval = KADM5_OK; + if (!PyArg_ParseTuple(args, "i", &flag)) + return NULL; - // todo: parse as a pyobject, if we pass in a PolicyObject we need to accept that too. + if (flag <= kFLAG_MAX) { - if (!PyArg_ParseTuple(args, "|z", &self->entry.policy)) - return NULL; + self->entry.attributes |= flag; + self->mask |= KADM5_ATTRIBUTES; - if (self->entry.policy == NULL) { - PyKAdminPrincipal_clear_policy(self); - } else { - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_POLICY); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + //retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); + //if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } } Py_RETURN_TRUE; } +static PyObject *PyKAdminPrincipal_unset_attributes(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { -static PyObject *PyKAdminPrincipal_set_flags(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - - kadm5_ret_t retval = KADM5_OK; + //kadm5_ret_t retval = KADM5_OK; unsigned int flag = 0; - if (!PyArg_ParseTuple(args, "i", &flag)) + if (!PyArg_ParseTuple(args, "(i)", &flag)) return NULL; if (flag <= kFLAG_MAX) { - self->entry.attributes |= flag; + self->entry.attributes &= ~flag; + self->mask |= KADM5_ATTRIBUTES; - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + //retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); + //if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } } Py_RETURN_TRUE; } -static PyObject *PyKAdminPrincipal_clear_flags(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { - kadm5_ret_t retval = KADM5_OK; - unsigned int flag = 0; - if (!PyArg_ParseTuple(args, "(i)", &flag)) - return NULL; +static PyObject *PyKAdminPrincipal_commit(PyKAdminPrincipalObject *self) { - if (flag <= kFLAG_MAX) { + kadm5_ret_t retval = KADM5_OK; - self->entry.attributes &= ~flag; + if (self && self->mask) { + + retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, self->mask); + if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); } - retval = kadm5_modify_principal(self->kadmin->server_handle, &self->entry, KADM5_ATTRIBUTES); - if (retval != KADM5_OK) { PyKAdmin_RaiseKAdminError(retval, "kadm5_modify_principal"); return NULL; } + self->mask = 0; } Py_RETURN_TRUE; } - static PyObject *PyKAdminPrincipal_reload(PyKAdminPrincipalObject *self) { krb5_error_code ret = 0; @@ -196,6 +179,12 @@ static PyObject *PyKAdminPrincipal_reload(PyKAdminPrincipalObject *self) { Py_RETURN_TRUE; } + +static PyObject *PyKAdminPrincipal_unlock(PyKAdminPrincipalObject *self) { + return NULL; +} + + static PyObject *PyKAdminPrincipal_change_password(PyKAdminPrincipalObject *self, PyObject *args, PyObject *kwds) { kadm5_ret_t retval = KADM5_OK; @@ -250,8 +239,14 @@ PyObject *PyKAdminPrincipal_RichCompare(PyObject *o1, PyObject *o2, int opid) { done: Py_XINCREF(result); return result; + + } +/* + * GETTERS + */ + static PyObject *PyKAdminPrincipal_get_principal(PyKAdminPrincipalObject *self, void *closure) { krb5_error_code ret = 0; @@ -288,139 +283,328 @@ static PyObject *PyKAdminPrincipal_get_mod_name(PyKAdminPrincipalObject *self, v } static PyObject *PyKAdminPrincipal_get_last_pwd_change(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.last_pwd_change); +} - PyObject *value = NULL; +static PyObject *PyKAdminPrincipal_get_expire(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.princ_expire_time); +} - value = pykadmin_pydatetime_from_timestamp(self->entry.last_pwd_change); +static PyObject *PyKAdminPrincipal_get_pwexpire(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.pw_expiration); +} - if (!value) { - // todo: raise exception - } +static PyObject *PyKAdminPrincipal_get_mod_date(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.mod_date); +} - return value; +static PyObject *PyKAdminPrincipal_get_last_success(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.last_success); } -static PyObject *PyKAdminPrincipal_get_princ_expire_time(PyKAdminPrincipalObject *self, void *closure) { +static PyObject *PyKAdminPrincipal_get_last_failed(PyKAdminPrincipalObject *self, void *closure) { + return pykadmin_pydatetime_from_timestamp(self->entry.last_failed); +} - PyObject *value = NULL; +static PyObject *PyKAdminPrincipal_get_maxrenewlife(PyKAdminPrincipalObject *self, void *closure) { - value = pykadmin_pydatetime_from_timestamp(self->entry.princ_expire_time); - - if (!value) { - // todo: raise exception + PyDateTime_IMPORT; + + PyObject *delta = PyDelta_FromDSU(0, self->entry.max_renewable_life, 0); + if (!delta) { PyErr_SetString(PyExc_AttributeError, NULL); } + + return delta; +} + + +static PyObject *PyKAdminPrincipal_get_maxlife(PyKAdminPrincipalObject *self, void *closure) { + + PyDateTime_IMPORT; + + PyObject *delta = PyDelta_FromDSU(0, self->entry.max_life, 0); + if (!delta) { PyErr_SetString(PyExc_AttributeError, NULL); } + + return delta; +} + +static PyObject *PyKAdminPrincipal_get_attributes(PyKAdminPrincipalObject *self, void *closure) { + + + unsigned int mask = 1; + PyObject *attrs = PyList_New(0); + + while (mask < kFLAG_MAX) { + + if (mask & self->entry.attributes) { + PyList_Append(attrs, PyInt_FromLong(mask)); + } + + mask = mask << 1; } - return value; + return attrs; + } -static PyObject *PyKAdminPrincipal_get_pw_expiration(PyKAdminPrincipalObject *self, void *closure) { +static PyObject *PyKAdminPrincipal_get_policy(PyKAdminPrincipalObject *self, void *closure) { + + PyObject *result = Py_None; + + if (self) { + + if (self->entry.policy) { + result = PyString_FromString(self->entry.policy); + } + } + + Py_XINCREF(result); + return result; +} - PyObject *value = NULL; +static PyObject *PyKAdminPrincipal_get_kvno(PyKAdminPrincipalObject *self, void *closure) { - value = pykadmin_pydatetime_from_timestamp(self->entry.pw_expiration); + PyObject *result = NULL; - if (!value) { - // todo: raise exception + if (self) { +#if PY_MAJOR_VERSION > 2 + result = PyLong_FromLong((long) self->entry.kvno); +#else + result = PyInt_FromLong((long) self->entry.kvno); +#endif } - return value; + Py_XINCREF(result); + return result; } -static PyObject *PyKAdminPrincipal_get_mod_date(PyKAdminPrincipalObject *self, void *closure) { - PyObject *value = NULL; +/* + * SETTERS + */ + +static krb5_deltat _decode_timedelta_input(PyObject *timedelta) { + + PyDateTime_IMPORT; + + time_t now; + krb5_deltat delta = TIME_NONE; + + if (timedelta) { + + char *date_string = NULL; + + if (PyDelta_CheckExact(timedelta)) { + delta = pykadmin_seconds_from_pydatetime(timedelta); + } else if (PyUnicode_CheckExact(timedelta)) { + // TODO: unicode + } else if (PyString_CheckExact(timedelta)) { + date_string = PyString_AsString(timedelta); + + } else if (timedelta == Py_None) { + date_string = "never"; + } + + if (date_string) { + delta = get_date(date_string); + } - value = pykadmin_pydatetime_from_timestamp(self->entry.mod_date); - - if (!value) { - // todo: raise exception } - return value; + if (delta == TIME_NONE) { + PyErr_SetString(PyExc_ValueError, "Invalid input"); + } else if (delta != 0) { + time(&now); + delta -= now; + } + + return delta; + } -static PyObject *PyKAdminPrincipal_get_last_success(PyKAdminPrincipalObject *self, void *closure) { +static krb5_timestamp _decode_datetime_input(PyObject *date) { - PyObject *value = NULL; + PyDateTime_IMPORT; + + krb5_timestamp timestamp = TIME_NONE; + + //static const char *kDATE_NEVER = "never"; + + if (date) { + + char *date_string = NULL; + + if (PyDate_CheckExact(date) || PyDateTime_CheckExact(date)) { + timestamp = pykadmin_timestamp_from_pydatetime(date); + + } else if (PyUnicode_CheckExact(date)) { + // TODO: unicode + } else if (PyString_CheckExact(date)) { + date_string = PyString_AsString(date); + + } else if (date == Py_None) { + date_string = "never"; + + } + + if (date_string) { + timestamp = get_date(date_string); + } - value = pykadmin_pydatetime_from_timestamp(self->entry.last_success); - - if (!value) { - // todo: raise exception } - return value; + if (timestamp == TIME_NONE) + PyErr_SetString(PyExc_ValueError, "Invalid input"); + + return timestamp; } -static PyObject *PyKAdminPrincipal_get_last_failed(PyKAdminPrincipalObject *self, void *closure) { - PyObject *value = NULL; +int PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { - value = pykadmin_pydatetime_from_timestamp(self->entry.last_failed); - - if (!value) { - // todo: raise exception + krb5_timestamp timestamp = _decode_datetime_input(value); + + if (timestamp == TIME_NONE) { + return 1; } - return value; + self->entry.princ_expire_time = timestamp; + self->mask |= KADM5_PRINC_EXPIRE_TIME; + + return 0; } -static PyObject *PyKAdminPrincipal_get_max_renewable_life(PyKAdminPrincipalObject *self, void *closure) { +int PyKAdminPrincipal_set_pwexpire(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { - PyDateTime_IMPORT; + krb5_timestamp timestamp = _decode_datetime_input(value); - PyObject *value = NULL; + if (timestamp == TIME_NONE) { + return 1; + } - value = PyDelta_FromDSU(0, self->entry.max_renewable_life, 0); - - if (!value) { - // todo: raise exception + self->entry.princ_expire_time = timestamp; + self->mask |= KADM5_PW_EXPIRATION; + + return 0; + +} + +int PyKAdminPrincipal_set_maxlife(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { + + krb5_timestamp timestamp = _decode_timedelta_input(value); + + if (timestamp == TIME_NONE) { + return 1; } - return value; + self->entry.max_life = timestamp; + self->mask |= KADM5_MAX_LIFE; + + return 0; + } -static PyObject *PyKAdminPrincipal_get_attributes(PyKAdminPrincipalObject *self, void *closure) { +int PyKAdminPrincipal_set_maxrenewlife(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { + krb5_timestamp timestamp = _decode_timedelta_input(value); - unsigned int mask = 1; - PyObject *attrs = PyList_New(0); + if (timestamp == TIME_NONE) { + return 1; + } - while (mask < kFLAG_MAX) { + self->entry.max_renewable_life = timestamp; + self->mask |= KADM5_MAX_RLIFE; - if (mask & self->entry.attributes) { - PyList_Append(attrs, PyInt_FromLong(mask)); - } + return 0; - mask = mask << 1; +} + + +int PyKAdminPrincipal_set_kvno(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { + + unsigned long kvno = 0; + + if (self) { +#if PY_MAJOR_VERSION > 2 + kvno = PyLong_AsUnsignedLong(value); +#else + kvno = PyInt_AsUnsignedLongMask(value); +#endif + } + + if (!PyErr_Occurred()) { + self->entry.kvno = (unsigned int)kvno; + self->mask |= KADM5_KVNO; } - return attrs; + return 0; } +int PyKAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { + + char *policy_string = NULL; + + if (self) { + + if (value) { + + if (value == Py_None) { + self->mask &= ~KADM5_POLICY; + self->mask |= KADM5_POLICY_CLR; + } + + if (PyUnicode_CheckExact(value)) { + // TODO + } else if (PyString_CheckExact(value)) { + + policy_string = PyString_AsString(value); + + } else if (PyKAdminPolicyObject_CheckExact(value)) { + + policy_string = PyKAdminPolicyObject_policy_name((PyKAdminPolicyObject *)value); + + } + + if (policy_string) { + + if (pykadmin_policy_exists(self->kadmin->server_handle, policy_string)) { + + if (self->entry.policy) { + free(self->entry.policy); + } + + self->entry.policy = policy_string; + // set policy flag and remove policy clear flag if set. + self->mask |= KADM5_POLICY; + self->mask &= ~KADM5_POLICY_CLR; + } + } + + } + } + + return 0; + +} static PyMethodDef PyKAdminPrincipal_methods[] = { - {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, - {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, ""}, - {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, - {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, ""}, - - {"expire", (PyCFunction)PyKAdminPrincipal_set_expire, METH_VARARGS, ""}, - {"set_policy", (PyCFunction)PyKAdminPrincipal_set_policy, METH_VARARGS, ""}, - {"clear_policy", (PyCFunction)PyKAdminPrincipal_clear_policy, METH_NOARGS, ""}, + {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, "doc string"}, + {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, "doc string"}, + {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, "doc string"}, + {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, "doc string"}, - // TODO - {"set_flags", (PyCFunction)PyKAdminPrincipal_set_flags, METH_VARARGS, ""}, - {"clear_flags", (PyCFunction)PyKAdminPrincipal_clear_flags, METH_VARARGS, ""}, + // TODO: principal.modify(expire=a, pwexpire=b, maxlife=c, maxrenewlife=d, attributes=e, policy=f, kvno=g) + //{"modify" (PyCFunction)NULL, METH_KEYWORDS, "doc string"} - // TODO - // {"set_max_renew", (PyCFunction)NULL, METH_NOARGS, ""}, - // {"password_expire", (PyCFunction)NULL, METH_NOARGS, ""}, + {"commit", (PyCFunction)PyKAdminPrincipal_commit, METH_NOARGS, "doc string"}, + {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, "doc string"}, + {"unlock", (PyCFunction)PyKAdminPrincipal_unlock, METH_NOARGS, "doc string"}, - {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, ""}, + {"set_flags", (PyCFunction)PyKAdminPrincipal_set_attributes, METH_NOARGS, "doc string"}, + {"unset_flags", (PyCFunction)PyKAdminPrincipal_unset_attributes, METH_NOARGS, "doc string"}, + {NULL, NULL, 0, NULL} }; @@ -428,19 +612,27 @@ static PyMethodDef PyKAdminPrincipal_methods[] = { static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { - {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, - {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "Kerberos Principal", NULL}, - {"mod_name", (getter)PyKAdminPrincipal_get_mod_name, NULL, "Kerberos Principal", NULL}, + {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "doc string", NULL}, + {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "doc string", NULL}, - {"last_password_change", (getter)PyKAdminPrincipal_get_last_pwd_change, NULL, "Kerberos Principal", NULL}, - {"expire_time", (getter)PyKAdminPrincipal_get_princ_expire_time, NULL, "Kerberos Principal", NULL}, - {"password_expiration", (getter)PyKAdminPrincipal_get_pw_expiration, NULL, "Kerberos Principal", NULL}, - {"mod_date", (getter)PyKAdminPrincipal_get_mod_date, NULL, "Kerberos Principal", NULL}, - {"last_success", (getter)PyKAdminPrincipal_get_last_success, NULL, "Kerberos Principal", NULL}, - {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, "Kerberos Principal", NULL}, + {"mod_name", (getter)PyKAdminPrincipal_get_mod_name, NULL, "doc string", NULL}, + {"mod_date", (getter)PyKAdminPrincipal_get_mod_date, NULL, "doc string", NULL}, - {"max_renewable_life", (getter)PyKAdminPrincipal_get_max_renewable_life, NULL, "Kerberos Principal", NULL}, - {"attributes", (getter)PyKAdminPrincipal_get_attributes, NULL, "Kerberos Principal", NULL}, + {"last_pwd_change", (getter)PyKAdminPrincipal_get_last_pwd_change, NULL, "doc string", NULL}, + {"last_success", (getter)PyKAdminPrincipal_get_last_success, NULL, "doc string", NULL}, + {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, "doc string", NULL}, + + // setter attributes + + {"expire", (getter)PyKAdminPrincipal_get_expire, (setter)PyKAdminPrincipal_set_expire, "doc string", NULL}, + {"pwexpire", (getter)PyKAdminPrincipal_get_pwexpire, (setter)PyKAdminPrincipal_set_pwexpire, "doc string", NULL}, + + {"maxlife", (getter)PyKAdminPrincipal_get_maxlife, (setter)PyKAdminPrincipal_set_maxlife, "doc string", NULL}, + {"maxrenewlife", (getter)PyKAdminPrincipal_get_maxrenewlife, (setter)PyKAdminPrincipal_set_maxrenewlife, "doc string", NULL}, + {"attributes", (getter)PyKAdminPrincipal_get_attributes, (setter)PyKAdminPrincipal_set_attributes, "doc string", NULL}, + + {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, "doc string", NULL}, + {"kvno", (getter)PyKAdminPrincipal_get_kvno, (setter)PyKAdminPrincipal_set_kvno, "doc string", NULL}, {NULL, NULL, NULL, NULL, NULL} }; @@ -448,21 +640,17 @@ static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { static PyMemberDef PyKAdminPrincipal_members[] = { - {"failures", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, ""}, - {"kvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, kvno), READONLY, ""}, - {"mkvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, ""}, - - //{"attributes", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, attributes), READONLY, ""}, - - {"policy", T_STRING, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, policy), READONLY, ""}, + {"failures", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, "doc string"}, + {"mkvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, "doc string"}, {NULL} }; PyTypeObject PyKAdminPrincipalObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) + //PyObject_HEAD_INIT(NULL) + //0, /*ob_size*/ "kadmin.Principal", /*tp_name*/ sizeof(PyKAdminPrincipalObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ diff --git a/PyKAdminPrincipalObject.h b/PyKAdminPrincipalObject.h index 3648b4d..c77dba3 100644 --- a/PyKAdminPrincipalObject.h +++ b/PyKAdminPrincipalObject.h @@ -16,11 +16,16 @@ typedef struct { PyObject_HEAD PyKAdminObject *kadmin; kadm5_principal_ent_rec entry; -} PyKAdminPrincipalObject; -#define PyKAdminPrincipalObject_Check(principal) PyObject_TypeCheck(principal, &PyKAdminPrincipalObject_Type) + unsigned int mask; + +} PyKAdminPrincipalObject; PyTypeObject PyKAdminPrincipalObject_Type; + +//#define PyKAdminPrincipalObject_Check(principal) PyObject_TypeCheck(principal, &PyKAdminPrincipalObject_Type) +#define PyKAdminPrincipalObject_CheckExact(obj) (Py_TYPE(obj) == &PyKAdminPrincipalObject_Type) + PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name); PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdminObject *kadmin, krb5_db_entry *kdb); PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_kadm_entry(PyKAdminObject *kadmin, kadm5_principal_ent_rec *entry); From de4e64fdb5a515c3427efab533c0300bd2ce37c6 Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Wed, 16 Jul 2014 20:55:02 -0400 Subject: [PATCH 24/25] docstrings --- PyKAdminPrincipalObject.c | 89 +++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index 9e7ccaa..a2c11c9 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -386,7 +386,7 @@ static krb5_deltat _decode_timedelta_input(PyObject *timedelta) { PyDateTime_IMPORT; - time_t now; + time_t now = 0; krb5_deltat delta = TIME_NONE; if (timedelta) { @@ -421,14 +421,12 @@ static krb5_deltat _decode_timedelta_input(PyObject *timedelta) { } -static krb5_timestamp _decode_datetime_input(PyObject *date) { +static krb5_timestamp _decode_timestamp_input(PyObject *date) { PyDateTime_IMPORT; krb5_timestamp timestamp = TIME_NONE; - //static const char *kDATE_NEVER = "never"; - if (date) { char *date_string = NULL; @@ -461,7 +459,7 @@ static krb5_timestamp _decode_datetime_input(PyObject *date) { int PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { - krb5_timestamp timestamp = _decode_datetime_input(value); + krb5_timestamp timestamp = _decode_timestamp_input(value); if (timestamp == TIME_NONE) { return 1; @@ -475,7 +473,7 @@ int PyKAdminPrincipal_set_expire(PyKAdminPrincipalObject *self, PyObject *value, int PyKAdminPrincipal_set_pwexpire(PyKAdminPrincipalObject *self, PyObject *value, void *closure) { - krb5_timestamp timestamp = _decode_datetime_input(value); + krb5_timestamp timestamp = _decode_timestamp_input(value); if (timestamp == TIME_NONE) { return 1; @@ -587,23 +585,49 @@ int PyKAdminPrincipal_set_policy(PyKAdminPrincipalObject *self, PyObject *value, } +/* + * Documentation Strings + */ + +static char kDOCSTRING_COMMIT[] = "commit()\n\tCommit all staged changes to the kerberos database."; +static char kDOCSTRING_CPW[] = "change_password(str)\n\tChange the password for the given principal."; +static char kDOCSTRING_RANDKEY[] = "randkey()\n\tRandomize the key for the given principal."; +static char kDOCSTRING_RELOAD[] = "reload()\n\tReload the local entry from the kerberos database."; +static char kDOCSTRING_UNLOCK[] = "unlock()\n\tUnlock the principal."; +static char kDOCSTRING_SET_FLAGS[] = "set_flags(KADM5_ATTRIBUTES)\n\tSet attributes to their enabled (1) state."; +static char kDOCSTRING_UNSET_FLAGS[] = "unset_flags(KADM5_ATTRIBUTES)\n\tSet attributes to their diabled (0) state."; +static char kDOCSTRING_NAME[] = "str\n\tPrincipal name as a string."; +static char kDOCSTRING_MOD_NAME[] = "str\n\tThe account which last modified the principal as a string."; +static char kDOCSTRING_MOD_DATE[] = "datetime.datetime\n\tThe datetime at which the principal was last modified."; +static char kDOCSTRING_LAST_PWD_CHANGE[] = "datetime.datetime\n\tThe datetime at which the password was last changed."; +static char kDOCSTRING_LAST_SUCCESS[] = "datetime.datetime\n\tThe last successful authentication."; +static char kDOCSTRING_LAST_FAILURE[] = "datetime.datetime\n\tThe last failed authentication."; +static char kDOCSTRING_ATTRIBUTES[] = "list\n\tlist of all attributes which have been set."; +static char kDOCSTRING_EXPIRE[] = "getter: datetime.datetime\n\tsetter: [datetime.date|datetime.datetime|str|None]\n\twhen the account expires."; +static char kDOCSTRING_PWEXPIRE[] = "getter: datetime.datetime\n\tsetter: [datetime.date|datetime.datetime|str|None]\n\twhen the current password expires."; +static char kDOCSTRING_MAXLIFE[] = "getter: datetime.timedelta\n\tsetter: [datetime.timedelta|str|None]\n\tthe maximum ticket life."; +static char kDOCSTRING_MAXRENEWLIFE[] = "getter: datetime.timedelta\n\tsetter: [datetime.timedelta|str|None]\n\tthe maximum renewable life."; +static char kDOCSTRING_POLICY[] = "getter: [str|None]\n\tsetter: [str|kadmin.Policy|None]\n\tpolicy enabled for the principal."; +static char kDOCSTRING_KVNO[] = "getter: int\n\tsetter: [int]\n\tcurrent key version number."; +static char kDOCSTRING_FAILURES[] = "failed authentication count."; +static char kDOCSTRING_MKVNO[] = "master key version number."; static PyMethodDef PyKAdminPrincipal_methods[] = { - {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, "doc string"}, - {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, "doc string"}, - {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, "doc string"}, - {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, "doc string"}, + {"cpw", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, kDOCSTRING_CPW}, + {"change_password", (PyCFunction)PyKAdminPrincipal_change_password, METH_VARARGS, kDOCSTRING_CPW}, + {"randkey", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, kDOCSTRING_RANDKEY}, + {"randomize_key", (PyCFunction)PyKAdminPrincipal_randomize_key, METH_NOARGS, kDOCSTRING_RANDKEY}, // TODO: principal.modify(expire=a, pwexpire=b, maxlife=c, maxrenewlife=d, attributes=e, policy=f, kvno=g) //{"modify" (PyCFunction)NULL, METH_KEYWORDS, "doc string"} - {"commit", (PyCFunction)PyKAdminPrincipal_commit, METH_NOARGS, "doc string"}, - {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, "doc string"}, - {"unlock", (PyCFunction)PyKAdminPrincipal_unlock, METH_NOARGS, "doc string"}, + {"commit", (PyCFunction)PyKAdminPrincipal_commit, METH_NOARGS, kDOCSTRING_COMMIT}, + {"reload", (PyCFunction)PyKAdminPrincipal_reload, METH_NOARGS, kDOCSTRING_RELOAD}, + {"unlock", (PyCFunction)PyKAdminPrincipal_unlock, METH_NOARGS, kDOCSTRING_UNLOCK}, - {"set_flags", (PyCFunction)PyKAdminPrincipal_set_attributes, METH_NOARGS, "doc string"}, - {"unset_flags", (PyCFunction)PyKAdminPrincipal_unset_attributes, METH_NOARGS, "doc string"}, + {"set_flags", (PyCFunction)PyKAdminPrincipal_set_attributes, METH_VARARGS, kDOCSTRING_SET_FLAGS}, + {"unset_flags", (PyCFunction)PyKAdminPrincipal_unset_attributes, METH_VARARGS, kDOCSTRING_UNSET_FLAGS}, {NULL, NULL, 0, NULL} @@ -612,36 +636,37 @@ static PyMethodDef PyKAdminPrincipal_methods[] = { static PyGetSetDef PyKAdminPrincipal_getters_setters[] = { - {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, "doc string", NULL}, - {"name", (getter)PyKAdminPrincipal_get_principal, NULL, "doc string", NULL}, + {"principal", (getter)PyKAdminPrincipal_get_principal, NULL, kDOCSTRING_NAME, NULL}, + {"name", (getter)PyKAdminPrincipal_get_principal, NULL, kDOCSTRING_NAME, NULL}, - {"mod_name", (getter)PyKAdminPrincipal_get_mod_name, NULL, "doc string", NULL}, - {"mod_date", (getter)PyKAdminPrincipal_get_mod_date, NULL, "doc string", NULL}, + {"mod_name", (getter)PyKAdminPrincipal_get_mod_name, NULL, kDOCSTRING_MOD_NAME, NULL}, + {"mod_date", (getter)PyKAdminPrincipal_get_mod_date, NULL, kDOCSTRING_MOD_DATE, NULL}, + + {"last_pwd_change", (getter)PyKAdminPrincipal_get_last_pwd_change, NULL, kDOCSTRING_LAST_PWD_CHANGE, NULL}, + {"last_success", (getter)PyKAdminPrincipal_get_last_success, NULL, kDOCSTRING_LAST_SUCCESS, NULL}, + {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, kDOCSTRING_LAST_FAILURE, NULL}, + + {"attributes", (getter)PyKAdminPrincipal_get_attributes, NULL, kDOCSTRING_ATTRIBUTES, NULL}, - {"last_pwd_change", (getter)PyKAdminPrincipal_get_last_pwd_change, NULL, "doc string", NULL}, - {"last_success", (getter)PyKAdminPrincipal_get_last_success, NULL, "doc string", NULL}, - {"last_failure", (getter)PyKAdminPrincipal_get_last_failed, NULL, "doc string", NULL}, // setter attributes - {"expire", (getter)PyKAdminPrincipal_get_expire, (setter)PyKAdminPrincipal_set_expire, "doc string", NULL}, - {"pwexpire", (getter)PyKAdminPrincipal_get_pwexpire, (setter)PyKAdminPrincipal_set_pwexpire, "doc string", NULL}, + {"expire", (getter)PyKAdminPrincipal_get_expire, (setter)PyKAdminPrincipal_set_expire, kDOCSTRING_EXPIRE, NULL}, + {"pwexpire", (getter)PyKAdminPrincipal_get_pwexpire, (setter)PyKAdminPrincipal_set_pwexpire, kDOCSTRING_PWEXPIRE, NULL}, - {"maxlife", (getter)PyKAdminPrincipal_get_maxlife, (setter)PyKAdminPrincipal_set_maxlife, "doc string", NULL}, - {"maxrenewlife", (getter)PyKAdminPrincipal_get_maxrenewlife, (setter)PyKAdminPrincipal_set_maxrenewlife, "doc string", NULL}, - {"attributes", (getter)PyKAdminPrincipal_get_attributes, (setter)PyKAdminPrincipal_set_attributes, "doc string", NULL}, + {"maxlife", (getter)PyKAdminPrincipal_get_maxlife, (setter)PyKAdminPrincipal_set_maxlife, kDOCSTRING_MAXLIFE, NULL}, + {"maxrenewlife", (getter)PyKAdminPrincipal_get_maxrenewlife, (setter)PyKAdminPrincipal_set_maxrenewlife, kDOCSTRING_MAXRENEWLIFE, NULL}, - {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, "doc string", NULL}, - {"kvno", (getter)PyKAdminPrincipal_get_kvno, (setter)PyKAdminPrincipal_set_kvno, "doc string", NULL}, + {"policy", (getter)PyKAdminPrincipal_get_policy, (setter)PyKAdminPrincipal_set_policy, kDOCSTRING_POLICY, NULL}, + {"kvno", (getter)PyKAdminPrincipal_get_kvno, (setter)PyKAdminPrincipal_set_kvno, kDOCSTRING_KVNO, NULL}, {NULL, NULL, NULL, NULL, NULL} }; - static PyMemberDef PyKAdminPrincipal_members[] = { - {"failures", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, "doc string"}, - {"mkvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, "doc string"}, + {"failures", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, fail_auth_count), READONLY, kDOCSTRING_FAILURES}, + {"mkvno", T_INT, offsetof(PyKAdminPrincipalObject, entry) + offsetof(kadm5_principal_ent_rec, mkvno), READONLY, kDOCSTRING_MKVNO}, {NULL} }; From 2579a7d0be4a6528373a4bd7b5a952ee350d6cdf Mon Sep 17 00:00:00 2001 From: Russell Jancewicz Date: Wed, 16 Jul 2014 21:56:39 -0400 Subject: [PATCH 25/25] fixes to getprinc to prevent double free --- PyKAdminObject.c | 2 +- PyKAdminPrincipalObject.c | 14 +++++++++----- test/unittests.py | 13 +++++++------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/PyKAdminObject.c b/PyKAdminObject.c index 16a1eb0..b978f52 100644 --- a/PyKAdminObject.c +++ b/PyKAdminObject.c @@ -149,7 +149,7 @@ static PyKAdminPrincipalObject *PyKAdminObject_get_principal(PyKAdminObject *sel return NULL; } - if (self->server_handle) { + if (self) { principal = PyKAdminPrincipalObject_principal_with_name(self, client_name); } diff --git a/PyKAdminPrincipalObject.c b/PyKAdminPrincipalObject.c index a2c11c9..f7e4aa5 100644 --- a/PyKAdminPrincipalObject.c +++ b/PyKAdminPrincipalObject.c @@ -32,7 +32,7 @@ static const unsigned int kFLAG_MAX = static void PyKAdminPrincipal_dealloc(PyKAdminPrincipalObject *self) { - + kadm5_free_principal_ent(self->kadmin->server_handle, &self->entry); Py_XDECREF(self->kadmin); @@ -719,8 +719,10 @@ PyTypeObject PyKAdminPrincipalObject_Type = { PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObject *kadmin, char *client_name) { krb5_error_code errno; + kadm5_ret_t retval = KADM5_OK; PyKAdminPrincipalObject *principal = (PyKAdminPrincipalObject *)Py_None; + krb5_principal temp = NULL; if (client_name) { @@ -731,12 +733,14 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj Py_INCREF(kadmin); principal->kadmin = kadmin; - errno = krb5_parse_name(kadmin->context, client_name, &principal->entry.principal); - PyObject *result = PyKAdminPrincipal_reload(principal); + errno = krb5_parse_name(kadmin->context, client_name, &temp); + retval = kadm5_get_principal(kadmin->server_handle, temp, &principal->entry, KADM5_PRINCIPAL_NORMAL_MASK); - if (!result || errno) { - Py_INCREF(Py_None); + krb5_free_principal(kadmin->context, temp); + + if ((retval != KADM5_OK) || errno) { PyKAdminPrincipal_dealloc(principal); + Py_INCREF(Py_None); principal = (PyKAdminPrincipalObject *)Py_None; } diff --git a/test/unittests.py b/test/unittests.py index 13a616a..b5b84c0 100644 --- a/test/unittests.py +++ b/test/unittests.py @@ -66,7 +66,7 @@ def database_size(): return stdoutdata.count('\n') - 2 -class KAdminUnitTests(): +class KAdminUnitTests(unittest.TestCase): ''' Missing in 2.6 ''' def assertIsNotNone(self, expr, msg=None): @@ -87,7 +87,7 @@ def setUp(self): self.kadm = kadm self.logger = logging.getLogger('python-kadmin') - + def test_init_with_keytab(self): try: @@ -186,7 +186,7 @@ def test_double_delete(self): account = TEST_ACCOUNTS[0] self.assertRaises(kadmin.KAdminError, kadm.delprinc, account) - + def test_iteration(self): kadm = self.kadm @@ -198,7 +198,7 @@ def test_iteration(self): self.assertEqual(count, size) - + def test_not_exists(self): kadm = self.kadm @@ -241,11 +241,12 @@ def test_princ_compare_ne(self): b = kadm.getprinc(account) self.assertNotEqual(a, b) - + class KAdminLocalUnitTests(unittest.TestCase): - +#class KAdminLocalUnitTests(): + ''' Missing in 2.6 ''' def assertIsNotNone(self, expr, msg=None): self.assertFalse((expr is None), msg)