xref: /illumos-gate/usr/src/lib/smbsrv/libmlsvc/common/smbrdr_glue.c (revision b819cea2f73f98c5662230cc9affc8cc84f77fcf)
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 2012 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 ((err = smb_ctx_alloc(&ctx)) != 0)
119 		return (NT_STATUS_NO_MEMORY);
120 
121 	/*
122 	 * Set server, share, domain, user
123 	 * (in the ctx handle).
124 	 */
125 	(void) smb_ctx_setfullserver(ctx, server);
126 	(void) smb_ctx_setshare(ctx, "IPC$", USE_IPC);
127 	(void) smb_ctx_setdomain(ctx, domain, B_TRUE);
128 	(void) smb_ctx_setuser(ctx, user, B_TRUE);
129 
130 	/*
131 	 * Set auth. info (hash) and type.
132 	 */
133 	if (user[0] == '\0') {
134 		authflags = SMB_AT_ANON;
135 	} else {
136 		(void) smb_config_getnum(SMB_CI_LM_LEVEL, &lmcl);
137 		if (lmcl <= 2) {
138 			/* Send NTLM */
139 			authflags = SMB_AT_NTLM1;
140 		} else {
141 			/* Send NTLMv2 */
142 			authflags = SMB_AT_NTLM2;
143 		}
144 		smb_ipc_get_passwd(nthash, sizeof (nthash));
145 		(void) smb_ctx_setpwhash(ctx, nthash, NULL);
146 	}
147 	(void) smb_ctx_setauthflags(ctx, authflags);
148 
149 	/*
150 	 * Do lookup, connect, session setup, tree connect.
151 	 * Or find and reuse a session/tree, if one exists.
152 	 */
153 	if ((err = smb_ctx_resolve(ctx)) != 0) {
154 		err = NT_STATUS_BAD_NETWORK_PATH;
155 		goto errout;
156 	}
157 	if ((err = smb_ctx_get_ssn(ctx)) != 0) {
158 		err = NT_STATUS_NETWORK_ACCESS_DENIED;
159 		goto errout;
160 	}
161 	if ((err = smb_ctx_get_tree(ctx)) != 0) {
162 		err = NT_STATUS_BAD_NETWORK_NAME;
163 		goto errout;
164 	}
165 
166 	/* Success! */
167 	*ctx_p = ctx;
168 	return (0);
169 
170 errout:
171 	smb_ctx_free(ctx);
172 	return (err);
173 }
174