Print this page
12513 SMB 3.1.1 support for server
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/smbsrv/libsmb/common/smb_info.c
+++ new/usr/src/lib/smbsrv/libsmb/common/smb_info.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 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 + * Copyright 2020 RackTop Systems, Inc.
24 25 */
25 26
26 27 #include <sys/types.h>
27 28 #include <sys/sockio.h>
28 29 #include <sys/socket.h>
29 30 #include <sys/utsname.h>
30 31
31 32 #include <stdarg.h>
32 33 #include <unistd.h>
33 34 #include <stdlib.h>
34 35 #include <time.h>
35 36 #include <synch.h>
36 37 #include <syslog.h>
37 38 #include <string.h>
38 39 #include <strings.h>
39 40 #include <errno.h>
40 41 #include <net/if.h>
41 42 #include <netdb.h>
42 43 #include <netinet/in.h>
43 44 #include <arpa/nameser.h>
44 45 #include <resolv.h>
45 46
46 47 #include <smbsrv/smbinfo.h>
47 48 #include <smbsrv/netbios.h>
48 49 #include <smbsrv/libsmb.h>
49 50 #include <assert.h>
50 51
51 52 static mutex_t seqnum_mtx;
52 53
53 54 /*
54 55 * IPC connection information that may be passed to the SMB Redirector.
55 56 */
56 57 typedef struct {
57 58 char user[SMB_USERNAME_MAXLEN];
58 59 uint8_t passwd[SMBAUTH_HASH_SZ];
59 60 } smb_ipc_t;
60 61
61 62 static smb_ipc_t ipc_info;
62 63 static smb_ipc_t ipc_orig_info;
63 64 static rwlock_t smb_ipc_lock;
64 65
65 66 /*
66 67 * These three parameters are all related:
67 68 * skc_initial_credits
68 69 * skc_maximum_credits
69 70 * skc_maxworkers (max worker threads)
70 71 * They must be in non-decreasing order. Get the values in order:
71 72 * maxworkers, maximum_credits, initial_credits
72 73 * enforcing maximum values and relations as we go. Then in the
73 74 * opposite order check minimum values and relations.
74 75 *
75 76 * smb_config_getnum puts a zero in the &citem if it fails getting
76 77 * the parameter value. When fetch parameters for which zero is OK,
77 78 * the return code is intentionally ignored.
78 79 */
79 80 void
80 81 smb_load_kconfig(smb_kmod_cfg_t *kcfg)
81 82 {
82 83 struct utsname uts;
83 84 int64_t citem;
84 85 int rc;
85 86
86 87 bzero(kcfg, sizeof (smb_kmod_cfg_t));
87 88
88 89 /*
89 90 * skc_maxworkers (max. no. of taskq worker threads)
90 91 */
91 92 rc = smb_config_getnum(SMB_CI_MAX_WORKERS, &citem);
92 93 if (rc != SMBD_SMF_OK)
93 94 citem = SMB_PI_MAX_WORKERS_DEF;
94 95 if (citem > SMB_PI_MAX_WORKERS_MAX)
95 96 citem = SMB_PI_MAX_WORKERS_MAX;
96 97 kcfg->skc_maxworkers = (uint32_t)citem;
97 98
98 99 /*
99 100 * The largest number of credits we let a single client have.
100 101 * It never makes sense for this to be > max_workers
101 102 */
102 103 rc = smb_config_getnum(SMB_CI_MAXIMUM_CREDITS, &citem);
103 104 if (rc != SMBD_SMF_OK)
104 105 citem = SMB_PI_MAXIMUM_CREDITS_DEF;
105 106 if (citem > SMB_PI_MAXIMUM_CREDITS_MAX)
106 107 citem = SMB_PI_MAXIMUM_CREDITS_MAX;
107 108 kcfg->skc_maximum_credits = (uint16_t)citem;
108 109 if (kcfg->skc_maximum_credits > kcfg->skc_maxworkers)
109 110 kcfg->skc_maximum_credits = (uint16_t)kcfg->skc_maxworkers;
110 111
111 112 /*
112 113 * The number of credits we give a client initially.
113 114 * Should be enough for a "light" workload, as the
114 115 * client will request additional credits when the
115 116 * workload increases. Must be <= maximum_credits.
116 117 */
117 118 rc = smb_config_getnum(SMB_CI_INITIAL_CREDITS, &citem);
118 119 if (rc != SMBD_SMF_OK)
119 120 citem = SMB_PI_INITIAL_CREDITS_DEF;
120 121 if (citem > SMB_PI_INITIAL_CREDITS_MAX)
121 122 citem = SMB_PI_INITIAL_CREDITS_MAX;
122 123 kcfg->skc_initial_credits = (uint16_t)citem;
123 124 if (kcfg->skc_initial_credits > kcfg->skc_maximum_credits)
124 125 kcfg->skc_initial_credits = kcfg->skc_maximum_credits;
125 126
126 127 /*
127 128 * Now enforce minimums, smaller to larger.
128 129 */
129 130 if (kcfg->skc_initial_credits < SMB_PI_INITIAL_CREDITS_MIN)
130 131 kcfg->skc_initial_credits = SMB_PI_INITIAL_CREDITS_MIN;
131 132
132 133 if (kcfg->skc_maximum_credits < SMB_PI_MAXIMUM_CREDITS_MIN)
133 134 kcfg->skc_maximum_credits = SMB_PI_MAXIMUM_CREDITS_MIN;
134 135 if (kcfg->skc_maximum_credits < kcfg->skc_initial_credits)
135 136 kcfg->skc_maximum_credits = kcfg->skc_initial_credits;
136 137
137 138 if (kcfg->skc_maxworkers < SMB_PI_MAX_WORKERS_MIN)
138 139 kcfg->skc_maxworkers = SMB_PI_MAX_WORKERS_MIN;
139 140 if (kcfg->skc_maxworkers < kcfg->skc_maximum_credits)
140 141 kcfg->skc_maxworkers = kcfg->skc_maximum_credits;
141 142
142 143 (void) smb_config_getnum(SMB_CI_KEEPALIVE, &citem);
143 144 kcfg->skc_keepalive = (uint32_t)citem;
144 145 if ((kcfg->skc_keepalive != 0) &&
145 146 (kcfg->skc_keepalive < SMB_PI_KEEP_ALIVE_MIN))
146 147 kcfg->skc_keepalive = SMB_PI_KEEP_ALIVE_MIN;
147 148
148 149 (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &citem);
149 150 kcfg->skc_maxconnections = (uint32_t)citem;
150 151 kcfg->skc_restrict_anon = smb_config_getbool(SMB_CI_RESTRICT_ANON);
151 152 kcfg->skc_signing_enable = smb_config_getbool(SMB_CI_SIGNING_ENABLE);
152 153 kcfg->skc_signing_required = smb_config_getbool(SMB_CI_SIGNING_REQD);
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
153 154 kcfg->skc_netbios_enable = smb_config_getbool(SMB_CI_NETBIOS_ENABLE);
154 155 kcfg->skc_ipv6_enable = smb_config_getbool(SMB_CI_IPV6_ENABLE);
155 156 kcfg->skc_print_enable = smb_config_getbool(SMB_CI_PRINT_ENABLE);
156 157 kcfg->skc_oplock_enable = smb_config_getbool(SMB_CI_OPLOCK_ENABLE);
157 158 kcfg->skc_sync_enable = smb_config_getbool(SMB_CI_SYNC_ENABLE);
158 159 kcfg->skc_traverse_mounts = smb_config_getbool(SMB_CI_TRAVERSE_MOUNTS);
159 160 kcfg->skc_max_protocol = smb_config_get_max_protocol();
160 161 kcfg->skc_min_protocol = smb_config_get_min_protocol();
161 162 kcfg->skc_secmode = smb_config_get_secmode();
162 163 kcfg->skc_encrypt = smb_config_get_require(SMB_CI_ENCRYPT);
164 + kcfg->skc_encrypt_cipher = smb31_config_get_encrypt_cipher();
163 165
164 166 (void) smb_getdomainname(kcfg->skc_nbdomain,
165 167 sizeof (kcfg->skc_nbdomain));
166 168 (void) smb_getfqdomainname(kcfg->skc_fqdn,
167 169 sizeof (kcfg->skc_fqdn));
168 170 (void) smb_getnetbiosname(kcfg->skc_hostname,
169 171 sizeof (kcfg->skc_hostname));
170 172 (void) smb_config_getstr(SMB_CI_SYS_CMNT, kcfg->skc_system_comment,
171 173 sizeof (kcfg->skc_system_comment));
172 174 smb_config_get_version(&kcfg->skc_version);
173 175 kcfg->skc_execflags = smb_config_get_execinfo(NULL, NULL, 0);
174 176 if (smb_config_get_localuuid(kcfg->skc_machine_uuid) < 0) {
175 177 syslog(LOG_ERR, "smb_load_kconfig: no machine_uuid");
176 178 uuid_generate_time(kcfg->skc_machine_uuid);
177 179 }
178 180 /* skc_negtok, skc_negtok_len: see smbd_authsvc.c */
179 181
180 182 (void) uname(&uts);
181 183 (void) snprintf(kcfg->skc_native_os, sizeof (kcfg->skc_native_os),
182 184 "%s %s %s", uts.sysname, uts.release, uts.version);
183 185
184 186 (void) strlcpy(kcfg->skc_native_lm, "Native SMB service",
185 187 sizeof (kcfg->skc_native_lm));
186 188 }
187 189
188 190 /*
189 191 * Get the current system NetBIOS name. The hostname is truncated at
190 192 * the first `.` or 15 bytes, whichever occurs first, and converted
191 193 * to uppercase (by smb_gethostname). Text that appears after the
192 194 * first '.' is considered to be part of the NetBIOS scope.
193 195 *
194 196 * Returns 0 on success, otherwise -1 to indicate an error.
195 197 */
196 198 int
197 199 smb_getnetbiosname(char *buf, size_t buflen)
198 200 {
199 201 if (smb_gethostname(buf, buflen, SMB_CASE_UPPER) != 0)
200 202 return (-1);
201 203
202 204 if (buflen >= NETBIOS_NAME_SZ)
203 205 buf[NETBIOS_NAME_SZ - 1] = '\0';
204 206
205 207 return (0);
206 208 }
207 209
208 210 /*
209 211 * Get the SAM account of the current system.
210 212 * Returns 0 on success, otherwise, -1 to indicate an error.
211 213 */
212 214 int
213 215 smb_getsamaccount(char *buf, size_t buflen)
214 216 {
215 217 if (smb_getnetbiosname(buf, buflen - 1) != 0)
216 218 return (-1);
217 219
218 220 (void) strlcat(buf, "$", buflen);
219 221 return (0);
220 222 }
221 223
222 224 /*
223 225 * Get the current system node name. The returned name is guaranteed
224 226 * to be null-terminated (gethostname may not null terminate the name).
225 227 * If the hostname has been fully-qualified for some reason, the domain
226 228 * part will be removed. The returned hostname is converted to the
227 229 * specified case (lower, upper, or preserved).
228 230 *
229 231 * If gethostname fails, the returned buffer will contain an empty
230 232 * string.
231 233 */
232 234 int
233 235 smb_gethostname(char *buf, size_t buflen, smb_caseconv_t which)
234 236 {
235 237 char *p;
236 238
237 239 if (buf == NULL || buflen == 0)
238 240 return (-1);
239 241
240 242 if (gethostname(buf, buflen) != 0) {
241 243 *buf = '\0';
242 244 return (-1);
243 245 }
244 246
245 247 buf[buflen - 1] = '\0';
246 248
247 249 if ((p = strchr(buf, '.')) != NULL)
248 250 *p = '\0';
249 251
250 252 switch (which) {
251 253 case SMB_CASE_LOWER:
252 254 (void) smb_strlwr(buf);
253 255 break;
254 256
255 257 case SMB_CASE_UPPER:
256 258 (void) smb_strupr(buf);
257 259 break;
258 260
259 261 case SMB_CASE_PRESERVE:
260 262 default:
261 263 break;
262 264 }
263 265
264 266 return (0);
265 267 }
266 268
267 269 /*
268 270 * Obtain the fully-qualified name for this machine in lower case. If
269 271 * the hostname is fully-qualified, accept it. Otherwise, try to find an
270 272 * appropriate domain name to append to the hostname.
271 273 */
272 274 int
273 275 smb_getfqhostname(char *buf, size_t buflen)
274 276 {
275 277 char hostname[MAXHOSTNAMELEN];
276 278 char domain[MAXHOSTNAMELEN];
277 279
278 280 hostname[0] = '\0';
279 281 domain[0] = '\0';
280 282
281 283 if (smb_gethostname(hostname, MAXHOSTNAMELEN,
282 284 SMB_CASE_LOWER) != 0)
283 285 return (-1);
284 286
285 287 if (smb_getfqdomainname(domain, MAXHOSTNAMELEN) != 0)
286 288 return (-1);
287 289
288 290 if (hostname[0] == '\0')
289 291 return (-1);
290 292
291 293 if (domain[0] == '\0') {
292 294 (void) strlcpy(buf, hostname, buflen);
293 295 return (0);
294 296 }
295 297
296 298 (void) snprintf(buf, buflen, "%s.%s", hostname, domain);
297 299 return (0);
298 300 }
299 301
300 302 /*
301 303 * smb_getdomainname
302 304 *
303 305 * Returns NETBIOS name of the domain if the system is in domain
304 306 * mode. Or returns workgroup name if the system is in workgroup
305 307 * mode.
306 308 */
307 309 int
308 310 smb_getdomainname(char *buf, size_t buflen)
309 311 {
310 312 int rc;
311 313
312 314 if (buf == NULL || buflen == 0)
313 315 return (-1);
314 316
315 317 *buf = '\0';
316 318 rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, buf, buflen);
317 319
318 320 if ((rc != SMBD_SMF_OK) || (*buf == '\0'))
319 321 return (-1);
320 322
321 323 return (0);
322 324 }
323 325
324 326 /*
325 327 * smb_getfqdomainname
326 328 *
327 329 * In the system is in domain mode, the dns_domain property value
328 330 * is returned. Otherwise, it returns the local domain obtained via
329 331 * resolver.
330 332 *
331 333 * Returns 0 upon success. Otherwise, returns -1.
332 334 */
333 335 int
334 336 smb_getfqdomainname(char *buf, size_t buflen)
335 337 {
336 338 struct __res_state res_state;
337 339 int rc;
338 340
339 341 if (buf == NULL || buflen == 0)
340 342 return (-1);
341 343
342 344 *buf = '\0';
343 345 if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
344 346 rc = smb_config_getstr(SMB_CI_DOMAIN_FQDN, buf, buflen);
345 347
346 348 if ((rc != SMBD_SMF_OK) || (*buf == '\0'))
347 349 return (-1);
348 350 } else {
349 351 bzero(&res_state, sizeof (struct __res_state));
350 352 if (res_ninit(&res_state))
351 353 return (-1);
352 354
353 355 if (*res_state.defdname == '\0') {
354 356 res_ndestroy(&res_state);
355 357 return (-1);
356 358 }
357 359
358 360 (void) strlcpy(buf, res_state.defdname, buflen);
359 361 res_ndestroy(&res_state);
360 362 rc = 0;
361 363 }
362 364
363 365 return (rc);
364 366 }
365 367
366 368
367 369 /*
368 370 * smb_set_machine_passwd
369 371 *
370 372 * This function should be used when setting the machine password property.
371 373 * The associated sequence number is incremented.
372 374 */
373 375 static int
374 376 smb_set_machine_passwd(char *passwd)
375 377 {
376 378 int64_t num;
377 379 int rc = -1;
378 380
379 381 if (smb_config_set(SMB_CI_MACHINE_PASSWD, passwd) != SMBD_SMF_OK)
380 382 return (-1);
381 383
382 384 (void) mutex_lock(&seqnum_mtx);
383 385 (void) smb_config_getnum(SMB_CI_KPASSWD_SEQNUM, &num);
384 386 if (smb_config_setnum(SMB_CI_KPASSWD_SEQNUM, ++num)
385 387 == SMBD_SMF_OK)
386 388 rc = 0;
387 389 (void) mutex_unlock(&seqnum_mtx);
388 390 return (rc);
389 391 }
390 392
391 393 static int
392 394 smb_get_machine_passwd(uint8_t *buf, size_t buflen)
393 395 {
394 396 char pwd[SMB_PASSWD_MAXLEN + 1];
395 397 int rc;
396 398
397 399 if (buflen < SMBAUTH_HASH_SZ)
398 400 return (-1);
399 401
400 402 rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD, pwd, sizeof (pwd));
401 403 if ((rc != SMBD_SMF_OK) || *pwd == '\0')
402 404 return (-1);
403 405
404 406 if (smb_auth_ntlm_hash(pwd, buf) != 0)
405 407 return (-1);
406 408
407 409 return (rc);
408 410 }
409 411
410 412 /*
411 413 * Set up IPC connection credentials.
412 414 */
413 415 void
414 416 smb_ipc_init(void)
415 417 {
416 418 int rc;
417 419
418 420 (void) rw_wrlock(&smb_ipc_lock);
419 421 bzero(&ipc_info, sizeof (smb_ipc_t));
420 422 bzero(&ipc_orig_info, sizeof (smb_ipc_t));
421 423
422 424 (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
423 425 rc = smb_get_machine_passwd(ipc_info.passwd, SMBAUTH_HASH_SZ);
424 426 if (rc != 0)
425 427 *ipc_info.passwd = 0;
426 428 (void) rw_unlock(&smb_ipc_lock);
427 429
428 430 }
429 431
430 432 /*
431 433 * Set the IPC username and password hash in memory. If the domain
432 434 * join succeeds, the credentials will be committed for use with
433 435 * authenticated IPC. Otherwise, they should be rolled back.
434 436 */
435 437 void
436 438 smb_ipc_set(char *plain_user, uint8_t *passwd_hash)
437 439 {
438 440 (void) rw_wrlock(&smb_ipc_lock);
439 441 (void) strlcpy(ipc_info.user, plain_user, sizeof (ipc_info.user));
440 442 (void) memcpy(ipc_info.passwd, passwd_hash, SMBAUTH_HASH_SZ);
441 443 (void) rw_unlock(&smb_ipc_lock);
442 444
443 445 }
444 446
445 447 /*
446 448 * Save the host credentials to be used for authenticated IPC.
447 449 * The credentials are also saved to the original IPC info as
448 450 * rollback data in case the join domain process fails later.
449 451 */
450 452 void
451 453 smb_ipc_commit(void)
452 454 {
453 455 (void) rw_wrlock(&smb_ipc_lock);
454 456 (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
455 457 (void) smb_get_machine_passwd(ipc_info.passwd, SMBAUTH_HASH_SZ);
456 458 (void) memcpy(&ipc_orig_info, &ipc_info, sizeof (smb_ipc_t));
457 459 (void) rw_unlock(&smb_ipc_lock);
458 460 }
459 461
460 462 /*
461 463 * Restore the original credentials
462 464 */
463 465 void
464 466 smb_ipc_rollback(void)
465 467 {
466 468 (void) rw_wrlock(&smb_ipc_lock);
467 469 (void) strlcpy(ipc_info.user, ipc_orig_info.user,
468 470 sizeof (ipc_info.user));
469 471 (void) memcpy(ipc_info.passwd, ipc_orig_info.passwd,
470 472 sizeof (ipc_info.passwd));
471 473 (void) rw_unlock(&smb_ipc_lock);
472 474 }
473 475
474 476 void
475 477 smb_ipc_get_user(char *buf, size_t buflen)
476 478 {
477 479 (void) rw_rdlock(&smb_ipc_lock);
478 480 (void) strlcpy(buf, ipc_info.user, buflen);
479 481 (void) rw_unlock(&smb_ipc_lock);
480 482 }
481 483
482 484 void
483 485 smb_ipc_get_passwd(uint8_t *buf, size_t buflen)
484 486 {
485 487 if (buflen < SMBAUTH_HASH_SZ)
486 488 return;
487 489
488 490 (void) rw_rdlock(&smb_ipc_lock);
489 491 (void) memcpy(buf, ipc_info.passwd, SMBAUTH_HASH_SZ);
490 492 (void) rw_unlock(&smb_ipc_lock);
491 493 }
492 494
493 495 /*
494 496 * smb_match_netlogon_seqnum
495 497 *
496 498 * A sequence number is associated with each machine password property
497 499 * update and the netlogon credential chain setup. If the
498 500 * sequence numbers don't match, a NETLOGON credential chain
499 501 * establishment is required.
500 502 *
501 503 * Returns 0 if kpasswd_seqnum equals to netlogon_seqnum. Otherwise,
502 504 * returns -1.
503 505 */
504 506 boolean_t
505 507 smb_match_netlogon_seqnum(void)
506 508 {
507 509 int64_t setpasswd_seqnum;
508 510 int64_t netlogon_seqnum;
509 511
510 512 (void) mutex_lock(&seqnum_mtx);
511 513 (void) smb_config_getnum(SMB_CI_KPASSWD_SEQNUM, &setpasswd_seqnum);
512 514 (void) smb_config_getnum(SMB_CI_NETLOGON_SEQNUM, &netlogon_seqnum);
513 515 (void) mutex_unlock(&seqnum_mtx);
514 516 return (setpasswd_seqnum == netlogon_seqnum);
515 517 }
516 518
517 519 /*
518 520 * smb_setdomainprops
519 521 *
520 522 * This function should be called after joining an AD to
521 523 * set all the domain related SMF properties.
522 524 *
523 525 * The kpasswd_domain property is the AD domain to which the system
524 526 * is joined via kclient. If this function is invoked by the SMB
525 527 * daemon, fqdn should be set to NULL.
526 528 */
527 529 int
528 530 smb_setdomainprops(char *fqdn, char *server, char *passwd)
529 531 {
530 532 if (server == NULL || passwd == NULL)
531 533 return (-1);
532 534
533 535 if ((*server == '\0') || (*passwd == '\0'))
534 536 return (-1);
535 537
536 538 if (fqdn && (smb_config_set(SMB_CI_KPASSWD_DOMAIN, fqdn) != 0))
537 539 return (-1);
538 540
539 541 if (smb_config_set(SMB_CI_KPASSWD_SRV, server) != 0)
540 542 return (-1);
541 543
542 544 if (smb_set_machine_passwd(passwd) != 0) {
543 545 syslog(LOG_ERR, "smb_setdomainprops: failed to set"
544 546 " machine account password");
545 547 return (-1);
546 548 }
547 549
548 550 /*
549 551 * If we successfully create a trust account, we mark
550 552 * ourselves as a domain member in the environment so
551 553 * that we use the SAMLOGON version of the NETLOGON
552 554 * PDC location protocol.
553 555 */
554 556 (void) smb_config_setbool(SMB_CI_DOMAIN_MEMB, B_TRUE);
555 557
556 558 return (0);
557 559 }
558 560
559 561 /*
560 562 * smb_update_netlogon_seqnum
561 563 *
562 564 * This function should only be called upon a successful netlogon
563 565 * credential chain establishment to set the sequence number of the
564 566 * netlogon to match with that of the kpasswd.
565 567 */
566 568 void
567 569 smb_update_netlogon_seqnum(void)
568 570 {
569 571 int64_t num;
570 572
571 573 (void) mutex_lock(&seqnum_mtx);
572 574 (void) smb_config_getnum(SMB_CI_KPASSWD_SEQNUM, &num);
573 575 (void) smb_config_setnum(SMB_CI_NETLOGON_SEQNUM, num);
574 576 (void) mutex_unlock(&seqnum_mtx);
575 577 }
576 578
577 579
578 580 /*
579 581 * Temporary fbt for dtrace until user space sdt enabled.
580 582 */
581 583 void
582 584 smb_tracef(const char *fmt, ...)
583 585 {
584 586 va_list ap;
585 587 char buf[128];
586 588
587 589 va_start(ap, fmt);
588 590 (void) vsnprintf(buf, 128, fmt, ap);
589 591 va_end(ap);
590 592
591 593 smb_trace(buf);
592 594 }
593 595
594 596 /*
595 597 * Temporary fbt for dtrace until user space sdt enabled.
596 598 *
597 599 * This function is designed to be used with dtrace, i.e. see:
598 600 * usr/src/cmd/smbsrv/dtrace/smbd-all.d
599 601 *
600 602 * Outside of dtrace, the messages passed to this function usually
601 603 * lack sufficient context to be useful, so we don't log them.
602 604 */
603 605 /* ARGSUSED */
604 606 void
605 607 smb_trace(const char *s)
606 608 {
607 609 }
608 610
609 611 /*
610 612 * smb_tonetbiosname
611 613 *
612 614 * Creates a NetBIOS name based on the given name and suffix.
613 615 * NetBIOS name is 15 capital characters, padded with space if needed
614 616 * and the 16th byte is the suffix.
615 617 */
616 618 void
617 619 smb_tonetbiosname(char *name, char *nb_name, char suffix)
618 620 {
619 621 char tmp_name[NETBIOS_NAME_SZ];
620 622 smb_wchar_t wtmp_name[NETBIOS_NAME_SZ];
621 623 int len;
622 624 size_t rc;
623 625
624 626 len = 0;
625 627 rc = smb_mbstowcs(wtmp_name, (const char *)name, NETBIOS_NAME_SZ);
626 628
627 629 if (rc != (size_t)-1) {
628 630 wtmp_name[NETBIOS_NAME_SZ - 1] = 0;
629 631 rc = ucstooem(tmp_name, wtmp_name, NETBIOS_NAME_SZ,
630 632 OEM_CPG_850);
631 633 if (rc > 0)
632 634 len = strlen(tmp_name);
633 635 }
634 636
635 637 (void) memset(nb_name, ' ', NETBIOS_NAME_SZ - 1);
636 638 if (len) {
637 639 (void) smb_strupr(tmp_name);
638 640 (void) memcpy(nb_name, tmp_name, len);
639 641 }
640 642 nb_name[NETBIOS_NAME_SZ - 1] = suffix;
641 643 }
642 644
643 645 int
644 646 smb_get_nameservers(smb_inaddr_t *ips, int sz)
645 647 {
646 648 union res_sockaddr_union set[MAXNS];
647 649 int i, cnt;
648 650 struct __res_state res_state;
649 651 char ipstr[INET6_ADDRSTRLEN];
650 652
651 653 if (ips == NULL)
652 654 return (0);
653 655
654 656 bzero(&res_state, sizeof (struct __res_state));
655 657 if (res_ninit(&res_state) < 0)
656 658 return (0);
657 659
658 660 cnt = res_getservers(&res_state, set, MAXNS);
659 661 for (i = 0; i < cnt; i++) {
660 662 if (i >= sz)
661 663 break;
662 664 ips[i].a_family = AF_INET;
663 665 bcopy(&set[i].sin.sin_addr, &ips[i].a_ipv4, NS_INADDRSZ);
664 666 if (inet_ntop(AF_INET, &ips[i].a_ipv4, ipstr,
665 667 INET_ADDRSTRLEN)) {
666 668 syslog(LOG_DEBUG, "Found %s name server\n", ipstr);
667 669 continue;
668 670 }
669 671 ips[i].a_family = AF_INET6;
670 672 bcopy(&set[i].sin.sin_addr, &ips[i].a_ipv6, NS_IN6ADDRSZ);
671 673 if (inet_ntop(AF_INET6, &ips[i].a_ipv6, ipstr,
672 674 INET6_ADDRSTRLEN)) {
673 675 syslog(LOG_DEBUG, "Found %s name server\n", ipstr);
674 676 }
675 677 }
676 678 res_ndestroy(&res_state);
677 679 return (i);
678 680 }
679 681
680 682 /*
681 683 * smb_gethostbyname
682 684 *
683 685 * Looks up a host by the given name. The host entry can come
684 686 * from any of the sources for hosts specified in the
685 687 * /etc/nsswitch.conf and the NetBIOS cache.
686 688 *
687 689 * XXX Invokes nbt_name_resolve API once the NBTD is integrated
688 690 * to look in the NetBIOS cache if getipnodebyname fails.
689 691 *
690 692 * Caller should invoke freehostent to free the returned hostent.
691 693 */
692 694 struct hostent *
693 695 smb_gethostbyname(const char *name, int *err_num)
694 696 {
695 697 struct hostent *h;
696 698
697 699 h = getipnodebyname(name, AF_INET, 0, err_num);
698 700 if ((h == NULL) || h->h_length != INADDRSZ)
699 701 h = getipnodebyname(name, AF_INET6, AI_DEFAULT, err_num);
700 702 return (h);
701 703 }
702 704
703 705 /*
704 706 * smb_gethostbyaddr
705 707 *
706 708 * Looks up a host by the given IP address. The host entry can come
707 709 * from any of the sources for hosts specified in the
708 710 * /etc/nsswitch.conf and the NetBIOS cache.
709 711 *
710 712 * XXX Invokes nbt API to resolve name by IP once the NBTD is integrated
711 713 * to look in the NetBIOS cache if getipnodebyaddr fails.
712 714 *
713 715 * Caller should invoke freehostent to free the returned hostent.
714 716 */
715 717 struct hostent *
716 718 smb_gethostbyaddr(const char *addr, int len, int type, int *err_num)
717 719 {
718 720 struct hostent *h;
719 721
720 722 h = getipnodebyaddr(addr, len, type, err_num);
721 723
722 724 return (h);
723 725 }
↓ open down ↓ |
551 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX