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