2010-08-27 04:17:26 +04:00
/*
Unix SMB / CIFS implementation .
Python interface to DCE / RPC library - utility functions .
Copyright ( C ) 2010 Jelmer Vernooij < jelmer @ samba . org >
Copyright ( C ) 2010 Andrew Tridgell < tridge @ samba . org >
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 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
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 , see < http : //www.gnu.org/licenses/>.
*/
2023-11-09 13:35:56 +03:00
# include "lib/replace/system/python.h"
2017-02-15 11:19:33 +03:00
# include "python/py3compat.h"
2010-08-27 04:17:26 +04:00
# include "includes.h"
2019-05-02 21:35:56 +03:00
# include "python/modules.h"
2010-08-27 04:17:26 +04:00
# include "librpc/rpc/pyrpc_util.h"
2010-09-03 04:39:38 +04:00
# include "librpc/rpc/dcerpc.h"
# include "librpc/rpc/pyrpc.h"
# include "param/pyparam.h"
# include "auth/credentials/pycredentials.h"
# include "lib/events/events.h"
2010-09-17 11:04:28 +04:00
# include "lib/messaging/messaging.h"
# include "lib/messaging/irpc.h"
2010-08-27 04:17:26 +04:00
2010-12-09 11:59:52 +03:00
bool py_check_dcerpc_type ( PyObject * obj , const char * module , const char * type_name )
2010-08-27 04:17:26 +04:00
{
PyObject * mod ;
2010-09-03 04:39:38 +04:00
PyTypeObject * type ;
2010-08-27 04:17:26 +04:00
bool ret ;
mod = PyImport_ImportModule ( module ) ;
if ( mod = = NULL ) {
PyErr_Format ( PyExc_RuntimeError , " Unable to import %s to check type %s " ,
2010-12-09 11:59:52 +03:00
module , type_name ) ;
2012-08-16 13:38:26 +04:00
return false ;
2010-08-27 04:17:26 +04:00
}
2010-12-09 11:59:52 +03:00
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , type_name ) ;
2010-08-27 04:17:26 +04:00
Py_DECREF ( mod ) ;
if ( type = = NULL ) {
PyErr_Format ( PyExc_RuntimeError , " Unable to find type %s in module %s " ,
2010-12-09 11:59:52 +03:00
module , type_name ) ;
2012-08-16 13:38:26 +04:00
return false ;
2010-08-27 04:17:26 +04:00
}
ret = PyObject_TypeCheck ( obj , type ) ;
Py_DECREF ( type ) ;
if ( ! ret )
PyErr_Format ( PyExc_TypeError , " Expected type %s.%s, got %s " ,
2010-12-09 11:59:52 +03:00
module , type_name , Py_TYPE ( obj ) - > tp_name ) ;
2010-08-27 04:17:26 +04:00
return ret ;
}
2010-09-03 04:39:38 +04:00
2010-09-17 11:04:28 +04:00
/*
connect to a IRPC pipe from python
*/
static NTSTATUS pyrpc_irpc_connect ( TALLOC_CTX * mem_ctx , const char * irpc_server ,
const struct ndr_interface_table * table ,
struct tevent_context * event_ctx ,
struct loadparm_context * lp_ctx ,
struct dcerpc_binding_handle * * binding_handle )
{
2011-05-03 04:40:33 +04:00
struct imessaging_context * msg ;
2010-09-17 11:04:28 +04:00
2011-10-13 13:01:56 +04:00
msg = imessaging_client_init ( mem_ctx , lp_ctx , event_ctx ) ;
2010-09-17 11:04:28 +04:00
NT_STATUS_HAVE_NO_MEMORY ( msg ) ;
* binding_handle = irpc_binding_handle_by_name ( mem_ctx , msg , irpc_server , table ) ;
if ( * binding_handle = = NULL ) {
talloc_free ( msg ) ;
return NT_STATUS_INVALID_PIPE_STATE ;
}
2014-05-05 08:27:59 +04:00
/*
* Note : this allows nested event loops to happen ,
* but as there ' s no top level event loop it ' s not that critical .
*/
dcerpc_binding_handle_set_sync_ev ( * binding_handle , event_ctx ) ;
2010-09-17 11:04:28 +04:00
return NT_STATUS_OK ;
}
PyObject * py_dcerpc_interface_init_helper ( PyTypeObject * type , PyObject * args , PyObject * kwargs ,
const struct ndr_interface_table * table )
2010-09-03 04:39:38 +04:00
{
dcerpc_InterfaceObject * ret ;
const char * binding_string ;
PyObject * py_lp_ctx = Py_None , * py_credentials = Py_None , * py_basis = Py_None ;
NTSTATUS status ;
2016-07-09 07:36:52 +03:00
unsigned int timeout = ( unsigned int ) - 1 ;
2010-09-03 04:39:38 +04:00
const char * kwnames [ ] = {
2016-07-09 07:36:52 +03:00
" binding " , " lp_ctx " , " credentials " , " timeout " , " basis_connection " , NULL
2010-09-03 04:39:38 +04:00
} ;
2016-07-09 07:36:52 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|OOIO:samr " , discard_const_p ( char * , kwnames ) , & binding_string , & py_lp_ctx , & py_credentials , & timeout , & py_basis ) ) {
2010-09-03 04:39:38 +04:00
return NULL ;
}
2011-06-06 08:58:28 +04:00
status = dcerpc_init ( ) ;
2010-09-03 04:39:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
2010-09-17 11:04:28 +04:00
2010-09-03 04:39:38 +04:00
ret = PyObject_New ( dcerpc_InterfaceObject , type ) ;
2018-05-03 00:57:29 +03:00
if ( ret = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2014-02-15 13:12:04 +04:00
ret - > pipe = NULL ;
ret - > binding_handle = NULL ;
2019-05-08 02:30:20 +03:00
ret - > ev = NULL ;
2014-02-15 13:12:04 +04:00
ret - > mem_ctx = talloc_new ( NULL ) ;
if ( ret - > mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-09-03 04:39:38 +04:00
2010-09-17 11:04:28 +04:00
if ( strncmp ( binding_string , " irpc: " , 5 ) = = 0 ) {
2014-02-15 13:12:04 +04:00
struct loadparm_context * lp_ctx ;
2019-05-08 02:30:20 +03:00
ret - > ev = s4_event_context_init ( ret - > mem_ctx ) ;
if ( ret - > ev = = NULL ) {
2019-05-27 03:56:08 +03:00
PyErr_SetString ( PyExc_TypeError ,
" Unable to initialise event context " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2019-05-08 02:30:20 +03:00
lp_ctx = lpcfg_from_py_object ( ret - > ev , py_lp_ctx ) ;
2014-02-15 13:12:04 +04:00
if ( lp_ctx = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected loadparm context " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-17 11:04:28 +04:00
status = pyrpc_irpc_connect ( ret - > mem_ctx , binding_string + 5 , table ,
2019-05-08 02:30:20 +03:00
ret - > ev , lp_ctx , & ret - > binding_handle ) ;
2014-02-15 13:12:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-17 11:04:28 +04:00
} else if ( py_basis ! = Py_None ) {
2010-09-03 04:39:38 +04:00
struct dcerpc_pipe * base_pipe ;
PyObject * py_base ;
PyTypeObject * ClientConnection_Type ;
py_base = PyImport_ImportModule ( " samba.dcerpc.base " ) ;
if ( py_base = = NULL ) {
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2010-09-03 04:39:38 +04:00
return NULL ;
}
ClientConnection_Type = ( PyTypeObject * ) PyObject_GetAttrString ( py_base , " ClientConnection " ) ;
if ( ClientConnection_Type = = NULL ) {
PyErr_SetNone ( PyExc_TypeError ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
Py_DECREF ( py_base ) ;
2010-09-03 04:39:38 +04:00
return NULL ;
}
if ( ! PyObject_TypeCheck ( py_basis , ClientConnection_Type ) ) {
PyErr_SetString ( PyExc_TypeError , " basis_connection must be a DCE/RPC connection " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
Py_DECREF ( py_base ) ;
Py_DECREF ( ClientConnection_Type ) ;
2010-09-03 04:39:38 +04:00
return NULL ;
}
2014-02-15 13:12:04 +04:00
base_pipe = talloc_reference ( ret - > mem_ctx ,
( ( dcerpc_InterfaceObject * ) py_basis ) - > pipe ) ;
if ( base_pipe = = NULL ) {
PyErr_NoMemory ( ) ;
2019-05-08 02:30:20 +03:00
Py_DECREF ( ret ) ;
Py_DECREF ( py_base ) ;
Py_DECREF ( ClientConnection_Type ) ;
return NULL ;
}
ret - > ev = talloc_reference (
ret - > mem_ctx ,
( ( dcerpc_InterfaceObject * ) py_basis ) - > ev ) ;
if ( ret - > ev = = NULL ) {
PyErr_NoMemory ( ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
Py_DECREF ( py_base ) ;
Py_DECREF ( ClientConnection_Type ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-03 04:39:38 +04:00
status = dcerpc_secondary_context ( base_pipe , & ret - > pipe , table ) ;
2014-02-15 13:12:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
Py_DECREF ( py_base ) ;
Py_DECREF ( ClientConnection_Type ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-03 04:39:38 +04:00
ret - > pipe = talloc_steal ( ret - > mem_ctx , ret - > pipe ) ;
2018-05-03 00:53:56 +03:00
Py_XDECREF ( ClientConnection_Type ) ;
Py_XDECREF ( py_base ) ;
2010-09-03 04:39:38 +04:00
} else {
2014-02-15 13:12:04 +04:00
struct loadparm_context * lp_ctx ;
struct cli_credentials * credentials ;
2019-05-08 02:30:20 +03:00
ret - > ev = s4_event_context_init ( ret - > mem_ctx ) ;
if ( ret - > ev = = NULL ) {
2014-02-15 13:12:04 +04:00
PyErr_SetString ( PyExc_TypeError , " Expected loadparm context " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2019-05-08 02:30:20 +03:00
lp_ctx = lpcfg_from_py_object ( ret - > ev , py_lp_ctx ) ;
2014-02-15 13:12:04 +04:00
if ( lp_ctx = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected loadparm context " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-17 11:04:28 +04:00
credentials = cli_credentials_from_py_object ( py_credentials ) ;
if ( credentials = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected credentials " ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2010-09-17 11:04:28 +04:00
return NULL ;
}
2014-02-15 13:12:04 +04:00
status = dcerpc_pipe_connect ( ret - > mem_ctx , & ret - > pipe , binding_string ,
2019-05-08 02:30:20 +03:00
table , credentials , ret - > ev , lp_ctx ) ;
2014-02-15 13:12:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
2018-05-03 00:53:56 +03:00
Py_DECREF ( ret ) ;
2014-02-15 13:12:04 +04:00
return NULL ;
}
2010-09-03 04:39:38 +04:00
}
2010-09-17 11:04:28 +04:00
if ( ret - > pipe ) {
ret - > pipe - > conn - > flags | = DCERPC_NDR_REF_ALLOC ;
ret - > binding_handle = ret - > pipe - > binding_handle ;
}
2016-07-09 07:36:52 +03:00
/* reset timeout for the handle */
2016-07-20 11:50:14 +03:00
if ( ( timeout ! = ( ( unsigned int ) - 1 ) ) & & ( ret - > binding_handle ! = NULL ) ) {
2016-07-09 07:36:52 +03:00
dcerpc_binding_handle_set_timeout ( ret - > binding_handle , timeout ) ;
}
2010-09-03 04:39:38 +04:00
return ( PyObject * ) ret ;
}
static PyObject * py_dcerpc_run_function ( dcerpc_InterfaceObject * iface ,
const struct PyNdrRpcMethodDef * md ,
PyObject * args , PyObject * kwargs )
{
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
void * r ;
PyObject * result = Py_None ;
if ( md - > pack_in_data = = NULL | | md - > unpack_out_data = = NULL ) {
PyErr_SetString ( PyExc_NotImplementedError , " No marshalling code available yet " ) ;
return NULL ;
}
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
r = talloc_zero_size ( mem_ctx , md - > table - > calls [ md - > opnum ] . struct_size ) ;
if ( r = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
if ( ! md - > pack_in_data ( args , kwargs , r ) ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
status = md - > call ( iface - > binding_handle , mem_ctx , r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetDCERPCStatus ( iface - > pipe , status ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
result = md - > unpack_out_data ( r ) ;
talloc_free ( mem_ctx ) ;
return result ;
}
static PyObject * py_dcerpc_call_wrapper ( PyObject * self , PyObject * args , void * wrapped , PyObject * kwargs )
2023-11-08 11:09:14 +03:00
{
2010-09-03 04:39:38 +04:00
dcerpc_InterfaceObject * iface = ( dcerpc_InterfaceObject * ) self ;
const struct PyNdrRpcMethodDef * md = ( const struct PyNdrRpcMethodDef * ) wrapped ;
return py_dcerpc_run_function ( iface , md , args , kwargs ) ;
}
bool PyInterface_AddNdrRpcMethods ( PyTypeObject * ifacetype , const struct PyNdrRpcMethodDef * mds )
{
int i ;
for ( i = 0 ; mds [ i ] . name ; i + + ) {
PyObject * ret ;
struct wrapperbase * wb = ( struct wrapperbase * ) calloc ( sizeof ( struct wrapperbase ) , 1 ) ;
2013-07-18 02:30:35 +04:00
if ( wb = = NULL ) {
return false ;
}
2010-09-03 04:39:38 +04:00
wb - > name = discard_const_p ( char , mds [ i ] . name ) ;
wb - > flags = PyWrapperFlag_KEYWORDS ;
2019-05-02 21:35:56 +03:00
wb - > wrapper = PY_DISCARD_FUNC_SIG ( wrapperfunc ,
py_dcerpc_call_wrapper ) ;
2010-09-03 04:39:38 +04:00
wb - > doc = discard_const_p ( char , mds [ i ] . doc ) ;
ret = PyDescr_NewWrapper ( ifacetype , wb , discard_const_p ( void , & mds [ i ] ) ) ;
2023-11-08 11:09:14 +03:00
PyDict_SetItemString ( ifacetype - > tp_dict , mds [ i ] . name ,
2010-09-03 04:39:38 +04:00
( PyObject * ) ret ) ;
2019-01-31 20:01:26 +03:00
Py_CLEAR ( ret ) ;
2010-09-03 04:39:38 +04:00
}
return true ;
}
2014-03-27 17:54:29 +04:00
PyObject * py_dcerpc_syntax_init_helper ( PyTypeObject * type , PyObject * args , PyObject * kwargs ,
const struct ndr_syntax_id * syntax )
{
PyObject * ret ;
struct ndr_syntax_id * obj ;
const char * kwnames [ ] = { NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " :abstract_syntax " , discard_const_p ( char * , kwnames ) ) ) {
return NULL ;
}
ret = pytalloc_new ( struct ndr_syntax_id , type ) ;
if ( ret = = NULL ) {
return NULL ;
}
2018-11-29 18:47:15 +03:00
obj = pytalloc_get_type ( ret , struct ndr_syntax_id ) ;
2014-03-27 17:54:29 +04:00
* obj = * syntax ;
return ret ;
}
2010-09-03 04:39:38 +04:00
void PyErr_SetDCERPCStatus ( struct dcerpc_pipe * p , NTSTATUS status )
{
if ( p & & NT_STATUS_EQUAL ( status , NT_STATUS_NET_WRITE_FAULT ) ) {
status = dcerpc_fault_to_nt_status ( p - > last_fault_code ) ;
}
PyErr_SetNTSTATUS ( status ) ;
}
2010-09-15 12:49:06 +04:00
/*
take a NDR structure that has a type in a python module and return
it as a python object
r is the NDR structure pointer ( a C structure )
r_ctx is the context that is a parent of r . It will be referenced by
the resulting python object
2016-03-08 01:16:27 +03:00
This MUST only be used by objects that are based on pytalloc_Object
2016-03-08 01:18:56 +03:00
otherwise the pytalloc_reference_ex ( ) will fail .
2010-09-15 12:49:06 +04:00
*/
PyObject * py_return_ndr_struct ( const char * module_name , const char * type_name ,
TALLOC_CTX * r_ctx , void * r )
{
PyTypeObject * py_type ;
PyObject * module ;
2019-01-23 18:15:07 +03:00
PyObject * result = NULL ;
2010-09-15 12:49:06 +04:00
if ( r = = NULL ) {
Py_RETURN_NONE ;
}
module = PyImport_ImportModule ( module_name ) ;
if ( module = = NULL ) {
return NULL ;
}
py_type = ( PyTypeObject * ) PyObject_GetAttrString ( module , type_name ) ;
if ( py_type = = NULL ) {
2018-05-03 00:53:56 +03:00
Py_DECREF ( module ) ;
2010-09-15 12:49:06 +04:00
return NULL ;
}
2019-01-23 18:15:07 +03:00
result = pytalloc_reference_ex ( py_type , r_ctx , r ) ;
Py_CLEAR ( module ) ;
Py_CLEAR ( py_type ) ;
return result ;
2010-09-15 12:49:06 +04:00
}
2010-12-08 17:07:32 +03:00
PyObject * PyString_FromStringOrNULL ( const char * str )
{
if ( str = = NULL ) {
Py_RETURN_NONE ;
}
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( str ) ;
2010-12-08 17:07:32 +03:00
}
2016-09-13 05:48:13 +03:00
2023-12-21 01:51:19 +03:00
PyObject * PyBytes_FromUtf16StringOrNULL ( const unsigned char * str )
2023-11-16 01:20:22 +03:00
{
size_t len ;
if ( str = = NULL ) {
Py_RETURN_NONE ;
}
len = utf16_len ( str ) ;
return PyBytes_FromStringAndSize ( ( const char * ) str , len ) ;
}
2023-12-21 01:51:19 +03:00
unsigned char * PyUtf16String_FromBytes ( TALLOC_CTX * mem_ctx , PyObject * value )
2023-11-16 01:20:22 +03:00
{
char * bytes = NULL ;
Py_ssize_t len = 0 ;
2023-12-21 01:51:19 +03:00
unsigned char * utf16_string = NULL ;
2023-11-16 01:20:22 +03:00
int ret ;
ret = PyBytes_AsStringAndSize ( value , & bytes , & len ) ;
if ( ret ) {
return NULL ;
}
if ( len < 0 ) {
PyErr_SetString ( PyExc_ValueError , " bytes length is negative " ) ;
return NULL ;
}
2023-11-17 02:56:17 +03:00
if ( len & 1 ) {
PyErr_SetString ( PyExc_ValueError , " bytes length is odd " ) ;
return NULL ;
}
2023-11-16 01:20:22 +03:00
/* Ensure that the bytes object contains no embedded null terminator. */
if ( ( size_t ) len ! = utf16_len_n ( bytes , len ) ) {
PyErr_SetString ( PyExc_ValueError ,
" value contains an embedded null terminator " ) ;
return NULL ;
}
utf16_string = talloc_utf16_strlendup ( mem_ctx , bytes , len ) ;
if ( utf16_string = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
return utf16_string ;
}
2016-09-13 05:48:13 +03:00
PyObject * pyrpc_import_union ( PyTypeObject * type , TALLOC_CTX * mem_ctx , int level ,
const void * in , const char * typename )
{
PyObject * mem_ctx_obj = NULL ;
PyObject * in_obj = NULL ;
PyObject * ret = NULL ;
2017-02-20 20:02:09 +03:00
mem_ctx_obj = pytalloc_GenericObject_reference ( mem_ctx ) ;
2016-09-13 05:48:13 +03:00
if ( mem_ctx_obj = = NULL ) {
return NULL ;
}
2017-02-20 20:02:09 +03:00
in_obj = pytalloc_GenericObject_reference_ex ( mem_ctx , discard_const ( in ) ) ;
2016-09-13 05:48:13 +03:00
if ( in_obj = = NULL ) {
Py_XDECREF ( mem_ctx_obj ) ;
return NULL ;
}
ret = PyObject_CallMethod ( ( PyObject * ) type ,
discard_const_p ( char , " __import__ " ) ,
discard_const_p ( char , " OiO " ) ,
mem_ctx_obj , level , in_obj ) ;
Py_XDECREF ( mem_ctx_obj ) ;
Py_XDECREF ( in_obj ) ;
if ( ret = = NULL ) {
return NULL ;
}
return ret ;
}
void * pyrpc_export_union ( PyTypeObject * type , TALLOC_CTX * mem_ctx , int level ,
PyObject * in , const char * typename )
{
PyObject * mem_ctx_obj = NULL ;
PyObject * ret_obj = NULL ;
void * ret = NULL ;
2017-02-20 20:02:09 +03:00
mem_ctx_obj = pytalloc_GenericObject_reference ( mem_ctx ) ;
2016-09-13 05:48:13 +03:00
if ( mem_ctx_obj = = NULL ) {
return NULL ;
}
ret_obj = PyObject_CallMethod ( ( PyObject * ) type ,
discard_const_p ( char , " __export__ " ) ,
discard_const_p ( char , " OiO " ) ,
mem_ctx_obj , level , in ) ;
Py_XDECREF ( mem_ctx_obj ) ;
if ( ret_obj = = NULL ) {
return NULL ;
}
2017-02-20 20:02:09 +03:00
ret = _pytalloc_get_type ( ret_obj , typename ) ;
2016-09-13 05:48:13 +03:00
Py_XDECREF ( ret_obj ) ;
return ret ;
}
2018-11-29 14:41:34 +03:00
PyObject * py_dcerpc_ndr_pointer_deref ( PyTypeObject * type , PyObject * obj )
{
if ( ! PyObject_TypeCheck ( obj , type ) ) {
PyErr_Format ( PyExc_TypeError ,
" Expected type '%s' but got type '%s' " ,
( type ) - > tp_name , Py_TYPE ( obj ) - > tp_name ) ;
return NULL ;
}
return PyObject_GetAttrString ( obj , discard_const_p ( char , " value " ) ) ;
}
PyObject * py_dcerpc_ndr_pointer_wrap ( PyTypeObject * type , PyObject * obj )
{
PyObject * args = NULL ;
PyObject * ret_obj = NULL ;
args = PyTuple_New ( 1 ) ;
if ( args = = NULL ) {
return NULL ;
}
Py_XINCREF ( obj ) ;
PyTuple_SetItem ( args , 0 , obj ) ;
ret_obj = PyObject_Call ( ( PyObject * ) type , args , NULL ) ;
Py_XDECREF ( args ) ;
return ret_obj ;
}