r14577: BUG Fixes:
[Samba.git] / source / libmsrpc / libmsrpc.c
blob5f71af21da20859bc0114425fe7cd5f8f5d1f003
1 /*
2 * Unix SMB/CIFS implementation.
3 * MS-RPC client library implementation
4 * Copyright (C) Chris Nicholls 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "libmsrpc.h"
22 #include "libmsrpc_internal.h"
23 #include "libsmbclient.h"
24 #include "libsmb_internal.h"
26 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
27 void cac_Init(int debug) {
28 if(debug < 0 || debug > 99)
29 debug = 0;
31 DEBUGLEVEL = debug;
33 setup_logging("libmsrpc", True);
36 int cac_InitHandleMem(CacServerHandle *hnd) {
37 hnd->username = SMB_MALLOC_ARRAY(char, sizeof(fstring));
38 if(!hnd->username)
39 return CAC_FAILURE;
41 hnd->username[0] = '\0';
43 hnd->domain = SMB_MALLOC_ARRAY(char, sizeof(fstring));
44 if(!hnd->domain)
45 return CAC_FAILURE;
47 hnd->domain[0] = '\0';
49 hnd->netbios_name = SMB_MALLOC_ARRAY(char, sizeof(fstring));
50 if(!hnd->netbios_name)
51 return CAC_FAILURE;
53 hnd->netbios_name[0] = '\0';
55 hnd->password = SMB_MALLOC_ARRAY(char, sizeof(fstring));
56 if(!hnd->password)
57 return CAC_FAILURE;
59 hnd->password[0] = '\0';
61 hnd->server = SMB_MALLOC_ARRAY(char, sizeof(fstring));
62 if(!hnd->server)
63 return CAC_FAILURE;
65 hnd->server[0] = '\0';
67 return CAC_SUCCESS;
70 CacServerHandle *cac_NewServerHandle(BOOL allocate_fields) {
71 CacServerHandle * hnd;
73 hnd = SMB_MALLOC_P(CacServerHandle);
75 if(!hnd) {
76 errno = ENOMEM;
77 return NULL;
80 ZERO_STRUCTP(hnd);
82 if(allocate_fields == True) {
83 if(!cac_InitHandleMem(hnd)) {
84 SAFE_FREE(hnd);
85 return NULL;
89 hnd->_internal.ctx = smbc_new_context();
90 if(!hnd->_internal.ctx) {
91 cac_FreeHandle(hnd);
92 return NULL;
95 hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
97 /*add defaults*/
98 hnd->debug = 0;
100 /*start at the highest and it will fall down after trying the functions*/
101 hnd->_internal.srv_level = SRV_WIN_2K3;
103 hnd->_internal.user_supplied_ctx = False;
105 return hnd;
108 int cac_InitHandleData(CacServerHandle *hnd) {
109 /*store any automatically initialized values*/
110 if(!hnd->netbios_name) {
111 hnd->netbios_name = SMB_STRDUP(hnd->_internal.ctx->netbios_name);
113 else if(hnd->netbios_name[0] == '\0') {
114 strncpy(hnd->netbios_name, hnd->_internal.ctx->netbios_name, sizeof(fstring));
117 if(!hnd->username) {
118 hnd->username = SMB_STRDUP(hnd->_internal.ctx->user);
120 else if(hnd->username[0] == '\0') {
121 strncpy(hnd->username, hnd->_internal.ctx->user, sizeof(fstring));
124 if(!hnd->domain) {
125 hnd->domain = SMB_STRDUP(hnd->_internal.ctx->workgroup);
127 else if(hnd->domain[0] == '\0') {
128 strncpy(hnd->domain, hnd->_internal.ctx->workgroup, sizeof(fstring));
131 return CAC_SUCCESS;
134 void cac_SetAuthDataFn(CacServerHandle *hnd, smbc_get_auth_data_fn auth_fn) {
135 hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
138 void cac_SetSmbcContext(CacServerHandle *hnd, SMBCCTX *ctx) {
140 SAFE_FREE(hnd->_internal.ctx);
142 hnd->_internal.user_supplied_ctx = True;
144 hnd->_internal.ctx = ctx;
146 /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
147 /*cac_InitHandleData(hnd);*/
150 /*used internally*/
151 SMBCSRV *cac_GetServer(CacServerHandle *hnd) {
152 SMBCSRV *srv;
154 if(!hnd || !hnd->_internal.ctx) {
155 return NULL;
158 srv = smbc_attr_server(hnd->_internal.ctx, hnd->server, "IPC$", hnd->domain, hnd->username, hnd->password, NULL);
159 if(!srv) {
160 hnd->status=NT_STATUS_UNSUCCESSFUL;
161 DEBUG(1, ("cac_GetServer: Could not find server connection.\n"));
164 return srv;
168 int cac_Connect(CacServerHandle *hnd, const char *srv) {
169 if(!hnd) {
170 return CAC_FAILURE;
173 /*these values should be initialized by the user*/
174 if(!hnd->server && !srv) {
175 return CAC_FAILURE;
179 /*change the server name in the server handle if necessary*/
180 if(srv && hnd->server && strcmp(hnd->server, srv) == 0) {
181 SAFE_FREE(hnd->server);
182 hnd->server = SMB_STRDUP(srv);
186 /*first see if the context has already been setup*/
187 if( !(hnd->_internal.ctx->internal->_initialized) ) {
188 hnd->_internal.ctx->debug = hnd->debug;
190 /*initialize the context*/
191 if(!smbc_init_context(hnd->_internal.ctx)) {
192 return CAC_FAILURE;
196 /*copy any uninitialized values out of the smbc context into the handle*/
197 if(!cac_InitHandleData(hnd)) {
198 return CAC_FAILURE;
201 DEBUG(3, ("cac_Connect: Username: %s\n", hnd->username));
202 DEBUG(3, ("cac_Connect: Domain: %s\n", hnd->domain));
203 DEBUG(3, ("cac_Connect: Netbios Name: %s\n", hnd->netbios_name));
205 if(!cac_GetServer(hnd)) {
206 return CAC_FAILURE;
209 return CAC_SUCCESS;
214 void cac_FreeHandle(CacServerHandle * hnd) {
215 if(!hnd)
216 return;
218 /*only free the context if we created it*/
219 if(!hnd->_internal.user_supplied_ctx) {
220 smbc_free_context(hnd->_internal.ctx, True);
223 SAFE_FREE(hnd->netbios_name);
224 SAFE_FREE(hnd->domain);
225 SAFE_FREE(hnd->username);
226 SAFE_FREE(hnd->password);
227 SAFE_FREE(hnd->server);
228 SAFE_FREE(hnd);
232 void cac_InitCacTime(CacTime *cactime, NTTIME nttime) {
233 float high, low;
234 uint32 sec;
236 if(!cactime)
237 return;
239 ZERO_STRUCTP(cactime);
241 /*this code is taken from display_time() found in rpcclient/cmd_samr.c*/
242 if (nttime.high==0 && nttime.low==0)
243 return;
245 if (nttime.high==0x80000000 && nttime.low==0)
246 return;
248 high = 65536;
249 high = high/10000;
250 high = high*65536;
251 high = high/1000;
252 high = high * (~nttime.high);
254 low = ~nttime.low;
255 low = low/(1000*1000*10);
257 sec=high+low;
259 cactime->days=sec/(60*60*24);
260 cactime->hours=(sec - (cactime->days*60*60*24)) / (60*60);
261 cactime->minutes=(sec - (cactime->days*60*60*24) - (cactime->hours*60*60) ) / 60;
262 cactime->seconds=sec - (cactime->days*60*60*24) - (cactime->hours*60*60) - (cactime->minutes*60);
265 void cac_GetAuthDataFn(const char * pServer,
266 const char * pShare,
267 char * pWorkgroup,
268 int maxLenWorkgroup,
269 char * pUsername,
270 int maxLenUsername,
271 char * pPassword,
272 int maxLenPassword)
275 char temp[sizeof(fstring)];
277 static char authUsername[sizeof(fstring)];
278 static char authWorkgroup[sizeof(fstring)];
279 static char authPassword[sizeof(fstring)];
280 static char authSet = 0;
282 char *pass = NULL;
285 if (authSet)
287 strncpy(pWorkgroup, authWorkgroup, maxLenWorkgroup - 1);
288 strncpy(pUsername, authUsername, maxLenUsername - 1);
289 strncpy(pPassword, authPassword, maxLenPassword - 1);
291 else
293 d_printf("Domain: [%s] ", pWorkgroup);
294 fgets(temp, sizeof(fstring), stdin);
296 if (temp[strlen(temp) - 1] == '\n') /* A new line? */
298 temp[strlen(temp) - 1] = '\0';
302 if (temp[0] != '\0')
304 strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
305 strncpy(authWorkgroup, temp, maxLenWorkgroup - 1);
308 d_printf("Username: [%s] ", pUsername);
309 fgets(temp, sizeof(fstring), stdin);
311 if (temp[strlen(temp) - 1] == '\n') /* A new line? */
313 temp[strlen(temp) - 1] = '\0';
316 if (temp[0] != '\0')
318 strncpy(pUsername, temp, maxLenUsername - 1);
319 strncpy(authUsername, pUsername, maxLenUsername - 1);
322 pass = getpass("Password: ");
323 if (pass)
324 fstrcpy(temp, pass);
325 if (temp[strlen(temp) - 1] == '\n') /* A new line? */
327 temp[strlen(temp) - 1] = '\0';
329 if (temp[0] != '\0')
331 strncpy(pPassword, temp, maxLenPassword - 1);
332 strncpy(authPassword, pPassword, maxLenPassword - 1);
334 authSet = 1;