2008-12-21 01:38:30 +03:00
/*
Unix SMB / CIFS implementation .
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2007
2009-08-17 13:46:23 +04:00
Copyright ( C ) Matthias Dieter Wallnöfer 2009
2008-12-21 01:38:30 +03:00
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/>.
*/
2009-10-23 09:23:01 +04:00
# include <Python.h>
2016-12-05 14:14:28 +03:00
# include "python/py3compat.h"
2008-12-21 01:38:30 +03:00
# include "includes.h"
# include "version.h"
2008-12-22 06:38:57 +03:00
# include "param/pyparam.h"
2010-02-17 14:19:57 +03:00
# include "lib/socket/netif.h"
2018-11-07 16:14:05 +03:00
# include "lib/util/debug.h"
2008-12-21 02:24:54 +03:00
2010-12-18 00:17:25 +03:00
void init_glue ( void ) ;
2016-11-01 05:23:58 +03:00
static PyObject * PyExc_NTSTATUSError ;
static PyObject * PyExc_WERRORError ;
static PyObject * PyExc_HRESULTError ;
2016-11-01 06:09:20 +03:00
static PyObject * PyExc_DsExtendedError ;
2010-12-18 00:17:25 +03:00
2008-12-21 01:38:30 +03:00
static PyObject * py_generate_random_str ( PyObject * self , PyObject * args )
{
int len ;
PyObject * ret ;
char * retstr ;
if ( ! PyArg_ParseTuple ( args , " i " , & len ) )
return NULL ;
retstr = generate_random_str ( NULL , len ) ;
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( retstr ) ;
2008-12-21 01:38:30 +03:00
talloc_free ( retstr ) ;
return ret ;
}
2010-02-24 16:44:22 +03:00
static PyObject * py_generate_random_password ( PyObject * self , PyObject * args )
{
int min , max ;
PyObject * ret ;
char * retstr ;
if ( ! PyArg_ParseTuple ( args , " ii " , & min , & max ) )
return NULL ;
retstr = generate_random_password ( NULL , min , max ) ;
if ( retstr = = NULL ) {
return NULL ;
}
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( retstr ) ;
2010-02-24 16:44:22 +03:00
talloc_free ( retstr ) ;
return ret ;
}
2016-08-23 10:35:50 +03:00
static PyObject * py_generate_random_machine_password ( PyObject * self , PyObject * args )
{
int min , max ;
PyObject * ret ;
char * retstr ;
if ( ! PyArg_ParseTuple ( args , " ii " , & min , & max ) )
return NULL ;
retstr = generate_random_machine_password ( NULL , min , max ) ;
if ( retstr = = NULL ) {
return NULL ;
}
ret = PyUnicode_FromString ( retstr ) ;
talloc_free ( retstr ) ;
return ret ;
}
2017-11-28 05:45:30 +03:00
static PyObject * py_check_password_quality ( PyObject * self , PyObject * args )
{
char * pass ;
if ( ! PyArg_ParseTuple ( args , " s " , & pass ) ) {
return NULL ;
}
return PyBool_FromLong ( check_password_quality ( pass ) ) ;
}
2017-11-02 00:15:29 +03:00
static PyObject * py_generate_random_bytes ( PyObject * self , PyObject * args )
{
int len ;
PyObject * ret ;
uint8_t * bytes = NULL ;
if ( ! PyArg_ParseTuple ( args , " i " , & len ) )
return NULL ;
bytes = talloc_zero_size ( NULL , len ) ;
generate_random_buffer ( bytes , len ) ;
ret = PyBytes_FromStringAndSize ( ( const char * ) bytes , len ) ;
talloc_free ( bytes ) ;
return ret ;
}
2008-12-21 01:38:30 +03:00
static PyObject * py_unix2nttime ( PyObject * self , PyObject * args )
{
time_t t ;
2011-08-08 16:34:11 +04:00
unsigned int _t ;
2008-12-21 01:38:30 +03:00
NTTIME nt ;
2011-08-08 16:34:11 +04:00
if ( ! PyArg_ParseTuple ( args , " I " , & _t ) ) {
2008-12-21 01:38:30 +03:00
return NULL ;
2011-08-08 16:34:11 +04:00
}
t = _t ;
2008-12-21 01:38:30 +03:00
unix_to_nt_time ( & nt , t ) ;
2010-04-15 00:18:14 +04:00
return PyLong_FromLongLong ( ( uint64_t ) nt ) ;
}
static PyObject * py_nttime2unix ( PyObject * self , PyObject * args )
{
time_t t ;
NTTIME nt ;
if ( ! PyArg_ParseTuple ( args , " K " , & nt ) )
return NULL ;
t = nt_time_to_unix ( nt ) ;
2020-03-15 00:36:59 +03:00
return PyLong_FromLong ( ( uint64_t ) t ) ;
2010-04-15 00:18:14 +04:00
}
2020-12-02 17:42:10 +03:00
static PyObject * py_float2nttime ( PyObject * self , PyObject * args )
{
double ft = 0 ;
double ft_sec = 0 ;
double ft_nsec = 0 ;
struct timespec ts ;
NTTIME nt = 0 ;
if ( ! PyArg_ParseTuple ( args , " d " , & ft ) ) {
return NULL ;
}
ft_sec = ( double ) ( int ) ft ;
ft_nsec = ( ft - ft_sec ) * 1.0e+9 ;
ts . tv_sec = ( int ) ft_sec ;
ts . tv_nsec = ( int ) ft_nsec ;
nt = full_timespec_to_nt_time ( & ts ) ;
return PyLong_FromLongLong ( ( uint64_t ) nt ) ;
}
static PyObject * py_nttime2float ( PyObject * self , PyObject * args )
{
double ft = 0 ;
struct timespec ts ;
const struct timespec ts_zero = { . tv_sec = 0 , } ;
NTTIME nt = 0 ;
if ( ! PyArg_ParseTuple ( args , " K " , & nt ) ) {
return NULL ;
}
ts = nt_time_to_full_timespec ( nt ) ;
if ( is_omit_timespec ( & ts ) ) {
return PyFloat_FromDouble ( 1.0 ) ;
}
ft = timespec_elapsed2 ( & ts_zero , & ts ) ;
return PyFloat_FromDouble ( ft ) ;
}
2010-04-15 00:18:14 +04:00
static PyObject * py_nttime2string ( PyObject * self , PyObject * args )
{
PyObject * ret ;
2010-05-04 19:21:30 +04:00
NTTIME nt ;
2010-04-15 00:18:14 +04:00
TALLOC_CTX * tmp_ctx ;
const char * string ;
if ( ! PyArg_ParseTuple ( args , " K " , & nt ) )
return NULL ;
2010-05-04 19:21:30 +04:00
2010-04-15 00:18:14 +04:00
tmp_ctx = talloc_new ( NULL ) ;
2010-12-12 21:23:53 +03:00
if ( tmp_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-04-15 00:18:14 +04:00
string = nt_time_string ( tmp_ctx , nt ) ;
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( string ) ;
2010-04-15 00:18:14 +04:00
talloc_free ( tmp_ctx ) ;
2010-05-04 19:21:30 +04:00
2010-04-15 00:18:14 +04:00
return ret ;
2008-12-21 01:38:30 +03:00
}
2009-09-03 07:03:31 +04:00
static PyObject * py_set_debug_level ( PyObject * self , PyObject * args )
{
unsigned level ;
if ( ! PyArg_ParseTuple ( args , " I " , & level ) )
return NULL ;
2018-11-07 16:14:05 +03:00
debuglevel_set ( level ) ;
2009-09-03 07:03:31 +04:00
Py_RETURN_NONE ;
}
2019-05-02 21:47:29 +03:00
static PyObject * py_get_debug_level ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-11-29 05:26:48 +03:00
{
2020-03-15 00:36:59 +03:00
return PyLong_FromLong ( debuglevel_get ( ) ) ;
2010-11-29 05:26:48 +03:00
}
2019-05-02 21:47:29 +03:00
static PyObject * py_fault_setup ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2018-05-25 08:52:02 +03:00
{
static bool done ;
if ( ! done ) {
fault_setup ( ) ;
done = true ;
}
Py_RETURN_NONE ;
}
2019-05-02 21:47:29 +03:00
static PyObject * py_is_ntvfs_fileserver_built ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2015-10-09 23:30:17 +03:00
{
# ifdef WITH_NTVFS_FILESERVER
Py_RETURN_TRUE ;
# else
Py_RETURN_FALSE ;
# endif
}
2019-05-02 21:47:29 +03:00
static PyObject * py_is_heimdal_built ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2017-04-04 09:10:52 +03:00
{
# ifdef SAMBA4_USES_HEIMDAL
Py_RETURN_TRUE ;
# else
Py_RETURN_FALSE ;
# endif
}
2020-09-18 20:27:24 +03:00
static PyObject * py_is_ad_dc_built ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
{
# ifdef AD_DC_BUILD_IS_ENABLED
Py_RETURN_TRUE ;
# else
Py_RETURN_FALSE ;
# endif
}
2010-02-17 14:19:57 +03:00
/*
return the list of interface IPs we have configured
takes an loadparm context , returns a list of IPs in string form
2010-02-25 08:29:47 +03:00
Does not return addresses on 127.0 .0 .0 / 8
2010-02-17 14:19:57 +03:00
*/
static PyObject * py_interface_ips ( PyObject * self , PyObject * args )
{
PyObject * pylist ;
int count ;
TALLOC_CTX * tmp_ctx ;
PyObject * py_lp_ctx ;
struct loadparm_context * lp_ctx ;
struct interface * ifaces ;
2010-02-25 08:29:47 +03:00
int i , ifcount ;
2012-09-28 02:19:03 +04:00
int all_interfaces = 1 ;
2010-02-17 14:19:57 +03:00
2012-09-28 02:19:03 +04:00
if ( ! PyArg_ParseTuple ( args , " O|i " , & py_lp_ctx , & all_interfaces ) )
2010-02-17 14:19:57 +03:00
return NULL ;
2010-03-02 00:23:45 +03:00
tmp_ctx = talloc_new ( NULL ) ;
2010-09-23 03:44:17 +04:00
if ( tmp_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-03-02 00:23:45 +03:00
2010-09-23 02:35:36 +04:00
lp_ctx = lpcfg_from_py_object ( tmp_ctx , py_lp_ctx ) ;
2010-02-17 14:19:57 +03:00
if ( lp_ctx = = NULL ) {
2010-03-02 00:23:45 +03:00
talloc_free ( tmp_ctx ) ;
2010-02-17 14:19:57 +03:00
return NULL ;
}
2011-06-02 09:40:28 +04:00
load_interface_list ( tmp_ctx , lp_ctx , & ifaces ) ;
2010-02-17 14:19:57 +03:00
2011-05-02 09:57:19 +04:00
count = iface_list_count ( ifaces ) ;
2010-02-17 14:19:57 +03:00
2010-02-25 08:29:47 +03:00
/* first count how many are not loopback addresses */
for ( ifcount = i = 0 ; i < count ; i + + ) {
2011-05-02 09:57:19 +04:00
const char * ip = iface_list_n_ip ( ifaces , i ) ;
2013-08-30 16:59:01 +04:00
if ( all_interfaces ) {
2010-02-25 08:29:47 +03:00
ifcount + + ;
2013-08-30 16:59:01 +04:00
continue ;
}
if ( iface_list_same_net ( ip , " 127.0.0.1 " , " 255.0.0.0 " ) ) {
continue ;
}
if ( iface_list_same_net ( ip , " 169.254.0.0 " , " 255.255.0.0 " ) ) {
continue ;
2010-02-25 08:29:47 +03:00
}
2013-08-30 16:59:01 +04:00
if ( iface_list_same_net ( ip , " ::1 " , " ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff " ) ) {
continue ;
}
if ( iface_list_same_net ( ip , " fe80:: " , " ffff:ffff:ffff:ffff:: " ) ) {
continue ;
}
ifcount + + ;
2010-02-25 08:29:47 +03:00
}
pylist = PyList_New ( ifcount ) ;
for ( ifcount = i = 0 ; i < count ; i + + ) {
2011-05-02 09:57:19 +04:00
const char * ip = iface_list_n_ip ( ifaces , i ) ;
2013-08-30 16:59:01 +04:00
if ( all_interfaces ) {
2019-06-07 11:45:52 +03:00
PyList_SetItem ( pylist , ifcount , PyUnicode_FromString ( ip ) ) ;
2010-02-25 08:29:47 +03:00
ifcount + + ;
2013-08-30 16:59:01 +04:00
continue ;
}
if ( iface_list_same_net ( ip , " 127.0.0.1 " , " 255.0.0.0 " ) ) {
continue ;
}
if ( iface_list_same_net ( ip , " 169.254.0.0 " , " 255.255.0.0 " ) ) {
continue ;
2010-02-25 08:29:47 +03:00
}
2013-08-30 16:59:01 +04:00
if ( iface_list_same_net ( ip , " ::1 " , " ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff " ) ) {
continue ;
}
if ( iface_list_same_net ( ip , " fe80:: " , " ffff:ffff:ffff:ffff:: " ) ) {
continue ;
}
2019-06-07 11:45:52 +03:00
PyList_SetItem ( pylist , ifcount , PyUnicode_FromString ( ip ) ) ;
2013-08-30 16:59:01 +04:00
ifcount + + ;
2010-02-17 14:19:57 +03:00
}
talloc_free ( tmp_ctx ) ;
return pylist ;
}
2011-05-18 06:06:25 +04:00
static PyObject * py_strcasecmp_m ( PyObject * self , PyObject * args )
{
2018-08-07 18:21:35 +03:00
const char * s1 = NULL ;
const char * s2 = NULL ;
2018-11-09 19:47:00 +03:00
long cmp_result = 0 ;
2018-12-11 18:58:07 +03:00
if ( ! PyArg_ParseTuple ( args , PYARG_STR_UNI
PYARG_STR_UNI ,
" utf8 " , & s1 , " utf8 " , & s2 ) ) {
2011-05-18 06:06:25 +04:00
return NULL ;
2018-08-07 18:21:35 +03:00
}
2011-05-18 06:06:25 +04:00
2018-11-09 19:47:00 +03:00
cmp_result = strcasecmp_m ( s1 , s2 ) ;
PyMem_Free ( discard_const_p ( char , s1 ) ) ;
PyMem_Free ( discard_const_p ( char , s2 ) ) ;
2020-03-15 00:36:59 +03:00
return PyLong_FromLong ( cmp_result ) ;
2011-05-18 06:06:25 +04:00
}
static PyObject * py_strstr_m ( PyObject * self , PyObject * args )
{
2018-08-07 18:21:35 +03:00
const char * s1 = NULL ;
const char * s2 = NULL ;
2018-11-09 19:47:00 +03:00
char * strstr_ret = NULL ;
PyObject * result = NULL ;
2018-12-11 18:58:07 +03:00
if ( ! PyArg_ParseTuple ( args , PYARG_STR_UNI
PYARG_STR_UNI ,
" utf8 " , & s1 , " utf8 " , & s2 ) )
2011-05-18 06:06:25 +04:00
return NULL ;
2018-11-09 19:47:00 +03:00
strstr_ret = strstr_m ( s1 , s2 ) ;
if ( ! strstr_ret ) {
PyMem_Free ( discard_const_p ( char , s1 ) ) ;
PyMem_Free ( discard_const_p ( char , s2 ) ) ;
2011-05-18 06:06:25 +04:00
Py_RETURN_NONE ;
}
2018-11-09 19:47:00 +03:00
result = PyUnicode_FromString ( strstr_ret ) ;
PyMem_Free ( discard_const_p ( char , s1 ) ) ;
PyMem_Free ( discard_const_p ( char , s2 ) ) ;
return result ;
2011-05-18 06:06:25 +04:00
}
2008-12-21 01:38:30 +03:00
static PyMethodDef py_misc_methods [ ] = {
{ " generate_random_str " , ( PyCFunction ) py_generate_random_str , METH_VARARGS ,
2010-02-24 16:44:22 +03:00
" generate_random_str(len) -> string \n "
" Generate random string with specified length. " } ,
2010-06-19 19:19:48 +04:00
{ " generate_random_password " , ( PyCFunction ) py_generate_random_password ,
METH_VARARGS , " generate_random_password(min, max) -> string \n "
2016-08-23 10:35:50 +03:00
" Generate random password (based on printable ascii characters) "
" with a length >= min and <= max. " } ,
{ " generate_random_machine_password " , ( PyCFunction ) py_generate_random_machine_password ,
METH_VARARGS , " generate_random_machine_password(min, max) -> string \n "
" Generate random password "
" (based on random utf16 characters converted to utf8 or "
" random ascii characters if 'unix charset' is not 'utf8') "
" with a length >= min (at least 14) and <= max (at most 255). " } ,
2017-11-28 05:45:30 +03:00
{ " check_password_quality " , ( PyCFunction ) py_check_password_quality ,
METH_VARARGS , " check_password_quality(pass) -> bool \n "
" Check password quality against Samba's check_password_quality, "
" the implementation of Microsoft's rules: "
" http://msdn.microsoft.com/en-us/subscriptions/cc786468%28v=ws.10%29.aspx "
} ,
2008-12-21 01:38:30 +03:00
{ " unix2nttime " , ( PyCFunction ) py_unix2nttime , METH_VARARGS ,
" unix2nttime(timestamp) -> nttime " } ,
2010-04-15 00:18:14 +04:00
{ " nttime2unix " , ( PyCFunction ) py_nttime2unix , METH_VARARGS ,
" nttime2unix(nttime) -> timestamp " } ,
2020-12-02 17:42:10 +03:00
{ " float2nttime " , ( PyCFunction ) py_float2nttime , METH_VARARGS ,
" pytime2nttime(floattimestamp) -> nttime " } ,
{ " nttime2float " , ( PyCFunction ) py_nttime2float , METH_VARARGS ,
" nttime2pytime(nttime) -> floattimestamp " } ,
2010-04-15 00:18:14 +04:00
{ " nttime2string " , ( PyCFunction ) py_nttime2string , METH_VARARGS ,
" nttime2string(nttime) -> string " } ,
2009-09-03 07:03:31 +04:00
{ " set_debug_level " , ( PyCFunction ) py_set_debug_level , METH_VARARGS ,
" set debug level " } ,
2010-11-29 05:26:48 +03:00
{ " get_debug_level " , ( PyCFunction ) py_get_debug_level , METH_NOARGS ,
" get debug level " } ,
2018-05-25 08:52:02 +03:00
{ " fault_setup " , ( PyCFunction ) py_fault_setup , METH_NOARGS ,
" setup the default samba panic handler " } ,
2010-02-17 14:19:57 +03:00
{ " interface_ips " , ( PyCFunction ) py_interface_ips , METH_VARARGS ,
2012-09-28 02:13:37 +04:00
" interface_ips(lp_ctx[, all_interfaces) -> list_of_ifaces \n "
" \n "
2010-02-17 14:19:57 +03:00
" get interface IP address list " } ,
2011-05-18 06:06:25 +04:00
{ " strcasecmp_m " , ( PyCFunction ) py_strcasecmp_m , METH_VARARGS ,
" (for testing) compare two strings using Samba's strcasecmp_m() " } ,
{ " strstr_m " , ( PyCFunction ) py_strstr_m , METH_VARARGS ,
" (for testing) find one string in another with Samba's strstr_m() " } ,
2015-10-09 23:30:17 +03:00
{ " is_ntvfs_fileserver_built " , ( PyCFunction ) py_is_ntvfs_fileserver_built , METH_NOARGS ,
" is the NTVFS file server built in this installation? " } ,
2017-04-04 09:10:52 +03:00
{ " is_heimdal_built " , ( PyCFunction ) py_is_heimdal_built , METH_NOARGS ,
" is Samba built with Heimdal Kerberbos? " } ,
2017-11-02 00:15:29 +03:00
{ " generate_random_bytes " ,
( PyCFunction ) py_generate_random_bytes ,
METH_VARARGS ,
" generate_random_bytes(len) -> bytes \n "
" Generate random bytes with specified length. " } ,
2020-09-18 20:27:24 +03:00
{ " is_ad_dc_built " , ( PyCFunction ) py_is_ad_dc_built , METH_NOARGS ,
" is Samba built with AD DC? " } ,
2020-05-05 04:47:39 +03:00
{ 0 }
2008-12-21 01:38:30 +03:00
} ;
2016-12-05 14:14:28 +03:00
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " _glue " ,
. m_doc = " Python bindings for miscellaneous Samba functions. " ,
. m_size = - 1 ,
. m_methods = py_misc_methods ,
} ;
MODULE_INIT_FUNC ( _glue )
2008-12-21 01:38:30 +03:00
{
PyObject * m ;
2010-04-02 11:21:14 +04:00
debug_setup_talloc_log ( ) ;
2016-12-05 14:14:28 +03:00
m = PyModule_Create ( & moduledef ) ;
2008-12-21 01:38:30 +03:00
if ( m = = NULL )
2016-12-05 14:14:28 +03:00
return NULL ;
2008-12-21 01:38:30 +03:00
2010-06-19 19:19:48 +04:00
PyModule_AddObject ( m , " version " ,
2019-06-07 11:45:52 +03:00
PyUnicode_FromString ( SAMBA_VERSION_STRING ) ) ;
2016-11-01 05:23:58 +03:00
PyExc_NTSTATUSError = PyErr_NewException ( discard_const_p ( char , " samba.NTSTATUSError " ) , PyExc_RuntimeError , NULL ) ;
if ( PyExc_NTSTATUSError ! = NULL ) {
Py_INCREF ( PyExc_NTSTATUSError ) ;
PyModule_AddObject ( m , " NTSTATUSError " , PyExc_NTSTATUSError ) ;
}
PyExc_WERRORError = PyErr_NewException ( discard_const_p ( char , " samba.WERRORError " ) , PyExc_RuntimeError , NULL ) ;
if ( PyExc_WERRORError ! = NULL ) {
Py_INCREF ( PyExc_WERRORError ) ;
PyModule_AddObject ( m , " WERRORError " , PyExc_WERRORError ) ;
}
PyExc_HRESULTError = PyErr_NewException ( discard_const_p ( char , " samba.HRESULTError " ) , PyExc_RuntimeError , NULL ) ;
if ( PyExc_HRESULTError ! = NULL ) {
Py_INCREF ( PyExc_HRESULTError ) ;
PyModule_AddObject ( m , " HRESULTError " , PyExc_HRESULTError ) ;
}
2016-11-01 06:09:20 +03:00
PyExc_DsExtendedError = PyErr_NewException ( discard_const_p ( char , " samba.DsExtendedError " ) , PyExc_RuntimeError , NULL ) ;
if ( PyExc_DsExtendedError ! = NULL ) {
Py_INCREF ( PyExc_DsExtendedError ) ;
PyModule_AddObject ( m , " DsExtendedError " , PyExc_DsExtendedError ) ;
}
2016-12-05 14:14:28 +03:00
return m ;
2008-12-21 01:38:30 +03:00
}