Skip to content
This repository was archived by the owner on Sep 16, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions PyKAdminObject.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,40 @@ static int PyKAdminObject_init(PyKAdminObject *self, PyObject *args, PyObject *k
return 0;
}


static PyObject *PyKAdminObject_principal_exists(PyKAdminObject *self, PyObject *args, PyObject *kwds) {

kadm5_ret_t retval = KADM5_OK;
krb5_error_code code = 0;
krb5_principal princ = NULL;

char *client_name = NULL;
PyObject *result = NULL;

kadm5_principal_ent_rec entry;

if (!PyArg_ParseTuple(args, "s", &client_name))
return NULL;

if (self->server_handle) {

code = krb5_parse_name(self->context, client_name, &princ);
if (code) { PyKAdmin_RETURN_ERROR(retval, "krb5_parse_name"); }

retval = kadm5_get_principal(self->server_handle, princ, &entry, KADM5_PRINCIPAL);
if (retval == KADM5_OK) { result = Py_True; }
else if (retval == KADM5_UNK_PRINC) { result = Py_False; }
else { PyKAdmin_RETURN_ERROR(retval, "kadm5_delete_principal"); }
}

krb5_free_principal(self->context, princ);
kadm5_free_principal_ent(self->server_handle, &entry);

Py_XINCREF(result);
return result;

}

static PyObject *PyKAdminObject_delete_principal(PyKAdminObject *self, PyObject *args, PyObject *kwds) {


Expand Down Expand Up @@ -368,6 +402,8 @@ static PyMethodDef PyKAdminObject_methods[] = {
{"delprinc", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""},
{"delete_principal", (PyCFunction)PyKAdminObject_delete_principal, METH_VARARGS, ""},

{"principal_exists", (PyCFunction)PyKAdminObject_principal_exists, METH_VARARGS, ""},

// kadmin modify princ, rename princ

{"getprinc", (PyCFunction)PyKAdminObject_get_principal, METH_VARARGS, ""},
Expand Down
167 changes: 150 additions & 17 deletions PyKAdminPrincipalObject.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

#define TIME_NONE ((time_t) -1)


static PyObject *PyKAdminPrincipal_get_keys(PyKAdminPrincipalObject *self, void *closure);

static char kNEVER[] = "never";

static const unsigned int kFLAG_MAX =
Expand Down Expand Up @@ -68,12 +71,55 @@ static PyObject *PyKAdminPrincipal_str(PyKAdminPrincipalObject *self) {
}


static void _PyKAdminPrincipal_print_keys(PyKAdminPrincipalObject *self, FILE *file, int flags) {

PyObject *keys = PyKAdminPrincipal_get_keys(self, NULL);

PyObject *kvno;
PyObject *value;
PyObject *tuple;
PyObject *enctype;
PyObject *salttype;

ssize_t pos = 0;
ssize_t index = 0;

if (keys) {

while (PyDict_Next(keys, &pos, &kvno, &value)) {

if (PyList_Check(value)) {

for (index = 0; index < PyList_Size(value); index++) {

tuple = PyList_GetItem(value, index);

if (PyTuple_Check(tuple)) {

if (PyTuple_Size(tuple) == 2) {

enctype = PyTuple_GetItem(tuple, 0);
salttype = PyTuple_GetItem(tuple, 1);

fprintf(file, "Key: vno %ld, %s, %s\n", PyUnifiedLongInt_AsLong(kvno), PyUnicode_or_PyBytes_asCString(enctype), PyUnicode_or_PyBytes_asCString(salttype));

}
}
}
}
}

Py_DECREF(keys);
}

}

static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, int flags){

static char kNEVER_DATE[] = "[never]";
static char kNONE_DATE[] = "[none]";

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: %d\n%s: %s\n%s: %s";
//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: %d\n%s: %d\n%s: %s";

krb5_error_code errno;
char *client_name = NULL;
Expand All @@ -100,20 +146,23 @@ static int PyKAdminPrincipal_print(PyKAdminPrincipalObject *self, FILE *file, in
maxlife = pykadmin_timestamp_as_deltastr(self->entry.max_life, kNONE_DATE);
maxrlife = pykadmin_timestamp_as_deltastr(self->entry.max_renewable_life, kNONE_DATE);

fprintf(file, kPRINT_FORMAT,
"Principal", client_name,
"Expiration date", expire,
"Last password change", pwchange,
"Password expiration date", pwexpire,
"Maximum ticket life", maxlife,
"Maximum renewable life", maxrlife,
"Last modified", moddate,
"Last successful authentication", success,
"Last failed authentication", failure,
"Failed password attempts", self->entry.fail_auth_count,
"Number of keys", "(TODO)",
"Policy", self->entry.policy ? self->entry.policy : kNONE_DATE
);
//fprintf(file, kPRINT_FORMAT,
fprintf(file, "Principal: %s\n", client_name);
fprintf(file, "Expiration date: %s\n", expire);
fprintf(file, "Last password change: %s\n", pwchange);
fprintf(file, "Password expiration date: %s\n", pwexpire);
fprintf(file, "Maximum ticket life: %s\n", maxlife);
fprintf(file, "Maximum renewable life: %s\n", maxrlife);
fprintf(file, "Last modified: %s\n", moddate);
fprintf(file, "Last successful authentication: %s\n", success);
fprintf(file, "Last failed authentication: %s\n", failure);
fprintf(file, "Failed password attempts: %d\n", self->entry.fail_auth_count);
fprintf(file, "Number of keys: %d\n", self->entry.n_key_data);

_PyKAdminPrincipal_print_keys(self, file, flags);

fprintf(file, "Policy: %s", self->entry.policy ? self->entry.policy : kNONE_DATE );

}

if (client_name) { free(client_name); }
Expand Down Expand Up @@ -409,6 +458,89 @@ static PyObject *PyKAdminPrincipal_get_kvno(PyKAdminPrincipalObject *self, void
}



PyObject *pykadmin_key_enctype_name(krb5_key_data *key_data) {

PyObject *enctype = NULL;
// make sure this is enough.
char buffer[1024];

if (krb5_enctype_to_name(key_data->key_data_type[0], FALSE, buffer, sizeof(buffer)))
snprintf(buffer, sizeof(buffer), "<Encryption type 0x%x>", key_data->key_data_type[0]);

enctype = PyUnicode_FromString(buffer);

return enctype;
}

PyObject *pykadmin_key_salttype_name(krb5_key_data *key_data) {

PyObject *salttype = NULL;
// make sure this is enough.
char buffer[1024];

if (krb5_salttype_to_string(key_data->key_data_type[1], buffer, sizeof(buffer)))
snprintf(buffer, sizeof(buffer), "<Salt type 0x%x>", key_data->key_data_type[0]);

salttype = PyUnicode_FromString(buffer);

return salttype;
}

static PyObject *PyKAdminPrincipal_get_keys(PyKAdminPrincipalObject *self, void *closure) {

/*

key structure:

{
kvno: [("enctype", "salt"), ("enctype", "salt")],
kvno: ...
}

*/

PyObject *kvno = NULL;
PyObject *enctype = NULL;
PyObject *salttype = NULL;
PyObject *tuple = NULL;
PyObject *list = NULL;

PyObject *keys = PyDict_New();

ssize_t index = 0;

for (; index < self->entry.n_key_data; index++) {

krb5_key_data *key_data = &self->entry.key_data[index];

kvno = PyUnifiedLongInt_FromLong(key_data->key_data_kvno);

enctype = pykadmin_key_enctype_name(key_data);
salttype = pykadmin_key_salttype_name(key_data);

tuple = PyTuple_Pack(2, enctype, salttype);


if (kvno) {
if (PyDict_Contains(keys, kvno)) {
list = PyDict_GetItem(keys, kvno);
} else {
list = PyList_New(0);
PyDict_SetItem(keys, kvno, list);
}
}

if (list && tuple) {
PyList_Append(list, tuple);
}

}

return keys;
}


/*
* SETTERS
*/
Expand Down Expand Up @@ -747,6 +879,7 @@ static PyGetSetDef PyKAdminPrincipal_getters_setters[] = {

{"attributes", (getter)PyKAdminPrincipal_get_attributes, NULL, kDOCSTRING_ATTRIBUTES, NULL},

{"keys", (getter)PyKAdminPrincipal_get_keys, NULL, "", NULL},

// setter attributes

Expand Down Expand Up @@ -833,7 +966,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_name(PyKAdminObj
principal->kadmin = kadmin;

errno = krb5_parse_name(kadmin->context, client_name, &temp);
retval = kadm5_get_principal(kadmin->server_handle, temp, &principal->entry, KADM5_PRINCIPAL_NORMAL_MASK);
retval = kadm5_get_principal(kadmin->server_handle, temp, &principal->entry, (KADM5_PRINCIPAL_NORMAL_MASK | KADM5_KEY_DATA));

krb5_free_principal(kadmin->context, temp);

Expand All @@ -860,7 +993,7 @@ PyKAdminPrincipalObject *PyKAdminPrincipalObject_principal_with_db_entry(PyKAdmi
Py_INCREF(kadmin);
principal->kadmin = kadmin;

retval = pykadmin_kadm_from_kdb(kadmin, kdb, &principal->entry, KADM5_PRINCIPAL_NORMAL_MASK);
retval = pykadmin_kadm_from_kdb(kadmin, kdb, &principal->entry, (KADM5_PRINCIPAL_NORMAL_MASK | KADM5_KEY_DATA));

if (retval) {
PyKAdminPrincipal_dealloc(principal);
Expand Down
7 changes: 4 additions & 3 deletions kadmin.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ char **_kadmin_dict_to_db_args(PyObject *dict) {
Py_ssize_t index = 0;
Py_ssize_t position = 0;

Py_ssize_t length = PyDict_Size(dict) + 1;
if (dict) {

if (dict) {
Py_ssize_t length = PyDict_Size(dict) + 1;

db_args = calloc(length, sizeof(intptr_t));

Expand Down Expand Up @@ -256,7 +256,8 @@ static PyKAdminObject *_kadmin_local(PyObject *self, PyObject *args) {
if (!PyArg_ParseTuple(args, "|O!", &PyDict_Type, &db_args_dict))
return NULL;

db_args = _kadmin_dict_to_db_args(db_args_dict);
if (db_args_dict)
db_args = _kadmin_dict_to_db_args(db_args_dict);

kadm5_config_params *params = calloc(0x1, sizeof(kadm5_config_params));

Expand Down
2 changes: 2 additions & 0 deletions pykadmin.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ struct module_state {
# define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
# define PyUnifiedLongInt_FromLong(from) PyLong_FromLong((long) from)
# define PyUnifiedLongInt_AsUnsignedLong(ob) PyLong_AsUnsignedLong((PyObject *)ob)
# define PyUnifiedLongInt_AsLong(ob) PyLong_AsLong((PyObject *)ob)
#else
# define GETSTATE(m) (&_state)
# define PyUnifiedLongInt_FromLong(from) PyInt_FromLong((long) from)
# define PyUnifiedLongInt_AsUnsignedLong(ob) PyInt_AsUnsignedLongMask((PyObject *)ob)
# define PyUnifiedLongInt_AsLong(ob) PyInt_AsLong((PyObject *)ob)
#endif

#ifndef Py_TYPE
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[metadata]
description-file = README.md
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
version='0.1',
description='Python module for kerberos admin (kadm5)',
url='https://github.com/russjancewicz/python-kadmin',
download_url='https://github.com/russjancewicz/python-kadmin/tarball/0.0.1',
author='Russell Jancewicz',
author_email='russell.jancewicz@gmail.com',
license='MIT',
Expand All @@ -39,7 +40,7 @@
"./PyKAdminXDR.c",
"./getdate.c"
],
extra_compile_args=["-O0"]
#extra_compile_args=["-O0"]
)
],
classifiers=[
Expand All @@ -51,7 +52,7 @@
"Programming Language :: C",
"Programming Language :: Python",
"Programming Language :: YACC",
"License :: OSI Approved :: MIT"
"License :: OSI Approved :: MIT License",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Systems Administration :: Authentication/Directory",
]
Expand All @@ -61,6 +62,7 @@
version='0.1',
description='Python module for kerberos admin (kadm5) via root local interface',
url='https://github.com/russjancewicz/python-kadmin',
download_url='https://github.com/russjancewicz/python-kadmin/tarball/0.0.1',
author='Russell Jancewicz',
author_email='russell.jancewicz@gmail.com',
license='MIT',
Expand Down Expand Up @@ -92,7 +94,7 @@
"Programming Language :: C",
"Programming Language :: Python",
"Programming Language :: YACC",
"License :: OSI Approved :: MIT"
"License :: OSI Approved :: MIT License",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Systems Administration :: Authentication/Directory",
]
Expand Down