Python wrapper for winbind client functions.
- Copyright (C) Tim Potter 2002
+ Copyright (C) Tim Potter 2002-2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include "Python.h"
-
-#include "py_common_proto.h"
+#include "py_winbind.h"
/*
* Exceptions raised by this module
/* Prototypes from common.h */
-NSS_STATUS winbindd_request(int req_type,
+NSS_STATUS winbindd_request_response(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
struct winbindd_request request;
struct winbindd_response response;
PyObject *result;
- char *name, *p, *sep;
+ char *name, *p;
+ const char *sep;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
fstrcpy(request.data.name.name, name);
}
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response)
+ if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response)
+ if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response)
+ if (winbindd_request_response(WINBINDD_LIST_USERS, NULL, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
result = PyList_New(0);
- if (response.extra_data) {
- char *extra_data = response.extra_data;
+ if (response.extra_data.data) {
+ const char *extra_data = response.extra_data.data;
fstring name;
while (next_token(&extra_data, name, ",", sizeof(fstring)))
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response)
+ if (winbindd_request_response(WINBINDD_LIST_GROUPS, NULL, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
result = PyList_New(0);
- if (response.extra_data) {
- char *extra_data = response.extra_data;
+ if (response.extra_data.data) {
+ const char *extra_data = response.extra_data.data;
fstring name;
while (next_token(&extra_data, name, ",", sizeof(fstring)))
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response)
+ if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, NULL, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
result = PyList_New(0);
- if (response.extra_data) {
- char *extra_data = response.extra_data;
+ if (response.extra_data.data) {
+ const char *extra_data = response.extra_data.data;
fstring name;
while (next_token(&extra_data, name, ",", sizeof(fstring)))
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response)
+ if (winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
PyDict_SetItemString(result, "template_shell",
PyString_FromString(lp_template_shell()));
- /* Winbind uid/gid range */
+ /* idmap uid/gid range */
- if (lp_winbind_uid(&ulow, &uhi)) {
+ if (lp_idmap_uid(&ulow, &uhi)) {
PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow));
PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi));
}
- if (lp_winbind_gid(&glow, &ghi)) {
+ if (lp_idmap_gid(&glow, &ghi)) {
PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow));
PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi));
}
request.data.uid = id;
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response)
+ if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
request.data.gid = id;
- if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response)
+ if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response)
+ if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response)
+ if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
fstrcpy(request.data.auth.user, username);
fstrcpy(request.data.auth.pass, password);
- if (winbindd_request(WINBINDD_PAM_AUTH, &request, &response)
+ if (winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- fstrcpy(request.data.auth_crap.user, username);
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ PyErr_SetString(winbind_error, "unable to create utf8 string");
+ return NULL;
+ }
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
+ generate_random_buffer(request.data.auth_crap.chal, 8);
if (use_lm_hash) {
SMBencrypt((uchar *)password, request.data.auth_crap.chal,
request.data.auth_crap.nt_resp_len = 24;
}
- if (winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response)
+ if (winbindd_request_response(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);
+}
+
+#if 0 /* Include when auth_smbd merged to HEAD */
+
+/* Challenge/response authentication, with secret */
+
+static PyObject *py_auth_smbd(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] =
+ {"username", "password", "use_lm_hash", "use_nt_hash", NULL };
+ struct winbindd_request request;
+ struct winbindd_response response;
+ char *username, *password;
+ int use_lm_hash = 1, use_nt_hash = 1;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "ss|ii", kwlist, &username, &password,
+ &use_lm_hash, &use_nt_hash))
+ return NULL;
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ PyErr_SetString("unable to create utf8 string");
+ return NULL;
+ }
+
+ generate_random_buffer(request.data.smbd_auth_crap.chal, 8);
+
+ if (use_lm_hash) {
+ SMBencrypt((uchar *)password,
+ request.data.smbd_auth_crap.chal,
+ (uchar *)request.data.smbd_auth_crap.lm_resp);
+ request.data.smbd_auth_crap.lm_resp_len = 24;
+ }
+
+ if (use_nt_hash) {
+ SMBNTencrypt((uchar *)password,
+ request.data.smbd_auth_crap.chal,
+ (uchar *)request.data.smbd_auth_crap.nt_resp);
+ request.data.smbd_auth_crap.nt_resp_len = 24;
+ }
+
+ if (!secrets_fetch_trust_account_password(
+ lp_workgroup(), request.data.smbd_auth_crap.proof, NULL)) {
+ PyErr_SetString(
+ winbind_error, "unable to fetch domain secret");
+ return NULL;
+ }
+
+
+
+ if (winbindd_request_response(WINBINDD_SMBD_AUTH_CRAP, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
return PyInt_FromLong(response.data.auth.nt_status);
}
+#endif /* 0 */
+
/* Get user info from name */
static PyObject *py_getpwnam(PyObject *self, PyObject *args)
fstrcpy(request.data.username, username);
- if (winbindd_request(WINBINDD_GETPWNAM, &request, &response)
+ if (winbindd_request_response(WINBINDD_GETPWNAM, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
request.data.uid = uid;
- if (winbindd_request(WINBINDD_GETPWUID, &request, &response)
+ if (winbindd_request_response(WINBINDD_GETPWUID, &request, &response)
!= NSS_STATUS_SUCCESS) {
PyErr_SetString(winbind_error, "lookup failed");
return NULL;
static PyMethodDef winbind_methods[] = {
- { "getpwnam", py_getpwnam, METH_VARARGS, "getpwnam(3)" },
- { "getpwuid", py_getpwuid, METH_VARARGS, "getpwuid(3)" },
+ { "getpwnam", (PyCFunction)py_getpwnam, METH_VARARGS, "getpwnam(3)" },
+ { "getpwuid", (PyCFunction)py_getpwuid, METH_VARARGS, "getpwuid(3)" },
/* Name <-> SID conversion */
- { "name_to_sid", py_name_to_sid, METH_VARARGS,
- "name_to_sid(s) -> string
-
-Return the SID for a name.
-
-Example:
-
->>> winbind.name_to_sid('FOO/Administrator')
-'S-1-5-21-406022937-1377575209-526660263-500' " },
-
- { "sid_to_name", py_sid_to_name, METH_VARARGS,
- "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' " },
+ { "name_to_sid", (PyCFunction)py_name_to_sid, METH_VARARGS,
+ "name_to_sid(s) -> string\n"
+"\n"
+"Return the SID for a name.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.name_to_sid('FOO/Administrator')\n"
+"'S-1-5-21-406022937-1377575209-526660263-500' " },
+
+ { "sid_to_name", (PyCFunction)py_sid_to_name, METH_VARARGS,
+ "sid_to_name(s) -> string\n"
+"\n"
+"Return the name for a SID.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> import winbind\n"
+">>> winbind.sid_to_name('S-1-5-21-406022937-1377575209-526660263-500')\n"
+"'FOO/Administrator' " },
/* Enumerate users/groups */
- { "enum_domain_users", py_enum_domain_users, METH_VARARGS,
- "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,
- "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'] " },
+ { "enum_domain_users", (PyCFunction)py_enum_domain_users, METH_VARARGS,
+ "enum_domain_users() -> list of strings\n"
+"\n"
+"Return a list of domain users.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.enum_domain_users()\n"
+"['FOO/Administrator', 'FOO/anna', 'FOO/Anne Elk', 'FOO/build', \n"
+"'FOO/foo', 'FOO/foo2', 'FOO/foo3', 'FOO/Guest', 'FOO/user1', \n"
+"'FOO/whoops-ptang'] " },
+
+ { "enum_domain_groups", (PyCFunction)py_enum_domain_groups,
+ METH_VARARGS,
+ "enum_domain_groups() -> list of strings\n"
+"\n"
+"Return a list of domain groups.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.enum_domain_groups()\n"
+"['FOO/cows', 'FOO/Domain Admins', 'FOO/Domain Guests', \n"
+"'FOO/Domain Users'] " },
/* ID mapping */
- { "uid_to_sid", py_uid_to_sid, METH_VARARGS,
- "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,
- "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,
- "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,
- "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 " },
+ { "uid_to_sid", (PyCFunction)py_uid_to_sid, METH_VARARGS,
+ "uid_to_sid(int) -> string\n"
+"\n"
+"Return the SID for a UNIX uid.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.uid_to_sid(10000) \n"
+"'S-1-5-21-406022937-1377575209-526660263-500' " },
+
+ { "gid_to_sid", (PyCFunction)py_gid_to_sid, METH_VARARGS,
+ "gid_to_sid(int) -> string\n"
+"\n"
+"Return the UNIX gid for a SID.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.gid_to_sid(10001)\n"
+"'S-1-5-21-406022937-1377575209-526660263-512' " },
+
+ { "sid_to_uid", (PyCFunction)py_sid_to_uid, METH_VARARGS,
+ "sid_to_uid(string) -> int\n"
+"\n"
+"Return the UNIX uid for a SID.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.sid_to_uid('S-1-5-21-406022937-1377575209-526660263-500')\n"
+"10000 " },
+
+ { "sid_to_gid", (PyCFunction)py_sid_to_gid, METH_VARARGS,
+ "sid_to_gid(string) -> int\n"
+"\n"
+"Return the UNIX gid corresponding to a SID.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.sid_to_gid('S-1-5-21-406022937-1377575209-526660263-512')\n"
+"10001 " },
/* Miscellaneous */
- { "check_secret", py_check_secret, METH_VARARGS,
- "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,
- "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'] " },
+ { "check_secret", (PyCFunction)py_check_secret, METH_VARARGS,
+ "check_secret() -> int\n"
+"\n"
+"Check the machine trust account password. The NT status is returned\n"
+"with zero indicating success. " },
+
+ { "enum_trust_dom", (PyCFunction)py_enum_trust_dom, METH_VARARGS,
+ "enum_trust_dom() -> list of strings\n"
+"\n"
+"Return a list of trusted domains. The domain the server is a member \n"
+"of is not included.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> winbind.enum_trust_dom()\n"
+"['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." },
+ { "auth_plaintext", (PyCFunction)py_auth_plaintext, METH_VARARGS,
+ "auth_plaintext(s, s) -> int\n"
+"\n"
+"Authenticate a username and password using plaintext authentication.\n"
+"The NT status code is returned with zero indicating success." },
+
+ { "auth_crap", (PyCFunction)py_auth_crap, METH_VARARGS | METH_KEYWORDS,
+ "auth_crap(s, s) -> int\n"
+"\n"
+"Authenticate a username and password using the challenge/response\n"
+"protocol. The NT status code is returned with zero indicating\n"
+"success." },
+
+#if 0 /* Include when smbd_auth merged to HEAD */
+
+ { "auth_smbd", (PyCFunction)py_auth_crap, METH_VARARGS,
+ "auth_smbd(s, s) -> int\n"
+"\n"
+"Authenticate a username and password using the challenge/response\n"
+"protocol but using the domain secret to prove we are root. The NT \n"
+"status code is returned with zero indicating success." },
+
+#endif
{ NULL }
};