2004-10-03 10:46:29 +04:00
/*
Unix SMB / CIFS implementation .
a pass - thru NTVFS module to setup a security context using unix
uid / gid
Copyright ( C ) Andrew Tridgell 2004
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-10-03 10:46:29 +04:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-10-03 10:46:29 +04:00
*/
# include "includes.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
# include "system/passwd.h"
2004-11-02 05:57:18 +03:00
# include "auth/auth.h"
2005-12-28 01:51:30 +03:00
# include "ntvfs/ntvfs.h"
2008-03-28 13:00:52 +03:00
# include "libcli/wbclient/wbclient.h"
2004-10-03 10:46:29 +04:00
struct unixuid_private {
2008-03-28 13:00:52 +03:00
struct wbc_context * wbc_ctx ;
2004-10-12 09:59:56 +04:00
struct unix_sec_ctx * last_sec_ctx ;
2004-12-11 08:41:19 +03:00
struct security_token * last_token ;
2004-10-03 10:46:29 +04:00
} ;
struct unix_sec_ctx {
uid_t uid ;
gid_t gid ;
uint_t ngroups ;
gid_t * groups ;
} ;
/*
pull the current security context into a unix_sec_ctx
*/
static struct unix_sec_ctx * save_unix_security ( TALLOC_CTX * mem_ctx )
{
2005-01-27 10:08:20 +03:00
struct unix_sec_ctx * sec = talloc ( mem_ctx , struct unix_sec_ctx ) ;
2004-10-03 10:46:29 +04:00
if ( sec = = NULL ) {
return NULL ;
}
sec - > uid = geteuid ( ) ;
sec - > gid = getegid ( ) ;
sec - > ngroups = getgroups ( 0 , NULL ) ;
if ( sec - > ngroups = = - 1 ) {
talloc_free ( sec ) ;
return NULL ;
}
2005-01-27 10:08:20 +03:00
sec - > groups = talloc_array ( sec , gid_t , sec - > ngroups ) ;
2004-10-03 10:46:29 +04:00
if ( sec - > groups = = NULL ) {
talloc_free ( sec ) ;
return NULL ;
}
if ( getgroups ( sec - > ngroups , sec - > groups ) ! = sec - > ngroups ) {
talloc_free ( sec ) ;
return NULL ;
}
return sec ;
}
/*
set the current security context from a unix_sec_ctx
*/
static NTSTATUS set_unix_security ( struct unix_sec_ctx * sec )
{
seteuid ( 0 ) ;
if ( setgroups ( sec - > ngroups , sec - > groups ) ! = 0 ) {
return NT_STATUS_ACCESS_DENIED ;
}
if ( setegid ( sec - > gid ) ! = 0 ) {
return NT_STATUS_ACCESS_DENIED ;
}
if ( seteuid ( sec - > uid ) ! = 0 ) {
return NT_STATUS_ACCESS_DENIED ;
}
return NT_STATUS_OK ;
}
/*
2004-12-11 08:41:19 +03:00
form a unix_sec_ctx from the current security_token
2004-10-03 10:46:29 +04:00
*/
2004-10-12 15:30:48 +04:00
static NTSTATUS nt_token_to_unix_security ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req ,
2004-12-11 08:41:19 +03:00
struct security_token * token ,
2004-10-03 10:46:29 +04:00
struct unix_sec_ctx * * sec )
{
2008-03-28 13:00:52 +03:00
struct unixuid_private * priv = ntvfs - > private_data ;
2004-10-03 10:46:29 +04:00
int i ;
NTSTATUS status ;
2008-03-28 13:00:52 +03:00
struct id_mapping * ids ;
struct composite_context * ctx ;
2005-01-27 10:08:20 +03:00
* sec = talloc ( req , struct unix_sec_ctx ) ;
2004-10-03 10:46:29 +04:00
2004-10-12 15:30:48 +04:00
/* we can't do unix security without a user and group */
if ( token - > num_sids < 2 ) {
return NT_STATUS_ACCESS_DENIED ;
}
2008-03-28 13:00:52 +03:00
ids = talloc_array ( req , struct id_mapping , token - > num_sids ) ;
NT_STATUS_HAVE_NO_MEMORY ( ids ) ;
2004-10-03 10:46:29 +04:00
2008-03-28 13:00:52 +03:00
ids [ 0 ] . unixid = NULL ;
ids [ 0 ] . sid = token - > user_sid ;
ids [ 0 ] . status = NT_STATUS_NONE_MAPPED ;
ids [ 1 ] . unixid = NULL ;
ids [ 1 ] . sid = token - > group_sid ;
ids [ 1 ] . status = NT_STATUS_NONE_MAPPED ;
2004-10-03 10:46:29 +04:00
2004-10-12 15:30:48 +04:00
( * sec ) - > ngroups = token - > num_sids - 2 ;
2005-01-27 10:08:20 +03:00
( * sec ) - > groups = talloc_array ( * sec , gid_t , ( * sec ) - > ngroups ) ;
2008-03-28 13:00:52 +03:00
NT_STATUS_HAVE_NO_MEMORY ( ( * sec ) - > groups ) ;
for ( i = 0 ; i < ( * sec ) - > ngroups ; i + + ) {
ids [ i + 2 ] . unixid = NULL ;
ids [ i + 2 ] . sid = token - > sids [ i + 2 ] ;
ids [ i + 2 ] . status = NT_STATUS_NONE_MAPPED ;
}
ctx = wbc_sids_to_xids_send ( priv - > wbc_ctx , ids , token - > num_sids , ids ) ;
NT_STATUS_HAVE_NO_MEMORY ( ctx ) ;
status = wbc_sids_to_xids_recv ( ctx , & ids ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
if ( ids [ 0 ] . unixid - > type = = ID_TYPE_BOTH | |
ids [ 0 ] . unixid - > type = = ID_TYPE_UID ) {
( * sec ) - > uid = ids [ 0 ] . unixid - > id ;
} else {
return NT_STATUS_INVALID_SID ;
}
if ( ids [ 1 ] . unixid - > type = = ID_TYPE_BOTH | |
ids [ 1 ] . unixid - > type = = ID_TYPE_GID ) {
( * sec ) - > gid = ids [ 1 ] . unixid - > id ;
} else {
return NT_STATUS_INVALID_SID ;
2004-10-03 10:46:29 +04:00
}
for ( i = 0 ; i < ( * sec ) - > ngroups ; i + + ) {
2008-03-28 13:00:52 +03:00
if ( ids [ i + 2 ] . unixid - > type = = ID_TYPE_BOTH | |
ids [ i + 2 ] . unixid - > type = = ID_TYPE_GID ) {
( * sec ) - > groups [ i ] = ids [ i + 2 ] . unixid - > id ;
} else {
return NT_STATUS_INVALID_SID ;
2004-10-03 10:46:29 +04:00
}
}
return NT_STATUS_OK ;
}
/*
setup our unix security context according to the session authentication info
*/
static NTSTATUS unixuid_setup_security ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , struct unix_sec_ctx * * sec )
2004-10-03 10:46:29 +04:00
{
2004-10-12 09:59:56 +04:00
struct unixuid_private * private = ntvfs - > private_data ;
2005-08-16 14:57:21 +04:00
struct security_token * token ;
2004-10-03 10:46:29 +04:00
struct unix_sec_ctx * newsec ;
NTSTATUS status ;
2006-03-16 21:54:19 +03:00
if ( req - > session_info = = NULL ) {
2004-11-18 06:31:35 +03:00
return NT_STATUS_ACCESS_DENIED ;
}
2006-03-16 21:54:19 +03:00
token = req - > session_info - > security_token ;
2005-08-16 14:57:21 +04:00
2007-02-07 10:06:28 +03:00
* sec = save_unix_security ( ntvfs ) ;
2004-10-03 10:46:29 +04:00
if ( * sec = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2006-03-16 21:54:19 +03:00
if ( token = = private - > last_token ) {
2004-10-12 09:59:56 +04:00
newsec = private - > last_sec_ctx ;
} else {
2004-10-12 15:30:48 +04:00
status = nt_token_to_unix_security ( ntvfs , req , token , & newsec ) ;
2004-10-12 09:59:56 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-02-07 10:06:28 +03:00
talloc_free ( * sec ) ;
2004-10-12 09:59:56 +04:00
return status ;
}
if ( private - > last_sec_ctx ) {
talloc_free ( private - > last_sec_ctx ) ;
}
private - > last_sec_ctx = newsec ;
2006-03-16 21:54:19 +03:00
private - > last_token = token ;
2004-10-12 09:59:56 +04:00
talloc_steal ( private , newsec ) ;
2004-10-03 10:46:29 +04:00
}
status = set_unix_security ( newsec ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-02-07 10:06:28 +03:00
talloc_free ( * sec ) ;
2004-10-03 10:46:29 +04:00
return status ;
}
return NT_STATUS_OK ;
}
/*
this pass through macro operates on request contexts
*/
# define PASS_THRU_REQ(ntvfs, req, op, args) do { \
NTSTATUS status2 ; \
struct unix_sec_ctx * sec ; \
status = unixuid_setup_security ( ntvfs , req , & sec ) ; \
2006-05-23 07:53:23 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ; \
status = ntvfs_next_ # # op args ; \
2004-10-03 10:46:29 +04:00
status2 = set_unix_security ( sec ) ; \
2007-02-07 10:06:28 +03:00
talloc_free ( sec ) ; \
2004-10-03 10:46:29 +04:00
if ( ! NT_STATUS_IS_OK ( status2 ) ) smb_panic ( " Unable to reset security context " ) ; \
} while ( 0 )
/*
connect to a share - used when a tree_connect operation comes in .
*/
static NTSTATUS unixuid_connect ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , const char * sharename )
2004-10-03 10:46:29 +04:00
{
struct unixuid_private * private ;
NTSTATUS status ;
2006-01-25 15:19:49 +03:00
private = talloc ( ntvfs , struct unixuid_private ) ;
2004-10-03 10:46:29 +04:00
if ( ! private ) {
return NT_STATUS_NO_MEMORY ;
}
2008-03-28 13:00:52 +03:00
private - > wbc_ctx = wbc_init ( private , ntvfs - > ctx - > msg_ctx ,
ntvfs - > ctx - > event_ctx ) ;
if ( private - > wbc_ctx = = NULL ) {
talloc_free ( private ) ;
return NT_STATUS_INTERNAL_ERROR ;
2004-10-03 10:46:29 +04:00
}
ntvfs - > private_data = private ;
2004-10-12 09:59:56 +04:00
private - > last_sec_ctx = NULL ;
2004-10-12 15:30:48 +04:00
private - > last_token = NULL ;
2004-10-03 10:46:29 +04:00
2004-10-18 02:03:33 +04:00
/* we don't use PASS_THRU_REQ here, as the connect operation runs with
root privileges . This allows the backends to setup any database
links they might need during the connect . */
status = ntvfs_next_connect ( ntvfs , req , sharename ) ;
2004-10-03 10:46:29 +04:00
return status ;
}
/*
disconnect from a share
*/
2006-03-10 17:31:17 +03:00
static NTSTATUS unixuid_disconnect ( struct ntvfs_module_context * ntvfs )
2004-10-03 10:46:29 +04:00
{
struct unixuid_private * private = ntvfs - > private_data ;
NTSTATUS status ;
talloc_free ( private ) ;
2006-01-25 15:19:49 +03:00
ntvfs - > private_data = NULL ;
2004-10-03 10:46:29 +04:00
2006-03-10 17:31:17 +03:00
status = ntvfs_next_disconnect ( ntvfs ) ;
2004-10-03 10:46:29 +04:00
return status ;
}
/*
delete a file
*/
static NTSTATUS unixuid_unlink ( struct ntvfs_module_context * ntvfs ,
2006-03-10 23:49:20 +03:00
struct ntvfs_request * req ,
union smb_unlink * unl )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , unlink , ( ntvfs , req , unl ) ) ;
return status ;
}
/*
ioctl interface
*/
static NTSTATUS unixuid_ioctl ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_ioctl * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , ioctl , ( ntvfs , req , io ) ) ;
return status ;
}
/*
check if a directory exists
*/
static NTSTATUS unixuid_chkpath ( struct ntvfs_module_context * ntvfs ,
2006-03-10 23:49:20 +03:00
struct ntvfs_request * req ,
union smb_chkpath * cp )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , chkpath , ( ntvfs , req , cp ) ) ;
return status ;
}
/*
return info on a pathname
*/
static NTSTATUS unixuid_qpathinfo ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_fileinfo * info )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , qpathinfo , ( ntvfs , req , info ) ) ;
return status ;
}
/*
query info on a open file
*/
static NTSTATUS unixuid_qfileinfo ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_fileinfo * info )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , qfileinfo , ( ntvfs , req , info ) ) ;
return status ;
}
/*
set info on a pathname
*/
static NTSTATUS unixuid_setpathinfo ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_setfileinfo * st )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , setpathinfo , ( ntvfs , req , st ) ) ;
return status ;
}
/*
open a file
*/
2006-03-10 17:31:17 +03:00
static NTSTATUS unixuid_open ( struct ntvfs_module_context * ntvfs ,
struct ntvfs_request * req , union smb_open * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
2006-03-10 17:31:17 +03:00
PASS_THRU_REQ ( ntvfs , req , open , ( ntvfs , req , io ) ) ;
2004-10-03 10:46:29 +04:00
return status ;
}
/*
create a directory
*/
static NTSTATUS unixuid_mkdir ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_mkdir * md )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , mkdir , ( ntvfs , req , md ) ) ;
return status ;
}
/*
remove a directory
*/
static NTSTATUS unixuid_rmdir ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , struct smb_rmdir * rd )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , rmdir , ( ntvfs , req , rd ) ) ;
return status ;
}
/*
rename a set of files
*/
static NTSTATUS unixuid_rename ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_rename * ren )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , rename , ( ntvfs , req , ren ) ) ;
return status ;
}
/*
copy a set of files
*/
static NTSTATUS unixuid_copy ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , struct smb_copy * cp )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , copy , ( ntvfs , req , cp ) ) ;
return status ;
}
/*
read from a file
*/
static NTSTATUS unixuid_read ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_read * rd )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , read , ( ntvfs , req , rd ) ) ;
return status ;
}
/*
write to a file
*/
static NTSTATUS unixuid_write ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_write * wr )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , write , ( ntvfs , req , wr ) ) ;
return status ;
}
/*
seek in a file
*/
static NTSTATUS unixuid_seek ( struct ntvfs_module_context * ntvfs ,
2006-03-10 23:49:20 +03:00
struct ntvfs_request * req ,
union smb_seek * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , seek , ( ntvfs , req , io ) ) ;
return status ;
}
/*
flush a file
*/
static NTSTATUS unixuid_flush ( struct ntvfs_module_context * ntvfs ,
2006-03-10 23:49:20 +03:00
struct ntvfs_request * req ,
union smb_flush * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , flush , ( ntvfs , req , io ) ) ;
return status ;
}
/*
close a file
*/
static NTSTATUS unixuid_close ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_close * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , close , ( ntvfs , req , io ) ) ;
return status ;
}
/*
exit - closing files
*/
static NTSTATUS unixuid_exit ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , exit , ( ntvfs , req ) ) ;
return status ;
}
/*
logoff - closing files
*/
static NTSTATUS unixuid_logoff ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req )
2004-10-03 10:46:29 +04:00
{
2004-10-12 09:59:56 +04:00
struct unixuid_private * private = ntvfs - > private_data ;
2004-10-03 10:46:29 +04:00
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , logoff , ( ntvfs , req ) ) ;
2004-10-12 15:30:48 +04:00
private - > last_token = NULL ;
2004-10-12 09:59:56 +04:00
2004-10-03 10:46:29 +04:00
return status ;
}
2004-10-18 17:27:22 +04:00
/*
async setup
*/
static NTSTATUS unixuid_async_setup ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req ,
2004-10-18 17:27:22 +04:00
void * private )
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , async_setup , ( ntvfs , req , private ) ) ;
return status ;
}
2004-11-04 14:28:38 +03:00
/*
cancel an async request
*/
static NTSTATUS unixuid_cancel ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req )
2004-11-04 14:28:38 +03:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , cancel , ( ntvfs , req ) ) ;
return status ;
}
2006-03-21 14:40:38 +03:00
/*
change notify
*/
static NTSTATUS unixuid_notify ( struct ntvfs_module_context * ntvfs ,
2006-07-12 18:25:50 +04:00
struct ntvfs_request * req , union smb_notify * info )
2006-03-21 14:40:38 +03:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , notify , ( ntvfs , req , info ) ) ;
return status ;
}
2004-10-03 10:46:29 +04:00
/*
lock a byte range
*/
static NTSTATUS unixuid_lock ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_lock * lck )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , lock , ( ntvfs , req , lck ) ) ;
return status ;
}
/*
set info on a open file
*/
static NTSTATUS unixuid_setfileinfo ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req ,
2004-10-03 10:46:29 +04:00
union smb_setfileinfo * info )
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , setfileinfo , ( ntvfs , req , info ) ) ;
return status ;
}
/*
return filesystem space info
*/
static NTSTATUS unixuid_fsinfo ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_fsinfo * fs )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , fsinfo , ( ntvfs , req , fs ) ) ;
return status ;
}
/*
return print queue info
*/
static NTSTATUS unixuid_lpq ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_lpq * lpq )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , lpq , ( ntvfs , req , lpq ) ) ;
return status ;
}
/*
list files in a directory matching a wildcard pattern
*/
static NTSTATUS unixuid_search_first ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_search_first * io ,
2004-10-03 10:46:29 +04:00
void * search_private ,
2007-10-07 02:28:14 +04:00
bool ( * callback ) ( void * , const union smb_search_data * ) )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , search_first , ( ntvfs , req , io , search_private , callback ) ) ;
return status ;
}
/* continue a search */
static NTSTATUS unixuid_search_next ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_search_next * io ,
2004-10-03 10:46:29 +04:00
void * search_private ,
2007-10-07 02:28:14 +04:00
bool ( * callback ) ( void * , const union smb_search_data * ) )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , search_next , ( ntvfs , req , io , search_private , callback ) ) ;
return status ;
}
/* close a search */
static NTSTATUS unixuid_search_close ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , union smb_search_close * io )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , search_close , ( ntvfs , req , io ) ) ;
return status ;
}
/* SMBtrans - not used on file shares */
static NTSTATUS unixuid_trans ( struct ntvfs_module_context * ntvfs ,
2006-03-10 17:31:17 +03:00
struct ntvfs_request * req , struct smb_trans2 * trans2 )
2004-10-03 10:46:29 +04:00
{
NTSTATUS status ;
PASS_THRU_REQ ( ntvfs , req , trans , ( ntvfs , req , trans2 ) ) ;
return status ;
}
/*
initialise the unixuid backend , registering ourselves with the ntvfs subsystem
*/
NTSTATUS ntvfs_unixuid_init ( void )
{
NTSTATUS ret ;
struct ntvfs_ops ops ;
2006-04-24 05:26:31 +04:00
NTVFS_CURRENT_CRITICAL_SIZES ( vers ) ;
2004-10-03 10:46:29 +04:00
ZERO_STRUCT ( ops ) ;
/* fill in all the operations */
ops . connect = unixuid_connect ;
ops . disconnect = unixuid_disconnect ;
ops . unlink = unixuid_unlink ;
ops . chkpath = unixuid_chkpath ;
ops . qpathinfo = unixuid_qpathinfo ;
ops . setpathinfo = unixuid_setpathinfo ;
2006-03-10 17:31:17 +03:00
ops . open = unixuid_open ;
2004-10-03 10:46:29 +04:00
ops . mkdir = unixuid_mkdir ;
ops . rmdir = unixuid_rmdir ;
ops . rename = unixuid_rename ;
ops . copy = unixuid_copy ;
ops . ioctl = unixuid_ioctl ;
ops . read = unixuid_read ;
ops . write = unixuid_write ;
ops . seek = unixuid_seek ;
ops . flush = unixuid_flush ;
ops . close = unixuid_close ;
ops . exit = unixuid_exit ;
ops . lock = unixuid_lock ;
ops . setfileinfo = unixuid_setfileinfo ;
ops . qfileinfo = unixuid_qfileinfo ;
ops . fsinfo = unixuid_fsinfo ;
ops . lpq = unixuid_lpq ;
ops . search_first = unixuid_search_first ;
ops . search_next = unixuid_search_next ;
ops . search_close = unixuid_search_close ;
ops . trans = unixuid_trans ;
ops . logoff = unixuid_logoff ;
2004-10-18 17:27:22 +04:00
ops . async_setup = unixuid_async_setup ;
2004-11-04 14:28:38 +03:00
ops . cancel = unixuid_cancel ;
2006-03-21 14:40:38 +03:00
ops . notify = unixuid_notify ;
2004-10-03 10:46:29 +04:00
2004-10-03 11:31:32 +04:00
ops . name = " unixuid " ;
/* we register under all 3 backend types, as we are not type specific */
ops . type = NTVFS_DISK ;
2006-04-24 05:26:31 +04:00
ret = ntvfs_register ( & ops , & vers ) ;
2004-10-03 11:31:32 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) goto failed ;
2004-10-03 10:46:29 +04:00
2004-10-03 11:31:32 +04:00
ops . type = NTVFS_PRINT ;
2006-04-24 05:26:31 +04:00
ret = ntvfs_register ( & ops , & vers ) ;
2004-10-03 11:31:32 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) goto failed ;
ops . type = NTVFS_IPC ;
2006-04-24 05:26:31 +04:00
ret = ntvfs_register ( & ops , & vers ) ;
2004-10-03 11:31:32 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) goto failed ;
2004-10-03 10:46:29 +04:00
2004-10-03 11:31:32 +04:00
failed :
2004-10-03 10:46:29 +04:00
return ret ;
}