Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/librpc/rpc/pyrpc.c

    r414 r745  
    33   Samba utility functions
    44   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    1818*/
    1919
     20#include <Python.h>
    2021#include "includes.h"
    21 #include <Python.h>
    2222#include <structmember.h>
    2323#include "librpc/rpc/pyrpc.h"
    24 #include "librpc/rpc/dcerpc.h"
    2524#include "lib/events/events.h"
    2625#include "param/pyparam.h"
     26#include "librpc/rpc/dcerpc.h"
     27#include "librpc/rpc/pyrpc_util.h"
    2728#include "auth/credentials/pycredentials.h"
    2829
    29 #ifndef Py_RETURN_NONE
    30 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    31 #endif
    32 
    33 static PyObject *py_dcerpc_run_function(dcerpc_InterfaceObject *iface,
    34                                         const struct PyNdrRpcMethodDef *md,
    35                                         PyObject *args, PyObject *kwargs)
    36 {
    37         TALLOC_CTX *mem_ctx;
    38         NTSTATUS status;
    39         void *r;
    40         PyObject *result = Py_None;
    41 
    42         if (md->pack_in_data == NULL || md->unpack_out_data == NULL) {
    43                 PyErr_SetString(PyExc_NotImplementedError, "No marshalling code available yet");
    44                 return NULL;
    45         }
    46 
    47         mem_ctx = talloc_new(NULL);
    48         if (mem_ctx == NULL) {
    49                 PyErr_NoMemory();
    50                 return NULL;
    51         }
    52 
    53         r = talloc_zero_size(mem_ctx, md->table->calls[md->opnum].struct_size);
    54         if (r == NULL) {
    55                 PyErr_NoMemory();
    56                 return NULL;
    57         }
    58 
    59         if (!md->pack_in_data(args, kwargs, r)) {
    60                 talloc_free(mem_ctx);
    61                 return NULL;
    62         }
    63 
    64         status = md->call(iface->pipe, mem_ctx, r);
    65         if (NT_STATUS_IS_ERR(status)) {
    66                 PyErr_SetDCERPCStatus(iface->pipe, status);
    67                 talloc_free(mem_ctx);
    68                 return NULL;
    69         }
    70 
    71         result = md->unpack_out_data(r);
    72 
    73         talloc_free(mem_ctx);
    74         return result;
    75 }
    76 
    77 static PyObject *py_dcerpc_call_wrapper(PyObject *self, PyObject *args, void *wrapped, PyObject *kwargs)
    78 {       
    79         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
    80         const struct PyNdrRpcMethodDef *md = (const struct PyNdrRpcMethodDef *)wrapped;
    81 
    82         return py_dcerpc_run_function(iface, md, args, kwargs);
    83 }
    84 
    85 
    86 bool PyInterface_AddNdrRpcMethods(PyTypeObject *ifacetype, const struct PyNdrRpcMethodDef *mds)
    87 {
    88         int i;
    89         for (i = 0; mds[i].name; i++) {
    90                 PyObject *ret;
    91                 struct wrapperbase *wb = (struct wrapperbase *)calloc(sizeof(struct wrapperbase), 1);
    92 
    93                 wb->name = discard_const_p(char, mds[i].name);
    94                 wb->flags = PyWrapperFlag_KEYWORDS;
    95                 wb->wrapper = (wrapperfunc)py_dcerpc_call_wrapper;
    96                 wb->doc = discard_const_p(char, mds[i].doc);
    97                
    98                 ret = PyDescr_NewWrapper(ifacetype, wb, discard_const_p(void, &mds[i]));
    99 
    100                 PyDict_SetItemString(ifacetype->tp_dict, mds[i].name,
    101                                      (PyObject *)ret);
    102         }
    103 
    104         return true;
    105 }
     30void initbase(void);
     31
     32staticforward PyTypeObject dcerpc_InterfaceType;
    10633
    10734static bool PyString_AsGUID(PyObject *object, struct GUID *uuid)
     
    14774        PyErr_SetString(PyExc_TypeError, "Expected UUID or syntax id tuple");
    14875        return false;
    149 }       
     76}
    15077
    15178static PyObject *py_iface_server_name(PyObject *obj, void *closure)
     
    15380        const char *server_name;
    15481        dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
    155        
     82
    15683        server_name = dcerpc_server_name(iface->pipe);
    15784        if (server_name == NULL)
     
    207134        { NULL }
    208135};
    209 
    210 void PyErr_SetDCERPCStatus(struct dcerpc_pipe *p, NTSTATUS status)
    211 {
    212         if (p != NULL && NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
    213                 const char *errstr = dcerpc_errstr(NULL, p->last_fault_code);
    214                 PyErr_SetObject(PyExc_RuntimeError,
    215                         Py_BuildValue("(i,s)", p->last_fault_code,
    216                                       errstr));
    217         } else {
    218                 PyErr_SetNTSTATUS(status);
    219         }
    220 }
    221136
    222137static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwargs)
     
    232147        struct GUID object_guid;
    233148        TALLOC_CTX *mem_ctx = talloc_new(NULL);
     149        uint32_t out_flags = 0;
    234150        const char *kwnames[] = { "opnum", "data", "object", NULL };
    235151
    236152        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|O:request",
    237153                discard_const_p(char *, kwnames), &opnum, &in_data, &in_length, &object)) {
     154                talloc_free(mem_ctx);
    238155                return NULL;
    239156        }
     
    245162
    246163        if (object != NULL && !PyString_AsGUID(object, &object_guid)) {
    247                 return NULL;
    248         }
    249 
    250         status = dcerpc_request(iface->pipe, object?&object_guid:NULL,
    251                                 opnum, mem_ctx, &data_in, &data_out);
    252 
    253         if (NT_STATUS_IS_ERR(status)) {
     164                talloc_free(mem_ctx);
     165                return NULL;
     166        }
     167
     168        status = dcerpc_binding_handle_raw_call(iface->binding_handle,
     169                                                object?&object_guid:NULL,
     170                                                opnum,
     171                                                0, /* in_flags */
     172                                                data_in.data,
     173                                                data_in.length,
     174                                                mem_ctx,
     175                                                &data_out.data,
     176                                                &data_out.length,
     177                                                &out_flags);
     178        if (!NT_STATUS_IS_OK(status)) {
    254179                PyErr_SetDCERPCStatus(iface->pipe, status);
    255180                talloc_free(mem_ctx);
     
    291216                                      &transfer_syntax);
    292217
    293         if (NT_STATUS_IS_ERR(status)) {
     218        if (!NT_STATUS_IS_OK(status)) {
    294219                PyErr_SetDCERPCStatus(iface->pipe, status);
    295220                return NULL;
     
    299224}
    300225
    301 PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table)
     226static PyMethodDef dcerpc_interface_methods[] = {
     227        { "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" },
     228        { "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
     229        { NULL, NULL, 0, NULL },
     230};
     231
     232static void dcerpc_interface_dealloc(PyObject* self)
     233{
     234        dcerpc_InterfaceObject *interface = (dcerpc_InterfaceObject *)self;
     235        talloc_free(interface->mem_ctx);
     236        self->ob_type->tp_free(self);
     237}
     238
     239static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
    302240{
    303241        dcerpc_InterfaceObject *ret;
     
    305243        struct cli_credentials *credentials;
    306244        struct loadparm_context *lp_ctx = NULL;
    307         PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;
    308         TALLOC_CTX *mem_ctx = NULL;
     245        PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None;
     246        TALLOC_CTX *mem_ctx;
    309247        struct tevent_context *event_ctx;
    310248        NTSTATUS status;
    311249
     250        PyObject *syntax, *py_basis = Py_None;
    312251        const char *kwnames[] = {
    313                 "binding", "lp_ctx", "credentials", "basis_connection", NULL
     252                "binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL
    314253        };
    315 
    316         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO:samr", discard_const_p(char *, kwnames), &binding_string, &py_lp_ctx, &py_credentials, &py_basis)) {
    317                 return NULL;
    318         }
    319 
    320         lp_ctx = lp_from_py_object(py_lp_ctx);
     254        struct ndr_interface_table *table;
     255
     256        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) {
     257                return NULL;
     258        }
     259
     260        mem_ctx = talloc_new(NULL);
     261        if (mem_ctx == NULL) {
     262                PyErr_NoMemory();
     263                return NULL;
     264        }
     265
     266        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
    321267        if (lp_ctx == NULL) {
    322268                PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
    323                 return NULL;
    324         }
    325 
    326         status = dcerpc_init(lp_ctx);
    327         if (!NT_STATUS_IS_OK(status)) {
    328                 PyErr_SetNTSTATUS(status);
    329                 return NULL;
    330         }
     269                talloc_free(mem_ctx);
     270                return NULL;
     271        }
     272
    331273        credentials = cli_credentials_from_py_object(py_credentials);
    332274        if (credentials == NULL) {
    333275                PyErr_SetString(PyExc_TypeError, "Expected credentials");
     276                talloc_free(mem_ctx);
    334277                return NULL;
    335278        }
    336279        ret = PyObject_New(dcerpc_InterfaceObject, type);
    337 
    338         event_ctx = event_context_init(mem_ctx);
     280        ret->mem_ctx = mem_ctx;
     281
     282        event_ctx = s4_event_context_init(ret->mem_ctx);
     283
     284        /* Create a dummy interface table struct. TODO: In the future, we should
     285         * rather just allow connecting without requiring an interface table.
     286         */
     287
     288        table = talloc_zero(ret->mem_ctx, struct ndr_interface_table);
     289
     290        if (table == NULL) {
     291                PyErr_SetString(PyExc_MemoryError, "Allocating interface table");
     292                talloc_free(mem_ctx);
     293                return NULL;
     294        }
     295
     296        if (!ndr_syntax_from_py_object(syntax, &table->syntax_id)) {
     297                talloc_free(mem_ctx);
     298                return NULL;
     299        }
     300
     301        ret->pipe = NULL;
     302        ret->binding_handle = NULL;
    339303
    340304        if (py_basis != Py_None) {
     
    347311                }
    348312
    349                 base_pipe = ((dcerpc_InterfaceObject *)py_basis)->pipe;
     313                base_pipe = talloc_reference(ret->mem_ctx,
     314                                         ((dcerpc_InterfaceObject *)py_basis)->pipe);
    350315
    351316                status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
     317
     318                ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
    352319        } else {
    353                 status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string,
    354                              table, credentials, event_ctx, lp_ctx);
    355         }
    356         if (NT_STATUS_IS_ERR(status)) {
    357                 PyErr_SetNTSTATUS(status);
    358                 talloc_free(mem_ctx);
    359                 return NULL;
    360         }
    361 
     320                status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string,
     321                             table, credentials, event_ctx, lp_ctx);
     322        }
     323
     324        if (!NT_STATUS_IS_OK(status)) {
     325                PyErr_SetDCERPCStatus(ret->pipe, status);
     326                talloc_free(ret->mem_ctx);
     327                return NULL;
     328        }
    362329        ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
     330        ret->binding_handle = ret->pipe->binding_handle;
    363331        return (PyObject *)ret;
    364332}
    365333
    366 static PyMethodDef dcerpc_interface_methods[] = {
    367         { "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" },
    368         { "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
    369         { NULL, NULL, 0, NULL },
    370 };
    371 
    372 
    373 static void dcerpc_interface_dealloc(PyObject* self)
    374 {
    375         dcerpc_InterfaceObject *interface = (dcerpc_InterfaceObject *)self;
    376         talloc_free(interface->pipe);
    377         PyObject_Del(self);
    378 }
    379 
    380 static PyObject *dcerpc_interface_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
    381 {
    382         dcerpc_InterfaceObject *ret;
    383         const char *binding_string;
    384         struct cli_credentials *credentials;
    385         struct loadparm_context *lp_ctx = NULL;
    386         PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None;
    387         TALLOC_CTX *mem_ctx = NULL;
    388         struct tevent_context *event_ctx;
    389         NTSTATUS status;
    390 
    391         PyObject *syntax, *py_basis = Py_None;
    392         const char *kwnames[] = {
    393                 "binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL
    394         };
    395         struct ndr_interface_table *table;
    396 
    397         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) {
    398                 return NULL;
    399         }
    400 
    401         lp_ctx = lp_from_py_object(py_lp_ctx);
    402         if (lp_ctx == NULL) {
    403                 PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
    404                 return NULL;
    405         }
    406 
    407         credentials = cli_credentials_from_py_object(py_credentials);
    408         if (credentials == NULL) {
    409                 PyErr_SetString(PyExc_TypeError, "Expected credentials");
    410                 return NULL;
    411         }
    412         ret = PyObject_New(dcerpc_InterfaceObject, &dcerpc_InterfaceType);
    413 
    414         event_ctx = s4_event_context_init(mem_ctx);
    415 
    416         /* Create a dummy interface table struct. TODO: In the future, we should rather just allow
    417          * connecting without requiring an interface table.
    418          */
    419 
    420         table = talloc_zero(mem_ctx, struct ndr_interface_table);
    421 
    422         if (table == NULL) {
    423                 PyErr_SetString(PyExc_MemoryError, "Allocating interface table");
    424                 return NULL;
    425         }
    426 
    427         if (!ndr_syntax_from_py_object(syntax, &table->syntax_id)) {
    428                 return NULL;
    429         }
    430 
    431         ret->pipe = NULL;
    432 
    433         if (py_basis != Py_None) {
    434                 struct dcerpc_pipe *base_pipe;
    435 
    436                 if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {
    437                         PyErr_SetString(PyExc_ValueError, "basis_connection must be a DCE/RPC connection");
    438                         talloc_free(mem_ctx);
    439                         return NULL;
    440                 }
    441 
    442                 base_pipe = ((dcerpc_InterfaceObject *)py_basis)->pipe;
    443 
    444                 status = dcerpc_secondary_context(base_pipe, &ret->pipe,
    445                                      table);
    446                 ret->pipe = talloc_steal(NULL, ret->pipe);
    447         } else {
    448                 status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string,
    449                              table, credentials, event_ctx, lp_ctx);
    450         }
    451 
    452         if (NT_STATUS_IS_ERR(status)) {
    453                 PyErr_SetDCERPCStatus(ret->pipe, status);
    454                 talloc_free(mem_ctx);
    455                 return NULL;
    456         }
    457         ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
    458         return (PyObject *)ret;
    459 }
    460 
    461 PyTypeObject dcerpc_InterfaceType = {
     334static PyTypeObject dcerpc_InterfaceType = {
    462335        PyObject_HEAD_INIT(NULL) 0,
    463336        .tp_name = "dcerpc.ClientConnection",
Note: See TracChangeset for help on using the changeset viewer.