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/>.
*/
# include "includes.h"
# include "ldb.h"
2008-12-23 07:34:21 +03:00
# include "ldb_errors.h"
2009-08-17 13:46:23 +04:00
# include "ldb_wrap.h"
2008-12-21 01:38:30 +03:00
# include "param/param.h"
# include "auth/credentials/credentials.h"
# include "dsdb/samdb/samdb.h"
# include "lib/ldb-samba/ldif_handlers.h"
# include "librpc/ndr/libndr.h"
# include "version.h"
2009-01-08 14:20:20 +03:00
# include <Python.h>
2008-12-29 10:40:04 +03:00
# include "lib/ldb/pyldb.h"
2008-12-21 01:38:30 +03:00
# include "libcli/util/pyerrors.h"
2008-12-21 06:36:16 +03:00
# include "libcli/security/security.h"
2008-12-21 05:37:31 +03:00
# include "auth/pyauth.h"
2008-12-22 06:38:57 +03:00
# include "param/pyparam.h"
2009-04-23 03:21:47 +04:00
# include "auth/credentials/pycredentials.h"
2008-12-21 02:24:54 +03:00
2009-01-08 14:20:20 +03:00
# ifndef Py_RETURN_NONE
# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
# endif
2008-12-21 02:24:54 +03:00
/* FIXME: These should be in a header file somewhere, once we finish moving
* away from SWIG . . */
# define PyErr_LDB_OR_RAISE(py_ldb, ldb) \
2009-04-23 03:21:47 +04:00
/* if (!PyLdb_Check(py_ldb)) { \
PyErr_SetString ( py_ldb_get_exception ( ) , " Ldb connection object required " ) ; \
return NULL ; \
} */ \
2008-12-21 02:24:54 +03:00
ldb = PyLdb_AsLdbContext ( py_ldb ) ;
2009-07-18 18:11:21 +04:00
static void PyErr_SetLdbError ( PyObject * error , int ret , struct ldb_context * ldb_ctx )
{
if ( ret = = LDB_ERR_PYTHON_EXCEPTION )
return ; /* Python exception should already be set, just keep that */
PyErr_SetObject ( error ,
Py_BuildValue ( discard_const_p ( char , " (i,s) " ) , ret ,
ldb_ctx = = NULL ? ldb_strerror ( ret ) : ldb_errstring ( ldb_ctx ) ) ) ;
}
2008-12-21 01:38:30 +03:00
2009-04-23 03:21:47 +04:00
static PyObject * py_ldb_get_exception ( void )
{
PyObject * mod = PyImport_ImportModule ( " ldb " ) ;
if ( mod = = NULL )
return NULL ;
return PyObject_GetAttrString ( mod , " LdbError " ) ;
}
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 ) ;
ret = PyString_FromString ( retstr ) ;
talloc_free ( retstr ) ;
return ret ;
}
static PyObject * py_unix2nttime ( PyObject * self , PyObject * args )
{
time_t t ;
NTTIME nt ;
if ( ! PyArg_ParseTuple ( args , " I " , & t ) )
return NULL ;
unix_to_nt_time ( & nt , t ) ;
return PyInt_FromLong ( ( uint64_t ) nt ) ;
}
static PyObject * py_ldb_set_credentials ( PyObject * self , PyObject * args )
{
PyObject * py_creds , * py_ldb ;
struct cli_credentials * creds ;
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_creds ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
creds = cli_credentials_from_py_object ( py_creds ) ;
if ( creds = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected credentials object " ) ;
return NULL ;
}
2008-12-21 01:38:30 +03:00
2009-04-23 03:21:47 +04:00
ldb_set_opaque ( ldb , " credentials " , creds ) ;
2008-12-21 01:38:30 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
static PyObject * py_ldb_set_loadparm ( PyObject * self , PyObject * args )
{
PyObject * py_lp_ctx , * py_ldb ;
struct loadparm_context * lp_ctx ;
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_lp_ctx ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
lp_ctx = lp_from_py_object ( py_lp_ctx ) ;
if ( lp_ctx = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected loadparm object " ) ;
return NULL ;
}
2008-12-21 01:38:30 +03:00
ldb_set_opaque ( ldb , " loadparm " , lp_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
static PyObject * py_ldb_set_session_info ( PyObject * self , PyObject * args )
{
PyObject * py_session_info , * py_ldb ;
struct auth_session_info * info ;
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_session_info ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 05:37:31 +03:00
/*if (!PyAuthSession_Check(py_session_info)) {
PyErr_SetString ( PyExc_TypeError , " Expected session info object " ) ;
return NULL ;
} */
info = PyAuthSession_AsSession ( py_session_info ) ;
2008-12-21 01:38:30 +03:00
ldb_set_opaque ( ldb , " sessionInfo " , info ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
2009-08-17 13:46:23 +04:00
static PyObject * py_ldb_set_utf8_casefold ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_ldb ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
ldb_set_utf8_fns ( ldb , NULL , wrap_casefold ) ;
Py_RETURN_NONE ;
}
2008-12-21 01:38:30 +03:00
static PyObject * py_samdb_set_domain_sid ( PyLdbObject * self , PyObject * args )
{
PyObject * py_ldb , * py_sid ;
struct ldb_context * ldb ;
struct dom_sid * sid ;
bool ret ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_sid ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 06:36:16 +03:00
sid = dom_sid_parse_talloc ( NULL , PyString_AsString ( py_sid ) ) ;
2008-12-21 01:38:30 +03:00
ret = samdb_set_domain_sid ( ldb , sid ) ;
if ( ! ret ) {
PyErr_SetString ( PyExc_RuntimeError , " set_domain_sid failed " ) ;
return NULL ;
}
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
2009-08-27 13:38:04 +04:00
static PyObject * py_samdb_get_domain_sid ( PyLdbObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
const struct dom_sid * sid ;
PyObject * ret ;
char * retstr ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_ldb ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
sid = samdb_domain_sid ( ldb ) ;
if ( ! sid ) {
PyErr_SetString ( PyExc_RuntimeError , " samdb_domain_sid failed " ) ;
return NULL ;
}
retstr = dom_sid_string ( NULL , sid ) ;
ret = PyString_FromString ( retstr ) ;
talloc_free ( retstr ) ;
return ret ;
}
2008-12-21 01:38:30 +03:00
static PyObject * py_ldb_register_samba_handlers ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
int ret ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_ldb ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 01:38:30 +03:00
ret = ldb_register_samba_handlers ( ldb ) ;
2009-04-23 03:21:47 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( py_ldb_get_exception ( ) , ret , ldb ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
static PyObject * py_dsdb_set_ntds_invocation_id ( PyObject * self , PyObject * args )
{
PyObject * py_ldb , * py_guid ;
bool ret ;
2008-12-21 06:36:16 +03:00
struct GUID guid ;
2008-12-21 01:38:30 +03:00
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_guid ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 06:36:16 +03:00
GUID_from_string ( PyString_AsString ( py_guid ) , & guid ) ;
2008-12-21 01:38:30 +03:00
2008-12-21 06:36:16 +03:00
ret = samdb_set_ntds_invocation_id ( ldb , & guid ) ;
2008-12-21 01:38:30 +03:00
if ( ! ret ) {
PyErr_SetString ( PyExc_RuntimeError , " set_ntds_invocation_id failed " ) ;
return NULL ;
}
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
2009-07-14 02:00:09 +04:00
static PyObject * py_dsdb_set_opaque_integer ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
int value ;
int * old_val , * new_val ;
char * py_opaque_name , * opaque_name_talloc ;
struct ldb_context * ldb ;
TALLOC_CTX * tmp_ctx ;
if ( ! PyArg_ParseTuple ( args , " Osi " , & py_ldb , & py_opaque_name , & value ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
/* see if we have a cached copy */
old_val = ( int * ) ldb_get_opaque ( ldb ,
py_opaque_name ) ;
if ( old_val ) {
* old_val = value ;
Py_RETURN_NONE ;
}
tmp_ctx = talloc_new ( ldb ) ;
if ( tmp_ctx = = NULL ) {
goto failed ;
}
new_val = talloc ( tmp_ctx , int ) ;
if ( ! new_val ) {
goto failed ;
}
opaque_name_talloc = talloc_strdup ( tmp_ctx , py_opaque_name ) ;
if ( ! opaque_name_talloc ) {
goto failed ;
}
* new_val = value ;
/* cache the domain_sid in the ldb */
if ( ldb_set_opaque ( ldb , opaque_name_talloc , new_val ) ! = LDB_SUCCESS ) {
goto failed ;
}
talloc_steal ( ldb , new_val ) ;
talloc_steal ( ldb , opaque_name_talloc ) ;
talloc_free ( tmp_ctx ) ;
Py_RETURN_NONE ;
failed :
talloc_free ( tmp_ctx ) ;
PyErr_SetString ( PyExc_RuntimeError , " Failed to set opaque integer into the ldb! \n " ) ;
return NULL ;
}
2008-12-21 01:38:30 +03:00
static PyObject * py_dsdb_set_global_schema ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
int ret ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_ldb ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 01:38:30 +03:00
ret = dsdb_set_global_schema ( ldb ) ;
2009-04-23 03:21:47 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( py_ldb_get_exception ( ) , ret , ldb ) ;
2008-12-21 01:38:30 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
2009-08-13 03:58:38 +04:00
static PyObject * py_dsdb_set_schema_from_ldif ( PyObject * self , PyObject * args )
2008-12-21 01:38:30 +03:00
{
WERROR result ;
char * pf , * df ;
PyObject * py_ldb ;
struct ldb_context * ldb ;
if ( ! PyArg_ParseTuple ( args , " Oss " , & py_ldb , & pf , & df ) )
return NULL ;
2008-12-21 02:24:54 +03:00
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
2008-12-21 01:38:30 +03:00
2009-08-13 03:58:38 +04:00
result = dsdb_set_schema_from_ldif ( ldb , pf , df ) ;
2008-12-21 01:38:30 +03:00
PyErr_WERROR_IS_ERR_RAISE ( result ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 01:38:30 +03:00
}
2009-03-05 08:52:11 +03:00
static PyObject * py_dsdb_convert_schema_to_openldap ( PyObject * self , PyObject * args )
{
char * target_str , * mapping ;
PyObject * py_ldb ;
struct ldb_context * ldb ;
PyObject * ret ;
char * retstr ;
if ( ! PyArg_ParseTuple ( args , " Oss " , & py_ldb , & target_str , & mapping ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
retstr = dsdb_convert_schema_to_openldap ( ldb , target_str , mapping ) ;
if ( ! retstr ) {
PyErr_SetString ( PyExc_RuntimeError , " dsdb_convert_schema_to_openldap failed " ) ;
return NULL ;
}
ret = PyString_FromString ( retstr ) ;
talloc_free ( retstr ) ;
return ret ;
}
2009-08-26 07:43:33 +04:00
static PyObject * py_dsdb_write_prefixes_from_schema_to_ldb ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
WERROR result ;
struct dsdb_schema * schema ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_ldb ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
schema = dsdb_get_schema ( ldb ) ;
if ( ! schema ) {
PyErr_SetString ( PyExc_RuntimeError , " Failed to set find a schema on ldb! \n " ) ;
return NULL ;
}
result = dsdb_write_prefixes_from_schema_to_ldb ( NULL , ldb , schema ) ;
PyErr_WERROR_IS_ERR_RAISE ( result ) ;
Py_RETURN_NONE ;
}
2009-08-13 03:58:38 +04:00
static PyObject * py_dsdb_set_schema_from_ldb ( PyObject * self , PyObject * args )
{
PyObject * py_ldb ;
struct ldb_context * ldb ;
PyObject * py_from_ldb ;
struct ldb_context * from_ldb ;
struct dsdb_schema * schema ;
int ret ;
if ( ! PyArg_ParseTuple ( args , " OO " , & py_ldb , & py_from_ldb ) )
return NULL ;
PyErr_LDB_OR_RAISE ( py_ldb , ldb ) ;
PyErr_LDB_OR_RAISE ( py_from_ldb , from_ldb ) ;
schema = dsdb_get_schema ( from_ldb ) ;
if ( ! schema ) {
PyErr_SetString ( PyExc_RuntimeError , " Failed to set find a schema on 'from' ldb! \n " ) ;
return NULL ;
}
2009-08-13 08:33:57 +04:00
ret = dsdb_reference_schema ( ldb , schema , true ) ;
2009-08-13 03:58:38 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( py_ldb_get_exception ( ) , ret , ldb ) ;
Py_RETURN_NONE ;
}
2009-08-11 14:25:13 +04:00
static PyObject * py_dom_sid_to_rid ( PyLdbObject * self , PyObject * args )
{
PyObject * py_sid ;
struct dom_sid * sid ;
uint32_t rid ;
NTSTATUS status ;
if ( ! PyArg_ParseTuple ( args , " O " , & py_sid ) )
return NULL ;
sid = dom_sid_parse_talloc ( NULL , PyString_AsString ( py_sid ) ) ;
status = dom_sid_split_rid ( NULL , sid , NULL , & rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetString ( PyExc_RuntimeError , " dom_sid_split_rid failed " ) ;
return NULL ;
}
return PyInt_FromLong ( rid ) ;
}
2008-12-21 01:38:30 +03:00
static PyMethodDef py_misc_methods [ ] = {
{ " generate_random_str " , ( PyCFunction ) py_generate_random_str , METH_VARARGS ,
" random_password(len) -> string \n "
" Generate random password with specified length. " } ,
{ " unix2nttime " , ( PyCFunction ) py_unix2nttime , METH_VARARGS ,
" unix2nttime(timestamp) -> nttime " } ,
{ " ldb_set_credentials " , ( PyCFunction ) py_ldb_set_credentials , METH_VARARGS ,
" ldb_set_credentials(ldb, credentials) -> None \n "
" Set credentials to use when connecting. " } ,
{ " ldb_set_session_info " , ( PyCFunction ) py_ldb_set_session_info , METH_VARARGS ,
" ldb_set_session_info(ldb, session_info) \n "
" Set session info to use when connecting. " } ,
{ " ldb_set_loadparm " , ( PyCFunction ) py_ldb_set_loadparm , METH_VARARGS ,
" ldb_set_loadparm(ldb, session_info) \n "
" Set loadparm context to use when connecting. " } ,
{ " samdb_set_domain_sid " , ( PyCFunction ) py_samdb_set_domain_sid , METH_VARARGS ,
" samdb_set_domain_sid(samdb, sid) \n "
" Set SID of domain to use. " } ,
2009-08-27 13:38:04 +04:00
{ " samdb_get_domain_sid " , ( PyCFunction ) py_samdb_get_domain_sid , METH_VARARGS ,
" samdb_get_domain_sid(samdb) \n "
" Get SID of domain in use. " } ,
2008-12-21 01:38:30 +03:00
{ " ldb_register_samba_handlers " , ( PyCFunction ) py_ldb_register_samba_handlers , METH_VARARGS ,
" ldb_register_samba_handlers(ldb) \n "
" Register Samba-specific LDB modules and schemas. " } ,
2009-08-17 13:46:23 +04:00
{ " ldb_set_utf8_casefold " , ( PyCFunction ) py_ldb_set_utf8_casefold , METH_VARARGS ,
" ldb_set_utf8_casefold(ldb) \n "
" Set the right Samba casefolding function for UTF8 charset. " } ,
2008-12-21 01:38:30 +03:00
{ " dsdb_set_ntds_invocation_id " , ( PyCFunction ) py_dsdb_set_ntds_invocation_id , METH_VARARGS ,
NULL } ,
2009-07-14 02:00:09 +04:00
{ " dsdb_set_opaque_integer " , ( PyCFunction ) py_dsdb_set_opaque_integer , METH_VARARGS ,
NULL } ,
2008-12-21 01:38:30 +03:00
{ " dsdb_set_global_schema " , ( PyCFunction ) py_dsdb_set_global_schema , METH_VARARGS ,
NULL } ,
2009-08-13 03:58:38 +04:00
{ " dsdb_set_schema_from_ldif " , ( PyCFunction ) py_dsdb_set_schema_from_ldif , METH_VARARGS ,
NULL } ,
2009-08-26 07:43:33 +04:00
{ " dsdb_write_prefixes_from_schema_to_ldb " , ( PyCFunction ) py_dsdb_write_prefixes_from_schema_to_ldb , METH_VARARGS ,
NULL } ,
2009-08-13 03:58:38 +04:00
{ " dsdb_set_schema_from_ldb " , ( PyCFunction ) py_dsdb_set_schema_from_ldb , METH_VARARGS ,
2009-03-05 08:52:11 +03:00
NULL } ,
{ " dsdb_convert_schema_to_openldap " , ( PyCFunction ) py_dsdb_convert_schema_to_openldap , METH_VARARGS ,
2008-12-21 01:38:30 +03:00
NULL } ,
2009-08-11 14:25:13 +04:00
{ " dom_sid_to_rid " , ( PyCFunction ) py_dom_sid_to_rid , METH_VARARGS ,
NULL } ,
2008-12-21 01:38:30 +03:00
{ NULL }
} ;
2008-12-21 05:08:14 +03:00
void initglue ( void )
2008-12-21 01:38:30 +03:00
{
PyObject * m ;
2008-12-21 05:08:14 +03:00
m = Py_InitModule3 ( " glue " , py_misc_methods ,
2008-12-21 01:38:30 +03:00
" Python bindings for miscellaneous Samba functions. " ) ;
if ( m = = NULL )
return ;
PyModule_AddObject ( m , " version " , PyString_FromString ( SAMBA_VERSION_STRING ) ) ;
2009-07-14 02:15:50 +04:00
PyModule_AddObject ( m , " DS_BEHAVIOR_WIN2000 " , PyInt_FromLong ( DS_BEHAVIOR_WIN2000 ) ) ;
PyModule_AddObject ( m , " DS_BEHAVIOR_WIN2003_INTERIM " , PyInt_FromLong ( DS_BEHAVIOR_WIN2003_INTERIM ) ) ;
PyModule_AddObject ( m , " DS_BEHAVIOR_WIN2003 " , PyInt_FromLong ( DS_BEHAVIOR_WIN2003 ) ) ;
PyModule_AddObject ( m , " DS_BEHAVIOR_WIN2008 " , PyInt_FromLong ( DS_BEHAVIOR_WIN2008 ) ) ;
2008-12-21 01:38:30 +03:00
}