2007-08-14 19:17:50 +04:00
/*
2006-09-29 20:36:03 +04:00
* Unix SMB / CIFS implementation .
* Group Policy Object Support
* Copyright ( C ) Guenther Deschner 2006
2007-08-14 19:17:50 +04:00
*
2006-09-29 20:36: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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2006-09-29 20:36:03 +04:00
* ( at your option ) any later version .
2007-08-14 19:17:50 +04:00
*
2006-09-29 20:36:03 +04:00
* 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 .
2007-08-14 19:17:50 +04:00
*
2006-09-29 20:36:03 +04:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-09-29 20:36:03 +04:00
*/
# include "includes.h"
2010-05-10 02:07:10 +04:00
# include "../libgpo/gpo.h"
# include "libgpo/gpo_proto.h"
2006-09-29 20:36:03 +04:00
struct sync_context {
TALLOC_CTX * mem_ctx ;
struct cli_state * cli ;
char * remote_path ;
char * local_path ;
2007-11-16 05:27:26 +03:00
char * mask ;
2007-08-14 19:17:50 +04:00
uint16_t attribute ;
2006-09-29 20:36:03 +04:00
} ;
static void gpo_sync_func ( const char * mnt ,
2007-08-14 19:17:50 +04:00
file_info * info ,
const char * mask ,
void * state ) ;
2006-09-29 20:36:03 +04:00
NTSTATUS gpo_copy_file ( TALLOC_CTX * mem_ctx ,
struct cli_state * cli ,
const char * nt_path ,
const char * unix_path )
{
NTSTATUS result ;
2009-05-01 02:26:43 +04:00
uint16_t fnum ;
2009-05-04 01:05:11 +04:00
int fd = - 1 ;
2006-09-29 20:36:03 +04:00
char * data = NULL ;
static int io_bufsize = 64512 ;
int read_size = io_bufsize ;
off_t nread = 0 ;
2009-05-01 02:26:43 +04:00
result = cli_open ( cli , nt_path , O_RDONLY , DENY_NONE , & fnum ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-09-29 20:36:03 +04:00
goto out ;
}
if ( ( fd = sys_open ( unix_path , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ) = = - 1 ) {
result = map_nt_error_from_unix ( errno ) ;
goto out ;
}
2007-08-14 19:17:50 +04:00
2006-09-29 20:36:03 +04:00
if ( ( data = ( char * ) SMB_MALLOC ( read_size ) ) = = NULL ) {
result = NT_STATUS_NO_MEMORY ;
goto out ;
}
while ( 1 ) {
2007-08-29 18:08:29 +04:00
int n = cli_read ( cli , fnum , data , nread , read_size ) ;
2006-09-29 20:36:03 +04:00
if ( n < = 0 )
break ;
if ( write ( fd , data , n ) ! = n ) {
break ;
}
nread + = n ;
}
result = NT_STATUS_OK ;
out :
SAFE_FREE ( data ) ;
if ( fnum ) {
cli_close ( cli , fnum ) ;
}
2009-05-04 01:05:11 +04:00
if ( fd ! = - 1 ) {
2006-09-29 20:36:03 +04:00
close ( fd ) ;
}
return result ;
}
/****************************************************************
copy dir
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS gpo_copy_dir ( const char * unix_path )
{
if ( ( mkdir ( unix_path , 0644 ) ) < 0 & & errno ! = EEXIST ) {
return NT_STATUS_ACCESS_DENIED ;
}
return NT_STATUS_OK ;
}
/****************************************************************
sync files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool gpo_sync_files ( struct sync_context * ctx )
2006-09-29 20:36:03 +04:00
{
DEBUG ( 3 , ( " calling cli_list with mask: %s \n " , ctx - > mask ) ) ;
2007-08-14 19:17:50 +04:00
if ( cli_list ( ctx - > cli ,
ctx - > mask ,
ctx - > attribute ,
gpo_sync_func ,
ctx ) = = - 1 ) {
DEBUG ( 1 , ( " listing [%s] failed with error: %s \n " ,
2006-09-29 20:36:03 +04:00
ctx - > mask , cli_errstr ( ctx - > cli ) ) ) ;
2008-02-29 16:51:37 +03:00
return false ;
2006-09-29 20:36:03 +04:00
}
2008-02-29 16:51:37 +03:00
return true ;
2006-09-29 20:36:03 +04:00
}
/****************************************************************
syncronisation call back
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void gpo_sync_func ( const char * mnt ,
file_info * info ,
const char * mask ,
void * state )
{
NTSTATUS result ;
struct sync_context * ctx ;
fstring nt_filename , unix_filename ;
fstring nt_dir , unix_dir ;
char * old_nt_dir , * old_unix_dir ;
ctx = ( struct sync_context * ) state ;
if ( strequal ( info - > name , " . " ) | | strequal ( info - > name , " .. " ) ) {
return ;
}
2007-08-14 19:17:50 +04:00
DEBUG ( 5 , ( " gpo_sync_func: got mask: [%s], name: [%s] \n " ,
2006-09-29 20:36:03 +04:00
mask , info - > name ) ) ;
if ( info - > mode & aDIR ) {
DEBUG ( 3 , ( " got dir: [%s] \n " , info - > name ) ) ;
fstrcpy ( nt_dir , ctx - > remote_path ) ;
fstrcat ( nt_dir , " \\ " ) ;
fstrcat ( nt_dir , info - > name ) ;
fstrcpy ( unix_dir , ctx - > local_path ) ;
fstrcat ( unix_dir , " / " ) ;
fstrcat ( unix_dir , info - > name ) ;
result = gpo_copy_dir ( unix_dir ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2007-08-14 19:17:50 +04:00
DEBUG ( 1 , ( " failed to copy dir: %s \n " ,
nt_errstr ( result ) ) ) ;
2006-09-29 20:36:03 +04:00
}
old_nt_dir = ctx - > remote_path ;
2008-01-08 14:25:47 +03:00
ctx - > remote_path = talloc_strdup ( ctx - > mem_ctx , nt_dir ) ;
2007-08-14 19:17:50 +04:00
2006-09-29 20:36:03 +04:00
old_unix_dir = ctx - > local_path ;
ctx - > local_path = talloc_strdup ( ctx - > mem_ctx , unix_dir ) ;
2007-11-16 05:27:26 +03:00
ctx - > mask = talloc_asprintf ( ctx - > mem_ctx ,
" %s \\ * " ,
nt_dir ) ;
2008-01-08 14:25:47 +03:00
if ( ! ctx - > local_path | | ! ctx - > mask | | ! ctx - > remote_path ) {
2007-11-16 05:27:26 +03:00
DEBUG ( 0 , ( " gpo_sync_func: ENOMEM \n " ) ) ;
return ;
}
2006-09-29 20:36:03 +04:00
if ( ! gpo_sync_files ( ctx ) ) {
DEBUG ( 0 , ( " could not sync files \n " ) ) ;
}
ctx - > remote_path = old_nt_dir ;
ctx - > local_path = old_unix_dir ;
return ;
}
DEBUG ( 3 , ( " got file: [%s] \n " , info - > name ) ) ;
fstrcpy ( nt_filename , ctx - > remote_path ) ;
fstrcat ( nt_filename , " \\ " ) ;
fstrcat ( nt_filename , info - > name ) ;
fstrcpy ( unix_filename , ctx - > local_path ) ;
fstrcat ( unix_filename , " / " ) ;
fstrcat ( unix_filename , info - > name ) ;
2007-08-14 19:17:50 +04:00
result = gpo_copy_file ( ctx - > mem_ctx , ctx - > cli ,
nt_filename , unix_filename ) ;
2006-09-29 20:36:03 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2007-08-14 19:17:50 +04:00
DEBUG ( 1 , ( " failed to copy file: %s \n " ,
nt_errstr ( result ) ) ) ;
2006-09-29 20:36:03 +04:00
}
}
/****************************************************************
list a remote directory and download recursivly
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-14 19:17:50 +04:00
NTSTATUS gpo_sync_directories ( TALLOC_CTX * mem_ctx ,
struct cli_state * cli ,
const char * nt_path ,
2006-09-29 20:36:03 +04:00
const char * local_path )
{
struct sync_context ctx ;
ctx . mem_ctx = mem_ctx ;
ctx . cli = cli ;
ctx . remote_path = CONST_DISCARD ( char * , nt_path ) ;
ctx . local_path = CONST_DISCARD ( char * , local_path ) ;
ctx . attribute = ( aSYSTEM | aHIDDEN | aDIR ) ;
2007-11-16 05:27:26 +03:00
ctx . mask = talloc_asprintf ( mem_ctx ,
" %s \\ * " ,
nt_path ) ;
if ( ! ctx . mask ) {
return NT_STATUS_NO_MEMORY ;
}
2006-09-29 20:36:03 +04:00
if ( ! gpo_sync_files ( & ctx ) ) {
return NT_STATUS_NO_SUCH_FILE ;
}
return NT_STATUS_OK ;
}