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"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2010-05-10 02:07:10 +04:00
# include "../libgpo/gpo.h"
# include "libgpo/gpo_proto.h"
2020-08-07 21:17:34 +03:00
# include "lib/util/string_wrappers.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
} ;
2020-10-19 11:09:23 +03:00
static NTSTATUS gpo_sync_func ( struct file_info * info ,
2007-08-14 19:17:50 +04:00
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 ;
2018-04-11 21:40:18 +03:00
result = cli_open ( cli , nt_path , O_RDONLY , DENY_NONE , & fnum ) ;
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-09-29 20:36:03 +04:00
goto out ;
}
2012-03-28 05:48:00 +04:00
if ( ( fd = open ( unix_path , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ) = = - 1 ) {
2006-09-29 20:36:03 +04:00
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 ) {
2011-07-22 14:44:56 +04:00
size_t n = 0 ;
2006-09-29 20:36:03 +04:00
2011-07-22 14:44:56 +04:00
result = cli_read ( cli , fnum , data , nread , read_size , & n ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
goto out ;
}
2006-09-29 20:36:03 +04:00
2011-07-22 14:44:56 +04:00
if ( n = = 0 )
2006-09-29 20:36:03 +04:00
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 ) {
2010-10-29 22:56:51 +04:00
return map_nt_error_from_unix ( errno ) ;
2006-09-29 20:36:03 +04:00
}
return NT_STATUS_OK ;
}
/****************************************************************
sync files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
static NTSTATUS gpo_sync_files ( struct sync_context * ctx )
2006-09-29 20:36:03 +04:00
{
2010-08-02 21:22:22 +04:00
NTSTATUS status ;
2006-09-29 20:36:03 +04:00
DEBUG ( 3 , ( " calling cli_list with mask: %s \n " , ctx - > mask ) ) ;
2010-08-02 21:22:22 +04:00
status = cli_list ( ctx - > cli , ctx - > mask , ctx - > attribute , gpo_sync_func ,
ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " listing [%s] failed with error: %s \n " ,
ctx - > mask , nt_errstr ( status ) ) ) ;
2010-10-29 22:56:51 +04:00
return status ;
2006-09-29 20:36:03 +04:00
}
2010-10-29 22:56:51 +04:00
return status ;
2006-09-29 20:36:03 +04:00
}
/****************************************************************
syncronisation call back
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-10-19 11:09:23 +03:00
static NTSTATUS gpo_sync_func ( struct file_info * info ,
2006-09-29 20:36:03 +04:00
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 , " .. " ) ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2006-09-29 20:36:03 +04:00
}
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 ) ) ;
2020-06-03 20:41:27 +03:00
if ( info - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2006-09-29 20:36:03 +04:00
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 ) ) ) ;
2010-10-29 22:56:51 +04:00
return 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 " ) ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-11-16 05:27:26 +03:00
}
2010-10-29 22:56:51 +04:00
result = gpo_sync_files ( ctx ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-09-29 20:36:03 +04:00
DEBUG ( 0 , ( " could not sync files \n " ) ) ;
2010-10-29 22:56:51 +04:00
return result ;
2006-09-29 20:36:03 +04:00
}
ctx - > remote_path = old_nt_dir ;
ctx - > local_path = old_unix_dir ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2006-09-29 20:36:03 +04:00
}
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
}
2010-10-29 22:56:51 +04:00
return result ;
2006-09-29 20:36:03 +04:00
}
/****************************************************************
2019-10-26 03:41:09 +03:00
list a remote directory and download recursively
2006-09-29 20:36:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
2011-05-06 00:42:05 +04:00
ctx . remote_path = discard_const_p ( char , nt_path ) ;
ctx . local_path = discard_const_p ( char , local_path ) ;
2011-04-29 05:57:02 +04:00
ctx . attribute = ( FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY ) ;
2006-09-29 20:36:03 +04:00
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
2010-10-29 22:56:51 +04:00
return gpo_sync_files ( & ctx ) ;
2006-09-29 20:36:03 +04:00
}