Samba Client SPNEGO login failed: An invalid combination of parameters was specified
<p>I am trying to write a samba client program by making use of libsmbclient.so file. I hosted samba server on machine x and trying to access from a machine y. Even-though both are in the same work groups and I am able to successfully access from the command line smbclient tool, when I try to access from the program, I keep on getting the below error. Not able to figure out the problem, any help will be of great use. Tried searching with below error but not getting results related to SMB Client.</p>

<pre><code>SPNEGO login failed: An invalid combination of parameters was specified.
</code></pre>

<p>Full error log is</p>

<pre><code>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]
 -&gt; 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:
</code></pre>

<p>Example program is:</p>

<pre><code>#include &lt;iostream&gt;
using namespace std;

#include &lt;libsmbclient.h&gt;
#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

#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-&gt;workgroup, (size_t)wrkglen);
    strncpy(user, state-&gt;username, (size_t)userlen);
    strncpy(pass, state-&gt;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(&amp;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 *)&amp;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-&gt;smbc_type));
    printf("comment: %s, commentlen: %d\n", dirent-&gt;comment, dirent-&gt;commentlen);
    printf("name: %s, namelen: %d \n", dirent-&gt;name, dirent-&gt;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;
}
</code></pre>