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/lib/messaging/pymessaging.c

    r414 r745  
    2020*/
    2121
     22#include <Python.h>
    2223#include "includes.h"
    23 #include <Python.h>
    2424#include "scripting/python/modules.h"
    2525#include "libcli/util/pyerrors.h"
    26 #include "librpc/rpc/pyrpc.h"
    27 #include "lib/messaging/irpc.h"
     26#include "librpc/rpc/pyrpc_util.h"
     27#include "librpc/ndr/libndr.h"
    2828#include "lib/messaging/messaging.h"
    2929#include "lib/events/events.h"
     
    3131#include "param/param.h"
    3232#include "param/pyparam.h"
    33 
    34 #ifndef Py_RETURN_NONE
    35 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    36 #endif
    37 
    38 PyAPI_DATA(PyTypeObject) messaging_Type;
    39 PyAPI_DATA(PyTypeObject) irpc_ClientConnectionType;
    40 
    41 /* FIXME: This prototype should be in py_irpc.h, or shared otherwise */
    42 extern const struct PyNdrRpcMethodDef py_ndr_irpc_methods[];
     33#include "librpc/rpc/dcerpc.h"
     34#include "librpc/gen_ndr/server_id4.h"
     35
     36void initmessaging(void);
     37
     38extern PyTypeObject messaging_Type;
    4339
    4440static bool server_id_from_py(PyObject *object, struct server_id *server_id)
     
    6662} messaging_Object;
    6763
    68 PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
     64static PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
    6965{
    7066        struct tevent_context *ev;
     
    8884
    8985        if (messaging_path == NULL) {
    90                 messaging_path = lp_messaging_path(ret->mem_ctx,
     86                messaging_path = lpcfg_messaging_path(ret->mem_ctx,
    9187                                                                   py_default_loadparm_context(ret->mem_ctx));
    9288        } else {
     
    10399                                            messaging_path,
    104100                                            server_id,
    105                                         py_iconv_convenience(ret->mem_ctx),
    106101                                            ev);
    107102        } else {
    108103                ret->msg_ctx = messaging_client_init(ret->mem_ctx,
    109104                                            messaging_path,
    110                                         py_iconv_convenience(ret->mem_ctx),
    111105                                            ev);
    112106        }
     
    125119        messaging_Object *iface = (messaging_Object *)self;
    126120        talloc_free(iface->msg_ctx);
    127         PyObject_Del(self);
     121        self->ob_type->tp_free(self);
    128122}
    129123
     
    139133        int length;
    140134
    141         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ois#|:send",
     135        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ois#:send",
    142136                discard_const_p(char *, kwnames), &target, &msg_type, &data.data, &length)) {
     137
    143138                return NULL;
    144139        }
     
    146141        data.length = length;
    147142
    148         if (!server_id_from_py(target, &server)) 
     143        if (!server_id_from_py(target, &server))
    149144                return NULL;
    150145
     
    177172        const char *kwnames[] = { "callback", "msg_type", NULL };
    178173       
    179         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:send",
     174        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:register",
    180175                discard_const_p(char *, kwnames), &callback, &msg_type)) {
    181176                return NULL;
     
    208203        const char *kwnames[] = { "callback", "msg_type", NULL };
    209204
    210         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:send",
     205        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:deregister",
    211206                discard_const_p(char *, kwnames), &callback, &msg_type)) {
    212207                return NULL;
     
    216211
    217212        Py_DECREF(callback);
    218 
    219         Py_RETURN_NONE;
    220 }
    221 
    222 static PyObject *py_messaging_add_name(PyObject *self, PyObject *args, PyObject *kwargs)
    223 {
    224         messaging_Object *iface = (messaging_Object *)self;
    225         NTSTATUS status;
    226         char *name;
    227         const char *kwnames[] = { "name", NULL };
    228 
    229         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|:send",
    230                 discard_const_p(char *, kwnames), &name)) {
    231                 return NULL;
    232         }
    233 
    234         status = irpc_add_name(iface->msg_ctx, name);
    235         if (NT_STATUS_IS_ERR(status)) {
    236                 PyErr_SetNTSTATUS(status);
    237                 return NULL;
    238         }
    239 
    240         Py_RETURN_NONE;
    241 }
    242 
    243 
    244 static PyObject *py_messaging_remove_name(PyObject *self, PyObject *args, PyObject *kwargs)
    245 {
    246         messaging_Object *iface = (messaging_Object *)self;
    247         char *name;
    248         const char *kwnames[] = { "name", NULL };
    249 
    250         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|:send",
    251                 discard_const_p(char *, kwnames), &name)) {
    252                 return NULL;
    253         }
    254 
    255         irpc_remove_name(iface->msg_ctx, name);
    256213
    257214        Py_RETURN_NONE;
     
    265222        { "deregister", (PyCFunction)py_messaging_deregister, METH_VARARGS|METH_KEYWORDS,
    266223                "S.deregister(callback, msg_type) -> None\nDeregister a message handler" },
    267         { "add_name", (PyCFunction)py_messaging_add_name, METH_VARARGS|METH_KEYWORDS, "S.add_name(name) -> None\nListen on another name" },
    268         { "remove_name", (PyCFunction)py_messaging_remove_name, METH_VARARGS|METH_KEYWORDS, "S.remove_name(name) -> None\nStop listening on a name" },
    269224        { NULL, NULL, 0, NULL }
    270225};
     
    288243PyTypeObject messaging_Type = {
    289244        PyObject_HEAD_INIT(NULL) 0,
    290         .tp_name = "irpc.Messaging",
     245        .tp_name = "messaging.Messaging",
    291246        .tp_basicsize = sizeof(messaging_Object),
    292247        .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     
    300255};
    301256
    302 
    303 /*
    304   state of a irpc 'connection'
    305 */
    306 typedef struct {
    307         PyObject_HEAD
    308         const char *server_name;
    309         struct server_id *dest_ids;
    310         struct messaging_context *msg_ctx;
    311         TALLOC_CTX *mem_ctx;
    312 } irpc_ClientConnectionObject;
    313 
    314 /*
    315   setup a context for talking to a irpc server
    316      example:
    317         status = irpc.connect("smb_server");
    318 */
    319 
    320 PyObject *py_irpc_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs)
    321 {
    322         struct tevent_context *ev;
    323         const char *kwnames[] = { "server", "own_id", "messaging_path", NULL };
    324         char *server;
    325         const char *messaging_path = NULL;
    326         PyObject *own_id = Py_None;
    327         irpc_ClientConnectionObject *ret;
    328 
    329         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oz:connect",
    330                 discard_const_p(char *, kwnames), &server, &own_id, &messaging_path)) {
    331                 return NULL;
    332         }
    333 
    334         ret = PyObject_New(irpc_ClientConnectionObject, &irpc_ClientConnectionType);
    335         if (ret == NULL)
    336                 return NULL;
    337 
    338         ret->mem_ctx = talloc_new(NULL);
    339 
    340         ret->server_name = server;
    341 
    342         ev = s4_event_context_init(ret->mem_ctx);
    343 
    344         if (messaging_path == NULL) {
    345                 messaging_path = lp_messaging_path(ret->mem_ctx,
    346                                                                    py_default_loadparm_context(ret->mem_ctx));
    347         } else {
    348                 messaging_path = talloc_strdup(ret->mem_ctx, messaging_path);
    349         }
    350 
    351         if (own_id != Py_None) {
    352                 struct server_id server_id;
    353 
    354                 if (!server_id_from_py(own_id, &server_id))
    355                         return NULL;
    356 
    357                 ret->msg_ctx = messaging_init(ret->mem_ctx,
    358                                             messaging_path,
    359                                             server_id,
    360                                         py_iconv_convenience(ret->mem_ctx),
    361                                             ev);
    362         } else {
    363                 ret->msg_ctx = messaging_client_init(ret->mem_ctx,
    364                                             messaging_path,
    365                                         py_iconv_convenience(ret->mem_ctx),
    366                                             ev);
    367         }
    368 
    369         if (ret->msg_ctx == NULL) {
    370                 PyErr_SetString(PyExc_RuntimeError, "irpc_connect unable to create a messaging context");
    371                 talloc_free(ret->mem_ctx);
    372                 return NULL;
    373         }
    374 
    375         ret->dest_ids = irpc_servers_byname(ret->msg_ctx, ret->mem_ctx, ret->server_name);
    376         if (ret->dest_ids == NULL || ret->dest_ids[0].id == 0) {
    377                 talloc_free(ret->mem_ctx);
    378                 PyErr_SetNTSTATUS(NT_STATUS_OBJECT_NAME_NOT_FOUND);
    379                 return NULL;
    380         } else {
    381                 return (PyObject *)ret;
    382         }
    383 }
    384 
    385 typedef struct {
    386         PyObject_HEAD
    387         struct irpc_request **reqs;
    388         int count;
    389         int current;
    390         TALLOC_CTX *mem_ctx;
    391         py_data_unpack_fn unpack_fn;
    392 } irpc_ResultObject;
    393 
    394        
    395 static PyObject *irpc_result_next(irpc_ResultObject *iterator)
    396 {
    397         NTSTATUS status;
    398 
    399         if (iterator->current >= iterator->count) {
    400                 PyErr_SetString(PyExc_StopIteration, "No more results");
    401                 return NULL;
    402         }
    403 
    404         status = irpc_call_recv(iterator->reqs[iterator->current]);
    405         iterator->current++;
    406         if (!NT_STATUS_IS_OK(status)) {
    407                 PyErr_SetNTSTATUS(status);
    408                 return NULL;
    409         }
    410 
    411         return iterator->unpack_fn(iterator->reqs[iterator->current-1]->r);
    412 }
    413 
    414 static PyObject *irpc_result_len(irpc_ResultObject *self)
    415 {
    416         return PyLong_FromLong(self->count);
    417 }
    418 
    419 static PyMethodDef irpc_result_methods[] = {
    420         { "__len__", (PyCFunction)irpc_result_len, METH_NOARGS,
    421                 "Number of elements returned"},
    422         { NULL }
    423 };
    424 
    425 static void irpc_result_dealloc(PyObject *self)
    426 {
    427         talloc_free(((irpc_ResultObject *)self)->mem_ctx);
    428         PyObject_Del(self);
    429 }
    430 
    431 PyTypeObject irpc_ResultIteratorType = {
    432         PyObject_HEAD_INIT(NULL) 0,
    433         .tp_name = "irpc.ResultIterator",
    434         .tp_basicsize = sizeof(irpc_ResultObject),
    435         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
    436         .tp_iternext = (iternextfunc)irpc_result_next,
    437         .tp_iter = PyObject_SelfIter,
    438         .tp_methods = irpc_result_methods,
    439         .tp_dealloc = irpc_result_dealloc,
    440 };
    441 
    442 static PyObject *py_irpc_call(irpc_ClientConnectionObject *p, struct PyNdrRpcMethodDef *method_def, PyObject *args, PyObject *kwargs)
    443 {
    444         void *ptr;
    445         struct irpc_request **reqs;
    446         int i, count;
    447         NTSTATUS status;
    448         TALLOC_CTX *mem_ctx = talloc_new(NULL);
    449         irpc_ResultObject *ret;
    450 
    451         /* allocate the C structure */
    452         ptr = talloc_zero_size(mem_ctx, method_def->table->calls[method_def->opnum].struct_size);
    453         if (ptr == NULL) {
    454                 status = NT_STATUS_NO_MEMORY;
    455                 goto done;
    456         }
    457 
    458         /* convert the mpr object into a C structure */
    459         if (!method_def->pack_in_data(args, kwargs, ptr)) {
    460                 talloc_free(mem_ctx);
    461                 return NULL;
    462         }
    463 
    464         for (count=0;p->dest_ids[count].id;count++) /* noop */ ;
    465 
    466         /* we need to make a call per server */
    467         reqs = talloc_array(mem_ctx, struct irpc_request *, count);
    468         if (reqs == NULL) {
    469                 status = NT_STATUS_NO_MEMORY;
    470                 goto done;
    471         }
    472 
    473         /* make the actual calls */
    474         for (i=0;i<count;i++) {
    475                 reqs[i] = irpc_call_send(p->msg_ctx, p->dest_ids[i],
    476                                          method_def->table, method_def->opnum, ptr, ptr);
    477                 if (reqs[i] == NULL) {
    478                         status = NT_STATUS_NO_MEMORY;
    479                         goto done;
    480                 }
    481                 talloc_steal(reqs, reqs[i]);
    482         }
    483 
    484         ret = PyObject_New(irpc_ResultObject, &irpc_ResultIteratorType);
    485         ret->mem_ctx = mem_ctx;
    486         ret->reqs = reqs;
    487         ret->count = count;
    488         ret->current = 0;
    489         ret->unpack_fn = method_def->unpack_out_data;
    490 
    491         return (PyObject *)ret;
    492 done:
    493         talloc_free(mem_ctx);
    494         PyErr_SetNTSTATUS(status);
    495         return NULL;
    496 }
    497 
    498 static PyObject *py_irpc_call_wrapper(PyObject *self, PyObject *args, void *wrapped, PyObject *kwargs)
    499 {       
    500         irpc_ClientConnectionObject *iface = (irpc_ClientConnectionObject *)self;
    501         struct PyNdrRpcMethodDef *md = wrapped;
    502 
    503         return py_irpc_call(iface, md, args, kwargs);
    504 }
    505 
    506 static void py_irpc_dealloc(PyObject *self)
    507 {
    508         irpc_ClientConnectionObject *iface = (irpc_ClientConnectionObject *)self;
    509         talloc_free(iface->mem_ctx);
    510         PyObject_Del(self);
    511 }
    512 
    513 PyTypeObject irpc_ClientConnectionType = {
    514         PyObject_HEAD_INIT(NULL) 0,
    515         .tp_name = "irpc.ClientConnection",
    516         .tp_basicsize = sizeof(irpc_ClientConnectionObject),
    517         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
    518         .tp_new = py_irpc_connect,
    519         .tp_dealloc = py_irpc_dealloc,
    520         .tp_doc = "ClientConnection(server, own_id=None, messaging_path=None)\n" \
    521                   "Create a new IRPC client connection to communicate with the servers in the specified path.\n" \
    522                   "If no path is specified, the default path from smb.conf will be used."
    523 };
    524 
    525 static bool irpc_AddNdrRpcMethods(PyTypeObject *ifacetype, const struct PyNdrRpcMethodDef *mds)
    526 {
    527         int i;
    528         for (i = 0; mds[i].name; i++) {
    529                 PyObject *ret;
    530                 struct wrapperbase *wb = calloc(sizeof(struct wrapperbase), 1);
    531 
    532                 wb->name = discard_const_p(char, mds[i].name);
    533                 wb->flags = PyWrapperFlag_KEYWORDS;
    534                 wb->wrapper = (wrapperfunc)py_irpc_call_wrapper;
    535                 wb->doc = discard_const_p(char, mds[i].doc);
    536                
    537                 ret = PyDescr_NewWrapper(ifacetype, wb, discard_const_p(void, &mds[i]));
    538 
    539                 PyDict_SetItemString(ifacetype->tp_dict, mds[i].name,
    540                                      (PyObject *)ret);
    541         }
    542 
    543         return true;
    544 }
    545 
    546257void initmessaging(void)
    547258{
    548259        PyObject *mod;
    549         PyObject *dep_irpc;
    550 
    551         dep_irpc = PyImport_ImportModule("samba.dcerpc.irpc");
    552         if (dep_irpc == NULL)
    553                 return;
    554 
    555         if (PyType_Ready(&irpc_ClientConnectionType) < 0)
    556                 return;
    557260
    558261        if (PyType_Ready(&messaging_Type) < 0)
    559                 return;
    560 
    561         if (PyType_Ready(&irpc_ResultIteratorType) < 0)
    562                 return;
    563 
    564         if (!irpc_AddNdrRpcMethods(&irpc_ClientConnectionType, py_ndr_irpc_methods))
    565262                return;
    566263
     
    569266                return;
    570267
    571         Py_INCREF((PyObject *)&irpc_ClientConnectionType);
    572         PyModule_AddObject(mod, "ClientConnection", (PyObject *)&irpc_ClientConnectionType);
    573 
    574268        Py_INCREF((PyObject *)&messaging_Type);
    575269        PyModule_AddObject(mod, "Messaging", (PyObject *)&messaging_Type);
Note: See TracChangeset for help on using the changeset viewer.