2002-03-20 06:29:03 +03: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 .
*/
2003-02-20 01:47:49 +03:00
# include "python/py_common.h"
2002-04-14 04:58:16 +04:00
2002-04-05 08:47:43 +04:00
/* Return a tuple of (error code, error string) from a WERROR */
PyObject * py_werror_tuple ( WERROR werror )
{
2002-04-15 03:39:02 +04:00
return Py_BuildValue ( " [is] " , W_ERROR_V ( werror ) ,
2002-04-05 08:47:43 +04:00
dos_errstr ( werror ) ) ;
}
/* Return a tuple of (error code, error string) from a WERROR */
PyObject * py_ntstatus_tuple ( NTSTATUS ntstatus )
{
2002-04-15 03:39:02 +04:00
return Py_BuildValue ( " [is] " , NT_STATUS_V ( ntstatus ) ,
2002-04-05 08:47:43 +04:00
nt_errstr ( ntstatus ) ) ;
}
2002-03-20 06:29:03 +03:00
/* Initialise samba client routines */
static BOOL initialised ;
void py_samba_init ( void )
{
if ( initialised )
return ;
2006-04-28 00:52:04 +04:00
load_case_tables ( ) ;
2002-03-20 06:29:03 +03:00
/* Load configuration file */
2006-01-29 01:53:04 +03:00
if ( ! lp_load ( dyn_CONFIGFILE , True , False , False , True ) )
2002-03-20 06:29:03 +03:00
fprintf ( stderr , " Can't load %s \n " , dyn_CONFIGFILE ) ;
/* Misc other stuff */
load_interfaces ( ) ;
2002-11-29 04:10:31 +03:00
init_names ( ) ;
2002-05-27 10:32:11 +04:00
2002-03-20 06:29:03 +03:00
initialised = True ;
}
2002-04-11 09:04:05 +04:00
/* Debuglevel routines */
PyObject * get_debuglevel ( PyObject * self , PyObject * args )
{
PyObject * debuglevel ;
if ( ! PyArg_ParseTuple ( args , " " ) )
return NULL ;
debuglevel = PyInt_FromLong ( DEBUGLEVEL ) ;
return debuglevel ;
}
PyObject * set_debuglevel ( PyObject * self , PyObject * args )
{
int debuglevel ;
if ( ! PyArg_ParseTuple ( args , " i " , & debuglevel ) )
return NULL ;
DEBUGLEVEL = debuglevel ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
/* Initialise logging */
PyObject * py_setup_logging ( PyObject * self , PyObject * args , PyObject * kw )
{
BOOL interactive = False ;
char * logfilename = NULL ;
static char * kwlist [ ] = { " interactive " , " logfilename " , NULL } ;
2002-05-16 08:00:31 +04:00
if ( ! PyArg_ParseTupleAndKeywords (
args , kw , " |is " , kwlist , & interactive , & logfilename ) )
2002-04-11 09:04:05 +04:00
return NULL ;
if ( interactive & & logfilename ) {
PyErr_SetString ( PyExc_RuntimeError ,
" can't be interactive and set log file name " ) ;
return NULL ;
}
if ( interactive )
setup_logging ( " spoolss " , True ) ;
if ( logfilename ) {
lp_set_logfile ( logfilename ) ;
setup_logging ( logfilename , False ) ;
reopen_logs ( ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2002-04-14 04:58:16 +04:00
2002-08-02 09:28:54 +04:00
/* Parse credentials from a python dictionary. The dictionary can
only have the keys " username " , " domain " and " password " . Return
True for valid credentials in which case the username , domain and
password are set to pointers to their values from the dicationary .
If returns False , the errstr is set to point at some mallocated
memory describing the error . */
BOOL py_parse_creds ( PyObject * creds , char * * username , char * * domain ,
char * * password , char * * errstr )
2002-04-14 04:58:16 +04:00
{
2002-08-02 09:28:54 +04:00
/* Initialise anonymous credentials */
* username = " " ;
* domain = " " ;
* password = " " ;
2002-04-14 04:58:16 +04:00
if ( creds & & PyDict_Size ( creds ) > 0 ) {
PyObject * username_obj , * password_obj , * domain_obj ;
2002-09-09 05:06:20 +04:00
PyObject * key , * value ;
int i ;
2002-04-14 04:58:16 +04:00
2002-08-02 09:28:54 +04:00
/* Check for presence of required fields */
2002-04-14 04:58:16 +04:00
username_obj = PyDict_GetItemString ( creds , " username " ) ;
domain_obj = PyDict_GetItemString ( creds , " domain " ) ;
password_obj = PyDict_GetItemString ( creds , " password " ) ;
2002-08-02 09:28:54 +04:00
if ( ! username_obj ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " no username field in credential " ) ;
2002-08-02 09:28:54 +04:00
return False ;
}
if ( ! domain_obj ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " no domain field in credential " ) ;
2002-08-02 09:28:54 +04:00
return False ;
2002-04-14 04:58:16 +04:00
}
2002-08-02 09:28:54 +04:00
if ( ! password_obj ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " no password field in credential " ) ;
2002-08-02 09:28:54 +04:00
return False ;
}
/* Check type of required fields */
2002-04-14 04:58:16 +04:00
2002-08-02 09:28:54 +04:00
if ( ! PyString_Check ( username_obj ) ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " username field is not string type " ) ;
2002-08-02 09:28:54 +04:00
return False ;
}
if ( ! PyString_Check ( domain_obj ) ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " domain field is not string type " ) ;
2002-08-02 09:28:54 +04:00
return False ;
}
if ( ! PyString_Check ( password_obj ) ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " password field is not string type " ) ;
2002-08-02 09:28:54 +04:00
return False ;
}
2002-04-14 04:58:16 +04:00
2002-09-09 05:06:20 +04:00
/* Look for any extra fields */
i = 0 ;
while ( PyDict_Next ( creds , & i , & key , & value ) ) {
if ( strcmp ( PyString_AsString ( key ) , " domain " ) ! = 0 & &
strcmp ( PyString_AsString ( key ) , " username " ) ! = 0 & &
strcmp ( PyString_AsString ( key ) , " password " ) ! = 0 ) {
asprintf ( errstr ,
" creds contain extra field '%s' " ,
PyString_AsString ( key ) ) ;
return False ;
}
}
2002-08-02 09:28:54 +04:00
/* Assign values */
* username = PyString_AsString ( username_obj ) ;
* domain = PyString_AsString ( domain_obj ) ;
* password = PyString_AsString ( password_obj ) ;
2002-04-14 04:58:16 +04:00
}
2002-08-02 09:28:54 +04:00
* errstr = NULL ;
return True ;
}
/* Return a cli_state to a RPC pipe on the given server. Use the
credentials passed if not NULL . If an error occurs errstr is set to a
string describing the error and NULL is returned . If set , errstr must
be freed by calling free ( ) . */
struct cli_state * open_pipe_creds ( char * server , PyObject * creds ,
2002-11-04 23:33:16 +03:00
int pipe_idx , char * * errstr )
2002-08-02 09:28:54 +04:00
{
char * username , * password , * domain ;
struct cli_state * cli ;
2006-04-28 00:52:04 +04:00
struct rpc_pipe_client * pipe_hnd ;
2002-08-02 09:28:54 +04:00
NTSTATUS result ;
/* Extract credentials from the python dictionary */
2002-09-02 11:42:39 +04:00
if ( ! py_parse_creds ( creds , & username , & domain , & password , errstr ) )
2002-08-02 09:28:54 +04:00
return NULL ;
2002-04-14 04:58:16 +04:00
/* Now try to connect */
2002-05-27 10:32:11 +04:00
result = cli_full_connection (
2002-06-20 04:51:07 +04:00
& cli , NULL , server , NULL , 0 , " IPC$ " , " IPC " ,
2003-07-31 03:49:29 +04:00
username , domain , password , 0 , Undefined , NULL ) ;
2002-05-27 10:32:11 +04:00
2002-05-28 07:15:09 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2004-12-17 00:14:08 +03:00
* errstr = SMB_STRDUP ( " error connecting to IPC$ pipe " ) ;
2002-05-28 07:15:09 +04:00
return NULL ;
}
2006-04-28 00:52:04 +04:00
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , pipe_idx , & result ) ;
if ( ! pipe_hnd ) {
2002-05-27 10:32:11 +04:00
cli_shutdown ( cli ) ;
2002-11-04 23:33:16 +03:00
asprintf ( errstr , " error opening pipe index %d " , pipe_idx ) ;
2002-04-15 03:39:02 +04:00
return NULL ;
}
2002-04-14 04:58:16 +04:00
2002-05-16 08:00:31 +04:00
* errstr = NULL ;
2002-04-14 04:58:16 +04:00
return cli ;
}
2002-05-17 06:25:37 +04:00
/* Return true if a dictionary contains a "level" key with an integer
value . Set the value if so . */
BOOL get_level_value ( PyObject * dict , uint32 * level )
{
PyObject * obj ;
if ( ! ( obj = PyDict_GetItemString ( dict , " level " ) ) | |
! PyInt_Check ( obj ) )
return False ;
if ( level )
* level = PyInt_AsLong ( obj ) ;
return True ;
}