2008-12-21 05:37:31 +03:00
/*
Unix SMB / CIFS implementation .
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2007 - 2008
2011-01-11 08:43:54 +03:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2011
2008-12-21 05:37:31 +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/>.
*/
2010-01-20 06:27:38 +03:00
# include <Python.h>
2008-12-21 05:37:31 +03:00
# include "includes.h"
2010-12-22 09:17:07 +03:00
# include "libcli/util/pyerrors.h"
2008-12-21 05:37:31 +03:00
# include "param/param.h"
# include "pyauth.h"
2010-12-22 09:17:07 +03:00
# include "pyldb.h"
2008-12-21 05:37:31 +03:00
# include "auth/system_session_proto.h"
2011-01-11 08:43:54 +03:00
# include "auth/auth.h"
2008-12-22 06:38:57 +03:00
# include "param/pyparam.h"
2009-09-03 15:39:40 +04:00
# include "libcli/security/security.h"
2011-01-11 08:43:54 +03:00
# include "auth/credentials/pycredentials.h"
2011-01-17 08:22:31 +03:00
# include <tevent.h>
2011-01-11 08:43:54 +03:00
# include "librpc/rpc/pyrpc_util.h"
2011-03-19 02:44:56 +03:00
void initauth ( void ) ;
2011-01-17 08:22:31 +03:00
staticforward PyTypeObject PyAuthContext ;
2011-01-30 19:55:41 +03:00
/* There's no Py_ssize_t in 2.4, apparently */
# if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
typedef int Py_ssize_t ;
typedef inquiry lenfunc ;
typedef intargfunc ssizeargfunc ;
# endif
# ifndef Py_RETURN_NONE
# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
# endif
2011-04-05 10:15:27 +04:00
static PyObject * PyAuthSession_FromSession ( struct auth_session_info * session )
2011-01-11 08:43:54 +03:00
{
2011-04-05 10:15:27 +04:00
return py_return_ndr_struct ( " samba.dcerpc.auth " , " session_info " , session , session ) ;
2008-12-21 05:37:31 +03:00
}
static PyObject * py_system_session ( PyObject * module , PyObject * args )
{
PyObject * py_lp_ctx = Py_None ;
struct loadparm_context * lp_ctx = NULL ;
struct auth_session_info * session ;
2010-09-23 03:44:17 +04:00
TALLOC_CTX * mem_ctx ;
2008-12-21 05:37:31 +03:00
if ( ! PyArg_ParseTuple ( args , " |O " , & py_lp_ctx ) )
return NULL ;
2010-09-23 03:44:17 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
2008-12-21 05:37:31 +03:00
return NULL ;
2010-09-23 03:44:17 +04:00
}
lp_ctx = lpcfg_from_py_object ( mem_ctx , py_lp_ctx ) ;
if ( lp_ctx = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2008-12-21 05:37:31 +03:00
2009-10-23 07:19:28 +04:00
session = system_session ( lp_ctx ) ;
2008-12-21 05:37:31 +03:00
2010-09-23 03:44:17 +04:00
talloc_free ( mem_ctx ) ;
2010-09-23 02:35:36 +04:00
2008-12-21 05:37:31 +03:00
return PyAuthSession_FromSession ( session ) ;
}
2009-09-03 15:39:40 +04:00
static PyObject * py_admin_session ( PyObject * module , PyObject * args )
{
PyObject * py_lp_ctx ;
PyObject * py_sid ;
struct loadparm_context * lp_ctx = NULL ;
struct auth_session_info * session ;
struct dom_sid * domain_sid = NULL ;
2010-09-23 03:44:17 +04:00
TALLOC_CTX * mem_ctx ;
2009-09-03 15:39:40 +04:00
if ( ! PyArg_ParseTuple ( args , " OO " , & py_lp_ctx , & py_sid ) )
return NULL ;
2010-09-23 03:44:17 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
2009-09-03 15:39:40 +04:00
return NULL ;
2010-09-23 03:44:17 +04:00
}
2009-09-03 15:39:40 +04:00
2010-09-23 03:44:17 +04:00
lp_ctx = lpcfg_from_py_object ( mem_ctx , py_lp_ctx ) ;
if ( lp_ctx = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2009-09-03 15:39:40 +04:00
2010-09-23 03:44:17 +04:00
domain_sid = dom_sid_parse_talloc ( mem_ctx , PyString_AsString ( py_sid ) ) ;
if ( domain_sid = = NULL ) {
PyErr_Format ( PyExc_RuntimeError , " Unable to parse sid %s " ,
PyString_AsString ( py_sid ) ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
session = admin_session ( NULL , lp_ctx , domain_sid ) ;
talloc_free ( mem_ctx ) ;
2010-09-23 02:35:36 +04:00
2009-09-03 15:39:40 +04:00
return PyAuthSession_FromSession ( session ) ;
}
2010-12-22 09:17:07 +03:00
static PyObject * py_user_session ( PyObject * module , PyObject * args , PyObject * kwargs )
{
NTSTATUS nt_status ;
struct auth_session_info * session ;
TALLOC_CTX * mem_ctx ;
2011-01-11 08:43:54 +03:00
const char * const kwnames [ ] = { " ldb " , " lp_ctx " , " principal " , " dn " , " session_info_flags " , NULL } ;
2010-12-22 09:17:07 +03:00
struct ldb_context * ldb_ctx ;
PyObject * py_ldb = Py_None ;
PyObject * py_dn = Py_None ;
PyObject * py_lp_ctx = Py_None ;
struct loadparm_context * lp_ctx = NULL ;
struct ldb_dn * user_dn ;
char * principal = NULL ;
2011-01-11 08:43:54 +03:00
int session_info_flags = 0 ; /* This is an int, because that's
* what we need for the python
2010-12-22 09:17:07 +03:00
* PyArg_ParseTupleAndKeywords */
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|OzOi " ,
discard_const_p ( char * , kwnames ) ,
& py_ldb , & py_lp_ctx , & principal , & py_dn , & session_info_flags ) ) {
return NULL ;
}
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2011-08-07 19:08:56 +04:00
ldb_ctx = pyldb_Ldb_AsLdbContext ( py_ldb ) ;
2010-12-22 09:17:07 +03:00
if ( py_dn = = Py_None ) {
user_dn = NULL ;
} else {
2011-08-07 19:08:56 +04:00
if ( ! pyldb_Object_AsDn ( ldb_ctx , py_dn , ldb_ctx , & user_dn ) ) {
2010-12-22 09:17:07 +03:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
}
lp_ctx = lpcfg_from_py_object ( mem_ctx , py_lp_ctx ) ;
if ( lp_ctx = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
nt_status = authsam_get_session_info_principal ( mem_ctx , lp_ctx , ldb_ctx , principal , user_dn ,
session_info_flags , & session ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( mem_ctx ) ;
PyErr_NTSTATUS_IS_ERR_RAISE ( nt_status ) ;
}
talloc_steal ( NULL , session ) ;
talloc_free ( mem_ctx ) ;
return PyAuthSession_FromSession ( session ) ;
}
2011-01-18 11:13:19 +03:00
static const char * * PyList_AsStringList ( TALLOC_CTX * mem_ctx , PyObject * list ,
const char * paramname )
{
const char * * ret ;
Py_ssize_t i ;
if ( ! PyList_Check ( list ) ) {
PyErr_Format ( PyExc_TypeError , " %s is not a list " , paramname ) ;
return NULL ;
}
ret = talloc_array ( NULL , const char * , PyList_Size ( list ) + 1 ) ;
if ( ret = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
for ( i = 0 ; i < PyList_Size ( list ) ; i + + ) {
PyObject * item = PyList_GetItem ( list , i ) ;
if ( ! PyString_Check ( item ) ) {
PyErr_Format ( PyExc_TypeError , " %s should be strings " , paramname ) ;
return NULL ;
}
ret [ i ] = talloc_strndup ( ret , PyString_AsString ( item ) ,
PyString_Size ( item ) ) ;
}
ret [ i ] = NULL ;
return ret ;
}
2011-05-07 10:14:06 +04:00
static PyObject * PyAuthContext_FromContext ( struct auth4_context * auth_context )
2011-01-17 08:22:31 +03:00
{
2011-08-10 17:15:18 +04:00
return pytalloc_reference ( & PyAuthContext , auth_context ) ;
2011-01-17 08:22:31 +03:00
}
static PyObject * py_auth_context_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
2011-01-18 11:13:19 +03:00
PyObject * py_lp_ctx = Py_None ;
PyObject * py_ldb = Py_None ;
2011-05-03 04:40:33 +04:00
PyObject * py_imessaging_ctx = Py_None ;
2011-01-18 11:13:19 +03:00
PyObject * py_auth_context = Py_None ;
PyObject * py_methods = Py_None ;
2011-01-17 08:22:31 +03:00
TALLOC_CTX * mem_ctx ;
2011-05-07 10:14:06 +04:00
struct auth4_context * auth_context ;
2011-05-03 04:40:33 +04:00
struct imessaging_context * imessaging_context = NULL ;
2011-01-17 08:22:31 +03:00
struct loadparm_context * lp_ctx ;
struct tevent_context * ev ;
2011-01-18 11:13:19 +03:00
struct ldb_context * ldb ;
2011-01-17 08:22:31 +03:00
NTSTATUS nt_status ;
2011-01-18 11:13:19 +03:00
const char * * methods ;
2011-01-17 08:22:31 +03:00
2011-01-18 11:13:19 +03:00
const char * const kwnames [ ] = { " lp_ctx " , " messaging_ctx " , " ldb " , " methods " , NULL } ;
2011-01-17 08:22:31 +03:00
2011-01-18 11:13:19 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |OOOO " ,
2011-01-17 08:22:31 +03:00
discard_const_p ( char * , kwnames ) ,
2011-05-03 04:40:33 +04:00
& py_lp_ctx , & py_imessaging_ctx , & py_ldb , & py_methods ) )
2011-01-17 08:22:31 +03:00
return NULL ;
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2011-01-18 11:13:19 +03:00
if ( py_ldb ! = Py_None ) {
2011-08-07 19:08:56 +04:00
ldb = pyldb_Ldb_AsLdbContext ( py_ldb ) ;
2011-01-17 08:22:31 +03:00
}
2011-01-18 11:13:19 +03:00
lp_ctx = lpcfg_from_py_object ( mem_ctx , py_lp_ctx ) ;
2011-01-17 08:22:31 +03:00
ev = tevent_context_init ( mem_ctx ) ;
if ( ev = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2011-05-03 04:40:33 +04:00
if ( py_imessaging_ctx ! = Py_None ) {
2011-08-10 17:15:18 +04:00
imessaging_context = pytalloc_get_type ( py_imessaging_ctx , struct imessaging_context ) ;
2011-01-19 14:29:08 +03:00
}
2011-01-17 08:22:31 +03:00
2011-01-18 11:13:19 +03:00
if ( py_methods = = Py_None & & py_ldb = = Py_None ) {
2011-05-03 04:40:33 +04:00
nt_status = auth_context_create ( mem_ctx , ev , imessaging_context , lp_ctx , & auth_context ) ;
2011-01-18 11:13:19 +03:00
} else {
if ( py_methods ! = Py_None ) {
methods = PyList_AsStringList ( mem_ctx , py_methods , " methods " ) ;
if ( methods = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
} else {
methods = auth_methods_from_lp ( mem_ctx , lp_ctx ) ;
}
nt_status = auth_context_create_methods ( mem_ctx , methods , ev ,
2011-05-03 04:40:33 +04:00
imessaging_context , lp_ctx ,
2011-01-18 11:13:19 +03:00
ldb , & auth_context ) ;
}
2011-01-17 08:22:31 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( mem_ctx ) ;
PyErr_NTSTATUS_IS_ERR_RAISE ( nt_status ) ;
}
if ( ! talloc_reference ( auth_context , lp_ctx ) ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
if ( ! talloc_reference ( auth_context , ev ) ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
py_auth_context = PyAuthContext_FromContext ( auth_context ) ;
talloc_free ( mem_ctx ) ;
return py_auth_context ;
}
static PyTypeObject PyAuthContext = {
. tp_name = " AuthContext " ,
2011-08-10 17:15:18 +04:00
. tp_basicsize = sizeof ( pytalloc_Object ) ,
2011-01-17 08:22:31 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT ,
. tp_new = py_auth_context_new ,
} ;
2008-12-21 05:37:31 +03:00
static PyMethodDef py_auth_methods [ ] = {
{ " system_session " , ( PyCFunction ) py_system_session , METH_VARARGS , NULL } ,
2009-09-03 15:39:40 +04:00
{ " admin_session " , ( PyCFunction ) py_admin_session , METH_VARARGS , NULL } ,
2011-01-11 08:43:54 +03:00
{ " user_session " , ( PyCFunction ) py_user_session , METH_VARARGS | METH_KEYWORDS , NULL } ,
2008-12-21 05:37:31 +03:00
{ NULL } ,
} ;
void initauth ( void )
{
PyObject * m ;
2011-08-10 17:15:18 +04:00
PyAuthContext . tp_base = pytalloc_GetObjectType ( ) ;
2011-01-19 14:29:08 +03:00
if ( PyAuthContext . tp_base = = NULL )
return ;
if ( PyType_Ready ( & PyAuthContext ) < 0 )
return ;
2010-04-04 04:20:52 +04:00
m = Py_InitModule3 ( " auth " , py_auth_methods ,
" Authentication and authorization support. " ) ;
2008-12-21 05:37:31 +03:00
if ( m = = NULL )
return ;
2011-01-19 14:29:08 +03:00
Py_INCREF ( & PyAuthContext ) ;
PyModule_AddObject ( m , " AuthContext " , ( PyObject * ) & PyAuthContext ) ;
2011-01-11 08:43:54 +03:00
# define ADD_FLAG(val) PyModule_AddObject(m, #val, PyInt_FromLong(val))
ADD_FLAG ( AUTH_SESSION_INFO_DEFAULT_GROUPS ) ;
ADD_FLAG ( AUTH_SESSION_INFO_AUTHENTICATED ) ;
ADD_FLAG ( AUTH_SESSION_INFO_SIMPLE_PRIVILEGES ) ;
2008-12-21 05:37:31 +03:00
}