2008-05-08 13:23:38 +04:00
/*
Samba Unix / Linux SMB client library
2001-12-11 08:21:50 +03:00
net time command
Copyright ( C ) 2001 Andrew Tridgell ( tridge @ samba . org )
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
2001-12-11 08:21:50 +03:00
( at your option ) any later version .
2008-05-08 13:23:38 +04:00
2001-12-11 08:21:50 +03: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 .
2008-05-08 13:23:38 +04:00
2001-12-11 08:21:50 +03:00
You should have received a copy of the GNU General Public License
2008-05-10 01:22:12 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2001-12-11 08:21:50 +03:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2011-03-23 16:18:59 +03:00
# include "libsmb/nmblib.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2012-05-19 20:50:27 +04:00
# include "../libcli/smb/smbXcli_base.h"
2001-12-11 08:21:50 +03:00
/*
return the time on a server . This does not require any authentication
*/
2011-07-22 13:56:14 +04:00
static time_t cli_servertime ( const char * host ,
const struct sockaddr_storage * dest_ss ,
int * zone )
2001-12-11 08:21:50 +03:00
{
time_t ret = 0 ;
struct cli_state * cli = NULL ;
2007-06-20 21:38:42 +04:00
NTSTATUS status ;
2001-12-11 08:21:50 +03:00
2011-07-22 13:56:14 +04:00
status = cli_connect_nb ( host , dest_ss , 0 , 0x20 , lp_netbios_name ( ) ,
2011-11-02 21:41:50 +04:00
SMB_SIGNING_DEFAULT , 0 , & cli ) ;
2007-06-20 21:38:42 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-11 10:38:42 +04:00
fprintf ( stderr , _ ( " Can't contact server %s. Error %s \n " ) ,
host , nt_errstr ( status ) ) ;
2001-12-11 08:47:26 +03:00
goto done ;
}
2001-12-11 08:21:50 +03:00
2012-05-20 19:54:29 +04:00
status = smbXcli_negprot ( cli - > conn , cli - > timeout , PROTOCOL_CORE ,
PROTOCOL_NT1 ) ;
2008-09-11 20:57:49 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-11 10:38:42 +04:00
fprintf ( stderr , _ ( " Protocol negotiation failed: %s \n " ) ,
2008-09-11 20:57:49 +04:00
nt_errstr ( status ) ) ;
2001-12-11 08:47:26 +03:00
goto done ;
}
2001-12-11 08:21:50 +03:00
2011-09-13 23:48:58 +04:00
ret = cli_state_server_time ( cli ) ;
2012-05-19 20:50:27 +04:00
if ( zone ) * zone = smb1cli_conn_server_time_zone ( cli - > conn ) ;
2001-12-11 08:21:50 +03:00
done :
2006-07-11 22:01:26 +04:00
if ( cli ) {
cli_shutdown ( cli ) ;
}
2001-12-11 08:21:50 +03:00
return ret ;
}
/* find the servers time on the opt_host host */
2008-05-10 01:22:12 +04:00
static time_t nettime ( struct net_context * c , int * zone )
2001-12-11 08:21:50 +03:00
{
2008-05-10 01:22:12 +04:00
return cli_servertime ( c - > opt_host ,
c - > opt_have_ip ? & c - > opt_dest_ip : NULL , zone ) ;
2001-12-11 08:21:50 +03:00
}
2001-12-14 04:15:14 +03:00
/* return a time as a string ready to be passed to /bin/date */
2006-06-15 01:36:49 +04:00
static const char * systime ( time_t t )
2001-12-11 08:21:50 +03:00
{
struct tm * tm ;
2001-12-14 04:15:14 +03:00
tm = localtime ( & t ) ;
2006-06-15 01:36:49 +04:00
if ( ! tm ) {
return " unknown " ;
}
2007-10-25 01:16:54 +04:00
2009-07-25 20:57:46 +04:00
return talloc_asprintf ( talloc_tos ( ) , " %02d%02d%02d%02d%04d.%02d " ,
tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_hour ,
tm - > tm_min , tm - > tm_year + 1900 , tm - > tm_sec ) ;
2001-12-11 08:21:50 +03:00
}
2008-05-10 01:22:12 +04:00
int net_time_usage ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2009-08-11 10:38:42 +04:00
d_printf ( _ (
2014-07-30 01:12:31 +04:00
" net time \n \t displays time on a server (-S server) \n \n "
" net time system \n \t displays time on a server (-S server) in a format ready for /bin/date \n \n "
" net time set \n \t runs /bin/date with the time from the server (-S server) \n \n "
" net time zone \n \t displays the timezone in hours from GMT on the remote server (-S server) \n \n "
2009-08-11 10:38:42 +04:00
" \n " ) ) ;
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2001-12-11 08:21:50 +03:00
return - 1 ;
}
2010-12-14 15:28:49 +03:00
/* try to set the system clock */
2008-05-10 01:22:12 +04:00
static int net_time_set ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2010-12-14 15:28:49 +03:00
struct timeval tv ;
2006-01-18 00:22:00 +03:00
int result ;
2001-12-11 08:21:50 +03:00
2014-07-30 01:12:31 +04:00
if ( c - > display_usage | | c - > opt_host = = NULL ) {
d_printf ( " %s \n "
" net time set \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Set local time to that of remote time "
" server (-S server) " ) ) ;
return 0 ;
}
2010-12-14 15:28:49 +03:00
tv . tv_sec = nettime ( c , NULL ) ;
tv . tv_usec = 0 ;
if ( tv . tv_sec = = 0 ) return - 1 ;
2010-12-17 03:00:49 +03:00
result = settimeofday ( & tv , NULL ) ;
2007-10-25 01:16:54 +04:00
2006-01-18 00:22:00 +03:00
if ( result )
2010-12-14 15:28:49 +03:00
d_fprintf ( stderr , _ ( " setting system clock failed. Error was (%s) \n " ) ,
strerror ( errno ) ) ;
2001-12-11 08:21:50 +03:00
2006-01-18 00:22:00 +03:00
return result ;
2001-12-11 08:21:50 +03:00
}
/* display the time on a remote box in a format ready for /bin/date */
2008-05-10 01:22:12 +04:00
static int net_time_system ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2008-05-19 18:19:37 +04:00
time_t t ;
2014-07-30 01:12:31 +04:00
if ( c - > display_usage | | c - > opt_host = = NULL ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time system \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
2014-07-30 01:12:31 +04:00
_ ( " Output remote time server (-S server) "
" time in a format ready for /bin/date " ) ) ;
2008-05-19 18:19:37 +04:00
return 0 ;
}
2001-12-11 08:21:50 +03:00
2008-05-19 18:19:37 +04:00
t = nettime ( c , NULL ) ;
2001-12-11 08:47:26 +03:00
if ( t = = 0 ) return - 1 ;
2001-12-11 08:21:50 +03:00
printf ( " %s \n " , systime ( t ) ) ;
return 0 ;
}
2008-06-06 00:14:38 +04:00
/* display the remote time server's offset to UTC */
2008-05-10 01:22:12 +04:00
static int net_time_zone ( struct net_context * c , int argc , const char * * argv )
2001-12-12 12:37:17 +03:00
{
int zone = 0 ;
2002-01-05 02:02:14 +03:00
int hours , mins ;
char zsign ;
2001-12-12 12:37:17 +03:00
time_t t ;
2014-07-30 01:12:31 +04:00
if ( c - > display_usage | | c - > opt_host = = NULL ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time zone \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
2014-07-30 01:12:31 +04:00
_ ( " Display the remote time server's (-S server) "
" offset to UTC " ) ) ;
2008-05-19 18:19:37 +04:00
return 0 ;
}
2008-05-10 01:22:12 +04:00
t = nettime ( c , & zone ) ;
2001-12-12 12:37:17 +03:00
if ( t = = 0 ) return - 1 ;
2002-01-05 02:02:14 +03:00
zsign = ( zone > 0 ) ? ' - ' : ' + ' ;
if ( zone < 0 ) zone = - zone ;
2001-12-12 12:37:17 +03:00
zone / = 60 ;
2002-01-05 02:02:14 +03:00
hours = zone / 60 ;
mins = zone % 60 ;
2001-12-12 12:37:17 +03:00
2002-01-05 02:02:14 +03:00
printf ( " %c%02d%02d \n " , zsign , hours , mins ) ;
2001-12-12 12:37:17 +03:00
return 0 ;
}
2001-12-11 08:21:50 +03:00
/* display or set the time on a host */
2008-05-10 01:22:12 +04:00
int net_time ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
time_t t ;
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-19 18:19:37 +04:00
{
" system " ,
net_time_system ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Display time ready for /bin/date " ) ,
N_ ( " net time system \n "
" Display time ready for /bin/date " )
2008-05-19 18:19:37 +04:00
} ,
{
" set " ,
net_time_set ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Set the system time from time server " ) ,
N_ ( " net time set \n "
" Set the system time from time server " )
2008-05-19 18:19:37 +04:00
} ,
{
" zone " ,
net_time_zone ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Display timezone offset from UTC " ) ,
N_ ( " net time zone \n "
" Display timezone offset from UTC " )
2008-05-19 18:19:37 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2001-12-11 08:21:50 +03:00
} ;
2008-05-19 02:33:02 +04:00
if ( argc ! = 0 ) {
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net time " , func ) ;
2008-05-19 18:19:37 +04:00
}
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Display the remote time server's time " ) ) ;
2008-05-19 18:19:37 +04:00
net_display_usage_from_functable ( func ) ;
return 0 ;
2008-05-19 02:33:02 +04:00
}
2015-01-13 19:04:26 +03:00
if ( c - > opt_host = = NULL & & ! c - > opt_have_ip ) {
bool ok ;
ok = find_master_ip ( c - > opt_target_workgroup , & c - > opt_dest_ip ) ;
if ( ! ok ) {
d_fprintf ( stderr ,
_ ( " Could not locate a time server. "
" Try specifying a target host. \n " ) ) ;
net_time_usage ( c , argc , argv ) ;
return - 1 ;
}
c - > opt_have_ip = true ;
2001-12-11 08:21:50 +03:00
}
/* default - print the time */
2015-01-13 19:04:26 +03:00
t = cli_servertime ( c - > opt_host ,
c - > opt_have_ip ? & c - > opt_dest_ip : NULL ,
2008-05-10 01:22:12 +04:00
NULL ) ;
2001-12-11 08:47:26 +03:00
if ( t = = 0 ) return - 1 ;
2001-12-11 08:21:50 +03:00
d_printf ( " %s " , ctime ( & t ) ) ;
return 0 ;
}