From b1d54184c83faae9b3cab796b699ba6157b8cf64 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 28 Mar 2002 03:22:41 +0000 Subject: Use winbind separator in sid_to_name() function. Implemented auth() and auth_crap() functions. Expanded docstrings for exported functions, with examples. Now 'pydoc winbind' returns a nice looking manual page! Wrote module docstring. (This used to be commit 26a7333347e630d2f5ff9d017536d21ac4ecaa81) --- source3/python/py_winbind.c | 202 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 182 insertions(+), 20 deletions(-) diff --git a/source3/python/py_winbind.c b/source3/python/py_winbind.c index 73bc811409..87f348b8c3 100644 --- a/source3/python/py_winbind.c +++ b/source3/python/py_winbind.c @@ -102,10 +102,8 @@ static PyObject *py_sid_to_name(PyObject *self, PyObject *args) return NULL; } - /* FIXME: use actual winbind separator */ - - asprintf(&name, "%s%c%s", response.data.name.dom_name, - '\\', response.data.name.name); + asprintf(&name, "%s%s%s", response.data.name.dom_name, + lp_winbind_separator(), response.data.name.name); result = PyString_FromString(name); @@ -382,6 +380,71 @@ static PyObject *py_sid_to_gid(PyObject *self, PyObject *args) return PyInt_FromLong(response.data.gid); } +/* + * PAM authentication functions + */ + +/* Plaintext authentication */ + +static PyObject *py_auth_plaintext(PyObject *self, PyObject *args) +{ + struct winbindd_request request; + struct winbindd_response response; + char *username, *password; + + if (!PyArg_ParseTuple(args, "ss", &username, &password)) + return NULL; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.data.auth.user, username); + fstrcpy(request.data.auth.pass, password); + + if (winbindd_request(WINBINDD_PAM_AUTH, &request, &response) + != NSS_STATUS_SUCCESS) { + PyErr_SetString(winbind_error, "lookup failed"); + return NULL; + } + + return PyInt_FromLong(response.data.auth.nt_status); +} + +/* Challenge/response authentication */ + +static PyObject *py_auth_crap(PyObject *self, PyObject *args) +{ + struct winbindd_request request; + struct winbindd_response response; + char *username, *password; + + if (!PyArg_ParseTuple(args, "ss", &username, &password)) + return NULL; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.data.auth_crap.user, username); + + generate_random_buffer(request.data.auth_crap.chal, 8, False); + + SMBencrypt((uchar *)password, request.data.auth_crap.chal, + (uchar *)request.data.auth_crap.lm_resp); + SMBNTencrypt((uchar *)password, request.data.auth_crap.chal, + (uchar *)request.data.auth_crap.nt_resp); + + request.data.auth_crap.lm_resp_len = 24; + request.data.auth_crap.nt_resp_len = 24; + + if (winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response) + != NSS_STATUS_SUCCESS) { + PyErr_SetString(winbind_error, "lookup failed"); + return NULL; + } + + return PyInt_FromLong(response.data.auth.nt_status); +} + /* * Method dispatch table */ @@ -391,40 +454,123 @@ static PyMethodDef winbind_methods[] = { /* Name <-> SID conversion */ { "name_to_sid", py_name_to_sid, METH_VARARGS, - "Convert a name to a sid" }, + "name_to_sid(s) -> string\n +Return the SID for a name.\n +Example:\n +>>> winbind.name_to_sid('FOO/Administrator') +'S-1-5-21-406022937-1377575209-526660263-500' " }, { "sid_to_name", py_sid_to_name, METH_VARARGS, - "Convert a sid to a name" }, + "sid_to_name(s) -> string + +Return the name for a SID. + +Example: + +>>> import winbind +>>> winbind.sid_to_name('S-1-5-21-406022937-1377575209-526660263-500') +'FOO/Administrator' " }, /* Enumerate users/groups */ { "enum_domain_users", py_enum_domain_users, METH_VARARGS, - "Enumerate domain users" }, + "enum_domain_users() -> list of strings + +Return a list of domain users. + +Example: + +>>> winbind.enum_domain_users() +['FOO/Administrator', 'FOO/anna', 'FOO/Anne Elk', 'FOO/build', +'FOO/foo', 'FOO/foo2', 'FOO/foo3', 'FOO/Guest', 'FOO/user1', +'FOO/whoops-ptang'] " }, { "enum_domain_groups", py_enum_domain_groups, METH_VARARGS, - "Enumerate domain groups" }, + "enum_domain_groups() -> list of strings + +Return a list of domain groups. + +Example: + +>>> winbind.enum_domain_groups() +['FOO/cows', 'FOO/Domain Admins', 'FOO/Domain Guests', +'FOO/Domain Users'] " }, /* ID mapping */ { "uid_to_sid", py_uid_to_sid, METH_VARARGS, - "Convert a uid to a SID" }, + "uid_to_sid(int) -> string + +Return the SID for a UNIX uid. + +Example: + +>>> winbind.uid_to_sid(10000) +'S-1-5-21-406022937-1377575209-526660263-500' " }, { "gid_to_sid", py_gid_to_sid, METH_VARARGS, - "Convert a gid to a SID" }, + "gid_to_sid(int) -> string + +Return the UNIX gid for a SID. + +Example: + +>>> winbind.gid_to_sid(10001) +'S-1-5-21-406022937-1377575209-526660263-512' " }, { "sid_to_uid", py_sid_to_uid, METH_VARARGS, - "Convert a uid to a SID" }, + "sid_to_uid(string) -> int + +Return the UNIX uid for a SID. + +Example: + +>>> winbind.sid_to_uid('S-1-5-21-406022937-1377575209-526660263-500') +10000 " }, { "sid_to_gid", py_sid_to_gid, METH_VARARGS, - "Convert a gid to a SID" }, + "sid_to_gid(string) -> int + +Return the UNIX gid corresponding to a SID. + +Example: + +>>> winbind.sid_to_gid('S-1-5-21-406022937-1377575209-526660263-512') +10001 " }, /* Miscellaneous */ { "check_secret", py_check_secret, METH_VARARGS, - "Check machine account password" }, + "check_secret() -> int + +Check the machine trust account password. The NT status is returned +with zero indicating success. " }, { "enum_trust_dom", py_enum_trust_dom, METH_VARARGS, - "Enumerate trusted domains" }, + "enum_trust_dom() -> list of strings + +Return a list of trusted domains. The domain the server is a member +of is not included. + +Example: + +>>> winbind.enum_trust_dom() +['NPSD-TEST2', 'SP2NDOM'] " }, + + /* PAM authorisation functions */ + + { "auth_plaintext", py_auth_plaintext, METH_VARARGS, + "auth_plaintext(s, s) -> int + +Authenticate a username and password using plaintext authentication. +The NT status code is returned with zero indicating success." }, + + { "auth_crap", py_auth_crap, METH_VARARGS, + "auth_crap(s, s) -> int + +Authenticate a username and password using the challenge/response +protocol. The NT status code is returned with zero indicating +success." }, { NULL } }; @@ -432,15 +578,25 @@ static PyMethodDef winbind_methods[] = { static struct winbind_const { char *name; uint32 value; + char *docstring; } winbind_const_vals[] = { /* Well known RIDs */ - { "DOMAIN_USER_RID_ADMIN", DOMAIN_USER_RID_ADMIN }, - { "DOMAIN_USER_RID_GUEST", DOMAIN_USER_RID_GUEST }, - { "DOMAIN_GROUP_RID_ADMINS", DOMAIN_GROUP_RID_ADMINS }, - { "DOMAIN_GROUP_RID_USERS", DOMAIN_GROUP_RID_USERS }, - { "DOMAIN_GROUP_RID_GUESTS", DOMAIN_GROUP_RID_GUESTS }, + { "DOMAIN_USER_RID_ADMIN", DOMAIN_USER_RID_ADMIN, + "Well-known RID for Administrator user" }, + + { "DOMAIN_USER_RID_GUEST", DOMAIN_USER_RID_GUEST, + "Well-known RID for Guest user" }, + + { "DOMAIN_GROUP_RID_ADMINS", DOMAIN_GROUP_RID_ADMINS, + "Well-known RID for Domain Admins group" }, + + { "DOMAIN_GROUP_RID_USERS", DOMAIN_GROUP_RID_USERS, + "Well-known RID for Domain Users group" }, + + { "DOMAIN_GROUP_RID_GUESTS", DOMAIN_GROUP_RID_GUESTS, + "Well-known RID for Domain Guests group" }, { NULL } }; @@ -461,13 +617,19 @@ static void const_init(PyObject *dict) * Module initialisation */ +static char winbind_module__doc__[] = +"A python extension to winbind client functions."; + void initwinbind(void) { PyObject *module, *dict; /* Initialise module */ - module = Py_InitModule("winbind", winbind_methods); + module = Py_InitModule4("winbind", winbind_methods, + winbind_module__doc__, + (PyObject*)NULL,PYTHON_API_VERSION); + dict = PyModule_GetDict(module); winbind_error = PyErr_NewException("winbind.error", NULL, NULL); -- cgit