/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * There used to be a "redirector" library, which has been replaced, * leaving only the "glue" functions in this file that adapt this * library to the interface provided by libsmbfs. */ #include #include #include #include #include #include #include #include #include #include #include void smbrdr_initialize(void) { (void) smb_lib_init(); } /* * mlsvc_disconnect * * Disconnects the session with given server. * The new conection manager is smart enough * so that we don't need this to do anything. */ /* ARGSUSED */ void smbrdr_disconnect(const char *server) { } /* * smbrdr_logon * * I'm not sure this really needs to do anything, but for now * let's go ahead and authenticate here so this can return a * status reflecting the outcome of authentication. * * If this successfully builds an smb_ctx, it just frees it. * The driver retains sessions for a little while after the * last reference goes away, so the session created here will * usually still exist when the next call to smbrdr_ctx_new * asks for this server+user (immediately after this returns), * and only one session setup will go over the wire. */ int smbrdr_logon(char *srv, char *dom, char *user) { struct smb_ctx *ctx; int err; err = smbrdr_ctx_new(&ctx, srv, dom, user); if (err == 0) smb_ctx_free(ctx); return (err); } void smbrdr_ctx_free(struct smb_ctx *ctx) { smb_ctx_free(ctx); } /* * Setup a new SMB client context. * * Get the SMB server's configuration stuff and * store it in the new client context object. */ int smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server, char *domain, char *user) { struct smb_ctx *ctx = NULL; uchar_t nthash[SMBAUTH_HASH_SZ]; int64_t lmcl; int authflags, err; assert(server != NULL); assert(domain != NULL); assert(user != NULL); if (server[0] == '\0') return (NT_STATUS_INTERNAL_ERROR); if ((err = smb_ctx_alloc(&ctx)) != 0) return (NT_STATUS_NO_MEMORY); /* * Set server, share, domain, user * (in the ctx handle). */ (void) smb_ctx_setfullserver(ctx, server); (void) smb_ctx_setshare(ctx, "IPC$", USE_IPC); (void) smb_ctx_setdomain(ctx, domain, B_TRUE); (void) smb_ctx_setuser(ctx, user, B_TRUE); /* * Set auth. info (hash) and type. */ if (user[0] == '\0') { authflags = SMB_AT_ANON; } else { (void) smb_config_getnum(SMB_CI_LM_LEVEL, &lmcl); if (lmcl <= 2) { /* Send NTLM */ authflags = SMB_AT_NTLM1; } else { /* Send NTLMv2 */ authflags = SMB_AT_NTLM2; } smb_ipc_get_passwd(nthash, sizeof (nthash)); (void) smb_ctx_setpwhash(ctx, nthash, NULL); } (void) smb_ctx_setauthflags(ctx, authflags); /* * Do lookup, connect, session setup, tree connect. * Or find and reuse a session/tree, if one exists. */ if ((err = smb_ctx_resolve(ctx)) != 0) { err = NT_STATUS_BAD_NETWORK_PATH; goto errout; } if ((err = smb_ctx_get_ssn(ctx)) != 0) { switch (err) { case EAUTH: err = NT_STATUS_NETWORK_ACCESS_DENIED; break; default: err = NT_STATUS_BAD_NETWORK_PATH; break; } goto errout; } if ((err = smb_ctx_get_tree(ctx)) != 0) { err = NT_STATUS_BAD_NETWORK_NAME; goto errout; } /* Success! */ *ctx_p = ctx; return (0); errout: smb_ctx_free(ctx); return (err); }