2011-07-26 07:32:03 +04:00
/*
Unix SMB / CIFS implementation .
Copyright ( C ) Amitay Isaacs 2011
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/>.
*/
# include <Python.h>
2017-12-14 14:32:23 +03:00
# include "python/py3compat.h"
2011-07-26 07:32:03 +04:00
# include <tevent.h>
# include <pytalloc.h>
# include "includes.h"
# include "param/param.h"
# include "param/pyparam.h"
# include "system/dir.h"
2011-08-02 10:10:21 +04:00
# include "system/filesys.h"
2011-07-26 07:32:03 +04:00
# include "lib/events/events.h"
# include "auth/credentials/credentials.h"
# include "auth/credentials/pycredentials.h"
# include "auth/gensec/gensec.h"
# include "libcli/libcli.h"
# include "libcli/raw/libcliraw.h"
# include "libcli/raw/raw_proto.h"
# include "libcli/resolve/resolve.h"
# include "libcli/util/pyerrors.h"
# include "libcli/smb_composite/smb_composite.h"
# include "libcli/security/security_descriptor.h"
# include "librpc/rpc/pyrpc_util.h"
2014-12-03 15:59:58 +03:00
static PyTypeObject PySMB ;
2011-07-26 07:32:03 +04:00
void initsmb ( void ) ;
struct smb_private_data {
struct loadparm_context * lp_ctx ;
struct cli_credentials * creds ;
struct tevent_context * ev_ctx ;
struct smbcli_tree * tree ;
} ;
static void dos_format ( char * s )
{
string_replace ( s , ' / ' , ' \\ ' ) ;
}
2011-07-28 07:22:01 +04:00
/*
2011-08-02 10:04:52 +04:00
* Connect to SMB share using smb_full_connection
2011-07-28 07:22:01 +04:00
*/
static NTSTATUS do_smb_connect ( TALLOC_CTX * mem_ctx , struct smb_private_data * spdata ,
2017-03-22 01:07:49 +03:00
const char * hostname , const char * service ,
struct smbcli_options * options ,
struct smbcli_session_options * session_options ,
struct smbcli_tree * * tree )
2011-07-26 07:32:03 +04:00
{
2011-08-02 10:04:52 +04:00
struct smbcli_state * smb_state ;
2011-07-26 07:32:03 +04:00
NTSTATUS status ;
2011-07-28 07:22:01 +04:00
* tree = NULL ;
2011-08-02 10:04:52 +04:00
gensec_init ( ) ;
2011-07-26 07:32:03 +04:00
2011-08-02 10:04:52 +04:00
smb_state = smbcli_state_init ( mem_ctx ) ;
2011-07-26 07:32:03 +04:00
2011-08-02 10:04:52 +04:00
status = smbcli_full_connection ( mem_ctx , & smb_state , hostname ,
lpcfg_smb_ports ( spdata - > lp_ctx ) ,
service ,
NULL ,
lpcfg_socket_options ( spdata - > lp_ctx ) ,
spdata - > creds ,
2011-07-26 07:32:03 +04:00
lpcfg_resolve_context ( spdata - > lp_ctx ) ,
2011-08-02 10:04:52 +04:00
spdata - > ev_ctx ,
2017-03-22 01:07:49 +03:00
options ,
session_options ,
2011-08-02 10:04:52 +04:00
lpcfg_gensec_settings ( mem_ctx , spdata - > lp_ctx ) ) ;
2011-07-28 07:22:01 +04:00
if ( NT_STATUS_IS_OK ( status ) ) {
2011-08-02 10:04:52 +04:00
* tree = smb_state - > tree ;
2011-07-28 07:22:01 +04:00
}
2011-07-26 07:32:03 +04:00
2011-07-28 07:22:01 +04:00
return status ;
2011-07-26 07:32:03 +04:00
}
2011-07-28 07:22:01 +04:00
/*
* Read SMB file and return the contents of the file as python string
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_loadfile ( PyObject * self , PyObject * args )
2011-07-26 07:32:03 +04:00
{
struct smb_composite_loadfile io ;
const char * filename ;
NTSTATUS status ;
struct smb_private_data * spdata ;
2011-07-29 10:17:49 +04:00
if ( ! PyArg_ParseTuple ( args , " s:loadfile " , & filename ) ) {
2011-07-26 07:32:03 +04:00
return NULL ;
}
2011-07-28 07:22:01 +04:00
ZERO_STRUCT ( io ) ;
2011-07-26 07:32:03 +04:00
io . in . fname = filename ;
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2016-03-01 05:05:28 +03:00
status = smb_composite_loadfile ( spdata - > tree , pytalloc_get_mem_ctx ( self ) , & io ) ;
2011-07-26 07:32:03 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
2017-12-14 14:32:23 +03:00
return Py_BuildValue ( PYARG_BYTES_LEN , io . out . data , io . out . size ) ;
2011-07-26 07:32:03 +04:00
}
2011-07-28 07:22:01 +04:00
/*
* Create a SMB file with given string as the contents
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_savefile ( PyObject * self , PyObject * args )
2011-07-26 07:32:03 +04:00
{
struct smb_composite_savefile io ;
const char * filename ;
2017-12-14 14:32:23 +03:00
char * data = NULL ;
Py_ssize_t size = 0 ;
2011-07-26 07:32:03 +04:00
NTSTATUS status ;
struct smb_private_data * spdata ;
2017-12-14 14:32:23 +03:00
if ( ! PyArg_ParseTuple ( args , " s " PYARG_BYTES_LEN " :savefile " , & filename , & data , & size ) ) {
2011-07-26 07:32:03 +04:00
return NULL ;
}
io . in . fname = filename ;
io . in . data = ( unsigned char * ) data ;
2017-12-14 14:32:23 +03:00
io . in . size = size ;
2011-07-26 07:32:03 +04:00
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-26 07:32:03 +04:00
status = smb_composite_savefile ( spdata - > tree , & io ) ;
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
Py_RETURN_NONE ;
}
2011-07-28 07:22:01 +04:00
/*
* Callback function to accumulate directory contents in a python list
*/
2011-07-26 07:32:03 +04:00
static void py_smb_list_callback ( struct clilist_file_info * f , const char * mask , void * state )
{
PyObject * py_dirlist ;
PyObject * dict ;
if ( ! ISDOT ( f - > name ) & & ! ISDOTDOT ( f - > name ) ) {
py_dirlist = ( PyObject * ) state ;
dict = PyDict_New ( ) ;
if ( dict ) {
2017-12-14 14:32:23 +03:00
PyDict_SetItemString ( dict , " name " , PyStr_FromString ( f - > name ) ) ;
2011-08-02 10:07:43 +04:00
/* Windows does not always return short_name */
if ( f - > short_name ) {
2017-12-14 14:32:23 +03:00
PyDict_SetItemString ( dict , " short_name " , PyStr_FromString ( f - > short_name ) ) ;
2011-08-02 10:07:43 +04:00
} else {
PyDict_SetItemString ( dict , " short_name " , Py_None ) ;
}
2011-07-26 07:32:03 +04:00
PyDict_SetItemString ( dict , " size " , PyLong_FromUnsignedLongLong ( f - > size ) ) ;
PyDict_SetItemString ( dict , " attrib " , PyInt_FromLong ( f - > attrib ) ) ;
PyDict_SetItemString ( dict , " mtime " , PyInt_FromLong ( f - > mtime ) ) ;
PyList_Append ( py_dirlist , dict ) ;
}
}
}
2011-07-28 07:22:01 +04:00
/*
* List the directory contents for specified directory ( Ignore ' . ' and ' . . ' dirs )
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_list ( PyObject * self , PyObject * args , PyObject * kwargs )
2011-07-26 07:32:03 +04:00
{
struct smb_private_data * spdata ;
PyObject * py_dirlist ;
const char * kwnames [ ] = { " directory " , " mask " , " attribs " , NULL } ;
char * base_dir ;
char * user_mask = NULL ;
char * mask ;
2011-07-28 07:22:01 +04:00
uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE ;
2011-07-26 07:32:03 +04:00
2011-07-29 10:17:49 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " z|sH:list " ,
2011-07-26 07:32:03 +04:00
discard_const_p ( char * , kwnames ) ,
& base_dir , & user_mask , & attribute ) ) {
return NULL ;
}
if ( user_mask = = NULL ) {
2016-03-01 05:05:28 +03:00
mask = talloc_asprintf ( pytalloc_get_mem_ctx ( self ) , " %s \\ * " , base_dir ) ;
2011-07-26 07:32:03 +04:00
} else {
2016-03-01 05:05:28 +03:00
mask = talloc_asprintf ( pytalloc_get_mem_ctx ( self ) , " %s \\ %s " , base_dir , user_mask ) ;
2011-07-26 07:32:03 +04:00
}
dos_format ( mask ) ;
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-26 07:32:03 +04:00
if ( ( py_dirlist = PyList_New ( 0 ) ) = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
smbcli_list ( spdata - > tree , mask , attribute , py_smb_list_callback , ( void * ) py_dirlist ) ;
talloc_free ( mask ) ;
return py_dirlist ;
}
2011-07-29 10:17:49 +04:00
/*
* Create a directory
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_mkdir ( PyObject * self , PyObject * args )
2011-07-29 10:17:49 +04:00
{
NTSTATUS status ;
const char * dirname ;
struct smb_private_data * spdata ;
if ( ! PyArg_ParseTuple ( args , " s:mkdir " , & dirname ) ) {
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-29 10:17:49 +04:00
status = smbcli_mkdir ( spdata - > tree , dirname ) ;
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
Py_RETURN_NONE ;
}
/*
* Remove a directory
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_rmdir ( PyObject * self , PyObject * args )
2011-07-29 10:17:49 +04:00
{
NTSTATUS status ;
const char * dirname ;
struct smb_private_data * spdata ;
if ( ! PyArg_ParseTuple ( args , " s:rmdir " , & dirname ) ) {
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-29 10:17:49 +04:00
status = smbcli_rmdir ( spdata - > tree , dirname ) ;
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
Py_RETURN_NONE ;
}
2012-07-03 04:58:37 +04:00
/*
* Remove a directory and all its contents
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_deltree ( PyObject * self , PyObject * args )
2012-07-03 04:58:37 +04:00
{
int status ;
const char * dirname ;
struct smb_private_data * spdata ;
if ( ! PyArg_ParseTuple ( args , " s:deltree " , & dirname ) ) {
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2012-07-03 04:58:37 +04:00
status = smbcli_deltree ( spdata - > tree , dirname ) ;
if ( status < = 0 ) {
return NULL ;
}
Py_RETURN_NONE ;
}
2011-07-29 10:17:49 +04:00
/*
* Check existence of a path
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_chkpath ( PyObject * self , PyObject * args )
2011-07-29 10:17:49 +04:00
{
NTSTATUS status ;
const char * path ;
struct smb_private_data * spdata ;
if ( ! PyArg_ParseTuple ( args , " s:chkpath " , & path ) ) {
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-29 10:17:49 +04:00
status = smbcli_chkpath ( spdata - > tree , path ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
Py_RETURN_TRUE ;
}
Py_RETURN_FALSE ;
}
2011-07-28 07:22:01 +04:00
/*
* Read ACL on a given file / directory as a security descriptor object
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_getacl ( PyObject * self , PyObject * args , PyObject * kwargs )
2011-07-26 07:32:03 +04:00
{
NTSTATUS status ;
2011-08-02 10:10:21 +04:00
union smb_open io ;
union smb_fileinfo fio ;
2011-07-26 07:32:03 +04:00
struct smb_private_data * spdata ;
const char * filename ;
2012-11-12 10:11:34 +04:00
uint32_t sinfo = 0 ;
int access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
2011-08-02 10:10:21 +04:00
int fnum ;
2011-07-26 07:32:03 +04:00
2012-11-12 10:11:34 +04:00
if ( ! PyArg_ParseTuple ( args , " s|Ii:get_acl " , & filename , & sinfo , & access_mask ) ) {
2011-07-26 07:32:03 +04:00
return NULL ;
}
2011-07-28 07:22:01 +04:00
ZERO_STRUCT ( io ) ;
2011-07-26 07:32:03 +04:00
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-08-02 10:10:21 +04:00
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . flags = 0 ;
2012-11-12 10:11:34 +04:00
io . ntcreatex . in . access_mask = access_mask ;
2011-08-02 10:10:21 +04:00
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = filename ;
2016-03-01 05:05:28 +03:00
status = smb_raw_open ( spdata - > tree , pytalloc_get_mem_ctx ( self ) , & io ) ;
2011-08-02 10:10:21 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
fnum = io . ntcreatex . out . file . fnum ;
ZERO_STRUCT ( fio ) ;
fio . query_secdesc . level = RAW_FILEINFO_SEC_DESC ;
fio . query_secdesc . in . file . fnum = fnum ;
2012-03-26 04:27:11 +04:00
if ( sinfo )
fio . query_secdesc . in . secinfo_flags = sinfo ;
else
fio . query_secdesc . in . secinfo_flags = SECINFO_OWNER |
2011-08-02 10:10:21 +04:00
SECINFO_GROUP |
SECINFO_DACL |
SECINFO_PROTECTED_DACL |
SECINFO_UNPROTECTED_DACL |
2012-03-07 09:40:23 +04:00
SECINFO_SACL |
2011-08-02 10:10:21 +04:00
SECINFO_PROTECTED_SACL |
SECINFO_UNPROTECTED_SACL ;
2011-07-26 07:32:03 +04:00
2016-03-01 05:05:28 +03:00
status = smb_raw_query_secdesc ( spdata - > tree , pytalloc_get_mem_ctx ( self ) , & fio ) ;
2011-08-02 10:10:21 +04:00
smbcli_close ( spdata - > tree , fnum ) ;
2011-08-03 04:50:31 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
2011-07-26 07:32:03 +04:00
return py_return_ndr_struct ( " samba.dcerpc.security " , " descriptor " ,
2016-03-01 05:05:28 +03:00
pytalloc_get_mem_ctx ( self ) , fio . query_secdesc . out . sd ) ;
2011-07-26 07:32:03 +04:00
}
2011-07-28 07:22:01 +04:00
/*
* Set ACL on file / directory using given security descriptor object
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_smb_setacl ( PyObject * self , PyObject * args , PyObject * kwargs )
2011-07-26 07:32:03 +04:00
{
NTSTATUS status ;
2011-08-02 10:10:21 +04:00
union smb_open io ;
union smb_setfileinfo fio ;
2011-07-26 07:32:03 +04:00
struct smb_private_data * spdata ;
const char * filename ;
PyObject * py_sd ;
struct security_descriptor * sd ;
2012-03-26 04:27:11 +04:00
uint32_t sinfo = 0 ;
2011-08-02 10:10:21 +04:00
int fnum ;
2011-07-26 07:32:03 +04:00
2012-06-20 11:29:55 +04:00
if ( ! PyArg_ParseTuple ( args , " sO|I:get_acl " , & filename , & py_sd , & sinfo ) ) {
2011-07-26 07:32:03 +04:00
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-07-26 07:32:03 +04:00
2011-08-10 17:15:18 +04:00
sd = pytalloc_get_type ( py_sd , struct security_descriptor ) ;
2011-07-26 07:32:03 +04:00
if ( ! sd ) {
2011-08-02 10:10:21 +04:00
PyErr_Format ( PyExc_TypeError ,
" Expected dcerpc.security.descriptor as argument, got %s " ,
2011-08-10 17:15:18 +04:00
talloc_get_name ( pytalloc_get_ptr ( py_sd ) ) ) ;
2011-07-26 07:32:03 +04:00
return NULL ;
}
2011-07-28 07:22:01 +04:00
ZERO_STRUCT ( io ) ;
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2011-08-02 10:10:21 +04:00
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . flags = 0 ;
io . ntcreatex . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = filename ;
2016-03-01 05:05:28 +03:00
status = smb_raw_open ( spdata - > tree , pytalloc_get_mem_ctx ( self ) , & io ) ;
2011-08-02 10:10:21 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
fnum = io . ntcreatex . out . file . fnum ;
ZERO_STRUCT ( fio ) ;
fio . set_secdesc . level = RAW_SFILEINFO_SEC_DESC ;
fio . set_secdesc . in . file . fnum = fnum ;
2012-03-26 04:27:11 +04:00
if ( sinfo )
fio . set_secdesc . in . secinfo_flags = sinfo ;
else
fio . set_secdesc . in . secinfo_flags = SECINFO_OWNER |
SECINFO_GROUP |
SECINFO_DACL |
SECINFO_PROTECTED_DACL |
SECINFO_UNPROTECTED_DACL |
SECINFO_SACL |
SECINFO_PROTECTED_SACL |
SECINFO_UNPROTECTED_SACL ;
2011-08-02 10:10:21 +04:00
fio . set_secdesc . in . sd = sd ;
2011-07-26 07:32:03 +04:00
2011-08-02 10:10:21 +04:00
status = smb_raw_set_secdesc ( spdata - > tree , & fio ) ;
2011-08-03 04:50:31 +04:00
smbcli_close ( spdata - > tree , fnum ) ;
2011-07-26 07:32:03 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
Py_RETURN_NONE ;
}
2012-03-31 09:04:28 +04:00
/*
* Open the file with the parameters passed in and return an object if OK
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_open_file ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-03-31 09:04:28 +04:00
{
NTSTATUS status ;
union smb_open io ;
struct smb_private_data * spdata ;
const char * filename ;
2012-04-02 00:14:49 +04:00
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
uint32_t share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
uint32_t open_disposition = NTCREATEX_DISP_OPEN ;
2012-03-31 09:04:28 +04:00
uint32_t create_options = 0 ;
2012-04-02 00:14:49 +04:00
TALLOC_CTX * mem_ctx ;
2012-03-31 09:04:28 +04:00
int fnum ;
2012-04-02 00:14:49 +04:00
if ( ! PyArg_ParseTuple ( args , " s|iiii:open_file " ,
2012-03-31 09:04:28 +04:00
& filename ,
& access_mask ,
& share_access ,
& open_disposition ,
& create_options ) ) {
return NULL ;
}
ZERO_STRUCT ( io ) ;
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2012-03-31 09:04:28 +04:00
2012-04-02 00:14:49 +04:00
mem_ctx = talloc_new ( NULL ) ;
2012-03-31 09:04:28 +04:00
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . flags = 0 ;
io . ntcreatex . in . access_mask = access_mask ;
io . ntcreatex . in . create_options = create_options ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = share_access ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . open_disposition = open_disposition ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = filename ;
2012-04-02 00:14:49 +04:00
status = smb_raw_open ( spdata - > tree , mem_ctx , & io ) ;
talloc_free ( mem_ctx ) ;
2012-03-31 09:04:28 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
fnum = io . ntcreatex . out . file . fnum ;
return Py_BuildValue ( " i " , fnum ) ;
}
/*
* Close the file based on the fnum passed in
*/
2016-03-01 05:08:26 +03:00
static PyObject * py_close_file ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-03-31 09:04:28 +04:00
{
struct smb_private_data * spdata ;
int fnum ;
if ( ! PyArg_ParseTuple ( args , " i:close_file " , & fnum ) ) {
return NULL ;
}
2016-03-01 04:55:59 +03:00
spdata = pytalloc_get_ptr ( self ) ;
2012-03-31 09:04:28 +04:00
/*
* Should check the status . . .
*/
smbcli_close ( spdata - > tree , fnum ) ;
Py_RETURN_NONE ;
}
2011-07-26 07:32:03 +04:00
static PyMethodDef py_smb_methods [ ] = {
2016-03-01 05:08:26 +03:00
{ " loadfile " , py_smb_loadfile , METH_VARARGS ,
2017-12-14 14:32:23 +03:00
" loadfile(path) -> file contents as a "
PY_DESC_PY3_BYTES
" \n \n Read contents of a file. " } ,
2016-03-01 05:08:26 +03:00
{ " savefile " , py_smb_savefile , METH_VARARGS ,
2017-12-14 14:32:23 +03:00
" savefile(path, str) -> None \n \n Write "
PY_DESC_PY3_BYTES
" str to file. " } ,
2011-07-26 07:32:03 +04:00
{ " list " , ( PyCFunction ) py_smb_list , METH_VARARGS | METH_KEYWORDS ,
2018-05-09 06:39:09 +03:00
" list(path, access_mask='*', attribs=DEFAULT_ATTRS) -> \
directory contents as a dictionary \ n \
DEFAULT_ATTRS : FILE_ATTRIBUTE_SYSTEM | \
FILE_ATTRIBUTE_DIRECTORY | \
FILE_ATTRIBUTE_ARCHIVE \ n \ n \
2011-07-29 10:17:49 +04:00
List contents of a directory . The keys are , \ n \
\ tname : Long name of the directory item \ n \
\ tshort_name : Short name of the directory item \ n \
\ tsize : File size in bytes \ n \
\ tattrib : Attributes \ n \
\ tmtime : Modification time \ n " },
2016-03-01 05:08:26 +03:00
{ " mkdir " , py_smb_mkdir , METH_VARARGS ,
2011-07-29 10:17:49 +04:00
" mkdir(path) -> None \n \n \
Create a directory . " },
2016-03-01 05:08:26 +03:00
{ " rmdir " , py_smb_rmdir , METH_VARARGS ,
2011-07-29 10:17:49 +04:00
" rmdir(path) -> None \n \n \
Delete a directory . " },
2016-03-01 05:08:26 +03:00
{ " deltree " , py_smb_deltree , METH_VARARGS ,
2012-07-03 04:58:37 +04:00
" deltree(path) -> None \n \n \
Delete a directory and all its contents . " },
2016-03-01 05:08:26 +03:00
{ " chkpath " , py_smb_chkpath , METH_VARARGS ,
2011-07-29 10:17:49 +04:00
" chkpath(path) -> True or False \n \n \
Return true if path exists , false otherwise . " },
2011-07-26 07:32:03 +04:00
{ " get_acl " , ( PyCFunction ) py_smb_getacl , METH_VARARGS ,
2012-03-26 04:27:11 +04:00
" get_acl(path[, security_info=0]) -> security_descriptor object \n \n \
2011-07-29 10:17:49 +04:00
Get security descriptor for file . " },
2011-07-26 07:32:03 +04:00
{ " set_acl " , ( PyCFunction ) py_smb_setacl , METH_VARARGS ,
2012-03-26 04:27:11 +04:00
" set_acl(path, security_descriptor[, security_info=0]) -> None \n \n \
2011-07-29 10:17:49 +04:00
Set security descriptor for file . " },
2012-03-31 09:04:28 +04:00
{ " open_file " , ( PyCFunction ) py_open_file , METH_VARARGS ,
" open_file(path, access_mask[, share_access[, open_disposition[, create_options]]] -> fnum \n \n \
2012-04-02 00:14:49 +04:00
Open a file . Throws NTSTATUS exceptions on errors . " },
2012-03-31 09:04:28 +04:00
{ " close_file " , ( PyCFunction ) py_close_file , METH_VARARGS ,
" close_file(fnum) -> None \n \n \
Close the file based on fnum . " },
2011-07-26 07:32:03 +04:00
{ NULL } ,
} ;
static PyObject * py_smb_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
PyObject * py_creds = Py_None ;
PyObject * py_lp = Py_None ;
2017-03-22 01:07:49 +03:00
const char * kwnames [ ] = { " hostname " , " service " , " creds " , " lp " ,
" ntlmv2_auth " , " use_spnego " , NULL } ;
2011-07-26 07:32:03 +04:00
const char * hostname = NULL ;
const char * service = NULL ;
2016-03-01 04:53:00 +03:00
PyObject * smb ;
2011-07-26 07:32:03 +04:00
struct smb_private_data * spdata ;
2011-07-28 07:22:01 +04:00
NTSTATUS status ;
2016-03-01 04:53:00 +03:00
TALLOC_CTX * frame = NULL ;
2017-03-22 01:07:49 +03:00
struct smbcli_options options ;
struct smbcli_session_options session_options ;
uint8_t ntlmv2_auth = 0xFF ;
uint8_t use_spnego = 0xFF ;
2011-07-26 07:32:03 +04:00
2017-03-22 01:07:49 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " zz|OObb " ,
discard_const_p ( char * , kwnames ) ,
& hostname , & service , & py_creds , & py_lp ,
& ntlmv2_auth , & use_spnego ) ) {
2011-07-26 07:32:03 +04:00
return NULL ;
}
2016-03-01 04:53:00 +03:00
frame = talloc_stackframe ( ) ;
2011-07-26 07:32:03 +04:00
2016-03-01 04:53:00 +03:00
spdata = talloc_zero ( frame , struct smb_private_data ) ;
2011-07-26 07:32:03 +04:00
if ( spdata = = NULL ) {
PyErr_NoMemory ( ) ;
2016-03-01 04:53:00 +03:00
TALLOC_FREE ( frame ) ;
2011-07-26 07:32:03 +04:00
return NULL ;
}
2016-03-01 04:53:00 +03:00
spdata - > lp_ctx = lpcfg_from_py_object ( spdata , py_lp ) ;
2011-07-26 07:32:03 +04:00
if ( spdata - > lp_ctx = = NULL ) {
2017-03-21 06:00:38 +03:00
PyErr_SetString ( PyExc_TypeError , " Expected loadparm context " ) ;
TALLOC_FREE ( frame ) ;
return NULL ;
}
spdata - > creds = cli_credentials_from_py_object ( py_creds ) ;
if ( spdata - > creds = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected credentials " ) ;
2016-03-01 04:53:00 +03:00
TALLOC_FREE ( frame ) ;
2011-07-26 07:32:03 +04:00
return NULL ;
}
2016-03-01 04:53:00 +03:00
spdata - > ev_ctx = s4_event_context_init ( spdata ) ;
2011-07-26 07:32:03 +04:00
if ( spdata - > ev_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
2016-03-01 04:53:00 +03:00
TALLOC_FREE ( frame ) ;
2011-07-26 07:32:03 +04:00
return NULL ;
}
2017-03-22 01:07:49 +03:00
lpcfg_smbcli_options ( spdata - > lp_ctx , & options ) ;
lpcfg_smbcli_session_options ( spdata - > lp_ctx , & session_options ) ;
if ( ntlmv2_auth ! = 0xFF ) {
session_options . ntlmv2_auth = ntlmv2_auth ;
}
if ( use_spnego ! = 0xFF ) {
options . use_spnego = use_spnego ;
}
status = do_smb_connect ( spdata , spdata , hostname , service ,
& options ,
& session_options ,
& spdata - > tree ) ;
2011-07-28 07:22:01 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
2011-07-26 07:32:03 +04:00
if ( spdata - > tree = = NULL ) {
2016-03-01 04:53:00 +03:00
TALLOC_FREE ( frame ) ;
2011-07-26 07:32:03 +04:00
return NULL ;
}
2016-03-01 04:53:00 +03:00
smb = pytalloc_steal ( type , spdata ) ;
TALLOC_FREE ( frame ) ;
return smb ;
2011-07-26 07:32:03 +04:00
}
static PyTypeObject PySMB = {
. tp_name = " smb.SMB " ,
. tp_new = py_smb_new ,
. tp_flags = Py_TPFLAGS_DEFAULT ,
. tp_methods = py_smb_methods ,
2012-03-26 04:27:11 +04:00
. tp_doc = " SMB(hostname, service[, creds[, lp]]) -> SMB connection object \n " ,
2011-07-29 10:17:49 +04:00
2011-07-26 07:32:03 +04:00
} ;
2017-12-14 14:32:23 +03:00
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " smb " ,
. m_doc = " SMB File I/O support " ,
. m_size = - 1 ,
. m_methods = NULL ,
} ;
void initsmb ( void ) ;
MODULE_INIT_FUNC ( smb )
2011-07-26 07:32:03 +04:00
{
2017-12-14 14:32:23 +03:00
PyObject * m = NULL ;
2011-07-26 07:32:03 +04:00
2016-03-01 05:17:44 +03:00
if ( pytalloc_BaseObject_PyType_Ready ( & PySMB ) < 0 ) {
2017-12-14 14:32:23 +03:00
return m ;
2011-07-26 07:32:03 +04:00
}
2017-12-14 14:32:23 +03:00
m = PyModule_Create ( & moduledef ) ;
2011-07-26 07:32:03 +04:00
if ( m = = NULL ) {
2017-12-14 14:32:23 +03:00
return m ;
2011-07-26 07:32:03 +04:00
}
Py_INCREF ( & PySMB ) ;
PyModule_AddObject ( m , " SMB " , ( PyObject * ) & PySMB ) ;
# define ADD_FLAGS(val) PyModule_AddObject(m, #val, PyInt_FromLong(val))
ADD_FLAGS ( FILE_ATTRIBUTE_READONLY ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_HIDDEN ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_SYSTEM ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_VOLUME ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_DIRECTORY ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_ARCHIVE ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_DEVICE ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_NORMAL ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_TEMPORARY ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_SPARSE ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_REPARSE_POINT ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_COMPRESSED ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_OFFLINE ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_NONINDEXED ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_ENCRYPTED ) ;
ADD_FLAGS ( FILE_ATTRIBUTE_ALL_MASK ) ;
2017-12-14 14:32:23 +03:00
return m ;
2011-07-26 07:32:03 +04:00
}