mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
rewrite. His comments: I've gotten the libmsrpc code to work with TRUNK. I've put the patch at: www.uoguelph.ca/~cnicholl/libmsrpc_trunk_v1.patch.gz It is from revision 11093. I also fixed a minor bug in the svcctl code, the timeout parameter for all the control functions was working in milliseconds instead of seconds. Also fixed bug in Makefile when building libmsrpc.a (This used to be commit d3a52900ec223316779e59a13cea87ecb500bccc)
349 lines
8.7 KiB
C
349 lines
8.7 KiB
C
/*
|
|
* Unix SMB/CIFS implementation.
|
|
* MS-RPC client library implementation
|
|
* Copyright (C) Chris Nicholls 2005.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "libmsrpc.h"
|
|
#include "libmsrpc_internal.h"
|
|
#include "libsmbclient.h"
|
|
#include "libsmb_internal.h"
|
|
|
|
/*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
|
|
void cac_Init(int debug) {
|
|
if(debug < 0 || debug > 99)
|
|
debug = 0;
|
|
|
|
DEBUGLEVEL = debug;
|
|
|
|
setup_logging("libmsrpc", True);
|
|
}
|
|
|
|
int cac_InitHandleMem(CacServerHandle *hnd) {
|
|
hnd->username = SMB_MALLOC_ARRAY(char, sizeof(fstring));
|
|
if(!hnd->username)
|
|
return CAC_FAILURE;
|
|
|
|
hnd->username[0] = '\0';
|
|
|
|
hnd->domain = SMB_MALLOC_ARRAY(char, sizeof(fstring));
|
|
if(!hnd->domain)
|
|
return CAC_FAILURE;
|
|
|
|
hnd->domain[0] = '\0';
|
|
|
|
hnd->netbios_name = SMB_MALLOC_ARRAY(char, sizeof(fstring));
|
|
if(!hnd->netbios_name)
|
|
return CAC_FAILURE;
|
|
|
|
hnd->netbios_name[0] = '\0';
|
|
|
|
hnd->password = SMB_MALLOC_ARRAY(char, sizeof(fstring));
|
|
if(!hnd->password)
|
|
return CAC_FAILURE;
|
|
|
|
hnd->password[0] = '\0';
|
|
|
|
hnd->server = SMB_MALLOC_ARRAY(char, sizeof(fstring));
|
|
if(!hnd->server)
|
|
return CAC_FAILURE;
|
|
|
|
hnd->server[0] = '\0';
|
|
|
|
return CAC_SUCCESS;
|
|
}
|
|
|
|
CacServerHandle *cac_NewServerHandle(BOOL allocate_fields) {
|
|
CacServerHandle * hnd;
|
|
|
|
hnd = SMB_MALLOC_P(CacServerHandle);
|
|
|
|
if(!hnd) {
|
|
errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
|
|
ZERO_STRUCTP(hnd);
|
|
|
|
if(allocate_fields == True) {
|
|
if(!cac_InitHandleMem(hnd)) {
|
|
SAFE_FREE(hnd);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
hnd->_internal.ctx = smbc_new_context();
|
|
if(!hnd->_internal.ctx) {
|
|
cac_FreeHandle(hnd);
|
|
return NULL;
|
|
}
|
|
|
|
hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
|
|
|
|
/*add defaults*/
|
|
hnd->debug = 0;
|
|
|
|
/*start at the highest and it will fall down after trying the functions*/
|
|
hnd->_internal.srv_level = SRV_WIN_2K3;
|
|
|
|
hnd->_internal.user_supplied_ctx = False;
|
|
|
|
return hnd;
|
|
}
|
|
|
|
int cac_InitHandleData(CacServerHandle *hnd) {
|
|
/*store any automatically initialized values*/
|
|
if(!hnd->netbios_name) {
|
|
hnd->netbios_name = SMB_STRDUP(hnd->_internal.ctx->netbios_name);
|
|
}
|
|
else if(hnd->netbios_name[0] == '\0') {
|
|
strncpy(hnd->netbios_name, hnd->_internal.ctx->netbios_name, sizeof(fstring));
|
|
}
|
|
|
|
if(!hnd->username) {
|
|
hnd->username = SMB_STRDUP(hnd->_internal.ctx->user);
|
|
}
|
|
else if(hnd->username[0] == '\0') {
|
|
strncpy(hnd->username, hnd->_internal.ctx->user, sizeof(fstring));
|
|
}
|
|
|
|
if(!hnd->domain) {
|
|
hnd->domain = SMB_STRDUP(hnd->_internal.ctx->workgroup);
|
|
}
|
|
else if(hnd->domain[0] == '\0') {
|
|
strncpy(hnd->domain, hnd->_internal.ctx->workgroup, sizeof(fstring));
|
|
}
|
|
|
|
return CAC_SUCCESS;
|
|
}
|
|
|
|
void cac_SetAuthDataFn(CacServerHandle *hnd, smbc_get_auth_data_fn auth_fn) {
|
|
hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
|
|
}
|
|
|
|
void cac_SetSmbcContext(CacServerHandle *hnd, SMBCCTX *ctx) {
|
|
|
|
SAFE_FREE(hnd->_internal.ctx);
|
|
|
|
hnd->_internal.user_supplied_ctx = True;
|
|
|
|
hnd->_internal.ctx = ctx;
|
|
|
|
/*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
|
|
/*cac_InitHandleData(hnd);*/
|
|
}
|
|
|
|
/*used internally*/
|
|
SMBCSRV *cac_GetServer(CacServerHandle *hnd) {
|
|
SMBCSRV *srv;
|
|
|
|
if(!hnd || !hnd->_internal.ctx) {
|
|
return NULL;
|
|
}
|
|
|
|
srv = smbc_attr_server(hnd->_internal.ctx, hnd->server, "IPC$", hnd->domain, hnd->username, hnd->password, NULL);
|
|
if(!srv) {
|
|
hnd->status=NT_STATUS_UNSUCCESSFUL;
|
|
DEBUG(1, ("cac_GetServer: Could not find server connection.\n"));
|
|
}
|
|
|
|
return srv;
|
|
}
|
|
|
|
|
|
int cac_Connect(CacServerHandle *hnd, const char *srv) {
|
|
if(!hnd) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
/*these values should be initialized by the user*/
|
|
if(!hnd->server && !srv) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
|
|
/*change the server name in the server handle if necessary*/
|
|
if(srv && hnd->server && strcmp(hnd->server, srv) == 0) {
|
|
SAFE_FREE(hnd->server);
|
|
hnd->server = SMB_STRDUP(srv);
|
|
}
|
|
|
|
|
|
/*first see if the context has already been setup*/
|
|
if( !(hnd->_internal.ctx->internal->_initialized) ) {
|
|
hnd->_internal.ctx->debug = hnd->debug;
|
|
|
|
/*initialize the context*/
|
|
if(!smbc_init_context(hnd->_internal.ctx)) {
|
|
return CAC_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*copy any uninitialized values out of the smbc context into the handle*/
|
|
if(!cac_InitHandleData(hnd)) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
DEBUG(3, ("cac_Connect: Username: %s\n", hnd->username));
|
|
DEBUG(3, ("cac_Connect: Domain: %s\n", hnd->domain));
|
|
DEBUG(3, ("cac_Connect: Netbios Name: %s\n", hnd->netbios_name));
|
|
|
|
if(!cac_GetServer(hnd)) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
return CAC_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
void cac_FreeHandle(CacServerHandle * hnd) {
|
|
SMBCSRV *srv = NULL;
|
|
uint32 i = 0;
|
|
struct rpc_pipe_client *pipe_hnd = NULL;
|
|
|
|
if(!hnd)
|
|
return;
|
|
|
|
|
|
if(srv) {
|
|
/*close all pipe sessions*/
|
|
cli_nt_pipes_close(&(srv->cli));
|
|
}
|
|
|
|
|
|
/*only free the context if we created it*/
|
|
if(!hnd->_internal.user_supplied_ctx) {
|
|
smbc_free_context(hnd->_internal.ctx, True);
|
|
}
|
|
|
|
SAFE_FREE(hnd->netbios_name);
|
|
SAFE_FREE(hnd->domain);
|
|
SAFE_FREE(hnd->username);
|
|
SAFE_FREE(hnd->password);
|
|
SAFE_FREE(hnd->server);
|
|
SAFE_FREE(hnd);
|
|
|
|
}
|
|
|
|
void cac_InitCacTime(CacTime *cactime, NTTIME nttime) {
|
|
float high, low;
|
|
uint32 sec;
|
|
|
|
if(!cactime)
|
|
return;
|
|
|
|
ZERO_STRUCTP(cactime);
|
|
|
|
/*this code is taken from display_time() found in rpcclient/cmd_samr.c*/
|
|
if (nttime.high==0 && nttime.low==0)
|
|
return;
|
|
|
|
if (nttime.high==0x80000000 && nttime.low==0)
|
|
return;
|
|
|
|
high = 65536;
|
|
high = high/10000;
|
|
high = high*65536;
|
|
high = high/1000;
|
|
high = high * (~nttime.high);
|
|
|
|
low = ~nttime.low;
|
|
low = low/(1000*1000*10);
|
|
|
|
sec=high+low;
|
|
|
|
cactime->days=sec/(60*60*24);
|
|
cactime->hours=(sec - (cactime->days*60*60*24)) / (60*60);
|
|
cactime->minutes=(sec - (cactime->days*60*60*24) - (cactime->hours*60*60) ) / 60;
|
|
cactime->seconds=sec - (cactime->days*60*60*24) - (cactime->hours*60*60) - (cactime->minutes*60);
|
|
}
|
|
|
|
void cac_GetAuthDataFn(const char * pServer,
|
|
const char * pShare,
|
|
char * pWorkgroup,
|
|
int maxLenWorkgroup,
|
|
char * pUsername,
|
|
int maxLenUsername,
|
|
char * pPassword,
|
|
int maxLenPassword)
|
|
|
|
{
|
|
char temp[sizeof(fstring)];
|
|
|
|
static char authUsername[sizeof(fstring)];
|
|
static char authWorkgroup[sizeof(fstring)];
|
|
static char authPassword[sizeof(fstring)];
|
|
static char authSet = 0;
|
|
|
|
char *pass = NULL;
|
|
|
|
|
|
if (authSet)
|
|
{
|
|
strncpy(pWorkgroup, authWorkgroup, maxLenWorkgroup - 1);
|
|
strncpy(pUsername, authUsername, maxLenUsername - 1);
|
|
strncpy(pPassword, authPassword, maxLenPassword - 1);
|
|
}
|
|
else
|
|
{
|
|
d_printf("Domain: [%s] ", pWorkgroup);
|
|
fgets(temp, sizeof(fstring), stdin);
|
|
|
|
if (temp[strlen(temp) - 1] == '\n') /* A new line? */
|
|
{
|
|
temp[strlen(temp) - 1] = '\0';
|
|
}
|
|
|
|
|
|
if (temp[0] != '\0')
|
|
{
|
|
strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
|
|
strncpy(authWorkgroup, temp, maxLenWorkgroup - 1);
|
|
}
|
|
|
|
d_printf("Username: [%s] ", pUsername);
|
|
fgets(temp, sizeof(fstring), stdin);
|
|
|
|
if (temp[strlen(temp) - 1] == '\n') /* A new line? */
|
|
{
|
|
temp[strlen(temp) - 1] = '\0';
|
|
}
|
|
|
|
if (temp[0] != '\0')
|
|
{
|
|
strncpy(pUsername, temp, maxLenUsername - 1);
|
|
strncpy(authUsername, pUsername, maxLenUsername - 1);
|
|
}
|
|
|
|
pass = getpass("Password: ");
|
|
if (pass)
|
|
fstrcpy(temp, pass);
|
|
if (temp[strlen(temp) - 1] == '\n') /* A new line? */
|
|
{
|
|
temp[strlen(temp) - 1] = '\0';
|
|
}
|
|
if (temp[0] != '\0')
|
|
{
|
|
strncpy(pPassword, temp, maxLenPassword - 1);
|
|
strncpy(authPassword, pPassword, maxLenPassword - 1);
|
|
}
|
|
authSet = 1;
|
|
}
|
|
}
|
|
|