Print this page
NEX-16818 Add fksmbcl development tool
NEX-17264 SMB client test tp_smbutil_013 fails after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (fix ref leaks)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libsmbfs/smb/keychain.c
+++ new/usr/src/lib/libsmbfs/smb/keychain.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 25 * Use is subject to license terms.
26 26 */
27 27
28 28 /*
29 29 * External interface to the libsmbfs/netsmb keychain
30 30 * storage mechanism. This interface is consumed by
31 31 * the "smbutil" commands: login, logout, ...
32 32 * and by the SMBFS PAM module.
33 33 */
34 34
35 35 #include <sys/types.h>
36 36
37 37 #include <errno.h>
38 38 #include <stdio.h>
39 39 #include <stdlib.h>
40 40 #include <string.h>
41 41 #include <unistd.h>
42 42 #include <libintl.h>
43 43
44 44 #include <cflib.h>
45 45 #include <netsmb/smb_dev.h>
46 46 #include <netsmb/smb_lib.h>
47 47 #include <netsmb/smb_keychain.h>
48 48
49 49 #include "charsets.h"
50 50 #include "private.h"
51 51 #include "ntlm.h"
52 52
53 53 /* common func. for add/del/chk */
54 54 static int
55 55 smbfs_keychain_cmn(
56 56 int cmd,
57 57 uid_t uid,
58 58 const char *dom,
59 59 const char *usr,
60 60 uchar_t *lmhash,
61 61 uchar_t *nthash)
62 62 {
63 63 smbioc_pk_t pk;
64 64 int err, fd, sz;
65 65
66 66 memset(&pk, 0, sizeof (pk));
67 67 pk.pk_uid = uid;
68 68 err = 0;
69 69 fd = -1;
70 70
71 71 switch (cmd) {
72 72
73 73 case SMBIOC_PK_ADD:
74 74 /*
75 75 * Add password hashes to the keychain.
76 76 */
77 77 if (lmhash == NULL || nthash == NULL) {
78 78 err = SMB_KEYCHAIN_BADPASSWD;
79 79 goto out;
80 80 }
81 81 memcpy(pk.pk_lmhash, lmhash, SMBIOC_HASH_SZ);
82 82 memcpy(pk.pk_nthash, nthash, SMBIOC_HASH_SZ);
83 83 /* FALLTHROUGH */
84 84
85 85 case SMBIOC_PK_CHK:
86 86 case SMBIOC_PK_DEL:
87 87 /*
88 88 * Copy domain and user.
89 89 */
90 90 if (dom == NULL) {
91 91 err = SMB_KEYCHAIN_BADDOMAIN;
92 92 goto out;
93 93 }
94 94 sz = sizeof (pk.pk_dom);
95 95 if (strlcpy(pk.pk_dom, dom, sz) >= sz) {
96 96 err = SMB_KEYCHAIN_BADDOMAIN;
97 97 goto out;
98 98 }
99 99 if (usr == NULL) {
100 100 err = SMB_KEYCHAIN_BADUSER;
101 101 goto out;
102 102 }
103 103 sz = sizeof (pk.pk_usr);
104 104 if (strlcpy(pk.pk_usr, usr, sz) >= sz) {
105 105 err = SMB_KEYCHAIN_BADUSER;
106 106 goto out;
107 107 }
108 108 break;
109 109
110 110 case SMBIOC_PK_DEL_OWNER: /* all owned by the caller */
111 111 case SMBIOC_PK_DEL_EVERYONE: /* all owned by everyone */
112 112 /*
113 113 * These two do not copyin any args, but we'll
114 114 * pass pk here anyway just so we can use the
115 115 * common code path below.
116 116 */
117 117 break;
118 118
119 119 default:
120 120 err = SMB_KEYCHAIN_UNKNOWN;
|
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
121 121 goto out;
122 122 }
123 123
124 124 fd = smb_open_driver();
125 125 if (fd < 0) {
126 126 err = SMB_KEYCHAIN_NODRIVER;
127 127 goto out;
128 128 }
129 129
130 130 err = 0;
131 - if (ioctl(fd, cmd, &pk) < 0) {
131 + if (nsmb_ioctl(fd, cmd, &pk) < 0) {
132 132 err = errno;
133 133 goto out;
134 134 }
135 135
136 136 if (cmd == SMBIOC_PK_CHK) {
137 137 if (lmhash != NULL)
138 138 memcpy(lmhash, pk.pk_lmhash, SMBIOC_HASH_SZ);
139 139 if (nthash != NULL)
140 140 memcpy(nthash, pk.pk_nthash, SMBIOC_HASH_SZ);
141 141 }
142 142
143 143 out:
144 144 if (fd != -1)
145 - close(fd);
145 + nsmb_close(fd);
146 146
147 147 return (err);
148 148 }
149 149
150 150 /*
151 151 * Add a password to the keychain.
152 152 *
153 153 * Note: pass is a cleartext password.
154 154 * We use it here to compute the LM hash and NT hash,
155 155 * and then store ONLY the hashes.
156 156 */
157 157 int
158 158 smbfs_keychain_add(uid_t uid, const char *dom, const char *usr,
159 159 const char *pass)
160 160 {
161 161 uchar_t lmhash[SMBIOC_HASH_SZ];
162 162 uchar_t nthash[SMBIOC_HASH_SZ];
163 163 int err, cmd = SMBIOC_PK_ADD;
164 164
165 165 if (pass == NULL)
166 166 return (SMB_KEYCHAIN_BADPASSWD);
167 167
168 168 if ((err = ntlm_compute_lm_hash(lmhash, pass)) != 0)
169 169 return (err);
170 170 if ((err = ntlm_compute_nt_hash(nthash, pass)) != 0)
171 171 return (err);
172 172
173 173 err = smbfs_keychain_cmn(cmd, uid, dom, usr, lmhash, nthash);
174 174 return (err);
175 175 }
176 176
177 177 /* Variant of the above that takes an NT hash. */
178 178 int
179 179 smbfs_keychain_addhash(uid_t uid, const char *dom, const char *usr,
180 180 const uchar_t *nthash)
181 181 {
182 182 static const uchar_t lmhash[SMBIOC_HASH_SZ] = { 0 };
183 183 int err, cmd = SMBIOC_PK_ADD;
184 184 err = smbfs_keychain_cmn(cmd, uid, dom, usr,
185 185 (uchar_t *)lmhash, (uchar_t *)nthash);
186 186 return (err);
187 187 }
188 188
189 189 /* Delete a password from the keychain. */
190 190 int
191 191 smbfs_keychain_del(uid_t uid, const char *dom, const char *usr)
192 192 {
193 193 return (smbfs_keychain_cmn(SMBIOC_PK_DEL, uid, dom, usr, NULL, NULL));
194 194 }
195 195
196 196 /*
197 197 * Check for existence of a keychain entry.
198 198 * Returns 0 if it exists, else ENOENT.
199 199 */
200 200 int
201 201 smbfs_keychain_chk(const char *dom, const char *usr)
202 202 {
203 203 uid_t uid = (uid_t)-1;
204 204 return (smbfs_keychain_cmn(SMBIOC_PK_CHK, uid, dom, usr, NULL, NULL));
205 205 }
206 206
207 207 /*
208 208 * Get the stored hashes
209 209 */
210 210 int
211 211 smbfs_keychain_get(const char *dom, const char *usr,
212 212 uchar_t *lmhash, uchar_t *nthash)
213 213 {
214 214 uid_t uid = (uid_t)-1;
215 215 int err, cmd = SMBIOC_PK_CHK;
216 216
217 217 err = smbfs_keychain_cmn(cmd, uid, dom, usr, lmhash, nthash);
218 218 return (err);
219 219 }
220 220
221 221 /*
222 222 * Delete all keychain entries owned by the caller.
223 223 */
224 224 int
225 225 smbfs_keychain_del_owner()
226 226 {
227 227 int cmd = SMBIOC_PK_DEL_OWNER;
228 228 uid_t uid = getuid();
229 229 return (smbfs_keychain_cmn(cmd, uid, NULL, NULL, NULL, NULL));
230 230 }
231 231
232 232 /*
233 233 * Delete all keychain entries (regardless of onwer).
234 234 * Requires super-user privliege.
235 235 */
236 236 int
237 237 smbfs_keychain_del_everyone()
238 238 {
239 239 int cmd = SMBIOC_PK_DEL_EVERYONE;
240 240 uid_t uid = getuid();
241 241 return (smbfs_keychain_cmn(cmd, uid, NULL, NULL, NULL, NULL));
242 242 }
243 243
244 244 /*
245 245 * Private function to get keychain p/w hashes.
246 246 */
247 247 int
248 248 smb_get_keychain(struct smb_ctx *ctx)
249 249 {
250 250 int err;
251 251
252 252 if (ctx->ct_fullserver == NULL) {
253 253 DPRINT("ct_fullserver == NULL");
254 254 return (EINVAL);
255 255 }
256 256
257 257 /*
258 258 * 1st: try lookup using system name
259 259 */
260 260 err = smbfs_keychain_get(ctx->ct_fullserver, ctx->ct_user,
261 261 ctx->ct_lmhash, ctx->ct_nthash);
262 262 if (!err) {
263 263 ctx->ct_flags |= SMBCF_KCFOUND;
264 264 DPRINT("found keychain entry for"
265 265 " server/user: %s/%s\n",
266 266 ctx->ct_fullserver, ctx->ct_user);
267 267 return (0);
268 268 }
269 269
270 270 /*
271 271 * 2nd: try lookup using domain name
272 272 */
273 273 err = smbfs_keychain_get(ctx->ct_domain, ctx->ct_user,
274 274 ctx->ct_lmhash, ctx->ct_nthash);
275 275 if (!err) {
276 276 ctx->ct_flags |= (SMBCF_KCFOUND | SMBCF_KCDOMAIN);
277 277 DPRINT("found keychain entry for"
278 278 " domain/user: %s/%s\n",
279 279 ctx->ct_domain, ctx->ct_user);
280 280 return (0);
281 281 }
282 282
283 283 return (err);
284 284 }
285 285
286 286
287 287 /*
288 288 * This is not really part of the keychain library,
289 289 * but is typically needed in code that wants to
290 290 * provide (editable) defaults for domain/user
291 291 *
292 292 * Get default domain and user names
293 293 * Server name is optional.
294 294 */
295 295 int
296 296 smbfs_default_dom_usr(const char *home, const char *server,
297 297 char *dom, int maxdom, char *usr, int maxusr)
298 298 {
299 299 struct smb_ctx *ctx;
300 300 int err;
301 301
302 302 err = smb_ctx_alloc(&ctx);
303 303 if (err)
304 304 return (err);
305 305
306 306 if (server) {
307 307 err = smb_ctx_setfullserver(ctx, server);
308 308 if (err != 0)
309 309 goto out;
310 310 }
311 311
312 312 if (home && *home) {
313 313 if (ctx->ct_home)
314 314 free(ctx->ct_home);
315 315 ctx->ct_home = strdup(home);
316 316 }
317 317
318 318 err = smb_ctx_readrc(ctx);
319 319 if (err)
320 320 goto out;
321 321
322 322 if (dom)
323 323 strlcpy(dom, ctx->ct_domain, maxdom);
324 324
325 325 if (usr)
326 326 strlcpy(usr, ctx->ct_user, maxusr);
327 327
328 328 out:
329 329 smb_ctx_free(ctx);
330 330 return (err);
331 331 }
|
↓ open down ↓ |
176 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX