c# - Mono DllImport libsmbclient not authenticating -
i need able access samba/cifs share mono using specific credentials.
the best option i've found far use libsmbclient. unfortunately, can't authenticate. rule out firewall/security/etc, i've tried using smbclient
executable can connect without issue.
the low-level dllimport stuff , hard-coded creds testing...
public static void initialise() { log.trace("initialising libsmbclient wrapper"); try { smbc_init(callbackauth, 1); } catch (exception e) { log.trace(string.format("{0}: {1}", e.gettype().name, e.tostring())); throw; } } public static void callbackauth( [marshalas(unmanagedtype.lpstr)]string server, [marshalas(unmanagedtype.lpstr)]string share, [marshalas(unmanagedtype.lpstr)]string workgroup, int workgroupmaxlen, [marshalas(unmanagedtype.lpstr)]string username, int usernamemaxlen, [marshalas(unmanagedtype.lpstr)]string password, int passwordmaxlen) { server = "targetserver"; share = "public"; username = "management.service"; password = @"{somecomplexpassword}"; workgroup = "targetserver"; usernamemaxlen = username.length; passwordmaxlen = password.length; workgroupmaxlen = workgroup.length; } [dllimport("libsmbclient.so", setlasterror = true)] extern internal static int smbc_init(smbcgetauthdatafn callbackauth, int debug); [dllimport("libsmbclient.so", setlasterror = true)] extern internal static int smbc_opendir([marshalas(unmanagedtype.lpstr)]string durl);
i'm attempting use this...
public bool directoryexists(string path) { log.trace("checking directory exists {0}", path); int handle; string fullpath = @"smb:" + parseuncpath(path); handle = sambawrapper.smbc_opendir(fullpath); if (handle < 0) { var error = stdlib.getlasterror().tostring(); if (error == "enoent" |error == "einval") return false; else throw new exception(error); } else { wrappersambaclient.smbc_close(fd); return true; } }
the initialise()
call succeeds when directoryexists
calls sambawrapper.smbc_opendir(fullpath)
negative handle , throw following exception...
slurpy.exceptions.fetchexception: exception: failed fetch: eacces > (file:////targetserver/public/validsubfolder) ---> system.exception: eacces
what doing wrong? there way can debug this?
edit: seems issues values auth callback have no effect (but callback being called log statement in there processed). i'm wondering if it's immutability of strings , new string instance being created new values rather overwriting old?
edit: full debug output libsmbclient attempting connect removed. can see in edit history if required.
as requested, definition of method headers...
/**@ingroup misc * initialize samba client library. * * must called before using of smbclient api function * * @param fn function called obtaion * authentication credentials. * * @param debug allows caller set debug level. can * changed in smb.conf file. allows caller set * debugging if no smb.conf. * * @return 0 on success, < 0 on error errno set: * - enomem out of memory * - enoent smb.conf file not load * */ int smbc_init(smbc_get_auth_data_fn fn, int debug); /**@ingroup callback * authentication callback function type (traditional method) * * type the authentication function called library * obtain authentication credentals * * kerberos support function should called without * prompting user credentials. means simple 'return' * should work. take @ examples/libsmbclient/get_auth_data_fn.h * , examples/libsmbclient/testbrowse.c. * * @param srv server being authenticated * * @param shr share being authenticated * * @param wg pointer buffer containing "hint" * workgroup authenticated. should filled in * correct workgroup if hint wrong. * * @param wglen size of workgroup buffer in bytes * * @param un pointer buffer containing "hint" * user name use authentication. should * filled in correct workgroup if hint * wrong. * * @param unlen size of username buffer in bytes * * @param pw pointer buffer containing password * copied * * @param pwlen size of password buffer in bytes * */ typedef void (*smbc_get_auth_data_fn)(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen);
your callback gets invoked libsmbclient, , passing buffer , length unmanaged code, expecting populate username , password. since allocated memory controlled calling side, cannot use string or stringbuilder. suggest use intptr, , populate buffer on lowest possible level.
(on other hand, server , share read-only strings, , not expected change, can keep them string).
public static void callbackauth( [marshalas(unmanagedtype.lpstr)]string server, [marshalas(unmanagedtype.lpstr)]string share, intptr workgroup, int workgroupmaxlen, intptr username, int usernamemaxlen, intptr password, int passwordmaxlen) { //server = "targetserver"; //share = "public"; // should not assigned - // must provide credentials specified server setstring(username, "management.service", username.length); setstring(password, @"{somecomplexpassword}", password.length); setstring(workgroup, "targetserver", workgroup.length); } private void setstring(intptr dest, string str, int maxlen) { // include null string terminator byte[] buffer = encoding.ascii.getbytes(str + "\0"); if (buffer.length >= maxlen) return; // buffer not big enough marshal.copy(buffer, 0, dest, buffer.length); }
Comments
Post a Comment