r18959: reformat using indent
[sfrench/samba-autobuild/.git] / source3 / libmsrpc / libmsrpc.c
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
27 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
28 void cac_Init( int debug )
29 {
30         if ( debug < 0 || debug > 99 )
31                 debug = 0;
32
33         DEBUGLEVEL = debug;
34
35         setup_logging( "libmsrpc", True );
36 }
37
38 int cac_InitHandleMem( CacServerHandle * hnd )
39 {
40         hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
41
42         if ( !hnd->username )
43                 return CAC_FAILURE;
44
45         hnd->username[0] = '\0';
46
47         hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
48         if ( !hnd->domain )
49                 return CAC_FAILURE;
50
51         hnd->domain[0] = '\0';
52
53         hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
54         if ( !hnd->netbios_name )
55                 return CAC_FAILURE;
56
57         hnd->netbios_name[0] = '\0';
58
59         hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
60         if ( !hnd->password )
61                 return CAC_FAILURE;
62
63         hnd->password[0] = '\0';
64
65         hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
66         if ( !hnd->server )
67                 return CAC_FAILURE;
68
69         hnd->server[0] = '\0';
70
71         return CAC_SUCCESS;
72 }
73
74 CacServerHandle *cac_NewServerHandle( BOOL allocate_fields )
75 {
76         CacServerHandle *hnd;
77
78         hnd = SMB_MALLOC_P( CacServerHandle );
79
80         if ( !hnd ) {
81                 errno = ENOMEM;
82                 return NULL;
83         }
84
85         ZERO_STRUCTP( hnd );
86
87         if ( allocate_fields == True ) {
88                 if ( !cac_InitHandleMem( hnd ) ) {
89                         SAFE_FREE( hnd );
90                         return NULL;
91                 }
92         }
93
94         hnd->_internal.ctx = smbc_new_context(  );
95         if ( !hnd->_internal.ctx ) {
96                 cac_FreeHandle( hnd );
97                 return NULL;
98         }
99
100         hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
101
102         /*add defaults */
103         hnd->debug = 0;
104
105         /*start at the highest and it will fall down after trying the functions */
106         hnd->_internal.srv_level = SRV_WIN_2K3;
107
108         hnd->_internal.user_supplied_ctx = False;
109
110         return hnd;
111 }
112
113 int cac_InitHandleData( CacServerHandle * hnd )
114 {
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 ) );
122         }
123
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 ) );
129         }
130
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 ) );
136         }
137
138         return CAC_SUCCESS;
139 }
140
141 void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn )
142 {
143         hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
144 }
145
146 void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx )
147 {
148
149         SAFE_FREE( hnd->_internal.ctx );
150
151         hnd->_internal.user_supplied_ctx = True;
152
153         hnd->_internal.ctx = ctx;
154
155    /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
156         /*cac_InitHandleData(hnd); */
157 }
158
159 /*used internally*/
160 SMBCSRV *cac_GetServer( CacServerHandle * hnd )
161 {
162         SMBCSRV *srv;
163
164         if ( !hnd || !hnd->_internal.ctx ) {
165                 return NULL;
166         }
167
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" ) );
175         }
176
177         return srv;
178 }
179
180
181 int cac_Connect( CacServerHandle * hnd, const char *srv )
182 {
183         if ( !hnd ) {
184                 return CAC_FAILURE;
185         }
186
187         /*these values should be initialized by the user */
188         if ( !hnd->server && !srv ) {
189                 return CAC_FAILURE;
190         }
191
192
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 );
197         }
198
199
200         /*first see if the context has already been setup */
201         if ( !( hnd->_internal.ctx->internal->_initialized ) ) {
202                 hnd->_internal.ctx->debug = hnd->debug;
203
204                 /*initialize the context */
205                 if ( !smbc_init_context( hnd->_internal.ctx ) ) {
206                         return CAC_FAILURE;
207                 }
208         }
209
210         /*copy any uninitialized values out of the smbc context into the handle */
211         if ( !cac_InitHandleData( hnd ) ) {
212                 return CAC_FAILURE;
213         }
214
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 ) );
218
219         if ( !cac_GetServer( hnd ) ) {
220                 return CAC_FAILURE;
221         }
222
223         return CAC_SUCCESS;
224
225 }
226
227
228 void cac_FreeHandle( CacServerHandle * hnd )
229 {
230         if ( !hnd )
231                 return;
232
233         /*only free the context if we created it */
234         if ( !hnd->_internal.user_supplied_ctx ) {
235                 smbc_free_context( hnd->_internal.ctx, True );
236         }
237
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 );
244
245 }
246
247 void cac_InitCacTime( CacTime * cactime, NTTIME nttime )
248 {
249         float high, low;
250         uint32 sec;
251
252         if ( !cactime )
253                 return;
254
255         ZERO_STRUCTP( cactime );
256
257         /*this code is taken from display_time() found in rpcclient/cmd_samr.c */
258         if ( nttime == 0 )
259                 return;
260
261         if ( nttime == 0x80000000000000LL )
262                 return;
263
264         high = 65536;
265         high = high / 10000;
266         high = high * 65536;
267         high = high / 1000;
268         high = high * ( ~( nttime >> 32 ) );
269
270         low = ~( nttime & 0xFFFFFFFF );
271         low = low / ( 1000 * 1000 * 10 );
272
273         sec = high + low;
274
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 );
284 }
285
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 )
293 {
294         char temp[sizeof( fstring )];
295
296         static char authUsername[sizeof( fstring )];
297         static char authWorkgroup[sizeof( fstring )];
298         static char authPassword[sizeof( fstring )];
299         static char authSet = 0;
300
301         char *pass = NULL;
302
303
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 );
311
312                 if ( temp[strlen( temp ) - 1] == '\n' ) {       /* A new line? */
313                         temp[strlen( temp ) - 1] = '\0';
314                 }
315
316
317                 if ( temp[0] != '\0' ) {
318                         strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 );
319                         strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 );
320                 }
321
322                 d_printf( "Username: [%s] ", pUsername );
323                 fgets( temp, sizeof( fstring ), stdin );
324
325                 if ( temp[strlen( temp ) - 1] == '\n' ) {       /* A new line? */
326                         temp[strlen( temp ) - 1] = '\0';
327                 }
328
329                 if ( temp[0] != '\0' ) {
330                         strncpy( pUsername, temp, maxLenUsername - 1 );
331                         strncpy( authUsername, pUsername,
332                                  maxLenUsername - 1 );
333                 }
334
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';
340                 }
341                 if ( temp[0] != '\0' ) {
342                         strncpy( pPassword, temp, maxLenPassword - 1 );
343                         strncpy( authPassword, pPassword,
344                                  maxLenPassword - 1 );
345                 }
346                 authSet = 1;
347         }
348 }