1 2/* 3 * Unix SMB/CIFS implementation. 4 * MS-RPC client library implementation 5 * Copyright (C) Chris Nicholls 2005. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "libmsrpc.h" 23#include "libmsrpc_internal.h" 24#include "libsmbclient.h" 25#include "libsmb_internal.h" 26 27int cac_InitHandleData( CacServerHandle * hnd ); 28 29/*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/ 30void cac_Init( int debug ) 31{ 32 if ( debug < 0 || debug > 99 ) 33 debug = 0; 34 35 DEBUGLEVEL = debug; 36 37 setup_logging( "libmsrpc", True ); 38} 39 40int cac_InitHandleMem( CacServerHandle * hnd ) 41{ 42 hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) ); 43 44 if ( !hnd->username ) 45 return CAC_FAILURE; 46 47 hnd->username[0] = '\0'; 48 49 hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) ); 50 if ( !hnd->domain ) 51 return CAC_FAILURE; 52 53 hnd->domain[0] = '\0'; 54 55 hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) ); 56 if ( !hnd->netbios_name ) 57 return CAC_FAILURE; 58 59 hnd->netbios_name[0] = '\0'; 60 61 hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) ); 62 if ( !hnd->password ) 63 return CAC_FAILURE; 64 65 hnd->password[0] = '\0'; 66 67 hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) ); 68 if ( !hnd->server ) 69 return CAC_FAILURE; 70 71 hnd->server[0] = '\0'; 72 73 return CAC_SUCCESS; 74} 75 76CacServerHandle *cac_NewServerHandle( BOOL allocate_fields ) 77{ 78 CacServerHandle *hnd; 79 80 hnd = SMB_MALLOC_P( CacServerHandle ); 81 82 if ( !hnd ) { 83 errno = ENOMEM; 84 return NULL; 85 } 86 87 ZERO_STRUCTP( hnd ); 88 89 if ( allocate_fields == True ) { 90 if ( !cac_InitHandleMem( hnd ) ) { 91 SAFE_FREE( hnd ); 92 return NULL; 93 } 94 } 95 96 hnd->_internal.ctx = smbc_new_context( ); 97 if ( !hnd->_internal.ctx ) { 98 cac_FreeHandle( hnd ); 99 return NULL; 100 } 101 102 hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn; 103 104 /*add defaults */ 105 hnd->debug = 0; 106 107 /*start at the highest and it will fall down after trying the functions */ 108 hnd->_internal.srv_level = SRV_WIN_2K3; 109 110 hnd->_internal.user_supplied_ctx = False; 111 112 return hnd; 113} 114 115int cac_InitHandleData( CacServerHandle * hnd ) 116{ 117 /*store any automatically initialized values */ 118 if ( !hnd->netbios_name ) { 119 hnd->netbios_name = 120 SMB_STRDUP( hnd->_internal.ctx->netbios_name ); 121 } else if ( hnd->netbios_name[0] == '\0' ) { 122 strncpy( hnd->netbios_name, hnd->_internal.ctx->netbios_name, 123 sizeof( fstring ) ); 124 } 125 126 if ( !hnd->username ) { 127 hnd->username = SMB_STRDUP( hnd->_internal.ctx->user ); 128 } else if ( hnd->username[0] == '\0' ) { 129 strncpy( hnd->username, hnd->_internal.ctx->user, 130 sizeof( fstring ) ); 131 } 132 133 if ( !hnd->domain ) { 134 hnd->domain = SMB_STRDUP( hnd->_internal.ctx->workgroup ); 135 } else if ( hnd->domain[0] == '\0' ) { 136 strncpy( hnd->domain, hnd->_internal.ctx->workgroup, 137 sizeof( fstring ) ); 138 } 139 140 return CAC_SUCCESS; 141} 142 143void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn ) 144{ 145 hnd->_internal.ctx->callbacks.auth_fn = auth_fn; 146} 147 148void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx ) 149{ 150 151 SAFE_FREE( hnd->_internal.ctx ); 152 153 hnd->_internal.user_supplied_ctx = True; 154 155 hnd->_internal.ctx = ctx; 156 157 /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/ 158 /*cac_InitHandleData(hnd); */ 159} 160 161/*used internally*/ 162SMBCSRV *cac_GetServer( CacServerHandle * hnd ) 163{ 164 SMBCSRV *srv; 165 166 if ( !hnd || !hnd->_internal.ctx ) { 167 return NULL; 168 } 169 170 srv = smbc_attr_server( hnd->_internal.ctx, hnd->server, "IPC$", 171 hnd->domain, hnd->username, hnd->password, 172 NULL ); 173 if ( !srv ) { 174 hnd->status = NT_STATUS_UNSUCCESSFUL; 175 DEBUG( 1, 176 ( "cac_GetServer: Could not find server connection.\n" ) ); 177 } 178 179 return srv; 180} 181 182 183int cac_Connect( CacServerHandle * hnd, const char *srv ) 184{ 185 if ( !hnd ) { 186 return CAC_FAILURE; 187 } 188 189 /*these values should be initialized by the user */ 190 if ( !hnd->server && !srv ) { 191 return CAC_FAILURE; 192 } 193 194 195 /*change the server name in the server handle if necessary */ 196 if ( srv && hnd->server && strcmp( hnd->server, srv ) == 0 ) { 197 SAFE_FREE( hnd->server ); 198 hnd->server = SMB_STRDUP( srv ); 199 } 200 201 202 /*first see if the context has already been setup */ 203 if ( !( hnd->_internal.ctx->internal->_initialized ) ) { 204 hnd->_internal.ctx->debug = hnd->debug; 205 206 /*initialize the context */ 207 if ( !smbc_init_context( hnd->_internal.ctx ) ) { 208 return CAC_FAILURE; 209 } 210 } 211 212 /*copy any uninitialized values out of the smbc context into the handle */ 213 if ( !cac_InitHandleData( hnd ) ) { 214 return CAC_FAILURE; 215 } 216 217 DEBUG( 3, ( "cac_Connect: Username: %s\n", hnd->username ) ); 218 DEBUG( 3, ( "cac_Connect: Domain: %s\n", hnd->domain ) ); 219 DEBUG( 3, ( "cac_Connect: Netbios Name: %s\n", hnd->netbios_name ) ); 220 221 if ( !cac_GetServer( hnd ) ) { 222 return CAC_FAILURE; 223 } 224 225 return CAC_SUCCESS; 226 227} 228 229 230void cac_FreeHandle( CacServerHandle * hnd ) 231{ 232 if ( !hnd ) 233 return; 234 235 /*only free the context if we created it */ 236 if ( !hnd->_internal.user_supplied_ctx ) { 237 smbc_free_context( hnd->_internal.ctx, True ); 238 } 239 240 SAFE_FREE( hnd->netbios_name ); 241 SAFE_FREE( hnd->domain ); 242 SAFE_FREE( hnd->username ); 243 SAFE_FREE( hnd->password ); 244 SAFE_FREE( hnd->server ); 245 SAFE_FREE( hnd ); 246 247} 248 249void cac_InitCacTime( CacTime * cactime, NTTIME nttime ) 250{ 251 float high, low; 252 uint32 sec; 253 254 if ( !cactime ) 255 return; 256 257 ZERO_STRUCTP( cactime ); 258 259 /*this code is taken from display_time() found in rpcclient/cmd_samr.c */ 260 if ( nttime == 0 ) 261 return; 262 263 if ( nttime == 0x80000000000000LL ) 264 return; 265 266 high = 65536; 267 high = high / 10000; 268 high = high * 65536; 269 high = high / 1000; 270 high = high * ( ~( nttime >> 32 ) ); 271 272 low = ~( nttime & 0xFFFFFFFF ); 273 low = low / ( 1000 * 1000 * 10 ); 274 275 sec = high + low; 276 277 cactime->days = sec / ( 60 * 60 * 24 ); 278 cactime->hours = 279 ( sec - ( cactime->days * 60 * 60 * 24 ) ) / ( 60 * 60 ); 280 cactime->minutes = 281 ( sec - ( cactime->days * 60 * 60 * 24 ) - 282 ( cactime->hours * 60 * 60 ) ) / 60; 283 cactime->seconds = 284 sec - ( cactime->days * 60 * 60 * 24 ) - 285 ( cactime->hours * 60 * 60 ) - ( cactime->minutes * 60 ); 286} 287 288void cac_GetAuthDataFn( const char *pServer, 289 const char *pShare, 290 char *pWorkgroup, 291 int maxLenWorkgroup, 292 char *pUsername, 293 int maxLenUsername, 294 char *pPassword, int maxLenPassword ) 295{ 296 char temp[sizeof( fstring )]; 297 298 static char authUsername[sizeof( fstring )]; 299 static char authWorkgroup[sizeof( fstring )]; 300 static char authPassword[sizeof( fstring )]; 301 static char authSet = 0; 302 303 char *pass = NULL; 304 305 306 if ( authSet ) { 307 strncpy( pWorkgroup, authWorkgroup, maxLenWorkgroup - 1 ); 308 strncpy( pUsername, authUsername, maxLenUsername - 1 ); 309 strncpy( pPassword, authPassword, maxLenPassword - 1 ); 310 } else { 311 d_printf( "Domain: [%s] ", pWorkgroup ); 312 fgets( temp, sizeof( fstring ), stdin ); 313 314 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */ 315 temp[strlen( temp ) - 1] = '\0'; 316 } 317 318 319 if ( temp[0] != '\0' ) { 320 strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 ); 321 strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 ); 322 } 323 324 d_printf( "Username: [%s] ", pUsername ); 325 fgets( temp, sizeof( fstring ), stdin ); 326 327 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */ 328 temp[strlen( temp ) - 1] = '\0'; 329 } 330 331 if ( temp[0] != '\0' ) { 332 strncpy( pUsername, temp, maxLenUsername - 1 ); 333 strncpy( authUsername, pUsername, 334 maxLenUsername - 1 ); 335 } 336 337 pass = getpass( "Password: " ); 338 if ( pass ) 339 fstrcpy( temp, pass ); 340 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */ 341 temp[strlen( temp ) - 1] = '\0'; 342 } 343 if ( temp[0] != '\0' ) { 344 strncpy( pPassword, temp, maxLenPassword - 1 ); 345 strncpy( authPassword, pPassword, 346 maxLenPassword - 1 ); 347 } 348 authSet = 1; 349 } 350} 351