libgpo: Setup the stack frame in ads_connect
[nivanova/samba-autobuild/.git] / libgpo / pygpo.c
index 757c713b0278ca537079e3c7cc81f9c5c75bb65d..aaa74296cb8d02134187e1bac4e000507c76dec6 100644 (file)
 #include "ads.h"
 #include "secrets.h"
 #include "../libds/common/flags.h"
+#include "librpc/rpc/pyrpc_util.h"
 #include "auth/credentials/pycredentials.h"
 #include "libcli/util/pyerrors.h"
 
 /* A Python C API module to use LIBGPO */
 
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
 typedef struct {
        PyObject_HEAD
        TALLOC_CTX *frame;
@@ -196,17 +193,27 @@ static int py_ads_init(ADS *self, PyObject *args, PyObject *kwds)
        const char *realm = NULL;
        const char *workgroup = NULL;
        const char *ldap_server = NULL;
-       PyObject *creds = NULL;
+       PyObject *py_creds = NULL;
        PyObject *lp_obj = NULL;
        struct loadparm_context *lp_ctx = NULL;
 
        static const char *kwlist[] = {"ldap_server", "loadparm_context", "credentials", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|O", discard_const_p(char *, kwlist), &ldap_server, &lp_obj, &creds))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|O", discard_const_p(char *, kwlist), &ldap_server, &lp_obj, &py_creds))
                return -1;
 
        self->frame = talloc_stackframe();
 
-       if (creds) self->cli_creds = pytalloc_get_type(creds, struct cli_credentials);
+       if (py_creds) {
+               if (!py_check_dcerpc_type(py_creds, "samba.credentials",
+                                         "Credentials")) {
+                       PyErr_Format(PyExc_TypeError,
+                                    "Expected samba.credentaials "
+                                    "for credentials argument");
+                       return -1;
+               }
+               self->cli_creds
+                       = PyCredentials_AsCliCredentials(py_creds);
+       }
 
        if (lp_obj) {
                lp_ctx = pytalloc_get_type(lp_obj, struct loadparm_context);
@@ -234,6 +241,7 @@ static int py_ads_init(ADS *self, PyObject *args, PyObject *kwds)
 static PyObject* py_ads_connect(ADS *self)
 {
        ADS_STATUS status;
+       TALLOC_CTX *frame = talloc_stackframe();
        if (self->cli_creds) {
                self->ads_ptr->auth.user_name = SMB_STRDUP(cli_credentials_get_username(self->cli_creds));
 self->ads_ptr->auth.flags |= ADS_AUTH_USER_CREDS;
@@ -243,6 +251,7 @@ self->ads_ptr->auth.flags |= ADS_AUTH_USER_CREDS;
                status = ads_connect_user_creds(self->ads_ptr);
                if (!ADS_ERR_OK(status)) {
                        PyErr_SetString(PyExc_SystemError, "ads_connect() failed");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                }
        } else {
@@ -250,31 +259,38 @@ self->ads_ptr->auth.flags |= ADS_AUTH_USER_CREDS;
 
                if (asprintf(&(self->ads_ptr->auth.user_name), "%s$", lp_netbios_name()) == -1) {
                        PyErr_SetString(PyExc_SystemError, "Failed to asprintf");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                } else
                        self->ads_ptr->auth.flags |= ADS_AUTH_USER_CREDS;
                if (!secrets_init()) {
                        PyErr_SetString(PyExc_SystemError, "secrets_init() failed");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                }
+
                if (!(passwd = secrets_fetch_machine_password(self->ads_ptr->server.workgroup, NULL, NULL))) {
                        PyErr_SetString(PyExc_SystemError, "Failed to fetch the machine account password");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                }
                self->ads_ptr->auth.password = smb_xstrdup(passwd);
                self->ads_ptr->auth.realm = smb_xstrdup(self->ads_ptr->server.realm);
                if (!strupper_m(self->ads_ptr->auth.realm)) {
                        PyErr_SetString(PyExc_SystemError, "Failed to strdup");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                }
 
                status = ads_connect(self->ads_ptr);
                if (!ADS_ERR_OK(status)) {
                        PyErr_SetString(PyExc_SystemError, "ads_connect() failed");
+                       TALLOC_FREE(frame);
                        Py_RETURN_FALSE;
                }
        }
 
+       TALLOC_FREE(frame);
        Py_RETURN_TRUE;
 }