r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[samba.git] / source / python / py_winbind.c
index 783ac5443904ab1bbd5a5dcfb815b6cdc53af464..7d3a9cdf087dea9c85d7b346616810c9f386dd44 100644 (file)
@@ -3,11 +3,11 @@
 
    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 
@@ -33,7 +29,7 @@ PyObject *winbind_error;      /* A winbind call returned WINBINDD_ERROR */
 
 /* 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);
 
@@ -49,7 +45,8 @@ static PyObject *py_name_to_sid(PyObject *self, PyObject *args)
        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;
@@ -68,7 +65,7 @@ static PyObject *py_name_to_sid(PyObject *self, PyObject *args)
                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;
@@ -96,7 +93,7 @@ static PyObject *py_sid_to_name(PyObject *self, PyObject *args)
 
        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;
@@ -128,7 +125,7 @@ static PyObject *py_enum_domain_users(PyObject *self, PyObject *args)
 
        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;            
@@ -136,8 +133,8 @@ static PyObject *py_enum_domain_users(PyObject *self, PyObject *args)
 
        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)))
@@ -159,7 +156,7 @@ static PyObject *py_enum_domain_groups(PyObject *self, PyObject *args)
 
        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;            
@@ -167,8 +164,8 @@ static PyObject *py_enum_domain_groups(PyObject *self, PyObject *args)
 
        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)))
@@ -194,7 +191,7 @@ static PyObject *py_enum_trust_dom(PyObject *self, PyObject *args)
 
        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;            
@@ -202,8 +199,8 @@ static PyObject *py_enum_trust_dom(PyObject *self, PyObject *args)
 
        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)))
@@ -224,7 +221,7 @@ static PyObject *py_check_secret(PyObject *self, PyObject *args)
 
        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;            
@@ -261,14 +258,14 @@ static PyObject *py_config_dict(void)
        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));
        }
@@ -296,7 +293,7 @@ static PyObject *py_uid_to_sid(PyObject *self, PyObject *args)
 
        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;            
@@ -321,7 +318,7 @@ static PyObject *py_gid_to_sid(PyObject *self, PyObject *args)
 
        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;            
@@ -346,7 +343,7 @@ static PyObject *py_sid_to_uid(PyObject *self, PyObject *args)
 
        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;            
@@ -371,7 +368,7 @@ static PyObject *py_sid_to_gid(PyObject *self, PyObject *args)
 
        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;            
@@ -401,7 +398,7 @@ static PyObject *py_auth_plaintext(PyObject *self, PyObject *args)
        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;            
@@ -429,9 +426,12 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
        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, 
@@ -445,7 +445,67 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
                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;            
@@ -454,6 +514,8 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
        return PyInt_FromLong(response.data.auth.nt_status);
 }
 
+#endif /* 0 */
+
 /* Get user info from name */
 
 static PyObject *py_getpwnam(PyObject *self, PyObject *args)
@@ -471,7 +533,7 @@ 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;            
@@ -502,7 +564,7 @@ static PyObject *py_getpwuid(PyObject *self, PyObject *args)
 
        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;            
@@ -522,132 +584,144 @@ static PyObject *py_getpwuid(PyObject *self, PyObject *args)
 
 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 }
 };