2002-07-29 07:50:35 +04:00
/*
Python wrappers for DCERPC / SMB client routines .
Copyright ( C ) Tim Potter , 2002
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
( 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "python/py_smb.h"
/* Create a new cli_state python object */
PyObject * new_cli_state_object ( struct cli_state * cli )
{
cli_state_object * o ;
o = PyObject_New ( cli_state_object , & cli_state_type ) ;
o - > cli = cli ;
return ( PyObject * ) o ;
}
2002-08-02 09:35:09 +04:00
static PyObject * py_smb_connect ( PyObject * self , PyObject * args , PyObject * kw )
{
static char * kwlist [ ] = { " server " , NULL } ;
struct cli_state * cli ;
char * server ;
struct in_addr ip ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s " , kwlist , & server ) )
return NULL ;
2006-07-11 22:01:26 +04:00
if ( ! ( cli = cli_initialise ( ) ) )
2002-08-02 09:35:09 +04:00
return NULL ;
ZERO_STRUCT ( ip ) ;
if ( ! cli_connect ( cli , server , & ip ) )
return NULL ;
return new_cli_state_object ( cli ) ;
}
static PyObject * py_smb_session_request ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " called " , " calling " , NULL } ;
char * calling_name = NULL , * called_name ;
struct nmb_name calling , called ;
BOOL result ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|s " , kwlist , & called_name ,
& calling_name ) )
return NULL ;
if ( ! calling_name )
2002-11-29 04:13:05 +03:00
calling_name = global_myname ( ) ;
2002-08-02 09:35:09 +04:00
make_nmb_name ( & calling , calling_name , 0x00 ) ;
make_nmb_name ( & called , called_name , 0x20 ) ;
result = cli_session_request ( cli - > cli , & calling , & called ) ;
return Py_BuildValue ( " i " , result ) ;
}
static PyObject * py_smb_negprot ( PyObject * self , PyObject * args , PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { NULL } ;
BOOL result ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " " , kwlist ) )
return NULL ;
result = cli_negprot ( cli - > cli ) ;
return Py_BuildValue ( " i " , result ) ;
}
static PyObject * py_smb_session_setup ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
2002-11-04 23:33:16 +03:00
static char * kwlist [ ] = { " creds " , NULL } ;
2002-08-02 09:35:09 +04:00
PyObject * creds ;
char * username , * domain , * password , * errstr ;
BOOL result ;
2002-11-04 23:33:16 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " |O " , kwlist , & creds ) )
2002-08-02 09:35:09 +04:00
return NULL ;
if ( ! py_parse_creds ( creds , & username , & domain , & password , & errstr ) ) {
free ( errstr ) ;
return NULL ;
}
result = cli_session_setup (
cli - > cli , username , password , strlen ( password ) + 1 ,
password , strlen ( password ) + 1 , domain ) ;
2002-11-04 23:33:16 +03:00
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " session setup failed " ) ;
return NULL ;
}
2002-08-02 09:35:09 +04:00
return Py_BuildValue ( " i " , result ) ;
}
static PyObject * py_smb_tconx ( PyObject * self , PyObject * args , PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
2002-11-04 23:33:16 +03:00
static char * kwlist [ ] = { " service " , NULL } ;
char * service ;
2002-08-02 09:35:09 +04:00
BOOL result ;
2002-11-04 23:33:16 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s " , kwlist , & service ) )
2002-08-02 09:35:09 +04:00
return NULL ;
2002-11-04 23:33:16 +03:00
result = cli_send_tconX (
cli - > cli , service , strequal ( service , " IPC$ " ) ? " IPC " :
" ????? " , " " , 1 ) ;
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " tconx failed " ) ;
2002-08-02 09:35:09 +04:00
return NULL ;
}
return Py_BuildValue ( " i " , result ) ;
}
2002-11-04 23:33:16 +03:00
static PyObject * py_smb_nt_create_andx ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " filename " , " desired_access " ,
" file_attributes " , " share_access " ,
2004-10-05 05:36:37 +04:00
" create_disposition " , " create_options " ,
NULL } ;
2002-11-04 23:33:16 +03:00
char * filename ;
uint32 desired_access , file_attributes = 0 ,
share_access = FILE_SHARE_READ | FILE_SHARE_WRITE ,
2005-07-14 01:10:12 +04:00
create_disposition = OPENX_FILE_EXISTS_OPEN , create_options = 0 ;
2002-11-04 23:33:16 +03:00
int result ;
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
2004-10-05 05:36:37 +04:00
args , kw , " si|iiii " , kwlist , & filename , & desired_access ,
2002-11-04 23:33:16 +03:00
& file_attributes , & share_access , & create_disposition ,
& create_options ) )
return NULL ;
result = cli_nt_create_full (
2003-04-15 23:51:17 +04:00
cli - > cli , filename , 0 , desired_access , file_attributes ,
share_access , create_disposition , create_options , 0 ) ;
2002-11-04 23:33:16 +03:00
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " nt_create_andx failed " ) ;
return NULL ;
}
/* Return FID */
return PyInt_FromLong ( result ) ;
}
2005-02-09 02:17:44 +03:00
static PyObject * py_smb_open ( PyObject * self , PyObject * args , PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " filename " , " flags " ,
" share_mode " , NULL } ;
char * filename ;
uint32 flags , share_mode = DENY_NONE ;
int result ;
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " si|i " , kwlist , & filename , & flags , & share_mode ) )
return NULL ;
result = cli_open ( cli - > cli , filename , flags , share_mode ) ;
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " open failed " ) ;
return NULL ;
}
/* Return FID */
return PyInt_FromLong ( result ) ;
}
static PyObject * py_smb_read ( PyObject * self , PyObject * args , PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " fnum " , " offset " , " size " , NULL } ;
int fnum , offset = 0 , size = 0 ;
ssize_t result ;
2005-03-23 00:17:01 +03:00
SMB_OFF_T fsize ;
2005-02-09 02:17:44 +03:00
char * data ;
PyObject * ret ;
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " i|ii " , kwlist , & fnum , & offset , & size ) )
return NULL ;
if ( ! cli_qfileinfo ( cli - > cli , fnum , NULL , & fsize , NULL , NULL ,
NULL , NULL , NULL ) & &
! cli_getattrE ( cli - > cli , fnum , NULL , & fsize , NULL , NULL , NULL ) ) {
PyErr_SetString ( PyExc_RuntimeError , " getattrib failed " ) ;
return NULL ;
}
if ( offset < 0 )
offset = 0 ;
if ( size < 1 | | size > fsize - offset )
size = fsize - offset ;
2005-05-09 16:43:12 +04:00
if ( ! ( data = SMB_XMALLOC_ARRAY ( char , size ) ) ) {
2005-02-09 02:17:44 +03:00
PyErr_SetString ( PyExc_RuntimeError , " malloc failed " ) ;
return NULL ;
}
result = cli_read ( cli - > cli , fnum , data , ( off_t ) offset , ( size_t ) size ) ;
if ( result = = - 1 | | cli_is_error ( cli - > cli ) ) {
SAFE_FREE ( data ) ;
PyErr_SetString ( PyExc_RuntimeError , " read failed " ) ;
return NULL ;
}
/* Return a python string */
ret = Py_BuildValue ( " s# " , data , result ) ;
SAFE_FREE ( data ) ;
return ret ;
}
2002-11-04 23:33:16 +03:00
static PyObject * py_smb_close ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " fnum " , NULL } ;
BOOL result ;
int fnum ;
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " i " , kwlist , & fnum ) )
return NULL ;
result = cli_close ( cli - > cli , fnum ) ;
return PyInt_FromLong ( result ) ;
}
static PyObject * py_smb_unlink ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " filename " , NULL } ;
char * filename ;
BOOL result ;
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " s " , kwlist , & filename ) )
return NULL ;
result = cli_unlink ( cli - > cli , filename ) ;
return PyInt_FromLong ( result ) ;
}
static PyObject * py_smb_query_secdesc ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " fnum " , NULL } ;
2003-08-04 04:48:49 +04:00
PyObject * result = NULL ;
2002-11-04 23:33:16 +03:00
SEC_DESC * secdesc = NULL ;
int fnum ;
2003-08-04 04:48:49 +04:00
TALLOC_CTX * mem_ctx = NULL ;
2002-11-04 23:33:16 +03:00
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " i " , kwlist , & fnum ) )
return NULL ;
2002-12-24 02:54:10 +03:00
mem_ctx = talloc_init ( " py_smb_query_secdesc " ) ;
2002-11-04 23:33:16 +03:00
secdesc = cli_query_secdesc ( cli - > cli , fnum , mem_ctx ) ;
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " query_secdesc failed " ) ;
2003-07-23 05:26:46 +04:00
goto done ;
2002-11-04 23:33:16 +03:00
}
if ( ! secdesc ) {
Py_INCREF ( Py_None ) ;
result = Py_None ;
goto done ;
}
if ( ! py_from_SECDESC ( & result , secdesc ) ) {
PyErr_SetString (
PyExc_TypeError ,
" Invalid security descriptor returned " ) ;
goto done ;
}
done :
talloc_destroy ( mem_ctx ) ;
return result ;
}
static PyObject * py_smb_set_secdesc ( PyObject * self , PyObject * args ,
PyObject * kw )
{
cli_state_object * cli = ( cli_state_object * ) self ;
static char * kwlist [ ] = { " fnum " , " security_descriptor " , NULL } ;
2003-08-04 04:48:49 +04:00
PyObject * result = NULL ;
2002-11-04 23:33:16 +03:00
PyObject * py_secdesc ;
SEC_DESC * secdesc ;
2003-08-04 04:48:49 +04:00
TALLOC_CTX * mem_ctx = NULL ;
2002-11-04 23:33:16 +03:00
int fnum ;
2003-08-04 04:48:49 +04:00
BOOL err ;
2002-11-04 23:33:16 +03:00
/* Parse parameters */
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " iO " , kwlist , & fnum , & py_secdesc ) )
return NULL ;
2003-08-04 04:48:49 +04:00
mem_ctx = talloc_init ( " py_smb_set_secdesc " ) ;
2002-11-04 23:33:16 +03:00
if ( ! py_to_SECDESC ( & secdesc , py_secdesc , mem_ctx ) ) {
PyErr_SetString ( PyExc_TypeError ,
" Invalid security descriptor " ) ;
2003-08-04 04:48:49 +04:00
goto done ;
2002-11-04 23:33:16 +03:00
}
2003-08-04 04:48:49 +04:00
err = cli_set_secdesc ( cli - > cli , fnum , secdesc ) ;
2002-11-04 23:33:16 +03:00
if ( cli_is_error ( cli - > cli ) ) {
PyErr_SetString ( PyExc_RuntimeError , " set_secdesc failed " ) ;
2003-08-04 04:48:49 +04:00
goto done ;
2002-11-04 23:33:16 +03:00
}
2003-08-04 04:48:49 +04:00
result = PyInt_FromLong ( err ) ;
done :
talloc_destroy ( mem_ctx ) ;
return result ;
2002-11-04 23:33:16 +03:00
}
2002-08-02 09:35:09 +04:00
static PyMethodDef smb_hnd_methods [ ] = {
2002-11-04 23:33:16 +03:00
/* Session and connection handling */
2002-08-02 09:35:09 +04:00
{ " session_request " , ( PyCFunction ) py_smb_session_request ,
METH_VARARGS | METH_KEYWORDS , " Request a session " } ,
{ " negprot " , ( PyCFunction ) py_smb_negprot ,
METH_VARARGS | METH_KEYWORDS , " Protocol negotiation " } ,
{ " session_setup " , ( PyCFunction ) py_smb_session_setup ,
METH_VARARGS | METH_KEYWORDS , " Session setup " } ,
{ " tconx " , ( PyCFunction ) py_smb_tconx ,
METH_VARARGS | METH_KEYWORDS , " Tree connect " } ,
2002-11-04 23:33:16 +03:00
/* File operations */
{ " nt_create_andx " , ( PyCFunction ) py_smb_nt_create_andx ,
METH_VARARGS | METH_KEYWORDS , " NT Create&X " } ,
2005-02-09 02:17:44 +03:00
{ " open " , ( PyCFunction ) py_smb_open ,
METH_VARARGS | METH_KEYWORDS ,
" Open a file \n "
" \n "
" This function returns a fnum handle to an open file. The file is \n "
" opened with flags and optional share mode. If unspecified, the \n "
" default share mode is DENY_NONE \n "
" \n "
" Example: \n "
" \n "
" >>> fnum=conn.open(filename, os.O_RDONLY) " } ,
{ " read " , ( PyCFunction ) py_smb_read ,
METH_VARARGS | METH_KEYWORDS ,
" Read from an open file \n "
" \n "
" This function returns a string read from an open file starting at \n "
" offset for size bytes (until EOF is reached). If unspecified, the \n "
" default offset is 0, and default size is the remainder of the file. \n "
" \n "
" Example: \n "
" \n "
" >>> conn.read(fnum) # read entire file \n "
" >>> conn.read(fnum,5) # read entire file from offset 5 \n "
" >>> conn.read(fnum,size=64) # read 64 bytes from start of file \n "
" >>> conn.read(fnum,4096,1024) # read 1024 bytes from offset 4096 \n " } ,
2002-11-04 23:33:16 +03:00
{ " close " , ( PyCFunction ) py_smb_close ,
METH_VARARGS | METH_KEYWORDS , " Close " } ,
{ " unlink " , ( PyCFunction ) py_smb_unlink ,
METH_VARARGS | METH_KEYWORDS , " Unlink " } ,
/* Security descriptors */
{ " query_secdesc " , ( PyCFunction ) py_smb_query_secdesc ,
METH_VARARGS | METH_KEYWORDS , " Query security descriptor " } ,
{ " set_secdesc " , ( PyCFunction ) py_smb_set_secdesc ,
METH_VARARGS | METH_KEYWORDS , " Set security descriptor " } ,
2002-08-02 09:35:09 +04:00
{ NULL }
} ;
/*
* Method dispatch tables
*/
static PyMethodDef smb_methods [ ] = {
{ " connect " , ( PyCFunction ) py_smb_connect , METH_VARARGS | METH_KEYWORDS ,
" Connect to a host " } ,
2003-07-29 04:05:17 +04:00
/* Other stuff - this should really go into a samba config module
but for the moment let ' s leave it here . */
{ " setup_logging " , ( PyCFunction ) py_setup_logging ,
METH_VARARGS | METH_KEYWORDS ,
" Set up debug logging. \n "
" \n "
" Initialises Samba's debug logging system. One argument is expected which \n "
" is a boolean specifying whether debugging is interactive and sent to stdout \n "
" or logged to a file. \n "
" \n "
" Example: \n "
" \n "
" >>> smb.setup_logging(interactive = 1) " } ,
{ " get_debuglevel " , ( PyCFunction ) get_debuglevel ,
METH_VARARGS ,
" Set the current debug level. \n "
" \n "
" Example: \n "
" \n "
" >>> smb.get_debuglevel() \n "
" 0 " } ,
{ " set_debuglevel " , ( PyCFunction ) set_debuglevel ,
METH_VARARGS ,
" Get the current debug level. \n "
" \n "
" Example: \n "
" \n "
" >>> smb.set_debuglevel(10) " } ,
2002-08-02 09:35:09 +04:00
{ NULL }
} ;
2002-07-29 07:50:35 +04:00
static void py_cli_state_dealloc ( PyObject * self )
{
2003-07-23 05:26:46 +04:00
cli_state_object * cli = ( cli_state_object * ) self ;
if ( cli - > cli )
cli_shutdown ( cli - > cli ) ;
2002-07-29 07:50:35 +04:00
PyObject_Del ( self ) ;
}
static PyObject * py_cli_state_getattr ( PyObject * self , char * attrname )
{
2002-08-02 09:35:09 +04:00
return Py_FindMethod ( smb_hnd_methods , self , attrname ) ;
2002-07-29 07:50:35 +04:00
}
PyTypeObject cli_state_type = {
PyObject_HEAD_INIT ( NULL )
0 ,
" SMB client connection " ,
sizeof ( cli_state_object ) ,
0 ,
py_cli_state_dealloc , /*tp_dealloc*/
0 , /*tp_print*/
py_cli_state_getattr , /*tp_getattr*/
0 , /*tp_setattr*/
0 , /*tp_compare*/
0 , /*tp_repr*/
0 , /*tp_as_number*/
0 , /*tp_as_sequence*/
0 , /*tp_as_mapping*/
0 , /*tp_hash */
} ;
/*
* Module initialisation
*/
void initsmb ( void )
{
PyObject * module , * dict ;
/* Initialise module */
module = Py_InitModule ( " smb " , smb_methods ) ;
dict = PyModule_GetDict ( module ) ;
/* Initialise policy handle object */
cli_state_type . ob_type = & PyType_Type ;
/* Do samba initialisation */
py_samba_init ( ) ;
setup_logging ( " smb " , True ) ;
2003-07-29 04:05:17 +04:00
DEBUGLEVEL = 3 ;
2002-07-29 07:50:35 +04:00
}