1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21148c5f43SAlan Wright 22da6c28aaSamw /* 23148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24*b3700b07SGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25da6c28aaSamw */ 26da6c28aaSamw 27da6c28aaSamw /* 28da6c28aaSamw * Server Service (srvsvc) client side RPC library interface. The 29da6c28aaSamw * srvsvc interface allows a client to query a server for information 30da6c28aaSamw * on shares, sessions, connections and files on the server. Some 31da6c28aaSamw * functions are available via anonymous IPC while others require 32da6c28aaSamw * administrator privilege. Also, some functions return NT status 33da6c28aaSamw * values while others return Win32 errors codes. 34da6c28aaSamw */ 35da6c28aaSamw 36da6c28aaSamw #include <sys/errno.h> 37da6c28aaSamw #include <stdio.h> 38da6c28aaSamw #include <time.h> 39da6c28aaSamw #include <strings.h> 40da6c28aaSamw 41da6c28aaSamw #include <smbsrv/libsmb.h> 428d7e4166Sjose borrego #include <smbsrv/libmlsvc.h> 43da6c28aaSamw #include <smbsrv/smbinfo.h> 44da6c28aaSamw #include <smbsrv/ndl/srvsvc.ndl> 45da6c28aaSamw 46da6c28aaSamw /* 47da6c28aaSamw * Information level for NetShareGetInfo. 48da6c28aaSamw */ 49da6c28aaSamw DWORD srvsvc_info_level = 1; 50da6c28aaSamw 51da6c28aaSamw /* 528d7e4166Sjose borrego * Bind to the the SRVSVC. 53da6c28aaSamw * 5455bf511dSas * If username argument is NULL, an anonymous connection will be established. 5555bf511dSas * Otherwise, an authenticated connection will be established. 56da6c28aaSamw */ 5755bf511dSas static int 588d7e4166Sjose borrego srvsvc_open(char *server, char *domain, char *username, mlsvc_handle_t *handle) 59da6c28aaSamw { 60a0aa776eSAlan Wright smb_domainex_t di; 61da6c28aaSamw 62da6c28aaSamw if (server == NULL || domain == NULL) { 638d7e4166Sjose borrego if (!smb_domain_getinfo(&di)) 6455bf511dSas return (-1); 65da6c28aaSamw 66*b3700b07SGordon Ross server = di.d_dci.dc_name; 67a0aa776eSAlan Wright domain = di.d_primary.di_nbname; 6855bf511dSas } 69da6c28aaSamw 7055bf511dSas if (username == NULL) 7155bf511dSas username = MLSVC_ANON_USER; 72da6c28aaSamw 73*b3700b07SGordon Ross if (ndr_rpc_bind(handle, server, domain, username, "SRVSVC") != 0) 74da6c28aaSamw return (-1); 75da6c28aaSamw 768d7e4166Sjose borrego return (0); 77da6c28aaSamw } 78da6c28aaSamw 79da6c28aaSamw /* 808d7e4166Sjose borrego * Unbind the SRVSVC connection. 81da6c28aaSamw */ 828d7e4166Sjose borrego static void 838d7e4166Sjose borrego srvsvc_close(mlsvc_handle_t *handle) 84da6c28aaSamw { 858d7e4166Sjose borrego ndr_rpc_unbind(handle); 86da6c28aaSamw } 87da6c28aaSamw 88da6c28aaSamw /* 89da6c28aaSamw * This is a client side routine for NetShareGetInfo. 90da6c28aaSamw * Levels 0 and 1 work with an anonymous connection but 91da6c28aaSamw * level 2 requires administrator access. 92da6c28aaSamw */ 93da6c28aaSamw int 94da6c28aaSamw srvsvc_net_share_get_info(char *server, char *domain, char *netname) 95da6c28aaSamw { 96da6c28aaSamw struct mlsm_NetShareGetInfo arg; 97da6c28aaSamw mlsvc_handle_t handle; 98da6c28aaSamw int rc; 99da6c28aaSamw int opnum; 100eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States struct mslm_NetShareInfo_0 *info0; 101eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States struct mslm_NetShareInfo_1 *info1; 102eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States struct mslm_NetShareInfo_2 *info2; 103da6c28aaSamw int len; 104a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 105da6c28aaSamw 106da6c28aaSamw if (netname == NULL) 107da6c28aaSamw return (-1); 108da6c28aaSamw 109da6c28aaSamw if (srvsvc_info_level == 2) 110a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 111da6c28aaSamw 1128d7e4166Sjose borrego if (srvsvc_open(server, domain, user, &handle) != 0) 113da6c28aaSamw return (-1); 114da6c28aaSamw 115da6c28aaSamw opnum = SRVSVC_OPNUM_NetShareGetInfo; 116da6c28aaSamw bzero(&arg, sizeof (struct mlsm_NetShareGetInfo)); 117da6c28aaSamw 118da6c28aaSamw len = strlen(server) + 4; 1198d7e4166Sjose borrego arg.servername = ndr_rpc_malloc(&handle, len); 120da6c28aaSamw if (arg.servername == NULL) { 1218d7e4166Sjose borrego srvsvc_close(&handle); 122da6c28aaSamw return (-1); 123da6c28aaSamw } 124da6c28aaSamw 125da6c28aaSamw (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 126da6c28aaSamw arg.netname = (LPTSTR)netname; 127da6c28aaSamw arg.level = srvsvc_info_level; /* share information level */ 128da6c28aaSamw 1298d7e4166Sjose borrego rc = ndr_rpc_call(&handle, opnum, &arg); 130da6c28aaSamw if ((rc != 0) || (arg.status != 0)) { 1318d7e4166Sjose borrego srvsvc_close(&handle); 132da6c28aaSamw return (-1); 133da6c28aaSamw } 134da6c28aaSamw 135da6c28aaSamw switch (arg.result.switch_value) { 136da6c28aaSamw case 0: 137da6c28aaSamw info0 = arg.result.ru.info0; 138da6c28aaSamw smb_tracef("srvsvc shi0_netname=%s", info0->shi0_netname); 139da6c28aaSamw break; 140da6c28aaSamw 141da6c28aaSamw case 1: 142da6c28aaSamw info1 = arg.result.ru.info1; 143da6c28aaSamw smb_tracef("srvsvc shi1_netname=%s", info1->shi1_netname); 144da6c28aaSamw smb_tracef("srvsvc shi1_type=%u", info1->shi1_type); 145da6c28aaSamw 146da6c28aaSamw if (info1->shi1_comment) 147da6c28aaSamw smb_tracef("srvsvc shi1_comment=%s", 148da6c28aaSamw info1->shi1_comment); 149da6c28aaSamw break; 150da6c28aaSamw 151da6c28aaSamw case 2: 152da6c28aaSamw info2 = arg.result.ru.info2; 153da6c28aaSamw smb_tracef("srvsvc shi2_netname=%s", info2->shi2_netname); 154da6c28aaSamw smb_tracef("srvsvc shi2_type=%u", info2->shi2_type); 155da6c28aaSamw 156da6c28aaSamw if (info2->shi2_comment) 157da6c28aaSamw smb_tracef("srvsvc shi2_comment=%s", 158da6c28aaSamw info2->shi2_comment); 159da6c28aaSamw 160da6c28aaSamw smb_tracef("srvsvc shi2_perms=%d", info2->shi2_permissions); 161da6c28aaSamw smb_tracef("srvsvc shi2_max_use=%d", info2->shi2_max_uses); 162da6c28aaSamw smb_tracef("srvsvc shi2_cur_use=%d", info2->shi2_current_uses); 163da6c28aaSamw 164da6c28aaSamw if (info2->shi2_path) 165da6c28aaSamw smb_tracef("srvsvc shi2_path=%s", info2->shi2_path); 166da6c28aaSamw 167da6c28aaSamw if (info2->shi2_passwd) 168da6c28aaSamw smb_tracef("srvsvc shi2_passwd=%s", info2->shi2_passwd); 169da6c28aaSamw break; 170da6c28aaSamw 171da6c28aaSamw default: 172da6c28aaSamw smb_tracef("srvsvc: unknown level"); 173da6c28aaSamw break; 174da6c28aaSamw } 175da6c28aaSamw 1768d7e4166Sjose borrego srvsvc_close(&handle); 177da6c28aaSamw return (0); 178da6c28aaSamw } 179da6c28aaSamw 180da6c28aaSamw /* 181da6c28aaSamw * This is a client side routine for NetSessionEnum. 182da6c28aaSamw * NetSessionEnum requires administrator rights. 183da6c28aaSamw */ 184da6c28aaSamw int 185da6c28aaSamw srvsvc_net_session_enum(char *server, char *domain, char *netname) 186da6c28aaSamw { 187da6c28aaSamw struct mslm_NetSessionEnum arg; 188da6c28aaSamw mlsvc_handle_t handle; 189da6c28aaSamw int rc; 190da6c28aaSamw int opnum; 191da6c28aaSamw struct mslm_infonres infonres; 192da6c28aaSamw struct mslm_SESSION_INFO_1 *nsi1; 193da6c28aaSamw int len; 194a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 195da6c28aaSamw 196da6c28aaSamw if (netname == NULL) 197da6c28aaSamw return (-1); 198da6c28aaSamw 199a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 200a0aa776eSAlan Wright 2018d7e4166Sjose borrego rc = srvsvc_open(server, domain, user, &handle); 202da6c28aaSamw if (rc != 0) 203da6c28aaSamw return (-1); 204da6c28aaSamw 205da6c28aaSamw opnum = SRVSVC_OPNUM_NetSessionEnum; 206da6c28aaSamw bzero(&arg, sizeof (struct mslm_NetSessionEnum)); 207da6c28aaSamw 208da6c28aaSamw len = strlen(server) + 4; 2098d7e4166Sjose borrego arg.servername = ndr_rpc_malloc(&handle, len); 210da6c28aaSamw if (arg.servername == NULL) { 2118d7e4166Sjose borrego srvsvc_close(&handle); 212da6c28aaSamw return (-1); 213da6c28aaSamw } 214da6c28aaSamw 215da6c28aaSamw (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 216da6c28aaSamw infonres.entriesread = 0; 217da6c28aaSamw infonres.entries = 0; 218da6c28aaSamw arg.level = 1; 219da6c28aaSamw arg.result.level = 1; 220da6c28aaSamw arg.result.bufptr.p = &infonres; 221da6c28aaSamw arg.resume_handle = 0; 222da6c28aaSamw arg.pref_max_len = 0xFFFFFFFF; 223da6c28aaSamw 2248d7e4166Sjose borrego rc = ndr_rpc_call(&handle, opnum, &arg); 225da6c28aaSamw if ((rc != 0) || (arg.status != 0)) { 2268d7e4166Sjose borrego srvsvc_close(&handle); 227da6c28aaSamw return (-1); 228da6c28aaSamw } 229da6c28aaSamw 230da6c28aaSamw /* Only the first session info is dereferenced. */ 231da6c28aaSamw nsi1 = ((struct mslm_infonres *)arg.result.bufptr.p)->entries; 232da6c28aaSamw 233da6c28aaSamw smb_tracef("srvsvc switch_value=%d", arg.level); 234da6c28aaSamw smb_tracef("srvsvc sesi1_cname=%s", nsi1->sesi1_cname); 235da6c28aaSamw smb_tracef("srvsvc sesi1_uname=%s", nsi1->sesi1_uname); 236da6c28aaSamw smb_tracef("srvsvc sesi1_nopens=%u", nsi1->sesi1_nopens); 237da6c28aaSamw smb_tracef("srvsvc sesi1_time=%u", nsi1->sesi1_time); 238da6c28aaSamw smb_tracef("srvsvc sesi1_itime=%u", nsi1->sesi1_itime); 239da6c28aaSamw smb_tracef("srvsvc sesi1_uflags=%u", nsi1->sesi1_uflags); 240da6c28aaSamw 2418d7e4166Sjose borrego srvsvc_close(&handle); 242da6c28aaSamw return (0); 243da6c28aaSamw } 244da6c28aaSamw 245da6c28aaSamw /* 246da6c28aaSamw * This is a client side routine for NetConnectEnum. 247da6c28aaSamw * NetConnectEnum requires administrator rights. 248da6c28aaSamw * Level 0 and level 1 requests are supported. 249da6c28aaSamw */ 250da6c28aaSamw int 251da6c28aaSamw srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level) 252da6c28aaSamw { 253da6c28aaSamw struct mslm_NetConnectEnum arg; 254da6c28aaSamw mlsvc_handle_t handle; 255da6c28aaSamw int rc; 256da6c28aaSamw int opnum; 257da6c28aaSamw struct mslm_NetConnectInfo1 info1; 258da6c28aaSamw struct mslm_NetConnectInfo0 info0; 259da6c28aaSamw struct mslm_NetConnectInfoBuf1 *cib1; 260da6c28aaSamw int len; 261a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 262da6c28aaSamw 263da6c28aaSamw if (netname == NULL) 264da6c28aaSamw return (-1); 265da6c28aaSamw 266a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 267a0aa776eSAlan Wright 2688d7e4166Sjose borrego rc = srvsvc_open(server, domain, user, &handle); 269da6c28aaSamw if (rc != 0) 270da6c28aaSamw return (-1); 271da6c28aaSamw 272da6c28aaSamw opnum = SRVSVC_OPNUM_NetConnectEnum; 273da6c28aaSamw bzero(&arg, sizeof (struct mslm_NetConnectEnum)); 274da6c28aaSamw 275da6c28aaSamw len = strlen(server) + 4; 2768d7e4166Sjose borrego arg.servername = ndr_rpc_malloc(&handle, len); 277da6c28aaSamw if (arg.servername == NULL) { 2788d7e4166Sjose borrego srvsvc_close(&handle); 279da6c28aaSamw return (-1); 280da6c28aaSamw } 281da6c28aaSamw 282da6c28aaSamw (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 283da6c28aaSamw arg.qualifier = (LPTSTR)netname; 284da6c28aaSamw 285da6c28aaSamw switch (level) { 286da6c28aaSamw case 0: 287da6c28aaSamw arg.info.level = 0; 288da6c28aaSamw arg.info.switch_value = 0; 289da6c28aaSamw arg.info.ru.info0 = &info0; 290da6c28aaSamw info0.entries_read = 0; 291da6c28aaSamw info0.ci0 = 0; 292da6c28aaSamw break; 293da6c28aaSamw case 1: 294da6c28aaSamw arg.info.level = 1; 295da6c28aaSamw arg.info.switch_value = 1; 296da6c28aaSamw arg.info.ru.info1 = &info1; 297da6c28aaSamw info1.entries_read = 0; 298da6c28aaSamw info1.ci1 = 0; 299da6c28aaSamw break; 300da6c28aaSamw default: 3018d7e4166Sjose borrego srvsvc_close(&handle); 302da6c28aaSamw return (-1); 303da6c28aaSamw } 304da6c28aaSamw 305da6c28aaSamw arg.resume_handle = 0; 306da6c28aaSamw arg.pref_max_len = 0xFFFFFFFF; 307da6c28aaSamw 3088d7e4166Sjose borrego rc = ndr_rpc_call(&handle, opnum, &arg); 309da6c28aaSamw if ((rc != 0) || (arg.status != 0)) { 3108d7e4166Sjose borrego srvsvc_close(&handle); 311da6c28aaSamw return (-1); 312da6c28aaSamw } 313da6c28aaSamw 314da6c28aaSamw smb_tracef("srvsvc switch_value=%d", arg.info.switch_value); 315da6c28aaSamw 316da6c28aaSamw switch (level) { 317da6c28aaSamw case 0: 318da6c28aaSamw if (arg.info.ru.info0 && arg.info.ru.info0->ci0) { 319da6c28aaSamw smb_tracef("srvsvc coni0_id=%x", 320da6c28aaSamw arg.info.ru.info0->ci0->coni0_id); 321da6c28aaSamw } 322da6c28aaSamw break; 323da6c28aaSamw case 1: 324da6c28aaSamw if (arg.info.ru.info1 && arg.info.ru.info1->ci1) { 325da6c28aaSamw cib1 = arg.info.ru.info1->ci1; 326da6c28aaSamw 327da6c28aaSamw smb_tracef("srvsvc coni_uname=%s", 328da6c28aaSamw cib1->coni1_username ? 329da6c28aaSamw (char *)cib1->coni1_username : "(null)"); 330da6c28aaSamw smb_tracef("srvsvc coni1_netname=%s", 331da6c28aaSamw cib1->coni1_netname ? 332da6c28aaSamw (char *)cib1->coni1_netname : "(null)"); 333da6c28aaSamw smb_tracef("srvsvc coni1_nopens=%u", 334da6c28aaSamw cib1->coni1_num_opens); 335da6c28aaSamw smb_tracef("srvsvc coni1_time=%u", cib1->coni1_time); 336da6c28aaSamw smb_tracef("srvsvc coni1_num_users=%u", 337da6c28aaSamw cib1->coni1_num_users); 338da6c28aaSamw } 339da6c28aaSamw break; 340da6c28aaSamw 341da6c28aaSamw default: 342da6c28aaSamw smb_tracef("srvsvc: unknown level"); 343da6c28aaSamw break; 344da6c28aaSamw } 345da6c28aaSamw 3468d7e4166Sjose borrego srvsvc_close(&handle); 347da6c28aaSamw return (0); 348da6c28aaSamw } 349da6c28aaSamw 350a0aa776eSAlan Wright /* 351a0aa776eSAlan Wright * Windows 95+ and Windows NT4.0 both report the version as 4.0. 352a0aa776eSAlan Wright * Windows 2000+ reports the version as 5.x. 353a0aa776eSAlan Wright */ 3541fcced4cSJordan Brown int 3551fcced4cSJordan Brown srvsvc_net_server_getinfo(char *server, char *domain, 3561fcced4cSJordan Brown srvsvc_server_info_t *svinfo) 3571fcced4cSJordan Brown { 3581fcced4cSJordan Brown mlsvc_handle_t handle; 3591fcced4cSJordan Brown struct mslm_NetServerGetInfo arg; 3601fcced4cSJordan Brown struct mslm_SERVER_INFO_101 *sv101; 3611fcced4cSJordan Brown int len, opnum, rc; 362a0aa776eSAlan Wright char user[SMB_USERNAME_MAXLEN]; 363a0aa776eSAlan Wright 364a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 3651fcced4cSJordan Brown 3661fcced4cSJordan Brown if (srvsvc_open(server, domain, user, &handle) != 0) 3671fcced4cSJordan Brown return (-1); 3681fcced4cSJordan Brown 3691fcced4cSJordan Brown opnum = SRVSVC_OPNUM_NetServerGetInfo; 3701fcced4cSJordan Brown bzero(&arg, sizeof (arg)); 3711fcced4cSJordan Brown 3721fcced4cSJordan Brown len = strlen(server) + 4; 3731fcced4cSJordan Brown arg.servername = ndr_rpc_malloc(&handle, len); 3741fcced4cSJordan Brown if (arg.servername == NULL) 3751fcced4cSJordan Brown return (-1); 3761fcced4cSJordan Brown 3771fcced4cSJordan Brown (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 3781fcced4cSJordan Brown arg.level = 101; 3791fcced4cSJordan Brown 3801fcced4cSJordan Brown rc = ndr_rpc_call(&handle, opnum, &arg); 3811fcced4cSJordan Brown if ((rc != 0) || (arg.status != 0)) { 3821fcced4cSJordan Brown srvsvc_close(&handle); 3831fcced4cSJordan Brown return (-1); 3841fcced4cSJordan Brown } 3851fcced4cSJordan Brown 3861fcced4cSJordan Brown sv101 = arg.result.bufptr.bufptr101; 3871fcced4cSJordan Brown 3881fcced4cSJordan Brown bzero(svinfo, sizeof (srvsvc_server_info_t)); 3891fcced4cSJordan Brown svinfo->sv_platform_id = sv101->sv101_platform_id; 3901fcced4cSJordan Brown svinfo->sv_version_major = sv101->sv101_version_major; 3911fcced4cSJordan Brown svinfo->sv_version_minor = sv101->sv101_version_minor; 3921fcced4cSJordan Brown svinfo->sv_type = sv101->sv101_type; 3931fcced4cSJordan Brown if (sv101->sv101_name) 3941fcced4cSJordan Brown svinfo->sv_name = strdup((char *)sv101->sv101_name); 3951fcced4cSJordan Brown if (sv101->sv101_comment) 3961fcced4cSJordan Brown svinfo->sv_comment = strdup((char *)sv101->sv101_comment); 3971fcced4cSJordan Brown 398a0aa776eSAlan Wright if (svinfo->sv_type & SV_TYPE_WFW) 399a0aa776eSAlan Wright svinfo->sv_os = NATIVE_OS_WIN95; 400a0aa776eSAlan Wright if (svinfo->sv_type & SV_TYPE_WINDOWS) 401a0aa776eSAlan Wright svinfo->sv_os = NATIVE_OS_WIN95; 402a0aa776eSAlan Wright if ((svinfo->sv_type & SV_TYPE_NT) || 403a0aa776eSAlan Wright (svinfo->sv_type & SV_TYPE_SERVER_NT)) 404a0aa776eSAlan Wright svinfo->sv_os = NATIVE_OS_WINNT; 405a0aa776eSAlan Wright if (svinfo->sv_version_major > 4) 406a0aa776eSAlan Wright svinfo->sv_os = NATIVE_OS_WIN2000; 407a0aa776eSAlan Wright 4081fcced4cSJordan Brown srvsvc_close(&handle); 4091fcced4cSJordan Brown return (0); 4101fcced4cSJordan Brown } 4111fcced4cSJordan Brown 412da6c28aaSamw /* 413da6c28aaSamw * Synchronize the local system clock with the domain controller. 414da6c28aaSamw */ 415da6c28aaSamw void 416da6c28aaSamw srvsvc_timesync(void) 417da6c28aaSamw { 418a0aa776eSAlan Wright smb_domainex_t di; 419da6c28aaSamw struct timeval tv; 420da6c28aaSamw struct tm tm; 421da6c28aaSamw time_t tsecs; 422da6c28aaSamw 4238d7e4166Sjose borrego if (!smb_domain_getinfo(&di)) 424da6c28aaSamw return; 425da6c28aaSamw 426*b3700b07SGordon Ross if (srvsvc_net_remote_tod(di.d_dci.dc_name, di.d_primary.di_nbname, 427*b3700b07SGordon Ross &tv, &tm) != 0) 428da6c28aaSamw return; 429da6c28aaSamw 430da6c28aaSamw if (settimeofday(&tv, 0)) 431da6c28aaSamw smb_tracef("unable to set system time"); 432da6c28aaSamw 433da6c28aaSamw tsecs = time(0); 434da6c28aaSamw (void) localtime_r(&tsecs, &tm); 435da6c28aaSamw smb_tracef("SrvsvcTimeSync %s", ctime((time_t *)&tv.tv_sec)); 436da6c28aaSamw } 437da6c28aaSamw 438da6c28aaSamw /* 439da6c28aaSamw * NetRemoteTOD to get the current GMT time from a Windows NT server. 440da6c28aaSamw */ 441da6c28aaSamw int 442da6c28aaSamw srvsvc_gettime(unsigned long *t) 443da6c28aaSamw { 444a0aa776eSAlan Wright smb_domainex_t di; 445da6c28aaSamw struct timeval tv; 446da6c28aaSamw struct tm tm; 447da6c28aaSamw 4488d7e4166Sjose borrego if (!smb_domain_getinfo(&di)) 449da6c28aaSamw return (-1); 450da6c28aaSamw 451*b3700b07SGordon Ross if (srvsvc_net_remote_tod(di.d_dci.dc_name, di.d_primary.di_nbname, 452*b3700b07SGordon Ross &tv, &tm) != 0) 453da6c28aaSamw return (-1); 454da6c28aaSamw 455da6c28aaSamw *t = tv.tv_sec; 456da6c28aaSamw return (0); 457da6c28aaSamw } 458da6c28aaSamw 459da6c28aaSamw /* 460da6c28aaSamw * This is a client side routine for NetRemoteTOD, which gets the time 461da6c28aaSamw * and date from a remote system. The time information is returned in 462da6c28aaSamw * the timeval and tm. 463da6c28aaSamw * 464da6c28aaSamw * typedef struct _TIME_OF_DAY_INFO { 465da6c28aaSamw * DWORD tod_elapsedt; // seconds since 00:00:00 January 1 1970 GMT 466da6c28aaSamw * DWORD tod_msecs; // arbitrary milliseconds (since reset) 467da6c28aaSamw * DWORD tod_hours; // current hour [0-23] 468da6c28aaSamw * DWORD tod_mins; // current minute [0-59] 469da6c28aaSamw * DWORD tod_secs; // current second [0-59] 470da6c28aaSamw * DWORD tod_hunds; // current hundredth (0.01) second [0-99] 471da6c28aaSamw * LONG tod_timezone; // time zone of the server 472da6c28aaSamw * DWORD tod_tinterval; // clock tick time interval 473da6c28aaSamw * DWORD tod_day; // day of the month [1-31] 474da6c28aaSamw * DWORD tod_month; // month of the year [1-12] 475da6c28aaSamw * DWORD tod_year; // current year 476da6c28aaSamw * DWORD tod_weekday; // day of the week since sunday [0-6] 477da6c28aaSamw * } TIME_OF_DAY_INFO; 478da6c28aaSamw * 479da6c28aaSamw * The time zone of the server is calculated in minutes from Greenwich 480da6c28aaSamw * Mean Time (GMT). For time zones west of Greenwich, the value is 481da6c28aaSamw * positive; for time zones east of Greenwich, the value is negative. 482da6c28aaSamw * A value of -1 indicates that the time zone is undefined. 483da6c28aaSamw * 484da6c28aaSamw * The clock tick value represents a resolution of one ten-thousandth 485da6c28aaSamw * (0.0001) second. 486da6c28aaSamw */ 487da6c28aaSamw int 488da6c28aaSamw srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv, 489da6c28aaSamw struct tm *tm) 490da6c28aaSamw { 4919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct mslm_NetRemoteTOD arg; 4929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct mslm_TIME_OF_DAY_INFO *tod; 4939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mlsvc_handle_t handle; 4949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 4959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int opnum; 4969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int len; 4979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char user[SMB_USERNAME_MAXLEN]; 498a0aa776eSAlan Wright 499a0aa776eSAlan Wright smb_ipc_get_user(user, SMB_USERNAME_MAXLEN); 500da6c28aaSamw 5018d7e4166Sjose borrego rc = srvsvc_open(server, domain, user, &handle); 502da6c28aaSamw if (rc != 0) 503da6c28aaSamw return (-1); 504da6c28aaSamw 505da6c28aaSamw opnum = SRVSVC_OPNUM_NetRemoteTOD; 506da6c28aaSamw bzero(&arg, sizeof (struct mslm_NetRemoteTOD)); 507da6c28aaSamw 508da6c28aaSamw len = strlen(server) + 4; 5098d7e4166Sjose borrego arg.servername = ndr_rpc_malloc(&handle, len); 510da6c28aaSamw if (arg.servername == NULL) { 5118d7e4166Sjose borrego srvsvc_close(&handle); 512da6c28aaSamw return (-1); 513da6c28aaSamw } 514da6c28aaSamw 515da6c28aaSamw (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 516da6c28aaSamw 5178d7e4166Sjose borrego rc = ndr_rpc_call(&handle, opnum, &arg); 518da6c28aaSamw if ((rc != 0) || (arg.status != 0)) { 5198d7e4166Sjose borrego srvsvc_close(&handle); 520da6c28aaSamw return (-1); 521da6c28aaSamw } 522da6c28aaSamw 523da6c28aaSamw /* 524da6c28aaSamw * We're assigning milliseconds to microseconds 525da6c28aaSamw * here but the value's not really relevant. 526da6c28aaSamw */ 527da6c28aaSamw tod = arg.bufptr; 528da6c28aaSamw 529da6c28aaSamw if (tv) { 530da6c28aaSamw tv->tv_sec = tod->tod_elapsedt; 531da6c28aaSamw tv->tv_usec = tod->tod_msecs; 532da6c28aaSamw } 533da6c28aaSamw 534da6c28aaSamw if (tm) { 535da6c28aaSamw tm->tm_sec = tod->tod_secs; 536da6c28aaSamw tm->tm_min = tod->tod_mins; 537da6c28aaSamw tm->tm_hour = tod->tod_hours; 538da6c28aaSamw tm->tm_mday = tod->tod_day; 539da6c28aaSamw tm->tm_mon = tod->tod_month - 1; 540da6c28aaSamw tm->tm_year = tod->tod_year - 1900; 541da6c28aaSamw tm->tm_wday = tod->tod_weekday; 542da6c28aaSamw } 543da6c28aaSamw 5448d7e4166Sjose borrego srvsvc_close(&handle); 545da6c28aaSamw return (0); 546da6c28aaSamw } 547da6c28aaSamw 548da6c28aaSamw void 549da6c28aaSamw srvsvc_net_test(char *server, char *domain, char *netname) 550da6c28aaSamw { 551a0aa776eSAlan Wright smb_domainex_t di; 5521fcced4cSJordan Brown srvsvc_server_info_t svinfo; 553da6c28aaSamw 554da6c28aaSamw (void) smb_tracef("%s %s %s", server, domain, netname); 555da6c28aaSamw 5568d7e4166Sjose borrego if (smb_domain_getinfo(&di)) { 557*b3700b07SGordon Ross server = di.d_dci.dc_name; 558a0aa776eSAlan Wright domain = di.d_primary.di_nbname; 559da6c28aaSamw } 560da6c28aaSamw 5611fcced4cSJordan Brown if (srvsvc_net_server_getinfo(server, domain, &svinfo) == 0) { 5621fcced4cSJordan Brown smb_tracef("NetServerGetInfo: %s %s (%d.%d) id=%d type=0x%08x", 5631fcced4cSJordan Brown svinfo.sv_name ? svinfo.sv_name : "NULL", 5641fcced4cSJordan Brown svinfo.sv_comment ? svinfo.sv_comment : "NULL", 5651fcced4cSJordan Brown svinfo.sv_version_major, svinfo.sv_version_minor, 5661fcced4cSJordan Brown svinfo.sv_platform_id, svinfo.sv_type); 5671fcced4cSJordan Brown 5681fcced4cSJordan Brown free(svinfo.sv_name); 5691fcced4cSJordan Brown free(svinfo.sv_comment); 5701fcced4cSJordan Brown } 5711fcced4cSJordan Brown 572da6c28aaSamw (void) srvsvc_net_share_get_info(server, domain, netname); 573da6c28aaSamw #if 0 574da6c28aaSamw /* 575da6c28aaSamw * The NetSessionEnum server-side definition was updated. 576da6c28aaSamw * Disabled until the client-side has been updated. 577da6c28aaSamw */ 578da6c28aaSamw (void) srvsvc_net_session_enum(server, domain, netname); 579da6c28aaSamw #endif 580da6c28aaSamw (void) srvsvc_net_connect_enum(server, domain, netname, 0); 581da6c28aaSamw (void) srvsvc_net_connect_enum(server, domain, netname, 1); 582da6c28aaSamw } 583