我正在尝试使用libsmbclient.so文件编写一个samba客户端程序。我在机器x上托管了samba服务器并尝试从机器y访问。即使 - 虽然两者都在相同的工作组中,并且我能够从命令行smbclient工具成功访问,但当我尝试从程序访问时,我继续得到以下错误。无法弄清楚问题,任何帮助都会有很大的用处。尝试使用以下错误进行搜索但未获得与SMB客户端相关的结果。
SPNEGO login failed: An invalid combination of parameters was specified.
完整错误日志
Initilizing SMB Context... 0xf2bb20
Using netbios name SUMAN
Using workgroup WORKGROUP.
Initilizing SMB Context is successfull: 0xf2bb20.
Opening directory... smb://192.168.140.128/smbshare
parsed path: fname='smb://192.168.140.128/smbshare' server='192.168.140.128' share='smbshare' path='' options=''
SMBC_check_options(): server='192.168.140.128' share='smbshare' path='' options=''
Server: 192.168.140.128
Share: smbshare
Workgroup: WORKGROUP
Username: smbuser
Password: password
SMBC_server: server_n=[192.168.140.128] server=[192.168.140.128]
-> server_n=[192.168.140.128] server=[192.168.140.128]
Connecting to 192.168.140.128 at port 445
Socket options:
SO_KEEPALIVE = 0
SO_REUSEADDR = 0
SO_BROADCAST = 0
TCP_NODELAY = 1
TCP_KEEPCNT = 9
TCP_KEEPIDLE = 7200
TCP_KEEPINTVL = 75
IPTOS_LOWDELAY = 0
IPTOS_THROUGHPUT = 0
SO_REUSEPORT = 0
SO_SNDBUF = 87040
SO_RCVBUF = 372480
SO_SNDLOWAT = 1
SO_RCVLOWAT = 1
SO_SNDTIMEO = 0
SO_RCVTIMEO = 0
TCP_QUICKACK = 1
TCP_DEFER_ACCEPT = 0
Doing spnego session setup (blob length=74)
got OID=1.3.6.1.4.1.311.2.2.10
got principal=not_defined_in_RFC4178@please_ignore
GENSEC backend 'gssapi_spnego' registered
GENSEC backend 'gssapi_krb5' registered
GENSEC backend 'gssapi_krb5_sasl' registered
GENSEC backend 'spnego' registered
GENSEC backend 'schannel' registered
GENSEC backend 'naclrpc_as_system' registered
GENSEC backend 'sasl-EXTERNAL' registered
GENSEC backend 'ntlmssp' registered
GENSEC backend 'ntlmssp_resume_ccache' registered
GENSEC backend 'http_basic' registered
GENSEC backend 'http_ntlm' registered
GENSEC backend 'krb5' registered
GENSEC backend 'fake_gssapi_krb5' registered
SPNEGO login failed: An invalid combination of parameters was specified.
Doing spnego session setup (blob length=74)
got OID=1.3.6.1.4.1.311.2.2.10
got principal=not_defined_in_RFC4178@please_ignore
SPNEGO login failed: An invalid combination of parameters was specified.
Couldn't open SMB directory smb://192.168.140.128/smbshare: Workgroup not found
Freeing up the context.
Performing aggressive shutdown.
Context 0xf2bb20 successfully freed
Freeing parametrics:
示例程序是:
#include <iostream>
using namespace std;
#include <libsmbclient.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_BUFFER_LENGTH 1024
#define SMB_WORKGROUP "WORKGROUP"
#define SMB_USERNAME "smbuser"
#define SMB_PASSWORD "password"
#define SMB_PATH "smb://192.168.140.128/smbshare"
typedef struct _SmbClientStruct
{
SMBCCTX *smbContext;
char workgroup[MAX_BUFFER_LENGTH];
char username[MAX_BUFFER_LENGTH];
char password[MAX_BUFFER_LENGTH];
int error;
} SmbClientStruct;
void
smbclient_auth_func (SMBCCTX *ctx, const char *server, const char *share, char *wrkg, int wrkglen, char *user, int userlen, char *pass, int passlen)
{
/* Given context, server and share, return workgroup, username and password.
* String lengths are the max allowable lengths. */
SmbClientStruct *state;
printf("Server: %s\n", server);
printf("Share: %s\n", share);
if (ctx == NULL || (state = (SmbClientStruct *)smbc_getOptionUserData(ctx)) == NULL) {
printf("Not able to get user data. \n");
return;
}
strncpy(wrkg, state->workgroup, (size_t)wrkglen);
strncpy(user, state->username, (size_t)userlen);
strncpy(pass, state->password, (size_t)passlen);
printf("Workgroup: %s\n", wrkg);
printf("Username: %s\n", user);
printf("Password: %s\n", pass);
}
static const char *
type_to_string (unsigned int type)
{
switch (type) {
case SMBC_WORKGROUP : return "workgroup";
case SMBC_SERVER : return "server";
case SMBC_FILE_SHARE : return "file share";
case SMBC_PRINTER_SHARE : return "printer share";
case SMBC_COMMS_SHARE : return "communication share";
case SMBC_IPC_SHARE : return "IPC share";
case SMBC_DIR : return "directory";
case SMBC_FILE : return "file";
case SMBC_LINK : return "link";
}
return "unknown";
}
int main(int argc,char *argv[])
{
SmbClientStruct stSmbClient;
memset(&stSmbClient, 0x0, sizeof(stSmbClient));
stSmbClient.smbContext = smbc_new_context();
strncpy(stSmbClient.workgroup, SMB_WORKGROUP, MAX_BUFFER_LENGTH);
strncpy(stSmbClient.username, SMB_USERNAME, MAX_BUFFER_LENGTH);
strncpy(stSmbClient.password, SMB_PASSWORD, MAX_BUFFER_LENGTH);
smbc_setDebug(stSmbClient.smbContext, atoi(argv[1]));
smbc_setOptionUserData(stSmbClient.smbContext, (void *)&stSmbClient);
smbc_setFunctionAuthDataWithContext(stSmbClient.smbContext, smbclient_auth_func);
smbc_setOptionUseNTHash(stSmbClient.smbContext, 1);
//smbc_setOptionUseKerberos(stSmbClient.smbContext, 1);
//smbc_setOptionFallbackAfterKerberos(stSmbClient.smbContext, 1);
/* Must also save a pointer to the state object inside the context, to
* find the state from the context in the auth function: */
/* Force full, modern timenames when getting xattrs: */
//smbc_setOptionFullTimeNames(stSmbClient.smbContext, 1);
/* Tell the compatibility layer to use this context */
smbc_set_context(stSmbClient.smbContext);
//Init the SMB Context
SMBCCTX *ctx;
printf("\nInitilizing SMB Context... %p\n", stSmbClient.smbContext);
if ((ctx = smbc_init_context(stSmbClient.smbContext)) != NULL) {
stSmbClient.smbContext = ctx;
printf("Initilizing SMB Context is successfull: %p.\n", stSmbClient.smbContext);
} else {
switch (stSmbClient.error = errno) {
case EBADF: printf("Couldn't init SMB context: null context given\n"); break;
case ENOMEM: printf("Couldn't init SMB context: insufficient memory\n"); break;
case ENOENT: printf("Couldn't init SMB context: cannot load smb.conf\n"); break;
default: printf("Couldn't init SMB context: unknown error (%d) (0x%X) \n", errno, errno); break;
}
return -1;
}
//Open the directory
SMBCFILE *dir;
smbc_opendir_fn smbc_opendir;
const char *path = SMB_PATH;
errno = 0;
printf("\nOpening directory... %s\n", path);
if ((smbc_opendir = smbc_getFunctionOpendir(stSmbClient.smbContext)) == NULL) {
printf("Not able to get open directory function.\n");
goto ERROR;
}
if ((dir = smbc_opendir(stSmbClient.smbContext, path)) != NULL) {
printf("Able to open the directory\n");
} else {
switch (stSmbClient.error = errno) {
case EACCES: printf("Couldn't open SMB directory %s: Permission denied\n", path); break;
case EINVAL: printf("Couldn't open SMB directory %s: Invalid URL\n", path); break;
case ENOENT: printf("Couldn't open SMB directory %s: Path does not exist\n", path); break;
case ENOMEM: printf("Couldn't open SMB directory %s: Insufficient memory\n", path); break;
case ENOTDIR: printf("Couldn't open SMB directory %s: Not a directory\n", path); break;
case EPERM: printf("Couldn't open SMB directory %s: Workgroup not found\n", path); break;
case ENODEV: printf("Couldn't open SMB directory %s: Workgroup or server not found\n", path); break;
default: printf("Couldn't open SMB directory %s: unknown error (%d) (0x%X)\n", path, errno, errno); break;
}
goto ERROR;
}
//Read directory
printf("\nReading directory...\n");
struct smbc_dirent *dirent;
smbc_readdir_fn smbc_readdir;
if ((smbc_readdir = smbc_getFunctionReaddir(stSmbClient.smbContext)) == NULL) {
printf("Not able to get read directory function.\n");
goto ERROR;
}
errno = 0;
if ((dirent = smbc_readdir(stSmbClient.smbContext, dir)) == NULL) {
switch (stSmbClient.error = errno) {
//case 0: RETURN_FALSE;
case EBADF: printf("Couldn't read " SMB_PATH ": Not a directory resource\n"); break;
case EINVAL: printf("Couldn't read " SMB_PATH ": State resource not initialized\n"); break;
default: printf("Couldn't read " SMB_PATH ": unknown error (%d)\n", errno); break;
}
goto ERROR;
}
printf("type: %s\n", type_to_string(dirent->smbc_type));
printf("comment: %s, commentlen: %d\n", dirent->comment, dirent->commentlen);
printf("name: %s, namelen: %d \n", dirent->name, dirent->namelen);
//Close directory
printf("\n Closing directory...");
smbc_closedir_fn smbc_closedir;
if ((smbc_closedir = smbc_getFunctionClosedir(stSmbClient.smbContext)) == NULL) {
printf("Not ale to get close directory function\n");
goto ERROR;
}
if (smbc_closedir(stSmbClient.smbContext, dir) == 0) {
printf("Able to close directory successfull.\n");
} else {
switch (stSmbClient.error = errno) {
case EBADF: printf("Couldn't close " SMB_PATH ": Not a directory resource\n"); break;
default: printf("Couldn't close " SMB_PATH ": unknown error (%d)\n", errno); break;
}
goto ERROR;
}
ERROR:
printf("Freeing up the context.\n");
//At the end, destroy the context
smbc_free_context(stSmbClient.smbContext, 1);
return -0;
}
答案 0 :(得分:0)
这个特殊的下面一行引起了这个问题,在我评论之后,它开始工作了。
smbc_setOptionUseNTHash(stSmbClient.smbContext, 1);