1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 /* 28 * There used to be a "redirector" library, which has been replaced, 29 * leaving only the "glue" functions in this file that adapt this 30 * library to the interface provided by libsmbfs. 31 */ 32 33 #include <errno.h> 34 #include <string.h> 35 #include <strings.h> 36 #include <unistd.h> 37 #include <priv.h> 38 39 #include <netsmb/smbfs_api.h> 40 #include <smbsrv/libsmb.h> 41 #include <smbsrv/libmlsvc.h> 42 #include <libsmbrdr.h> 43 #include <mlsvc.h> 44 45 #include <assert.h> 46 47 void 48 smbrdr_initialize(void) 49 { 50 (void) smb_lib_init(); 51 } 52 53 /* 54 * mlsvc_disconnect 55 * 56 * Disconnects the session with given server. 57 * The new conection manager is smart enough 58 * so that we don't need this to do anything. 59 */ 60 /* ARGSUSED */ 61 void 62 smbrdr_disconnect(const char *server) 63 { 64 } 65 66 67 /* 68 * smbrdr_logon 69 * 70 * I'm not sure this really needs to do anything, but for now 71 * let's go ahead and authenticate here so this can return a 72 * status reflecting the outcome of authentication. 73 * 74 * If this successfully builds an smb_ctx, it just frees it. 75 * The driver retains sessions for a little while after the 76 * last reference goes away, so the session created here will 77 * usually still exist when the next call to smbrdr_ctx_new 78 * asks for this server+user (immediately after this returns), 79 * and only one session setup will go over the wire. 80 */ 81 int 82 smbrdr_logon(char *srv, char *dom, char *user) 83 { 84 struct smb_ctx *ctx; 85 int err; 86 87 err = smbrdr_ctx_new(&ctx, srv, dom, user); 88 if (err == 0) 89 smb_ctx_free(ctx); 90 return (err); 91 } 92 93 void 94 smbrdr_ctx_free(struct smb_ctx *ctx) 95 { 96 smb_ctx_free(ctx); 97 } 98 99 /* 100 * Setup a new SMB client context. 101 * 102 * Get the SMB server's configuration stuff and 103 * store it in the new client context object. 104 */ 105 int 106 smbrdr_ctx_new(struct smb_ctx **ctx_p, char *server, 107 char *domain, char *user) 108 { 109 struct smb_ctx *ctx = NULL; 110 uchar_t nthash[SMBAUTH_HASH_SZ]; 111 int64_t lmcl; 112 int authflags, err; 113 114 assert(server != NULL); 115 assert(domain != NULL); 116 assert(user != NULL); 117 118 if (server[0] == '\0') 119 return (NT_STATUS_INTERNAL_ERROR); 120 121 if ((err = smb_ctx_alloc(&ctx)) != 0) 122 return (NT_STATUS_NO_MEMORY); 123 124 /* 125 * Set server, share, domain, user 126 * (in the ctx handle). 127 */ 128 (void) smb_ctx_setfullserver(ctx, server); 129 (void) smb_ctx_setshare(ctx, "IPC$", USE_IPC); 130 (void) smb_ctx_setdomain(ctx, domain, B_TRUE); 131 (void) smb_ctx_setuser(ctx, user, B_TRUE); 132 133 /* 134 * Set auth. info (hash) and type. 135 */ 136 if (user[0] == '\0') { 137 authflags = SMB_AT_ANON; 138 } else { 139 (void) smb_config_getnum(SMB_CI_LM_LEVEL, &lmcl); 140 if (lmcl <= 2) { 141 /* Send NTLM */ 142 authflags = SMB_AT_NTLM1; 143 } else { 144 /* Send NTLMv2 */ 145 authflags = SMB_AT_NTLM2; 146 } 147 smb_ipc_get_passwd(nthash, sizeof (nthash)); 148 (void) smb_ctx_setpwhash(ctx, nthash, NULL); 149 } 150 (void) smb_ctx_setauthflags(ctx, authflags); 151 152 /* 153 * Do lookup, connect, session setup, tree connect. 154 * Or find and reuse a session/tree, if one exists. 155 */ 156 if ((err = smb_ctx_resolve(ctx)) != 0) { 157 err = NT_STATUS_BAD_NETWORK_PATH; 158 goto errout; 159 } 160 if ((err = smb_ctx_get_ssn(ctx)) != 0) { 161 switch (err) { 162 case EAUTH: 163 err = NT_STATUS_NETWORK_ACCESS_DENIED; 164 break; 165 default: 166 err = NT_STATUS_BAD_NETWORK_PATH; 167 break; 168 } 169 goto errout; 170 } 171 if ((err = smb_ctx_get_tree(ctx)) != 0) { 172 err = NT_STATUS_BAD_NETWORK_NAME; 173 goto errout; 174 } 175 176 /* Success! */ 177 *ctx_p = ctx; 178 return (0); 179 180 errout: 181 smb_ctx_free(ctx); 182 return (err); 183 } 184