2012-05-07 10:24:03 +04:00
/*
Unix SMB / CIFS implementation .
2012-09-25 01:11:05 +04:00
Set NT and POSIX ACLs and other VFS operations from Python
2012-08-02 07:36:43 +04:00
Copyrigyt ( C ) Andrew Bartlett 2012
2012-05-07 10:24:03 +04:00
Copyright ( C ) Jeremy Allison 1994 - 2009.
Copyright ( C ) Andreas Gruenbacher 2002.
Copyright ( C ) Simo Sorce < idra @ samba . org > 2009.
2012-08-02 07:35:24 +04:00
Copyright ( C ) Simo Sorce 2002
Copyright ( C ) Eric Lorimer 2002
2012-05-07 10:24:03 +04: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/>.
*/
2015-06-12 12:45:39 +03:00
# include <Python.h>
2012-05-07 10:24:03 +04:00
# include "includes.h"
2018-02-05 14:10:46 +03:00
# include "python/py3compat.h"
2012-05-07 10:24:03 +04:00
# include "smbd/smbd.h"
# include "libcli/util/pyerrors.h"
2012-08-02 07:35:24 +04:00
# include "librpc/rpc/pyrpc_util.h"
# include <pytalloc.h>
# include "system/filesys.h"
2018-09-04 16:29:58 +03:00
# include "passdb.h"
# include "secrets.h"
# include "auth.h"
2012-05-07 10:24:03 +04:00
extern const struct generic_mapping file_generic_mapping ;
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_ACLS
2018-06-01 04:45:25 +03:00
# ifdef O_DIRECTORY
# define DIRECTORY_FLAGS O_RDONLY|O_DIRECTORY
# else
/* POSIX allows us to open a directory with O_RDONLY. */
# define DIRECTORY_FLAGS O_RDONLY
# endif
2018-07-04 01:05:50 +03:00
static connection_struct * get_conn_tos (
const char * service ,
const struct auth_session_info * session_info )
2012-05-07 10:24:03 +04:00
{
2018-05-24 17:16:19 +03:00
struct conn_struct_tos * c = NULL ;
2013-01-09 02:18:27 +04:00
int snum = - 1 ;
NTSTATUS status ;
2012-10-10 06:48:27 +04:00
if ( ! posix_locking_init ( false ) ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
if ( service ) {
2013-01-09 02:18:27 +04:00
snum = lp_servicenumber ( service ) ;
2012-10-10 06:48:27 +04:00
if ( snum = = - 1 ) {
PyErr_SetString ( PyExc_RuntimeError , " unknown service " ) ;
return NULL ;
}
2013-01-09 02:18:27 +04:00
}
2012-10-10 06:48:27 +04:00
2018-05-24 17:16:19 +03:00
status = create_conn_struct_tos ( NULL ,
snum ,
" / " ,
2018-07-04 01:05:50 +03:00
session_info ,
2018-05-24 17:16:19 +03:00
& c ) ;
2013-01-09 02:18:27 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
2012-10-10 06:48:27 +04:00
2013-01-09 02:18:27 +04:00
/* Ignore read-only and share restrictions */
2018-05-24 17:16:19 +03:00
c - > conn - > read_only = false ;
c - > conn - > share_access = SEC_RIGHTS_FILE_ALL ;
return c - > conn ;
2012-10-10 06:48:27 +04:00
}
2014-02-05 06:31:22 +04:00
static int set_sys_acl_conn ( const char * fname ,
2012-10-10 06:48:27 +04:00
SMB_ACL_TYPE_T acltype ,
SMB_ACL_T theacl , connection_struct * conn )
{
2012-05-07 10:24:03 +04:00
int ret ;
2017-05-24 20:47:46 +03:00
struct smb_filename * smb_fname = NULL ;
2012-10-26 07:22:07 +04:00
mode_t saved_umask ;
2012-05-07 10:24:03 +04:00
2012-10-10 06:48:27 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2012-05-07 10:24:03 +04:00
2012-10-26 07:22:07 +04:00
/* we want total control over the permissions on created files,
so set our umask to 0 */
saved_umask = umask ( 0 ) ;
2017-05-24 20:47:46 +03:00
smb_fname = synthetic_smb_fname_split ( frame ,
fname ,
lp_posix_pathnames ( ) ) ;
if ( smb_fname = = NULL ) {
TALLOC_FREE ( frame ) ;
umask ( saved_umask ) ;
return - 1 ;
}
ret = SMB_VFS_SYS_ACL_SET_FILE ( conn , smb_fname , acltype , theacl ) ;
2012-05-07 10:24:03 +04:00
2012-10-26 07:22:07 +04:00
umask ( saved_umask ) ;
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
2014-02-05 06:31:22 +04:00
return ret ;
2012-05-07 10:24:03 +04:00
}
2018-06-01 04:45:25 +03:00
static NTSTATUS init_files_struct ( TALLOC_CTX * mem_ctx ,
const char * fname ,
struct connection_struct * conn ,
int flags ,
struct files_struct * * _fsp )
2012-08-02 07:35:24 +04:00
{
struct smb_filename * smb_fname = NULL ;
2018-06-01 04:45:25 +03:00
int ret ;
2012-10-26 07:22:07 +04:00
mode_t saved_umask ;
2018-06-01 04:45:25 +03:00
struct files_struct * fsp ;
2012-10-26 07:22:07 +04:00
2018-06-01 04:45:25 +03:00
fsp = talloc_zero ( mem_ctx , struct files_struct ) ;
2012-08-02 07:35:24 +04:00
if ( fsp = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
fsp - > fh = talloc ( fsp , struct fd_handle ) ;
if ( fsp - > fh = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
fsp - > conn = conn ;
2012-10-26 07:22:07 +04:00
/* we want total control over the permissions on created files,
so set our umask to 0 */
saved_umask = umask ( 0 ) ;
2016-03-10 03:00:47 +03:00
smb_fname = synthetic_smb_fname_split ( fsp ,
2018-06-01 04:45:25 +03:00
fname ,
lp_posix_pathnames ( ) ) ;
2013-04-12 14:06:51 +04:00
if ( smb_fname = = NULL ) {
2012-10-26 07:22:07 +04:00
umask ( saved_umask ) ;
2013-04-12 14:06:51 +04:00
return NT_STATUS_NO_MEMORY ;
2012-08-02 07:35:24 +04:00
}
fsp - > fsp_name = smb_fname ;
2018-06-01 04:45:25 +03:00
fsp - > fh - > fd = SMB_VFS_OPEN ( conn , smb_fname , fsp , flags , 00644 ) ;
2012-08-02 07:35:24 +04:00
if ( fsp - > fh - > fd = = - 1 ) {
2018-09-19 17:52:54 +03:00
int err = errno ;
2012-10-26 07:22:07 +04:00
umask ( saved_umask ) ;
2018-09-19 17:52:54 +03:00
if ( err = = ENOENT ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2018-06-01 04:45:25 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2012-08-02 07:35:24 +04:00
}
2012-11-14 00:34:35 +04:00
ret = SMB_VFS_FSTAT ( fsp , & smb_fname - > st ) ;
if ( ret = = - 1 ) {
/* If we have an fd, this stat should succeed. */
2018-06-01 04:45:25 +03:00
DEBUG ( 0 , ( " Error doing fstat on open file %s (%s) \n " ,
smb_fname_str_dbg ( smb_fname ) ,
strerror ( errno ) ) ) ;
2012-11-14 00:34:35 +04:00
umask ( saved_umask ) ;
return map_nt_error_from_unix ( errno ) ;
}
fsp - > file_id = vfs_file_id_from_sbuf ( conn , & smb_fname - > st ) ;
fsp - > vuid = UID_FIELD_INVALID ;
fsp - > file_pid = 0 ;
fsp - > can_lock = True ;
fsp - > can_read = True ;
fsp - > can_write = True ;
fsp - > print_file = NULL ;
fsp - > modified = False ;
fsp - > sent_oplock_break = NO_BREAK_SENT ;
fsp - > is_directory = S_ISDIR ( smb_fname - > st . st_ex_mode ) ;
2018-06-01 04:45:25 +03:00
* _fsp = fsp ;
return NT_STATUS_OK ;
}
static NTSTATUS set_nt_acl_conn ( const char * fname ,
uint32_t security_info_sent , const struct security_descriptor * sd ,
connection_struct * conn )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct files_struct * fsp = NULL ;
NTSTATUS status = NT_STATUS_OK ;
/* first, try to open it as a file with flag O_RDWR */
status = init_files_struct ( frame ,
fname ,
conn ,
O_RDWR ,
& fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) & & errno = = EISDIR ) {
/* if fail, try to open as dir */
status = init_files_struct ( frame ,
fname ,
conn ,
DIRECTORY_FLAGS ,
& fsp ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
2018-09-19 17:52:54 +03:00
DBG_ERR ( " init_files_struct failed: %s \n " ,
nt_errstr ( status ) ) ;
if ( fsp ! = NULL ) {
SMB_VFS_CLOSE ( fsp ) ;
}
2018-06-01 04:45:25 +03:00
TALLOC_FREE ( frame ) ;
return status ;
}
status = SMB_VFS_FSET_NT_ACL ( fsp , security_info_sent , sd ) ;
2012-08-02 07:35:24 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " set_nt_acl_no_snum: fset_nt_acl returned %s. \n " , nt_errstr ( status ) ) ) ;
}
2012-10-26 03:07:02 +04:00
SMB_VFS_CLOSE ( fsp ) ;
2012-08-02 07:35:24 +04:00
TALLOC_FREE ( frame ) ;
return status ;
}
2012-10-10 06:48:27 +04:00
static NTSTATUS get_nt_acl_conn ( TALLOC_CTX * mem_ctx ,
const char * fname ,
connection_struct * conn ,
2015-05-03 07:01:14 +03:00
uint32_t security_info_wanted ,
2012-10-10 06:48:27 +04:00
struct security_descriptor * * sd )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2016-02-12 21:30:10 +03:00
NTSTATUS status ;
struct smb_filename * smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
2016-03-19 07:19:38 +03:00
fname ,
NULL ,
NULL ,
lp_posix_pathnames ( ) ?
SMB_FILENAME_POSIX_PATH : 0 ) ;
2016-02-12 21:30:10 +03:00
if ( smb_fname = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
status = SMB_VFS_GET_NT_ACL ( conn ,
smb_fname ,
security_info_wanted ,
mem_ctx ,
sd ) ;
2012-10-10 06:48:27 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " get_nt_acl_conn: get_nt_acl returned %s. \n " , nt_errstr ( status ) ) ) ;
}
TALLOC_FREE ( frame ) ;
return status ;
}
2017-12-05 21:49:03 +03:00
static int set_acl_entry_perms ( SMB_ACL_ENTRY_T entry , mode_t perm_mask )
{
SMB_ACL_PERMSET_T perms = NULL ;
if ( sys_acl_get_permset ( entry , & perms ) ! = 0 ) {
return - 1 ;
}
if ( sys_acl_clear_perms ( perms ) ! = 0 ) {
return - 1 ;
}
if ( ( perm_mask & SMB_ACL_READ ) ! = 0 & &
sys_acl_add_perm ( perms , SMB_ACL_READ ) ! = 0 ) {
return - 1 ;
}
if ( ( perm_mask & SMB_ACL_WRITE ) ! = 0 & &
sys_acl_add_perm ( perms , SMB_ACL_WRITE ) ! = 0 ) {
return - 1 ;
}
if ( ( perm_mask & SMB_ACL_EXECUTE ) ! = 0 & &
sys_acl_add_perm ( perms , SMB_ACL_EXECUTE ) ! = 0 ) {
return - 1 ;
}
if ( sys_acl_set_permset ( entry , perms ) ! = 0 ) {
return - 1 ;
}
return 0 ;
}
2012-05-07 10:24:03 +04:00
2018-05-24 17:16:19 +03:00
static SMB_ACL_T make_simple_acl ( TALLOC_CTX * mem_ctx ,
gid_t gid ,
mode_t chmod_mode )
2012-05-07 10:24:03 +04:00
{
2012-11-11 15:07:49 +04:00
mode_t mode = SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE ;
2012-08-22 12:35:01 +04:00
2012-10-25 09:25:22 +04:00
mode_t mode_user = ( chmod_mode & 0700 ) > > 6 ;
mode_t mode_group = ( chmod_mode & 070 ) > > 3 ;
2012-08-22 12:35:01 +04:00
mode_t mode_other = chmod_mode & 07 ;
2012-05-07 10:24:03 +04:00
SMB_ACL_ENTRY_T entry ;
2018-05-24 17:16:19 +03:00
SMB_ACL_T acl = sys_acl_init ( mem_ctx ) ;
2012-05-07 10:24:03 +04:00
if ( ! acl ) {
return NULL ;
}
if ( sys_acl_create_entry ( & acl , & entry ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_set_tag_type ( entry , SMB_ACL_USER_OBJ ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2017-12-05 21:49:03 +03:00
if ( set_acl_entry_perms ( entry , mode_user ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_create_entry ( & acl , & entry ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_set_tag_type ( entry , SMB_ACL_GROUP_OBJ ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2017-12-05 21:49:03 +03:00
if ( set_acl_entry_perms ( entry , mode_group ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_create_entry ( & acl , & entry ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_set_tag_type ( entry , SMB_ACL_OTHER ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2017-12-05 21:49:03 +03:00
if ( set_acl_entry_perms ( entry , mode_other ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2012-08-22 12:35:01 +04:00
if ( gid ! = - 1 ) {
if ( sys_acl_create_entry ( & acl , & entry ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-08-22 12:35:01 +04:00
return NULL ;
}
2012-09-25 01:11:05 +04:00
2012-08-22 12:35:01 +04:00
if ( sys_acl_set_tag_type ( entry , SMB_ACL_GROUP ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-08-22 12:35:01 +04:00
return NULL ;
}
2012-09-25 01:11:05 +04:00
2012-08-22 12:35:01 +04:00
if ( sys_acl_set_qualifier ( entry , & gid ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-08-22 12:35:01 +04:00
return NULL ;
}
2012-09-25 01:11:05 +04:00
2017-12-05 21:49:03 +03:00
if ( set_acl_entry_perms ( entry , mode_group ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-08-22 12:35:01 +04:00
return NULL ;
}
2012-05-07 10:24:03 +04:00
}
if ( sys_acl_create_entry ( & acl , & entry ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
if ( sys_acl_set_tag_type ( entry , SMB_ACL_MASK ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2017-12-05 21:49:03 +03:00
if ( set_acl_entry_perms ( entry , mode ) ! = 0 ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( acl ) ;
2012-05-07 10:24:03 +04:00
return NULL ;
}
2018-05-24 17:16:19 +03:00
2012-05-07 10:24:03 +04:00
return acl ;
}
/*
set a simple ACL on a file , as a test
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_set_simple_acl ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-05-07 10:24:03 +04:00
{
2012-12-15 14:17:30 +04:00
const char * const kwnames [ ] = { " fname " , " mode " , " gid " , " service " , NULL } ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2014-02-05 06:31:22 +04:00
int ret ;
2012-08-22 12:35:01 +04:00
int mode , gid = - 1 ;
2012-05-07 10:24:03 +04:00
SMB_ACL_T acl ;
2012-08-07 04:45:14 +04:00
TALLOC_CTX * frame ;
2012-10-10 06:48:27 +04:00
connection_struct * conn ;
2012-05-07 10:24:03 +04:00
2012-12-15 14:17:30 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " si|iz " ,
discard_const_p ( char * , kwnames ) ,
& fname , & mode , & gid , & service ) )
2012-05-07 10:24:03 +04:00
return NULL ;
2012-08-07 04:45:14 +04:00
frame = talloc_stackframe ( ) ;
2018-05-24 17:16:19 +03:00
acl = make_simple_acl ( frame , gid , mode ) ;
if ( acl = = NULL ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( frame ) ;
2012-10-10 06:48:27 +04:00
return NULL ;
}
2014-02-05 06:31:22 +04:00
ret = set_sys_acl_conn ( fname , SMB_ACL_TYPE_ACCESS , acl , conn ) ;
2012-08-07 04:45:14 +04:00
2014-02-05 06:31:22 +04:00
if ( ret ! = 0 ) {
TALLOC_FREE ( frame ) ;
errno = ret ;
return PyErr_SetFromErrno ( PyExc_OSError ) ;
}
2012-08-07 04:45:14 +04:00
2014-02-05 06:31:22 +04:00
TALLOC_FREE ( frame ) ;
2012-05-07 10:24:03 +04:00
Py_RETURN_NONE ;
}
2012-08-21 08:23:35 +04:00
/*
chown a file
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_chown ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-08-21 08:23:35 +04:00
{
2012-12-15 14:17:30 +04:00
const char * const kwnames [ ] = { " fname " , " uid " , " gid " , " service " , NULL } ;
2012-08-21 08:23:35 +04:00
connection_struct * conn ;
int ret ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2012-08-21 08:23:35 +04:00
int uid , gid ;
TALLOC_CTX * frame ;
2012-10-26 07:22:07 +04:00
mode_t saved_umask ;
2016-03-03 22:54:23 +03:00
struct smb_filename * smb_fname = NULL ;
2012-08-21 08:23:35 +04:00
2012-12-15 14:17:30 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " sii|z " ,
discard_const_p ( char * , kwnames ) ,
& fname , & uid , & gid , & service ) )
2012-08-21 08:23:35 +04:00
return NULL ;
frame = talloc_stackframe ( ) ;
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( frame ) ;
2012-08-21 08:23:35 +04:00
return NULL ;
}
2012-10-26 07:22:07 +04:00
/* we want total control over the permissions on created files,
so set our umask to 0 */
saved_umask = umask ( 0 ) ;
2016-03-03 22:54:23 +03:00
smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
fname ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
lp_posix_pathnames ( ) ?
SMB_FILENAME_POSIX_PATH : 0 ) ;
2016-03-03 22:54:23 +03:00
if ( smb_fname = = NULL ) {
umask ( saved_umask ) ;
TALLOC_FREE ( frame ) ;
errno = ENOMEM ;
return PyErr_SetFromErrno ( PyExc_OSError ) ;
}
ret = SMB_VFS_CHOWN ( conn , smb_fname , uid , gid ) ;
2012-08-21 08:23:35 +04:00
if ( ret ! = 0 ) {
2014-02-05 06:31:22 +04:00
umask ( saved_umask ) ;
TALLOC_FREE ( frame ) ;
errno = ret ;
return PyErr_SetFromErrno ( PyExc_OSError ) ;
2012-08-21 08:23:35 +04:00
}
2012-10-26 07:22:07 +04:00
umask ( saved_umask ) ;
2012-08-21 08:23:35 +04:00
TALLOC_FREE ( frame ) ;
Py_RETURN_NONE ;
}
2012-10-26 10:25:53 +04:00
/*
2014-02-05 06:31:22 +04:00
unlink a file
2012-10-26 10:25:53 +04:00
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_unlink ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-10-26 10:25:53 +04:00
{
2012-12-15 14:17:30 +04:00
const char * const kwnames [ ] = { " fname " , " service " , NULL } ;
2012-10-26 10:25:53 +04:00
connection_struct * conn ;
int ret ;
struct smb_filename * smb_fname = NULL ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2012-10-26 10:25:53 +04:00
TALLOC_CTX * frame ;
frame = talloc_stackframe ( ) ;
2012-12-15 14:17:30 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|z " ,
discard_const_p ( char * , kwnames ) ,
& fname , & service ) ) {
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
2012-10-26 10:25:53 +04:00
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
TALLOC_FREE ( frame ) ;
2012-10-26 10:25:53 +04:00
return NULL ;
}
2016-03-10 03:00:47 +03:00
smb_fname = synthetic_smb_fname_split ( frame ,
fname ,
lp_posix_pathnames ( ) ) ;
2013-04-12 14:14:32 +04:00
if ( smb_fname = = NULL ) {
2012-10-26 10:25:53 +04:00
TALLOC_FREE ( frame ) ;
2014-02-05 06:31:22 +04:00
return PyErr_NoMemory ( ) ;
2012-10-26 10:25:53 +04:00
}
ret = SMB_VFS_UNLINK ( conn , smb_fname ) ;
if ( ret ! = 0 ) {
2014-02-05 06:31:22 +04:00
TALLOC_FREE ( frame ) ;
errno = ret ;
return PyErr_SetFromErrno ( PyExc_OSError ) ;
2012-10-26 10:25:53 +04:00
}
TALLOC_FREE ( frame ) ;
Py_RETURN_NONE ;
}
2012-06-21 10:21:54 +04:00
/*
check if we have ACL support
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_have_posix_acls ( PyObject * self )
2012-06-21 10:21:54 +04:00
{
# ifdef HAVE_POSIX_ACLS
return PyBool_FromLong ( true ) ;
# else
return PyBool_FromLong ( false ) ;
# endif
}
2012-08-02 07:35:24 +04:00
/*
2012-08-21 09:10:43 +04:00
set the NT ACL on a file
2012-08-02 07:35:24 +04:00
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_set_nt_acl ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-08-02 07:35:24 +04:00
{
2018-07-04 01:18:30 +03:00
const char * const kwnames [ ] = {
" fname " , " security_info_sent " , " sd " ,
" service " , " session_info " , NULL } ;
2012-08-02 07:35:24 +04:00
NTSTATUS status ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2012-08-02 07:35:24 +04:00
int security_info_sent ;
PyObject * py_sd ;
struct security_descriptor * sd ;
2018-07-04 01:18:30 +03:00
PyObject * py_session = Py_None ;
struct auth_session_info * session_info = NULL ;
2012-10-10 06:48:27 +04:00
connection_struct * conn ;
TALLOC_CTX * frame ;
frame = talloc_stackframe ( ) ;
2012-08-02 07:35:24 +04:00
2018-07-04 01:18:30 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " siO|zO " ,
discard_const_p ( char * , kwnames ) ,
& fname , & security_info_sent , & py_sd ,
& service , & py_session ) ) {
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
2012-08-02 07:35:24 +04:00
return NULL ;
2012-10-10 06:48:27 +04:00
}
2012-08-02 07:35:24 +04:00
if ( ! py_check_dcerpc_type ( py_sd , " samba.dcerpc.security " , " descriptor " ) ) {
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:18:30 +03:00
if ( py_session ! = Py_None ) {
if ( ! py_check_dcerpc_type ( py_session ,
" samba.dcerpc.auth " ,
" session_info " ) ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
session_info = pytalloc_get_type ( py_session ,
struct auth_session_info ) ;
if ( ! session_info ) {
PyErr_Format ( PyExc_TypeError ,
" Expected auth_session_info for session_info argument got %s " ,
talloc_get_name ( pytalloc_get_ptr ( py_session ) ) ) ;
return NULL ;
}
}
conn = get_conn_tos ( service , session_info ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
TALLOC_FREE ( frame ) ;
2012-08-02 07:35:24 +04:00
return NULL ;
}
sd = pytalloc_get_type ( py_sd , struct security_descriptor ) ;
2012-10-10 06:48:27 +04:00
status = set_nt_acl_conn ( fname , security_info_sent , sd , conn ) ;
TALLOC_FREE ( frame ) ;
2012-08-02 07:35:24 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
Py_RETURN_NONE ;
}
2012-08-02 09:16:13 +04:00
/*
2012-08-21 09:10:43 +04:00
Return the NT ACL on a file
2012-08-02 09:16:13 +04:00
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_get_nt_acl ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-08-02 09:16:13 +04:00
{
2018-09-04 16:29:58 +03:00
const char * const kwnames [ ] = { " fname " ,
" security_info_wanted " ,
" service " ,
" session_info " ,
NULL } ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2012-08-23 03:45:07 +04:00
int security_info_wanted ;
2012-08-02 09:16:13 +04:00
PyObject * py_sd ;
struct security_descriptor * sd ;
2018-05-24 17:16:19 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2018-09-04 16:29:58 +03:00
PyObject * py_session = Py_None ;
struct auth_session_info * session_info = NULL ;
2012-10-10 06:48:27 +04:00
connection_struct * conn ;
2012-11-14 00:48:53 +04:00
NTSTATUS status ;
2018-09-04 16:29:58 +03:00
int ret = 1 ;
ret = PyArg_ParseTupleAndKeywords ( args ,
kwargs ,
" si|zO " ,
discard_const_p ( char * , kwnames ) ,
& fname ,
& security_info_wanted ,
& service ,
& py_session ) ;
if ( ! ret ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( frame ) ;
2012-08-02 09:16:13 +04:00
return NULL ;
2012-10-10 06:48:27 +04:00
}
2018-09-04 16:29:58 +03:00
if ( py_session ! = Py_None ) {
if ( ! py_check_dcerpc_type ( py_session ,
" samba.dcerpc.auth " ,
" session_info " ) ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
session_info = pytalloc_get_type ( py_session ,
struct auth_session_info ) ;
if ( ! session_info ) {
PyErr_Format (
PyExc_TypeError ,
" Expected auth_session_info for "
" session_info argument got %s " ,
talloc_get_name ( pytalloc_get_ptr ( py_session ) ) ) ;
return NULL ;
}
}
conn = get_conn_tos ( service , session_info ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( frame ) ;
2012-10-10 06:48:27 +04:00
return NULL ;
}
2012-09-25 01:11:05 +04:00
2018-05-24 17:16:19 +03:00
status = get_nt_acl_conn ( frame , fname , conn , security_info_wanted , & sd ) ;
2012-11-14 00:48:53 +04:00
PyErr_NTSTATUS_IS_ERR_RAISE ( status ) ;
2012-08-02 09:16:13 +04:00
2012-08-23 03:39:32 +04:00
py_sd = py_return_ndr_struct ( " samba.dcerpc.security " , " descriptor " , sd , sd ) ;
2012-08-02 09:16:13 +04:00
2018-05-24 17:16:19 +03:00
TALLOC_FREE ( frame ) ;
2012-08-02 09:16:13 +04:00
return py_sd ;
}
2012-08-21 09:11:30 +04:00
/*
set the posix ( or similar ) ACL on a file
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_set_sys_acl ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-08-21 09:11:30 +04:00
{
2012-12-15 14:17:30 +04:00
const char * const kwnames [ ] = { " fname " , " acl_type " , " acl " , " service " , NULL } ;
2012-10-10 06:48:27 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2014-02-05 06:31:22 +04:00
int ret ;
2012-10-10 06:48:27 +04:00
char * fname , * service = NULL ;
2012-08-21 09:11:30 +04:00
PyObject * py_acl ;
struct smb_acl_t * acl ;
int acl_type ;
2012-10-10 06:48:27 +04:00
connection_struct * conn ;
2012-08-21 09:11:30 +04:00
2012-12-15 14:17:30 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " siO|z " ,
discard_const_p ( char * , kwnames ) ,
& fname , & acl_type , & py_acl , & service ) ) {
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
2012-08-21 09:11:30 +04:00
return NULL ;
2012-10-10 06:48:27 +04:00
}
2012-08-21 09:11:30 +04:00
2012-08-21 16:41:13 +04:00
if ( ! py_check_dcerpc_type ( py_acl , " samba.dcerpc.smb_acl " , " t " ) ) {
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
TALLOC_FREE ( frame ) ;
2012-08-21 09:11:30 +04:00
return NULL ;
}
acl = pytalloc_get_type ( py_acl , struct smb_acl_t ) ;
2014-02-05 06:31:22 +04:00
ret = set_sys_acl_conn ( fname , acl_type , acl , conn ) ;
if ( ret ! = 0 ) {
TALLOC_FREE ( frame ) ;
errno = ret ;
return PyErr_SetFromErrno ( PyExc_OSError ) ;
}
2012-08-21 09:11:30 +04:00
2012-10-10 06:48:27 +04:00
TALLOC_FREE ( frame ) ;
2012-08-21 09:11:30 +04:00
Py_RETURN_NONE ;
}
/*
Return the posix ( or similar ) ACL on a file
*/
2012-12-15 14:17:30 +04:00
static PyObject * py_smbd_get_sys_acl ( PyObject * self , PyObject * args , PyObject * kwargs )
2012-08-21 09:11:30 +04:00
{
2012-12-15 14:17:30 +04:00
const char * const kwnames [ ] = { " fname " , " acl_type " , " service " , NULL } ;
2012-08-21 09:11:30 +04:00
char * fname ;
PyObject * py_acl ;
struct smb_acl_t * acl ;
int acl_type ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
connection_struct * conn ;
2012-10-10 06:48:27 +04:00
char * service = NULL ;
2017-05-24 03:11:18 +03:00
struct smb_filename * smb_fname = NULL ;
2012-12-15 14:17:30 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " si|z " ,
discard_const_p ( char * , kwnames ) ,
& fname , & acl_type , & service ) ) {
2012-08-21 09:11:30 +04:00
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2012-10-10 06:48:27 +04:00
if ( ! conn ) {
2012-08-21 09:11:30 +04:00
TALLOC_FREE ( frame ) ;
return NULL ;
}
2017-05-24 03:11:18 +03:00
smb_fname = synthetic_smb_fname_split ( frame ,
fname ,
lp_posix_pathnames ( ) ) ;
if ( smb_fname = = NULL ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-05-24 17:16:19 +03:00
acl = SMB_VFS_SYS_ACL_GET_FILE ( conn , smb_fname , acl_type , frame ) ;
2012-08-21 09:11:30 +04:00
if ( ! acl ) {
TALLOC_FREE ( frame ) ;
2014-02-05 06:31:22 +04:00
return PyErr_SetFromErrno ( PyExc_OSError ) ;
2012-08-21 09:11:30 +04:00
}
2012-08-21 16:41:13 +04:00
py_acl = py_return_ndr_struct ( " samba.dcerpc.smb_acl " , " t " , acl , acl ) ;
2012-08-21 09:11:30 +04:00
TALLOC_FREE ( frame ) ;
return py_acl ;
}
2018-06-01 04:40:42 +03:00
static PyObject * py_smbd_mkdir ( PyObject * self , PyObject * args , PyObject * kwargs )
{
const char * const kwnames [ ] = { " fname " , " service " , NULL } ;
char * fname , * service = NULL ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct connection_struct * conn = NULL ;
struct smb_filename * smb_fname = NULL ;
if ( ! PyArg_ParseTupleAndKeywords ( args ,
kwargs ,
" s|z " ,
discard_const_p ( char * ,
kwnames ) ,
& fname ,
& service ) ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2018-06-01 04:40:42 +03:00
if ( ! conn ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
fname ,
NULL ,
NULL ,
lp_posix_pathnames ( ) ?
SMB_FILENAME_POSIX_PATH : 0 ) ;
if ( smb_fname = = NULL ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
if ( SMB_VFS_MKDIR ( conn , smb_fname , 00755 ) = = - 1 ) {
DBG_ERR ( " mkdir error=%d (%s) \n " , errno , strerror ( errno ) ) ;
TALLOC_FREE ( frame ) ;
return NULL ;
}
TALLOC_FREE ( frame ) ;
Py_RETURN_NONE ;
}
2018-06-01 04:48:31 +03:00
/*
Create an empty file
*/
static PyObject * py_smbd_create_file ( PyObject * self , PyObject * args , PyObject * kwargs )
{
const char * const kwnames [ ] = { " fname " , " service " , NULL } ;
char * fname , * service = NULL ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct connection_struct * conn = NULL ;
struct files_struct * fsp = NULL ;
NTSTATUS status ;
if ( ! PyArg_ParseTupleAndKeywords ( args ,
kwargs ,
" s|z " ,
discard_const_p ( char * ,
kwnames ) ,
& fname ,
& service ) ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
2018-07-04 01:05:50 +03:00
conn = get_conn_tos ( service , NULL ) ;
2018-06-01 04:48:31 +03:00
if ( ! conn ) {
TALLOC_FREE ( frame ) ;
return NULL ;
}
status = init_files_struct ( frame ,
fname ,
conn ,
O_CREAT | O_EXCL | O_RDWR ,
& fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_ERR ( " init_files_struct failed: %s \n " ,
nt_errstr ( status ) ) ;
}
TALLOC_FREE ( frame ) ;
Py_RETURN_NONE ;
}
2012-05-07 10:24:03 +04:00
static PyMethodDef py_smbd_methods [ ] = {
2012-06-21 10:21:54 +04:00
{ " have_posix_acls " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_have_posix_acls , METH_NOARGS ,
2012-06-21 10:21:54 +04:00
NULL } ,
2012-05-07 10:24:03 +04:00
{ " set_simple_acl " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_set_simple_acl , METH_VARARGS | METH_KEYWORDS ,
2012-05-07 10:24:03 +04:00
NULL } ,
2012-08-02 07:35:24 +04:00
{ " set_nt_acl " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_set_nt_acl , METH_VARARGS | METH_KEYWORDS ,
2012-08-02 07:35:24 +04:00
NULL } ,
2012-08-02 09:16:13 +04:00
{ " get_nt_acl " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_get_nt_acl , METH_VARARGS | METH_KEYWORDS ,
2012-08-02 09:16:13 +04:00
NULL } ,
2012-08-21 09:11:30 +04:00
{ " get_sys_acl " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_get_sys_acl , METH_VARARGS | METH_KEYWORDS ,
2012-08-21 09:11:30 +04:00
NULL } ,
{ " set_sys_acl " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_set_sys_acl , METH_VARARGS | METH_KEYWORDS ,
2012-08-21 09:11:30 +04:00
NULL } ,
2012-08-21 08:23:35 +04:00
{ " chown " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_chown , METH_VARARGS | METH_KEYWORDS ,
2012-08-21 08:23:35 +04:00
NULL } ,
2012-10-26 10:25:53 +04:00
{ " unlink " ,
2012-12-15 14:17:30 +04:00
( PyCFunction ) py_smbd_unlink , METH_VARARGS | METH_KEYWORDS ,
2012-10-26 10:25:53 +04:00
NULL } ,
2018-06-01 04:40:42 +03:00
{ " mkdir " ,
( PyCFunction ) py_smbd_mkdir , METH_VARARGS | METH_KEYWORDS ,
NULL } ,
2018-06-01 04:48:31 +03:00
{ " create_file " ,
( PyCFunction ) py_smbd_create_file , METH_VARARGS | METH_KEYWORDS ,
NULL } ,
2012-05-07 10:24:03 +04:00
{ NULL }
} ;
void initsmbd ( void ) ;
2018-02-05 14:10:46 +03:00
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " smbd " ,
. m_doc = " Python bindings for the smbd file server. " ,
. m_size = - 1 ,
. m_methods = py_smbd_methods ,
} ;
MODULE_INIT_FUNC ( smbd )
{
PyObject * m = NULL ;
2012-05-07 10:24:03 +04:00
2018-02-05 14:10:46 +03:00
m = PyModule_Create ( & moduledef ) ;
return m ;
2012-05-07 10:24:03 +04:00
}