r20136: Fix #4290. Properly compute time to password expiration in message from
[Samba/bb.git] / source3 / libmsrpc / libmsrpc.c
blobadaf89d0feb169eb1526576f0d24ae4c1d05fb1e
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.
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.
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.
22 #include "libmsrpc.h"
23 #include "libmsrpc_internal.h"
24 #include "libsmbclient.h"
25 #include "libsmb_internal.h"
27 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
28 void cac_Init( int debug )
30 if ( debug < 0 || debug > 99 )
31 debug = 0;
33 DEBUGLEVEL = debug;
35 setup_logging( "libmsrpc", True );
38 int cac_InitHandleMem( CacServerHandle * hnd )
40 hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
42 if ( !hnd->username )
43 return CAC_FAILURE;
45 hnd->username[0] = '\0';
47 hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
48 if ( !hnd->domain )
49 return CAC_FAILURE;
51 hnd->domain[0] = '\0';
53 hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
54 if ( !hnd->netbios_name )
55 return CAC_FAILURE;
57 hnd->netbios_name[0] = '\0';
59 hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
60 if ( !hnd->password )
61 return CAC_FAILURE;
63 hnd->password[0] = '\0';
65 hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
66 if ( !hnd->server )
67 return CAC_FAILURE;
69 hnd->server[0] = '\0';
71 return CAC_SUCCESS;
74 CacServerHandle *cac_NewServerHandle( BOOL allocate_fields )
76 CacServerHandle *hnd;
78 hnd = SMB_MALLOC_P( CacServerHandle );
80 if ( !hnd ) {
81 errno = ENOMEM;
82 return NULL;
85 ZERO_STRUCTP( hnd );
87 if ( allocate_fields == True ) {
88 if ( !cac_InitHandleMem( hnd ) ) {
89 SAFE_FREE( hnd );
90 return NULL;
94 hnd->_internal.ctx = smbc_new_context( );
95 if ( !hnd->_internal.ctx ) {
96 cac_FreeHandle( hnd );
97 return NULL;
100 hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
102 /*add defaults */
103 hnd->debug = 0;
105 /*start at the highest and it will fall down after trying the functions */
106 hnd->_internal.srv_level = SRV_WIN_2K3;
108 hnd->_internal.user_supplied_ctx = False;
110 return hnd;
113 int cac_InitHandleData( CacServerHandle * hnd )
115 /*store any automatically initialized values */
116 if ( !hnd->netbios_name ) {
117 hnd->netbios_name =
118 SMB_STRDUP( hnd->_internal.ctx->netbios_name );
119 } else if ( hnd->netbios_name[0] == '\0' ) {
120 strncpy( hnd->netbios_name, hnd->_internal.ctx->netbios_name,
121 sizeof( fstring ) );
124 if ( !hnd->username ) {
125 hnd->username = SMB_STRDUP( hnd->_internal.ctx->user );
126 } else if ( hnd->username[0] == '\0' ) {
127 strncpy( hnd->username, hnd->_internal.ctx->user,
128 sizeof( fstring ) );
131 if ( !hnd->domain ) {
132 hnd->domain = SMB_STRDUP( hnd->_internal.ctx->workgroup );
133 } else if ( hnd->domain[0] == '\0' ) {
134 strncpy( hnd->domain, hnd->_internal.ctx->workgroup,
135 sizeof( fstring ) );
138 return CAC_SUCCESS;
141 void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn )
143 hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
146 void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx )
149 SAFE_FREE( hnd->_internal.ctx );
151 hnd->_internal.user_supplied_ctx = True;
153 hnd->_internal.ctx = ctx;
155 /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
156 /*cac_InitHandleData(hnd); */
159 /*used internally*/
160 SMBCSRV *cac_GetServer( CacServerHandle * hnd )
162 SMBCSRV *srv;
164 if ( !hnd || !hnd->_internal.ctx ) {
165 return NULL;
168 srv = smbc_attr_server( hnd->_internal.ctx, hnd->server, "IPC$",
169 hnd->domain, hnd->username, hnd->password,
170 NULL );
171 if ( !srv ) {
172 hnd->status = NT_STATUS_UNSUCCESSFUL;
173 DEBUG( 1,
174 ( "cac_GetServer: Could not find server connection.\n" ) );
177 return srv;
181 int cac_Connect( CacServerHandle * hnd, const char *srv )
183 if ( !hnd ) {
184 return CAC_FAILURE;
187 /*these values should be initialized by the user */
188 if ( !hnd->server && !srv ) {
189 return CAC_FAILURE;
193 /*change the server name in the server handle if necessary */
194 if ( srv && hnd->server && strcmp( hnd->server, srv ) == 0 ) {
195 SAFE_FREE( hnd->server );
196 hnd->server = SMB_STRDUP( srv );
200 /*first see if the context has already been setup */
201 if ( !( hnd->_internal.ctx->internal->_initialized ) ) {
202 hnd->_internal.ctx->debug = hnd->debug;
204 /*initialize the context */
205 if ( !smbc_init_context( hnd->_internal.ctx ) ) {
206 return CAC_FAILURE;
210 /*copy any uninitialized values out of the smbc context into the handle */
211 if ( !cac_InitHandleData( hnd ) ) {
212 return CAC_FAILURE;
215 DEBUG( 3, ( "cac_Connect: Username: %s\n", hnd->username ) );
216 DEBUG( 3, ( "cac_Connect: Domain: %s\n", hnd->domain ) );
217 DEBUG( 3, ( "cac_Connect: Netbios Name: %s\n", hnd->netbios_name ) );
219 if ( !cac_GetServer( hnd ) ) {
220 return CAC_FAILURE;
223 return CAC_SUCCESS;
228 void cac_FreeHandle( CacServerHandle * hnd )
230 if ( !hnd )
231 return;
233 /*only free the context if we created it */
234 if ( !hnd->_internal.user_supplied_ctx ) {
235 smbc_free_context( hnd->_internal.ctx, True );
238 SAFE_FREE( hnd->netbios_name );
239 SAFE_FREE( hnd->domain );
240 SAFE_FREE( hnd->username );
241 SAFE_FREE( hnd->password );
242 SAFE_FREE( hnd->server );
243 SAFE_FREE( hnd );
247 void cac_InitCacTime( CacTime * cactime, NTTIME nttime )
249 float high, low;
250 uint32 sec;
252 if ( !cactime )
253 return;
255 ZERO_STRUCTP( cactime );
257 /*this code is taken from display_time() found in rpcclient/cmd_samr.c */
258 if ( nttime == 0 )
259 return;
261 if ( nttime == 0x80000000000000LL )
262 return;
264 high = 65536;
265 high = high / 10000;
266 high = high * 65536;
267 high = high / 1000;
268 high = high * ( ~( nttime >> 32 ) );
270 low = ~( nttime & 0xFFFFFFFF );
271 low = low / ( 1000 * 1000 * 10 );
273 sec = high + low;
275 cactime->days = sec / ( 60 * 60 * 24 );
276 cactime->hours =
277 ( sec - ( cactime->days * 60 * 60 * 24 ) ) / ( 60 * 60 );
278 cactime->minutes =
279 ( sec - ( cactime->days * 60 * 60 * 24 ) -
280 ( cactime->hours * 60 * 60 ) ) / 60;
281 cactime->seconds =
282 sec - ( cactime->days * 60 * 60 * 24 ) -
283 ( cactime->hours * 60 * 60 ) - ( cactime->minutes * 60 );
286 void cac_GetAuthDataFn( const char *pServer,
287 const char *pShare,
288 char *pWorkgroup,
289 int maxLenWorkgroup,
290 char *pUsername,
291 int maxLenUsername,
292 char *pPassword, int maxLenPassword )
294 char temp[sizeof( fstring )];
296 static char authUsername[sizeof( fstring )];
297 static char authWorkgroup[sizeof( fstring )];
298 static char authPassword[sizeof( fstring )];
299 static char authSet = 0;
301 char *pass = NULL;
304 if ( authSet ) {
305 strncpy( pWorkgroup, authWorkgroup, maxLenWorkgroup - 1 );
306 strncpy( pUsername, authUsername, maxLenUsername - 1 );
307 strncpy( pPassword, authPassword, maxLenPassword - 1 );
308 } else {
309 d_printf( "Domain: [%s] ", pWorkgroup );
310 fgets( temp, sizeof( fstring ), stdin );
312 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
313 temp[strlen( temp ) - 1] = '\0';
317 if ( temp[0] != '\0' ) {
318 strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 );
319 strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 );
322 d_printf( "Username: [%s] ", pUsername );
323 fgets( temp, sizeof( fstring ), stdin );
325 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
326 temp[strlen( temp ) - 1] = '\0';
329 if ( temp[0] != '\0' ) {
330 strncpy( pUsername, temp, maxLenUsername - 1 );
331 strncpy( authUsername, pUsername,
332 maxLenUsername - 1 );
335 pass = getpass( "Password: " );
336 if ( pass )
337 fstrcpy( temp, pass );
338 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
339 temp[strlen( temp ) - 1] = '\0';
341 if ( temp[0] != '\0' ) {
342 strncpy( pPassword, temp, maxLenPassword - 1 );
343 strncpy( authPassword, pPassword,
344 maxLenPassword - 1 );
346 authSet = 1;