Samba客户端SPNEGO登录失败:指定了无效的参数组合

时间:2016-09-26 15:49:55

标签: samba

我正在尝试使用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;
}

1 个答案:

答案 0 :(得分:0)

这个特殊的下面一行引起了这个问题,在我评论之后,它开始工作了。

smbc_setOptionUseNTHash(stSmbClient.smbContext, 1);