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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 22 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 23 */ 24 25 /* 26 * SMB/CIFS share cache implementation. 27 */ 28 29 #include <errno.h> 30 #include <synch.h> 31 #include <stdlib.h> 32 #include <strings.h> 33 #include <syslog.h> 34 #include <thread.h> 35 #include <pthread.h> 36 #include <assert.h> 37 #include <libshare.h> 38 #include <libzfs.h> 39 #include <priv_utils.h> 40 #include <sys/types.h> 41 #include <sys/wait.h> 42 #include <unistd.h> 43 #include <pwd.h> 44 #include <signal.h> 45 #include <dirent.h> 46 #include <dlfcn.h> 47 48 #include <smbsrv/libsmb.h> 49 #include <smbsrv/libsmbns.h> 50 #include <smbsrv/libmlsvc.h> 51 #include <smbsrv/smb_share.h> 52 #include <smbsrv/smb.h> 53 #include <mlsvc.h> 54 #include <dfs.h> 55 56 #define SMB_SHR_ERROR_THRESHOLD 3 57 #define SMB_SHR_CSC_BUFSZ 64 58 59 typedef struct smb_transient { 60 char *name; 61 char *cmnt; 62 char *path; 63 char drive; 64 boolean_t check; 65 } smb_transient_t; 66 67 static smb_transient_t tshare[] = { 68 { "IPC$", "Remote IPC", NULL, '\0', B_FALSE }, 69 { "c$", "Default Share", SMB_CVOL, 'C', B_FALSE }, 70 { "vss$", "VSS", SMB_VSS, 'V', B_TRUE } 71 }; 72 73 static struct { 74 char *value; 75 uint32_t flag; 76 } cscopt[] = { 77 { "disabled", SMB_SHRF_CSC_DISABLED }, 78 { "manual", SMB_SHRF_CSC_MANUAL }, 79 { "auto", SMB_SHRF_CSC_AUTO }, 80 { "vdo", SMB_SHRF_CSC_VDO } 81 }; 82 83 /* 84 * Cache functions and vars 85 */ 86 #define SMB_SHR_HTAB_SZ 1024 87 88 /* 89 * Cache handle 90 * 91 * Shares cache is a hash table. 92 * 93 * sc_cache pointer to hash table handle 94 * sc_cache_lck synchronize cache read/write accesses 95 * sc_state cache state machine values 96 * sc_nops number of inflight/pending cache operations 97 * sc_mtx protects handle fields 98 */ 99 typedef struct smb_shr_cache { 100 HT_HANDLE *sc_cache; 101 rwlock_t sc_cache_lck; 102 mutex_t sc_mtx; 103 cond_t sc_cv; 104 uint32_t sc_state; 105 uint32_t sc_nops; 106 } smb_shr_cache_t; 107 108 /* 109 * Cache states 110 */ 111 #define SMB_SHR_CACHE_STATE_NONE 0 112 #define SMB_SHR_CACHE_STATE_CREATED 1 113 #define SMB_SHR_CACHE_STATE_DESTROYING 2 114 115 /* 116 * Cache lock modes 117 */ 118 #define SMB_SHR_CACHE_RDLOCK 0 119 #define SMB_SHR_CACHE_WRLOCK 1 120 121 static smb_shr_cache_t smb_shr_cache; 122 123 static uint32_t smb_shr_cache_create(void); 124 static void smb_shr_cache_destroy(void); 125 static uint32_t smb_shr_cache_lock(int); 126 static void smb_shr_cache_unlock(void); 127 static int smb_shr_cache_count(void); 128 static smb_share_t *smb_shr_cache_iterate(smb_shriter_t *); 129 130 static smb_share_t *smb_shr_cache_findent(char *); 131 static uint32_t smb_shr_cache_addent(smb_share_t *); 132 static void smb_shr_cache_delent(char *); 133 static void smb_shr_cache_freent(HT_ITEM *); 134 135 static boolean_t smb_shr_is_empty(const char *); 136 static boolean_t smb_shr_is_dot_or_dotdot(const char *); 137 138 /* 139 * sharemgr functions 140 */ 141 static void smb_shr_sa_loadgrp(sa_group_t); 142 static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t); 143 static uint32_t smb_shr_sa_loadbyname(char *); 144 static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *); 145 146 /* 147 * .ZFS management functions 148 */ 149 static void smb_shr_zfs_add(smb_share_t *); 150 static void smb_shr_zfs_remove(smb_share_t *); 151 static void smb_shr_zfs_rename(smb_share_t *, smb_share_t *); 152 153 /* 154 * share publishing 155 */ 156 #define SMB_SHR_PUBLISH 0 157 #define SMB_SHR_UNPUBLISH 1 158 159 typedef struct smb_shr_pitem { 160 list_node_t spi_lnd; 161 char spi_name[MAXNAMELEN]; 162 char spi_container[MAXPATHLEN]; 163 char spi_op; 164 } smb_shr_pitem_t; 165 166 /* 167 * publish queue states 168 */ 169 #define SMB_SHR_PQS_NOQUEUE 0 170 #define SMB_SHR_PQS_READY 1 /* the queue is ready */ 171 #define SMB_SHR_PQS_PUBLISHING 2 /* publisher thread is running */ 172 #define SMB_SHR_PQS_STOPPING 3 173 174 /* 175 * share publishing queue 176 */ 177 typedef struct smb_shr_pqueue { 178 list_t spq_list; 179 mutex_t spq_mtx; 180 cond_t spq_cv; 181 uint32_t spq_state; 182 } smb_shr_pqueue_t; 183 184 static smb_shr_pqueue_t ad_queue; 185 186 static int smb_shr_publisher_start(void); 187 static void smb_shr_publisher_stop(void); 188 static void smb_shr_publisher_send(smb_ads_handle_t *, list_t *, const char *); 189 static void smb_shr_publisher_queue(const char *, const char *, char); 190 static void *smb_shr_publisher(void *); 191 static void smb_shr_publisher_flush(list_t *); 192 static void smb_shr_publish(const char *, const char *); 193 static void smb_shr_unpublish(const char *, const char *); 194 195 /* 196 * Utility/helper functions 197 */ 198 static uint32_t smb_shr_lookup(char *, smb_share_t *); 199 static uint32_t smb_shr_add_transient(char *, char *, char *); 200 static int smb_shr_enable_all_privs(void); 201 static int smb_shr_expand_subs(char **, smb_share_t *, smb_shr_execinfo_t *); 202 static char **smb_shr_tokenize_cmd(char *); 203 static void smb_shr_sig_abnormal_term(int); 204 static void smb_shr_sig_child(int); 205 static int smb_shr_encode(smb_share_t *, nvlist_t **); 206 207 /* 208 * libshare handle and synchronization 209 */ 210 typedef struct smb_sa_handle { 211 sa_handle_t sa_handle; 212 mutex_t sa_mtx; 213 boolean_t sa_in_service; 214 } smb_sa_handle_t; 215 216 static smb_sa_handle_t smb_sa_handle; 217 218 static char smb_shr_exec_map[MAXPATHLEN]; 219 static char smb_shr_exec_unmap[MAXPATHLEN]; 220 static mutex_t smb_shr_exec_mtx; 221 222 /* 223 * Semaphore held during temporary, process-wide changes 224 * such as process privileges. It is a seamaphore and 225 * not a mutex so a child of fork can reset it. 226 */ 227 static sema_t smb_proc_sem = DEFAULTSEMA; 228 229 /* 230 * Creates and initializes the cache and starts the publisher 231 * thread. 232 */ 233 int 234 smb_shr_start(void) 235 { 236 smb_transient_t *ts; 237 uint32_t nerr; 238 int i; 239 240 (void) mutex_lock(&smb_sa_handle.sa_mtx); 241 smb_sa_handle.sa_in_service = B_TRUE; 242 (void) mutex_unlock(&smb_sa_handle.sa_mtx); 243 244 if (smb_shr_cache_create() != NERR_Success) 245 return (ENOMEM); 246 247 for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) { 248 ts = &tshare[i]; 249 250 if (ts->check && smb_shr_is_empty(ts->path)) 251 continue; 252 253 nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path); 254 if (nerr != NERR_Success) 255 return (ENOMEM); 256 } 257 258 return (smb_shr_publisher_start()); 259 } 260 261 void 262 smb_shr_stop(void) 263 { 264 smb_shr_cache_destroy(); 265 smb_shr_publisher_stop(); 266 267 (void) mutex_lock(&smb_sa_handle.sa_mtx); 268 smb_sa_handle.sa_in_service = B_FALSE; 269 270 if (smb_sa_handle.sa_handle != NULL) { 271 sa_fini(smb_sa_handle.sa_handle); 272 smb_sa_handle.sa_handle = NULL; 273 } 274 275 (void) mutex_unlock(&smb_sa_handle.sa_mtx); 276 } 277 278 /* 279 * Get a handle and exclusive access to the libshare API. 280 */ 281 sa_handle_t 282 smb_shr_sa_enter(void) 283 { 284 (void) mutex_lock(&smb_sa_handle.sa_mtx); 285 if (!smb_sa_handle.sa_in_service) { 286 (void) mutex_unlock(&smb_sa_handle.sa_mtx); 287 return (NULL); 288 } 289 290 if (smb_sa_handle.sa_handle != NULL && 291 sa_needs_refresh(smb_sa_handle.sa_handle)) { 292 sa_fini(smb_sa_handle.sa_handle); 293 smb_sa_handle.sa_handle = NULL; 294 } 295 296 if (smb_sa_handle.sa_handle == NULL) { 297 smb_sa_handle.sa_handle = sa_init(SA_INIT_SHARE_API); 298 if (smb_sa_handle.sa_handle == NULL) { 299 syslog(LOG_ERR, "share: failed to get libshare handle"); 300 (void) mutex_unlock(&smb_sa_handle.sa_mtx); 301 return (NULL); 302 } 303 } 304 305 return (smb_sa_handle.sa_handle); 306 } 307 308 /* 309 * Release exclusive access to the libshare API. 310 */ 311 void 312 smb_shr_sa_exit(void) 313 { 314 (void) mutex_unlock(&smb_sa_handle.sa_mtx); 315 } 316 317 /* 318 * Return the total number of shares 319 */ 320 int 321 smb_shr_count(void) 322 { 323 int n_shares = 0; 324 325 if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { 326 n_shares = smb_shr_cache_count(); 327 smb_shr_cache_unlock(); 328 } 329 330 return (n_shares); 331 } 332 333 /* 334 * smb_shr_iterinit 335 * 336 * Initialize given iterator for traversing hash table. 337 */ 338 void 339 smb_shr_iterinit(smb_shriter_t *shi) 340 { 341 bzero(shi, sizeof (smb_shriter_t)); 342 shi->si_first = B_TRUE; 343 } 344 345 /* 346 * smb_shr_iterate 347 * 348 * Iterate on the shares in the hash table. The iterator must be initialized 349 * before the first iteration. On subsequent calls, the iterator must be 350 * passed unchanged. 351 * 352 * Returns NULL on failure or when all shares are visited, otherwise 353 * returns information of visited share. 354 */ 355 smb_share_t * 356 smb_shr_iterate(smb_shriter_t *shi) 357 { 358 smb_share_t *share = NULL; 359 smb_share_t *cached_si; 360 361 if (shi == NULL) 362 return (NULL); 363 364 if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { 365 if ((cached_si = smb_shr_cache_iterate(shi)) != NULL) { 366 share = &shi->si_share; 367 bcopy(cached_si, share, sizeof (smb_share_t)); 368 } 369 smb_shr_cache_unlock(); 370 } 371 372 return (share); 373 } 374 375 /* 376 * Adds the given share to cache, publishes the share in ADS 377 * if it has an AD container, calls kernel to take a hold on 378 * the shared file system. If it can't take a hold on the 379 * shared file system, it's either because shared directory 380 * does not exist or some other error has occurred, in any 381 * case the share is removed from the cache. 382 * 383 * If the specified share is an autohome share which already 384 * exists in the cache, just increments the reference count. 385 */ 386 uint32_t 387 smb_shr_add(smb_share_t *si) 388 { 389 struct stat st; 390 smb_share_t *cached_si; 391 nvlist_t *shrlist; 392 boolean_t created_zfs = B_FALSE; 393 uint32_t status; 394 int rc; 395 396 assert(si != NULL); 397 398 if (smb_name_validate_share(si->shr_name) != ERROR_SUCCESS) 399 return (ERROR_INVALID_NAME); 400 401 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success) 402 return (NERR_InternalError); 403 404 cached_si = smb_shr_cache_findent(si->shr_name); 405 if (cached_si) { 406 if (si->shr_flags & SMB_SHRF_AUTOHOME) { 407 cached_si->shr_refcnt++; 408 status = NERR_Success; 409 } else { 410 status = NERR_DuplicateShare; 411 } 412 smb_shr_cache_unlock(); 413 return (status); 414 } 415 416 if (STYPE_ISDSK(si->shr_type)) { 417 /* 418 * If share type is STYPE_DISKTREE then the path to the 419 * share should exist so that we can add the share to cache. 420 * If path is ZFS, add the .zfs/shares/<share> entry. 421 * 422 * Both actions may require privileges that main dropped, 423 * so we need to temporarily make those effective. 424 */ 425 if (smb_proc_takesem() == 0) { 426 427 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 428 PRIV_FILE_DAC_READ, 429 PRIV_FILE_DAC_SEARCH, 430 PRIV_FILE_DAC_WRITE, 431 NULL); 432 433 rc = stat(si->shr_path, &st); 434 if (rc == 0) { 435 smb_shr_zfs_add(si); 436 created_zfs = B_TRUE; 437 } 438 439 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 440 PRIV_FILE_DAC_READ, 441 PRIV_FILE_DAC_SEARCH, 442 PRIV_FILE_DAC_WRITE, 443 NULL); 444 smb_proc_givesem(); 445 } else { 446 rc = NERR_InternalError; 447 } 448 if (rc != 0) { 449 smb_shr_cache_unlock(); 450 return (NERR_ItemNotFound); 451 } 452 } 453 454 if ((status = smb_shr_cache_addent(si)) != NERR_Success) { 455 /* This error should be impossible after findent above. */ 456 smb_shr_cache_unlock(); 457 return (status); 458 } 459 460 /* don't hold the lock across door call */ 461 smb_shr_cache_unlock(); 462 463 if ((rc = smb_shr_encode(si, &shrlist)) == 0) { 464 /* send the share to kernel */ 465 rc = smb_kmod_share(shrlist); 466 nvlist_free(shrlist); 467 468 if (rc == 0) { 469 smb_shr_publish(si->shr_name, si->shr_container); 470 471 if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) 472 dfs_namespace_load(si->shr_name); 473 474 return (NERR_Success); 475 } 476 } 477 478 /* 479 * Error code path, i.e. when the kernel could not accept 480 * the new share for some reason. 481 */ 482 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) { 483 smb_shr_cache_delent(si->shr_name); 484 smb_shr_cache_unlock(); 485 } 486 487 if (created_zfs && smb_proc_takesem() == 0) { 488 489 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 490 PRIV_FILE_DAC_READ, 491 PRIV_FILE_DAC_SEARCH, 492 PRIV_FILE_DAC_WRITE, 493 NULL); 494 495 smb_shr_zfs_remove(si); 496 497 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 498 PRIV_FILE_DAC_READ, 499 PRIV_FILE_DAC_SEARCH, 500 PRIV_FILE_DAC_WRITE, 501 NULL); 502 503 smb_proc_givesem(); 504 } 505 506 /* 507 * rc == ENOENT means the shared directory doesn't exist 508 */ 509 return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError); 510 } 511 512 /* 513 * Removes the specified share from cache, removes it from AD 514 * if it has an AD container, and calls the kernel to release 515 * the hold on the shared file system. 516 * 517 * If this is an autohome share then decrement the reference 518 * count. If it reaches 0 then it proceeds with removing steps. 519 */ 520 uint32_t 521 smb_shr_remove(char *sharename) 522 { 523 smb_share_t *si; 524 char container[MAXPATHLEN]; 525 boolean_t dfsroot; 526 nvlist_t *shrlist; 527 528 assert(sharename != NULL); 529 530 if (smb_name_validate_share(sharename) != ERROR_SUCCESS) 531 return (ERROR_INVALID_NAME); 532 533 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success) 534 return (NERR_InternalError); 535 536 if ((si = smb_shr_cache_findent(sharename)) == NULL) { 537 smb_shr_cache_unlock(); 538 return (NERR_NetNameNotFound); 539 } 540 541 if (STYPE_ISIPC(si->shr_type)) { 542 /* IPC$ share cannot be removed */ 543 smb_shr_cache_unlock(); 544 return (ERROR_ACCESS_DENIED); 545 } 546 547 if (si->shr_flags & SMB_SHRF_AUTOHOME) { 548 if ((--si->shr_refcnt) > 0) { 549 smb_shr_cache_unlock(); 550 return (NERR_Success); 551 } 552 } 553 554 /* 555 * If path is ZFS, remove the .zfs/shares/<share> entry. Need 556 * to remove before cleanup of cache occurs. These actions 557 * require temporary elevation of privileges. 558 */ 559 if (smb_proc_takesem() == 0) { 560 561 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 562 PRIV_FILE_DAC_READ, 563 PRIV_FILE_DAC_SEARCH, 564 PRIV_FILE_DAC_WRITE, 565 NULL); 566 567 smb_shr_zfs_remove(si); 568 569 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 570 PRIV_FILE_DAC_READ, 571 PRIV_FILE_DAC_SEARCH, 572 PRIV_FILE_DAC_WRITE, 573 NULL); 574 575 smb_proc_givesem(); 576 } 577 578 (void) smb_shr_encode(si, &shrlist); 579 580 (void) strlcpy(container, si->shr_container, sizeof (container)); 581 dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0); 582 smb_shr_cache_delent(sharename); 583 smb_shr_cache_unlock(); 584 585 smb_shr_unpublish(sharename, container); 586 587 /* call kernel to release the hold on the shared file system */ 588 if (shrlist != NULL) { 589 (void) smb_kmod_unshare(shrlist); 590 nvlist_free(shrlist); 591 } 592 593 if (dfsroot) 594 dfs_namespace_unload(sharename); 595 596 return (NERR_Success); 597 } 598 599 /* 600 * Rename a share. Check that the current name exists and the new name 601 * doesn't exist. The rename is performed by deleting the current share 602 * definition and creating a new share with the new name. 603 */ 604 uint32_t 605 smb_shr_rename(char *from_name, char *to_name) 606 { 607 smb_share_t *from_si; 608 smb_share_t to_si; 609 uint32_t status; 610 nvlist_t *shrlist; 611 612 assert((from_name != NULL) && (to_name != NULL)); 613 614 if (smb_name_validate_share(from_name) != ERROR_SUCCESS || 615 smb_name_validate_share(to_name) != ERROR_SUCCESS) 616 return (ERROR_INVALID_NAME); 617 618 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success) 619 return (NERR_InternalError); 620 621 if ((from_si = smb_shr_cache_findent(from_name)) == NULL) { 622 smb_shr_cache_unlock(); 623 return (NERR_NetNameNotFound); 624 } 625 626 if (STYPE_ISIPC(from_si->shr_type)) { 627 /* IPC$ share cannot be renamed */ 628 smb_shr_cache_unlock(); 629 return (ERROR_ACCESS_DENIED); 630 } 631 632 if (smb_shr_cache_findent(to_name) != NULL) { 633 smb_shr_cache_unlock(); 634 return (NERR_DuplicateShare); 635 } 636 637 bcopy(from_si, &to_si, sizeof (smb_share_t)); 638 (void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name)); 639 640 /* If path is ZFS, rename the .zfs/shares/<share> entry. */ 641 if (smb_proc_takesem() == 0) { 642 643 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 644 PRIV_FILE_DAC_READ, 645 PRIV_FILE_DAC_SEARCH, 646 PRIV_FILE_DAC_WRITE, 647 NULL); 648 649 smb_shr_zfs_rename(from_si, &to_si); 650 651 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 652 PRIV_FILE_DAC_READ, 653 PRIV_FILE_DAC_SEARCH, 654 PRIV_FILE_DAC_WRITE, 655 NULL); 656 657 smb_proc_givesem(); 658 } 659 660 if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) { 661 smb_shr_cache_unlock(); 662 return (status); 663 } 664 665 smb_shr_cache_delent(from_name); 666 smb_shr_cache_unlock(); 667 668 if (smb_shr_encode(from_si, &shrlist) == 0) { 669 (void) smb_kmod_unshare(shrlist); 670 nvlist_free(shrlist); 671 672 if (smb_shr_encode(&to_si, &shrlist) == 0) { 673 (void) smb_kmod_share(shrlist); 674 nvlist_free(shrlist); 675 } 676 } 677 678 smb_shr_unpublish(from_name, to_si.shr_container); 679 smb_shr_publish(to_name, to_si.shr_container); 680 681 return (NERR_Success); 682 } 683 684 /* 685 * Load the information for the specified share into the supplied share 686 * info structure. 687 * 688 * First looks up the cache to see if the specified share exists, if there 689 * is a miss then it looks up sharemgr. 690 */ 691 uint32_t 692 smb_shr_get(char *sharename, smb_share_t *si) 693 { 694 uint32_t status; 695 696 if (sharename == NULL || *sharename == '\0') 697 return (NERR_NetNameNotFound); 698 699 if ((status = smb_shr_lookup(sharename, si)) == NERR_Success) 700 return (status); 701 702 if ((status = smb_shr_sa_loadbyname(sharename)) == NERR_Success) 703 status = smb_shr_lookup(sharename, si); 704 705 return (status); 706 } 707 708 /* 709 * Modifies an existing share. Properties that can be modified are: 710 * 711 * o comment 712 * o AD container 713 * o host access 714 * o flags 715 */ 716 uint32_t 717 smb_shr_modify(smb_share_t *new_si) 718 { 719 smb_share_t old_si; 720 smb_share_t *si; 721 boolean_t adc_changed = B_FALSE; 722 boolean_t quota_flag_changed = B_FALSE; 723 uint32_t access, flag; 724 nvlist_t *shrlist; 725 726 assert(new_si != NULL); 727 728 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success) 729 return (NERR_InternalError); 730 731 if ((si = smb_shr_cache_findent(new_si->shr_name)) == NULL) { 732 smb_shr_cache_unlock(); 733 return (NERR_NetNameNotFound); 734 } 735 736 if (STYPE_ISIPC(si->shr_type)) { 737 /* IPC$ share cannot be modified */ 738 smb_shr_cache_unlock(); 739 return (ERROR_ACCESS_DENIED); 740 } 741 742 /* 743 * Keep a copy of what the share entry looks like before we 744 * modify it. We need this for things like unpublishing 745 * from the old share container, removing the quota dir. 746 */ 747 bcopy(si, &old_si, sizeof (old_si)); 748 749 /* Share comment */ 750 (void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt)); 751 752 /* Container */ 753 (void) strlcpy(si->shr_container, new_si->shr_container, 754 sizeof (si->shr_container)); 755 adc_changed = (strcmp(old_si.shr_container, si->shr_container) != 0); 756 757 flag = (new_si->shr_flags & SMB_SHRF_ABE); 758 si->shr_flags &= ~SMB_SHRF_ABE; 759 si->shr_flags |= flag; 760 761 flag = (new_si->shr_flags & SMB_SHRF_CATIA); 762 si->shr_flags &= ~SMB_SHRF_CATIA; 763 si->shr_flags |= flag; 764 765 flag = (new_si->shr_flags & SMB_SHRF_GUEST_OK); 766 si->shr_flags &= ~SMB_SHRF_GUEST_OK; 767 si->shr_flags |= flag; 768 769 flag = (new_si->shr_flags & SMB_SHRF_DFSROOT); 770 si->shr_flags &= ~SMB_SHRF_DFSROOT; 771 si->shr_flags |= flag; 772 773 flag = (new_si->shr_flags & SMB_SHRF_CA); 774 si->shr_flags &= ~SMB_SHRF_CA; 775 si->shr_flags |= flag; 776 777 flag = (new_si->shr_flags & SMB_SHRF_FSO); 778 si->shr_flags &= ~SMB_SHRF_FSO; 779 si->shr_flags |= flag; 780 781 flag = (new_si->shr_flags & SMB_SHRF_QUOTAS); 782 si->shr_flags &= ~SMB_SHRF_QUOTAS; 783 si->shr_flags |= flag; 784 if ((old_si.shr_flags ^ si->shr_flags) & SMB_SHRF_QUOTAS) 785 quota_flag_changed = B_TRUE; 786 787 flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK); 788 si->shr_flags &= ~SMB_SHRF_CSC_MASK; 789 si->shr_flags |= flag; 790 791 access = (new_si->shr_flags & SMB_SHRF_ACC_ALL); 792 si->shr_flags &= ~SMB_SHRF_ACC_ALL; 793 si->shr_flags |= access; 794 795 si->shr_encrypt = new_si->shr_encrypt; 796 797 if (access & SMB_SHRF_ACC_NONE) 798 (void) strlcpy(si->shr_access_none, new_si->shr_access_none, 799 sizeof (si->shr_access_none)); 800 801 if (access & SMB_SHRF_ACC_RO) 802 (void) strlcpy(si->shr_access_ro, new_si->shr_access_ro, 803 sizeof (si->shr_access_ro)); 804 805 if (access & SMB_SHRF_ACC_RW) 806 (void) strlcpy(si->shr_access_rw, new_si->shr_access_rw, 807 sizeof (si->shr_access_rw)); 808 809 smb_shr_cache_unlock(); 810 811 if (smb_shr_encode(si, &shrlist) == 0) { 812 (void) smb_kmod_unshare(shrlist); 813 nvlist_free(shrlist); 814 815 if (smb_shr_encode(new_si, &shrlist) == 0) { 816 (void) smb_kmod_share(shrlist); 817 nvlist_free(shrlist); 818 } 819 } 820 821 if (adc_changed) { 822 smb_shr_unpublish(old_si.shr_name, old_si.shr_container); 823 smb_shr_publish(new_si->shr_name, new_si->shr_container); 824 } 825 826 /* The following required privileges we dropped. */ 827 if (quota_flag_changed && smb_proc_takesem() == 0) { 828 829 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 830 PRIV_FILE_DAC_READ, 831 PRIV_FILE_DAC_SEARCH, 832 PRIV_FILE_DAC_WRITE, 833 NULL); 834 835 smb_shr_zfs_remove(&old_si); 836 smb_shr_zfs_add(si); 837 838 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 839 PRIV_FILE_DAC_READ, 840 PRIV_FILE_DAC_SEARCH, 841 PRIV_FILE_DAC_WRITE, 842 NULL); 843 844 smb_proc_givesem(); 845 } 846 847 return (NERR_Success); 848 } 849 850 /* 851 * smb_shr_exists 852 * 853 * Returns B_TRUE if the share exists. Otherwise returns B_FALSE 854 */ 855 boolean_t 856 smb_shr_exists(char *sharename) 857 { 858 boolean_t exists = B_FALSE; 859 860 if (sharename == NULL || *sharename == '\0') 861 return (B_FALSE); 862 863 if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { 864 exists = (smb_shr_cache_findent(sharename) != NULL); 865 smb_shr_cache_unlock(); 866 } 867 868 return (exists); 869 } 870 871 /* 872 * If the shared directory does not begin with a /, one will be 873 * inserted as a prefix. If ipaddr is not zero, then also return 874 * information about access based on the host level access lists, if 875 * present. Also return access check if there is an IP address and 876 * shr_accflags. 877 * 878 * The value of smb_chk_hostaccess is checked for an access match. 879 * -1 is wildcard match 880 * 0 is no match 881 * 1 is match 882 * 883 * Precedence is none is checked first followed by ro then rw if 884 * needed. If x is wildcard (< 0) then check to see if the other 885 * values are a match. If a match, that wins. 886 */ 887 uint32_t 888 smb_shr_hostaccess(smb_inaddr_t *ipaddr, char *none_list, char *ro_list, 889 char *rw_list, uint32_t flag) 890 { 891 uint32_t acc = SMB_SHRF_ACC_NONE; 892 int none = 0; 893 int ro = 0; 894 int rw = 0; 895 896 if (!smb_inet_iszero(ipaddr)) { 897 if ((flag & SMB_SHRF_ACC_NONE) != 0) 898 none = smb_chk_hostaccess(ipaddr, none_list); 899 if ((flag & SMB_SHRF_ACC_RO) != 0) 900 ro = smb_chk_hostaccess(ipaddr, ro_list); 901 if ((flag & SMB_SHRF_ACC_RW) != 0) 902 rw = smb_chk_hostaccess(ipaddr, rw_list); 903 904 /* make first pass to get basic value */ 905 if (none != 0) 906 acc = SMB_SHRF_ACC_NONE; 907 else if (ro != 0) 908 acc = SMB_SHRF_ACC_RO; 909 else if (rw != 0) 910 acc = SMB_SHRF_ACC_RW; 911 912 /* make second pass to handle '*' case */ 913 if (none < 0) { 914 acc = SMB_SHRF_ACC_NONE; 915 if (ro > 0) 916 acc = SMB_SHRF_ACC_RO; 917 else if (rw > 0) 918 acc = SMB_SHRF_ACC_RW; 919 } else if (ro < 0) { 920 acc = SMB_SHRF_ACC_RO; 921 if (none > 0) 922 acc = SMB_SHRF_ACC_NONE; 923 else if (rw > 0) 924 acc = SMB_SHRF_ACC_RW; 925 } else if (rw < 0) { 926 acc = SMB_SHRF_ACC_RW; 927 if (none > 0) 928 acc = SMB_SHRF_ACC_NONE; 929 else if (ro > 0) 930 acc = SMB_SHRF_ACC_RO; 931 } 932 } 933 934 return (acc); 935 } 936 937 /* 938 * smb_shr_is_special 939 * 940 * Special share reserved for interprocess communication (IPC$) or 941 * remote administration of the server (ADMIN$). Can also refer to 942 * administrative shares such as C$, D$, E$, and so forth. 943 */ 944 int 945 smb_shr_is_special(char *sharename) 946 { 947 int len; 948 949 if (sharename == NULL) 950 return (0); 951 952 if ((len = strlen(sharename)) == 0) 953 return (0); 954 955 if (sharename[len - 1] == '$') 956 return (STYPE_SPECIAL); 957 958 return (0); 959 } 960 961 /* 962 * smb_shr_is_restricted 963 * 964 * Check whether or not there is a restriction on a share. Restricted 965 * shares are generally STYPE_SPECIAL, for example, IPC$. All the 966 * administration share names are restricted: C$, D$ etc. Returns B_TRUE 967 * if the share is restricted. Otherwise B_FALSE is returned to indicate 968 * that there are no restrictions. 969 */ 970 boolean_t 971 smb_shr_is_restricted(char *sharename) 972 { 973 static char *restricted[] = { 974 "IPC$" 975 }; 976 977 int i; 978 979 if (sharename == NULL) 980 return (B_FALSE); 981 982 for (i = 0; i < sizeof (restricted)/sizeof (restricted[0]); i++) { 983 if (smb_strcasecmp(restricted[i], sharename, 0) == 0) 984 return (B_TRUE); 985 } 986 987 return (smb_shr_is_admin(sharename)); 988 } 989 990 /* 991 * smb_shr_is_admin 992 * 993 * Check whether or not access to the share should be restricted to 994 * administrators. This is a bit of a hack because what we're doing 995 * is checking for the default admin shares: C$, D$ etc.. There are 996 * other shares that have restrictions: see smb_shr_is_restricted(). 997 * 998 * Returns B_TRUE if the shares is an admin share. Otherwise B_FALSE 999 * is returned to indicate that there are no restrictions. 1000 */ 1001 boolean_t 1002 smb_shr_is_admin(char *sharename) 1003 { 1004 if (sharename == NULL) 1005 return (B_FALSE); 1006 1007 if (strlen(sharename) == 2 && 1008 smb_isalpha(sharename[0]) && sharename[1] == '$') { 1009 return (B_TRUE); 1010 } 1011 1012 return (B_FALSE); 1013 } 1014 1015 char 1016 smb_shr_drive_letter(const char *path) 1017 { 1018 smb_transient_t *ts; 1019 int i; 1020 1021 if (path == NULL) 1022 return ('\0'); 1023 1024 for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) { 1025 ts = &tshare[i]; 1026 1027 if (ts->path == NULL) 1028 continue; 1029 1030 if (strcasecmp(ts->path, path) == 0) 1031 return (ts->drive); 1032 } 1033 1034 return ('\0'); 1035 } 1036 1037 /* 1038 * Returns true if the specified directory is empty, 1039 * otherwise returns false. 1040 */ 1041 static boolean_t 1042 smb_shr_is_empty(const char *path) 1043 { 1044 DIR *dirp; 1045 struct dirent *dp; 1046 1047 if (path == NULL) 1048 return (B_TRUE); 1049 1050 if ((dirp = opendir(path)) == NULL) 1051 return (B_TRUE); 1052 1053 while ((dp = readdir(dirp)) != NULL) { 1054 if (!smb_shr_is_dot_or_dotdot(dp->d_name)) 1055 return (B_FALSE); 1056 } 1057 1058 (void) closedir(dirp); 1059 return (B_TRUE); 1060 } 1061 1062 /* 1063 * Returns true if name is "." or "..", otherwise returns false. 1064 */ 1065 static boolean_t 1066 smb_shr_is_dot_or_dotdot(const char *name) 1067 { 1068 if (*name != '.') 1069 return (B_FALSE); 1070 1071 if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0')) 1072 return (B_TRUE); 1073 1074 return (B_FALSE); 1075 } 1076 1077 /* 1078 * smb_shr_get_realpath 1079 * 1080 * Derive the real path for a share from the path provided by a client. 1081 * For instance, the real path of C:\ may be /cvol or the real path of 1082 * F:\home may be /vol1/home. 1083 * 1084 * clntpath - path provided by the Windows client is in the 1085 * format of <drive letter>:\<dir> 1086 * realpath - path that will be stored as the directory field of 1087 * the smb_share_t structure of the share. 1088 * maxlen - maximum length of the realpath buffer 1089 * 1090 * Return LAN Manager network error code. 1091 */ 1092 uint32_t 1093 smb_shr_get_realpath(const char *clntpath, char *realpath, int maxlen) 1094 { 1095 const char *p; 1096 int len; 1097 1098 if ((p = strchr(clntpath, ':')) != NULL) 1099 ++p; 1100 else 1101 p = clntpath; 1102 1103 (void) strlcpy(realpath, p, maxlen); 1104 (void) strcanon(realpath, "/\\"); 1105 (void) strsubst(realpath, '\\', '/'); 1106 1107 len = strlen(realpath); 1108 if ((len > 1) && (realpath[len - 1] == '/')) 1109 realpath[len - 1] = '\0'; 1110 1111 return (NERR_Success); 1112 } 1113 1114 void 1115 smb_shr_list(int offset, smb_shrlist_t *list) 1116 { 1117 smb_shriter_t iterator; 1118 smb_share_t *si; 1119 int n = 0; 1120 1121 bzero(list, sizeof (smb_shrlist_t)); 1122 smb_shr_iterinit(&iterator); 1123 1124 while ((si = smb_shr_iterate(&iterator)) != NULL) { 1125 if (--offset > 0) 1126 continue; 1127 1128 if ((si->shr_flags & SMB_SHRF_TRANS) && 1129 (!STYPE_ISIPC(si->shr_type))) { 1130 bcopy(si, &list->sl_shares[n], sizeof (smb_share_t)); 1131 if (++n == LMSHARES_PER_REQUEST) 1132 break; 1133 } 1134 } 1135 1136 list->sl_cnt = n; 1137 } 1138 1139 /* 1140 * Executes the map/unmap command associated with a share. 1141 * 1142 * Returns 0 on success. Otherwise non-zero for errors. 1143 */ 1144 int 1145 smb_shr_exec(smb_shr_execinfo_t *subs) 1146 { 1147 char cmd[MAXPATHLEN], **cmd_tokens, *path, *ptr; 1148 pid_t child_pid; 1149 int child_status; 1150 struct sigaction pact, cact; 1151 smb_share_t si; 1152 1153 if (smb_shr_get(subs->e_sharename, &si) != 0) 1154 return (-1); 1155 1156 *cmd = '\0'; 1157 1158 (void) mutex_lock(&smb_shr_exec_mtx); 1159 1160 switch (subs->e_type) { 1161 case SMB_EXEC_MAP: 1162 (void) strlcpy(cmd, smb_shr_exec_map, sizeof (cmd)); 1163 break; 1164 case SMB_EXEC_UNMAP: 1165 (void) strlcpy(cmd, smb_shr_exec_unmap, sizeof (cmd)); 1166 break; 1167 default: 1168 (void) mutex_unlock(&smb_shr_exec_mtx); 1169 return (-1); 1170 } 1171 1172 (void) mutex_unlock(&smb_shr_exec_mtx); 1173 1174 if (*cmd == '\0') 1175 return (0); 1176 1177 if (smb_proc_takesem() != 0) 1178 return (-1); 1179 1180 pact.sa_handler = smb_shr_sig_child; 1181 pact.sa_flags = 0; 1182 (void) sigemptyset(&pact.sa_mask); 1183 sigaction(SIGCHLD, &pact, NULL); 1184 1185 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL); 1186 1187 if ((child_pid = fork()) == -1) { 1188 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL); 1189 smb_proc_givesem(); 1190 return (-1); 1191 } 1192 1193 if (child_pid == 0) { 1194 1195 /* child process */ 1196 1197 cact.sa_handler = smb_shr_sig_abnormal_term; 1198 cact.sa_flags = 0; 1199 (void) sigemptyset(&cact.sa_mask); 1200 sigaction(SIGTERM, &cact, NULL); 1201 sigaction(SIGABRT, &cact, NULL); 1202 sigaction(SIGSEGV, &cact, NULL); 1203 1204 if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_EXEC, 1205 PRIV_FILE_DAC_EXECUTE, NULL)) 1206 _exit(-1); 1207 1208 if (smb_shr_enable_all_privs()) 1209 _exit(-1); 1210 1211 smb_proc_initsem(); 1212 1213 (void) trim_whitespace(cmd); 1214 (void) strcanon(cmd, " "); 1215 1216 if ((cmd_tokens = smb_shr_tokenize_cmd(cmd)) != NULL) { 1217 1218 if (smb_shr_expand_subs(cmd_tokens, &si, subs) != 0) { 1219 free(cmd_tokens[0]); 1220 free(cmd_tokens); 1221 _exit(-1); 1222 } 1223 1224 ptr = cmd; 1225 path = strsep(&ptr, " "); 1226 1227 (void) execv(path, cmd_tokens); 1228 } 1229 1230 _exit(-1); 1231 } 1232 1233 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL); 1234 smb_proc_givesem(); 1235 1236 /* parent process */ 1237 1238 while (waitpid(child_pid, &child_status, 0) < 0) { 1239 if (errno != EINTR) 1240 break; 1241 1242 /* continue if waitpid got interrupted by a signal */ 1243 errno = 0; 1244 continue; 1245 } 1246 1247 if (WIFEXITED(child_status)) 1248 return (WEXITSTATUS(child_status)); 1249 1250 return (child_status); 1251 } 1252 1253 /* 1254 * Locking for process-wide settings (i.e. privileges) 1255 */ 1256 void 1257 smb_proc_initsem(void) 1258 { 1259 (void) sema_init(&smb_proc_sem, 1, USYNC_THREAD, NULL); 1260 } 1261 1262 int 1263 smb_proc_takesem(void) 1264 { 1265 return (sema_wait(&smb_proc_sem)); 1266 } 1267 1268 void 1269 smb_proc_givesem(void) 1270 { 1271 (void) sema_post(&smb_proc_sem); 1272 } 1273 1274 /* 1275 * ============================================ 1276 * Private helper/utility functions 1277 * ============================================ 1278 */ 1279 1280 /* 1281 * Looks up the given share in the cache and return 1282 * the info in 'si' 1283 */ 1284 static uint32_t 1285 smb_shr_lookup(char *sharename, smb_share_t *si) 1286 { 1287 smb_share_t *cached_si; 1288 uint32_t status = NERR_NetNameNotFound; 1289 1290 if (sharename == NULL || *sharename == '\0') 1291 return (NERR_NetNameNotFound); 1292 if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) { 1293 cached_si = smb_shr_cache_findent(sharename); 1294 if (cached_si != NULL) { 1295 bcopy(cached_si, si, sizeof (smb_share_t)); 1296 status = NERR_Success; 1297 } 1298 1299 smb_shr_cache_unlock(); 1300 } 1301 return (status); 1302 } 1303 1304 /* 1305 * Add IPC$ or Admin shares to the cache upon startup. 1306 */ 1307 static uint32_t 1308 smb_shr_add_transient(char *name, char *cmnt, char *path) 1309 { 1310 smb_share_t trans; 1311 uint32_t status = NERR_InternalError; 1312 1313 if (name == NULL) 1314 return (status); 1315 1316 bzero(&trans, sizeof (smb_share_t)); 1317 (void) strlcpy(trans.shr_name, name, MAXNAMELEN); 1318 if (cmnt) 1319 (void) strlcpy(trans.shr_cmnt, cmnt, SMB_SHARE_CMNT_MAX); 1320 1321 if (path) 1322 (void) strlcpy(trans.shr_path, path, MAXPATHLEN); 1323 1324 if (strcasecmp(name, "IPC$") == 0) 1325 trans.shr_type = STYPE_IPC; 1326 1327 trans.shr_flags = SMB_SHRF_TRANS; 1328 1329 if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) { 1330 status = smb_shr_cache_addent(&trans); 1331 smb_shr_cache_unlock(); 1332 } 1333 1334 return (status); 1335 } 1336 1337 /* 1338 * ============================================ 1339 * Cache management functions 1340 * 1341 * All cache functions are private 1342 * ============================================ 1343 */ 1344 1345 /* 1346 * Create the share cache (hash table). 1347 */ 1348 static uint32_t 1349 smb_shr_cache_create(void) 1350 { 1351 uint32_t status = NERR_Success; 1352 1353 (void) mutex_lock(&smb_shr_cache.sc_mtx); 1354 switch (smb_shr_cache.sc_state) { 1355 case SMB_SHR_CACHE_STATE_NONE: 1356 smb_shr_cache.sc_cache = ht_create_table(SMB_SHR_HTAB_SZ, 1357 MAXNAMELEN, 0); 1358 if (smb_shr_cache.sc_cache == NULL) { 1359 status = NERR_InternalError; 1360 break; 1361 } 1362 1363 (void) ht_register_callback(smb_shr_cache.sc_cache, 1364 smb_shr_cache_freent); 1365 smb_shr_cache.sc_nops = 0; 1366 smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_CREATED; 1367 break; 1368 1369 default: 1370 assert(0); 1371 status = NERR_InternalError; 1372 break; 1373 } 1374 (void) mutex_unlock(&smb_shr_cache.sc_mtx); 1375 1376 return (status); 1377 } 1378 1379 /* 1380 * Destroy the share cache (hash table). 1381 * Wait for inflight/pending operations to finish or abort before 1382 * destroying the cache. 1383 */ 1384 static void 1385 smb_shr_cache_destroy(void) 1386 { 1387 (void) mutex_lock(&smb_shr_cache.sc_mtx); 1388 if (smb_shr_cache.sc_state == SMB_SHR_CACHE_STATE_CREATED) { 1389 smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_DESTROYING; 1390 while (smb_shr_cache.sc_nops > 0) 1391 (void) cond_wait(&smb_shr_cache.sc_cv, 1392 &smb_shr_cache.sc_mtx); 1393 1394 smb_shr_cache.sc_cache = NULL; 1395 smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_NONE; 1396 } 1397 (void) mutex_unlock(&smb_shr_cache.sc_mtx); 1398 } 1399 1400 /* 1401 * If the cache is in "created" state, lock the cache for read 1402 * or read/write based on the specified mode. 1403 * 1404 * Whenever a lock is granted, the number of inflight cache 1405 * operations is incremented. 1406 */ 1407 static uint32_t 1408 smb_shr_cache_lock(int mode) 1409 { 1410 (void) mutex_lock(&smb_shr_cache.sc_mtx); 1411 if (smb_shr_cache.sc_state != SMB_SHR_CACHE_STATE_CREATED) { 1412 (void) mutex_unlock(&smb_shr_cache.sc_mtx); 1413 return (NERR_InternalError); 1414 } 1415 smb_shr_cache.sc_nops++; 1416 (void) mutex_unlock(&smb_shr_cache.sc_mtx); 1417 1418 /* 1419 * Lock has to be taken outside the mutex otherwise 1420 * there could be a deadlock 1421 */ 1422 if (mode == SMB_SHR_CACHE_RDLOCK) 1423 (void) rw_rdlock(&smb_shr_cache.sc_cache_lck); 1424 else 1425 (void) rw_wrlock(&smb_shr_cache.sc_cache_lck); 1426 1427 return (NERR_Success); 1428 } 1429 1430 /* 1431 * Decrement the number of inflight operations and then unlock. 1432 */ 1433 static void 1434 smb_shr_cache_unlock(void) 1435 { 1436 (void) mutex_lock(&smb_shr_cache.sc_mtx); 1437 assert(smb_shr_cache.sc_nops > 0); 1438 smb_shr_cache.sc_nops--; 1439 (void) cond_broadcast(&smb_shr_cache.sc_cv); 1440 (void) mutex_unlock(&smb_shr_cache.sc_mtx); 1441 1442 (void) rw_unlock(&smb_shr_cache.sc_cache_lck); 1443 } 1444 1445 /* 1446 * Return the total number of shares 1447 */ 1448 static int 1449 smb_shr_cache_count(void) 1450 { 1451 return (ht_get_total_items(smb_shr_cache.sc_cache)); 1452 } 1453 1454 /* 1455 * looks up the given share name in the cache and if it 1456 * finds a match returns a pointer to the cached entry. 1457 * Note that since a pointer is returned this function 1458 * MUST be protected by smb_shr_cache_lock/unlock pair 1459 */ 1460 static smb_share_t * 1461 smb_shr_cache_findent(char *sharename) 1462 { 1463 HT_ITEM *item; 1464 1465 (void) smb_strlwr(sharename); 1466 item = ht_find_item(smb_shr_cache.sc_cache, sharename); 1467 if (item && item->hi_data) 1468 return ((smb_share_t *)item->hi_data); 1469 1470 return (NULL); 1471 } 1472 1473 /* 1474 * Return a pointer to the first/next entry in 1475 * the cache based on the given iterator. 1476 * 1477 * Calls to this function MUST be protected by 1478 * smb_shr_cache_lock/unlock. 1479 */ 1480 static smb_share_t * 1481 smb_shr_cache_iterate(smb_shriter_t *shi) 1482 { 1483 HT_ITEM *item; 1484 1485 if (shi->si_first) { 1486 item = ht_findfirst(smb_shr_cache.sc_cache, &shi->si_hashiter); 1487 shi->si_first = B_FALSE; 1488 } else { 1489 item = ht_findnext(&shi->si_hashiter); 1490 } 1491 1492 if (item && item->hi_data) 1493 return ((smb_share_t *)item->hi_data); 1494 1495 return (NULL); 1496 } 1497 1498 /* 1499 * Add the specified share to the cache. Memory needs to be allocated 1500 * for the cache entry and the passed information is copied to the 1501 * allocated space. 1502 */ 1503 static uint32_t 1504 smb_shr_cache_addent(smb_share_t *si) 1505 { 1506 smb_share_t *cache_ent; 1507 uint32_t status = NERR_Success; 1508 1509 if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL) 1510 return (ERROR_NOT_ENOUGH_MEMORY); 1511 1512 (void) smb_strlwr(si->shr_name); 1513 1514 si->shr_type |= smb_shr_is_special(cache_ent->shr_name); 1515 1516 if (smb_shr_is_admin(cache_ent->shr_name)) 1517 si->shr_flags |= SMB_SHRF_ADMIN; 1518 1519 bcopy(si, cache_ent, sizeof (smb_share_t)); 1520 1521 if (si->shr_flags & SMB_SHRF_AUTOHOME) 1522 cache_ent->shr_refcnt = 1; 1523 1524 if (ht_add_item(smb_shr_cache.sc_cache, cache_ent->shr_name, cache_ent) 1525 == NULL) { 1526 syslog(LOG_DEBUG, "share: %s: cache update failed", 1527 cache_ent->shr_name); 1528 free(cache_ent); 1529 status = NERR_InternalError; 1530 } 1531 1532 return (status); 1533 } 1534 1535 /* 1536 * Delete the specified share from the cache. 1537 */ 1538 static void 1539 smb_shr_cache_delent(char *sharename) 1540 { 1541 (void) smb_strlwr(sharename); 1542 (void) ht_remove_item(smb_shr_cache.sc_cache, sharename); 1543 } 1544 1545 /* 1546 * Call back to free the given cache entry. 1547 */ 1548 static void 1549 smb_shr_cache_freent(HT_ITEM *item) 1550 { 1551 if (item && item->hi_data) 1552 free(item->hi_data); 1553 } 1554 1555 /* 1556 * ============================================ 1557 * Interfaces to sharemgr 1558 * 1559 * All functions in this section are private 1560 * ============================================ 1561 */ 1562 1563 /* 1564 * Loads the SMB shares, from sharemgr, then: 1565 * - calls smb_shr_add which: 1566 * - adds the share into the share cache 1567 * - adds the share into in-kernel kshare table 1568 * - publishes the share in ADS 1569 * - updates the share list in sharefs/sharetab 1570 */ 1571 /*ARGSUSED*/ 1572 void * 1573 smb_shr_load(void *args) 1574 { 1575 sa_handle_t handle; 1576 sa_group_t group, subgroup; 1577 char *gstate; 1578 boolean_t gdisabled; 1579 1580 smb_shr_load_execinfo(); 1581 1582 if ((handle = smb_shr_sa_enter()) == NULL) { 1583 syslog(LOG_ERR, "smb_shr_load: load failed"); 1584 return (NULL); 1585 } 1586 1587 for (group = sa_get_group(handle, NULL); 1588 group != NULL; group = sa_get_next_group(group)) { 1589 gstate = sa_get_group_attr(group, "state"); 1590 if (gstate == NULL) 1591 continue; 1592 1593 gdisabled = (strcasecmp(gstate, "disabled") == 0); 1594 sa_free_attr_string(gstate); 1595 if (gdisabled) 1596 continue; 1597 1598 smb_shr_sa_loadgrp(group); 1599 1600 for (subgroup = sa_get_sub_group(group); 1601 subgroup != NULL; 1602 subgroup = sa_get_next_group(subgroup)) { 1603 smb_shr_sa_loadgrp(subgroup); 1604 } 1605 1606 } 1607 smb_shr_sa_exit(); 1608 return (NULL); 1609 } 1610 1611 void 1612 smb_shr_load_execinfo() 1613 { 1614 (void) mutex_lock(&smb_shr_exec_mtx); 1615 (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap, 1616 MAXPATHLEN); 1617 (void) mutex_unlock(&smb_shr_exec_mtx); 1618 } 1619 1620 /* 1621 * Handles disabling shares in sharefs when stoping smbd 1622 */ 1623 void 1624 smb_shr_unload() 1625 { 1626 smb_shriter_t iterator; 1627 smb_share_t *si; 1628 sa_handle_t handle; 1629 int rc; 1630 1631 if ((handle = smb_shr_sa_enter()) == NULL) { 1632 syslog(LOG_ERR, "smb_shr_unload: failed"); 1633 return; 1634 } 1635 1636 smb_shr_iterinit(&iterator); 1637 1638 while ((si = smb_shr_iterate(&iterator)) != NULL) { 1639 1640 /* Skip transient shares, IPC$, ... */ 1641 if ((si->shr_flags & SMB_SHRF_TRANS) || 1642 STYPE_ISIPC(si->shr_type)) 1643 continue; 1644 1645 rc = sa_delete_sharetab(handle, si->shr_path, "smb"); 1646 if (rc) { 1647 syslog(LOG_ERR, 1648 "sharefs remove %s failed, rc=%d, err=%d", 1649 si->shr_path, rc, errno); 1650 } 1651 } 1652 smb_shr_sa_exit(); 1653 } 1654 1655 /* 1656 * Load the shares contained in the specified group. 1657 * 1658 * Don't process groups on which the smb protocol is disabled. 1659 * The top level ZFS group won't have the smb protocol enabled 1660 * but sub-groups will. 1661 * 1662 * We will tolerate a limited number of errors and then give 1663 * up on the current group. A typical error might be that the 1664 * shared directory no longer exists. 1665 */ 1666 static void 1667 smb_shr_sa_loadgrp(sa_group_t group) 1668 { 1669 sa_share_t share; 1670 sa_resource_t resource; 1671 int error_count = 0; 1672 1673 if (sa_get_optionset(group, SMB_PROTOCOL_NAME) == NULL) 1674 return; 1675 1676 for (share = sa_get_share(group, NULL); 1677 share != NULL; 1678 share = sa_get_next_share(share)) { 1679 for (resource = sa_get_share_resource(share, NULL); 1680 resource != NULL; 1681 resource = sa_get_next_resource(resource)) { 1682 if (smb_shr_sa_load(share, resource)) 1683 ++error_count; 1684 1685 if (error_count > SMB_SHR_ERROR_THRESHOLD) 1686 break; 1687 } 1688 1689 if (error_count > SMB_SHR_ERROR_THRESHOLD) 1690 break; 1691 } 1692 } 1693 1694 /* 1695 * Load a share definition from sharemgr and add it to the cache. 1696 * If the share is already in the cache then it doesn't do anything. 1697 * 1698 * This function does not report duplicate shares as error since 1699 * a share might have been added by smb_shr_get() while load is 1700 * in progress. 1701 */ 1702 static uint32_t 1703 smb_shr_sa_load(sa_share_t share, sa_resource_t resource) 1704 { 1705 smb_share_t si; 1706 char *sharename; 1707 uint32_t status; 1708 boolean_t loaded; 1709 int rc; 1710 1711 if ((sharename = sa_get_resource_attr(resource, "name")) == NULL) 1712 return (NERR_InternalError); 1713 1714 loaded = smb_shr_exists(sharename); 1715 sa_free_attr_string(sharename); 1716 1717 if (loaded) 1718 return (NERR_Success); 1719 1720 if ((status = smb_shr_sa_get(share, resource, &si)) != NERR_Success) { 1721 syslog(LOG_DEBUG, "share: failed to load %s (%d)", 1722 si.shr_name, status); 1723 return (status); 1724 } 1725 1726 status = smb_shr_add(&si); 1727 if ((status != NERR_Success) && (status != NERR_DuplicateShare)) { 1728 syslog(LOG_DEBUG, "share: failed to cache %s (%d)", 1729 si.shr_name, status); 1730 return (status); 1731 } 1732 1733 rc = sa_update_sharetab(share, "smb"); 1734 if (rc) { 1735 syslog(LOG_ERR, "sharefs add %s failed, rc=%d, err=%d", 1736 sharename, rc, errno); 1737 } 1738 1739 return (NERR_Success); 1740 } 1741 1742 static char * 1743 smb_shr_sa_getprop(sa_optionset_t opts, char *propname) 1744 { 1745 sa_property_t prop; 1746 char *val = NULL; 1747 1748 prop = sa_get_property(opts, propname); 1749 if (prop != NULL) 1750 val = sa_get_property_attr(prop, "value"); 1751 1752 return (val); 1753 } 1754 1755 /* 1756 * Read the specified share information from sharemgr and return 1757 * it in the given smb_share_t structure. 1758 * 1759 * Shares read from sharemgr are marked as permanent/persistent. 1760 */ 1761 static uint32_t 1762 smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si) 1763 { 1764 sa_optionset_t opts; 1765 char *val = NULL; 1766 char *path; 1767 char *rname; 1768 1769 if ((path = sa_get_share_attr(share, "path")) == NULL) 1770 return (NERR_InternalError); 1771 1772 if ((rname = sa_get_resource_attr(resource, "name")) == NULL) { 1773 sa_free_attr_string(path); 1774 return (NERR_InternalError); 1775 } 1776 1777 bzero(si, sizeof (smb_share_t)); 1778 si->shr_flags = SMB_SHRF_PERM; 1779 1780 (void) strlcpy(si->shr_path, path, sizeof (si->shr_path)); 1781 (void) strlcpy(si->shr_name, rname, sizeof (si->shr_name)); 1782 sa_free_attr_string(path); 1783 sa_free_attr_string(rname); 1784 1785 val = sa_get_resource_description(resource); 1786 if (val == NULL) 1787 val = sa_get_share_description(share); 1788 1789 if (val != NULL) { 1790 (void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt)); 1791 sa_free_share_description(val); 1792 } 1793 1794 opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1); 1795 if (opts == NULL) 1796 return (NERR_Success); 1797 1798 val = smb_shr_sa_getprop(opts, SHOPT_AD_CONTAINER); 1799 if (val != NULL) { 1800 (void) strlcpy(si->shr_container, val, 1801 sizeof (si->shr_container)); 1802 free(val); 1803 } 1804 1805 val = smb_shr_sa_getprop(opts, SHOPT_CATIA); 1806 if (val != NULL) { 1807 smb_shr_sa_setflag(val, si, SMB_SHRF_CATIA); 1808 free(val); 1809 } 1810 1811 val = smb_shr_sa_getprop(opts, SHOPT_ABE); 1812 if (val != NULL) { 1813 smb_shr_sa_setflag(val, si, SMB_SHRF_ABE); 1814 free(val); 1815 } 1816 1817 val = smb_shr_sa_getprop(opts, SHOPT_GUEST); 1818 if (val != NULL) { 1819 smb_shr_sa_setflag(val, si, SMB_SHRF_GUEST_OK); 1820 free(val); 1821 } 1822 1823 val = smb_shr_sa_getprop(opts, SHOPT_DFSROOT); 1824 if (val != NULL) { 1825 smb_shr_sa_setflag(val, si, SMB_SHRF_DFSROOT); 1826 free(val); 1827 } 1828 1829 val = smb_shr_sa_getprop(opts, SHOPT_CA); 1830 if (val != NULL) { 1831 smb_shr_sa_setflag(val, si, SMB_SHRF_CA); 1832 free(val); 1833 } 1834 1835 val = smb_shr_sa_getprop(opts, SHOPT_FSO); 1836 if (val != NULL) { 1837 smb_shr_sa_setflag(val, si, SMB_SHRF_FSO); 1838 free(val); 1839 } 1840 1841 val = smb_shr_sa_getprop(opts, SHOPT_QUOTAS); 1842 if (val != NULL) { 1843 /* Turn the flag on or off */ 1844 smb_shr_sa_setflag(val, si, SMB_SHRF_QUOTAS); 1845 free(val); 1846 } else { 1847 /* Default for this is enabled. */ 1848 si->shr_flags |= SMB_SHRF_QUOTAS; 1849 } 1850 1851 val = smb_shr_sa_getprop(opts, SHOPT_ENCRYPT); 1852 if (val != NULL) { 1853 smb_cfg_set_require(val, &si->shr_encrypt); 1854 free(val); 1855 } 1856 1857 val = smb_shr_sa_getprop(opts, SHOPT_CSC); 1858 if (val != NULL) { 1859 smb_shr_sa_csc_option(val, si); 1860 free(val); 1861 } 1862 1863 val = smb_shr_sa_getprop(opts, SHOPT_NONE); 1864 if (val != NULL) { 1865 (void) strlcpy(si->shr_access_none, val, 1866 sizeof (si->shr_access_none)); 1867 free(val); 1868 si->shr_flags |= SMB_SHRF_ACC_NONE; 1869 } 1870 1871 val = smb_shr_sa_getprop(opts, SHOPT_RO); 1872 if (val != NULL) { 1873 (void) strlcpy(si->shr_access_ro, val, 1874 sizeof (si->shr_access_ro)); 1875 free(val); 1876 si->shr_flags |= SMB_SHRF_ACC_RO; 1877 } 1878 1879 val = smb_shr_sa_getprop(opts, SHOPT_RW); 1880 if (val != NULL) { 1881 (void) strlcpy(si->shr_access_rw, val, 1882 sizeof (si->shr_access_rw)); 1883 free(val); 1884 si->shr_flags |= SMB_SHRF_ACC_RW; 1885 } 1886 1887 sa_free_derived_optionset(opts); 1888 return (NERR_Success); 1889 } 1890 1891 /* 1892 * Map a client-side caching (CSC) option to the appropriate share 1893 * flag. Only one option is allowed; an error will be logged if 1894 * multiple options have been specified. We don't need to do anything 1895 * about multiple values here because the SRVSVC will not recognize 1896 * a value containing multiple flags and will return the default value. 1897 * 1898 * If the option value is not recognized, it will be ignored: invalid 1899 * values will typically be caught and rejected by sharemgr. 1900 */ 1901 void 1902 smb_shr_sa_csc_option(const char *value, smb_share_t *si) 1903 { 1904 int i; 1905 1906 for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { 1907 if (strcasecmp(value, cscopt[i].value) == 0) { 1908 si->shr_flags |= cscopt[i].flag; 1909 break; 1910 } 1911 } 1912 1913 switch (si->shr_flags & SMB_SHRF_CSC_MASK) { 1914 case 0: 1915 case SMB_SHRF_CSC_DISABLED: 1916 case SMB_SHRF_CSC_MANUAL: 1917 case SMB_SHRF_CSC_AUTO: 1918 case SMB_SHRF_CSC_VDO: 1919 break; 1920 1921 default: 1922 syslog(LOG_INFO, "csc option conflict: 0x%08x", 1923 si->shr_flags & SMB_SHRF_CSC_MASK); 1924 break; 1925 } 1926 } 1927 1928 /* 1929 * Return the option name for the first CSC flag (there should be only 1930 * one) encountered in the share flags. 1931 */ 1932 char * 1933 smb_shr_sa_csc_name(const smb_share_t *si) 1934 { 1935 int i; 1936 1937 for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) { 1938 if (si->shr_flags & cscopt[i].flag) 1939 return (cscopt[i].value); 1940 } 1941 1942 return (NULL); 1943 } 1944 1945 /* 1946 * Takes the value of a boolean share property and set/clear the 1947 * specified flag based on the property's value. 1948 */ 1949 void 1950 smb_shr_sa_setflag(const char *value, smb_share_t *si, uint32_t flag) 1951 { 1952 if ((strcasecmp(value, "true") == 0) || (strcmp(value, "1") == 0)) 1953 si->shr_flags |= flag; 1954 else 1955 si->shr_flags &= ~flag; 1956 } 1957 1958 /* 1959 * looks up sharemgr for the given share (resource) and loads 1960 * the definition into cache if lookup is successful 1961 */ 1962 static uint32_t 1963 smb_shr_sa_loadbyname(char *sharename) 1964 { 1965 sa_handle_t handle; 1966 sa_share_t share; 1967 sa_resource_t resource; 1968 uint32_t status; 1969 1970 if ((handle = smb_shr_sa_enter()) == NULL) 1971 return (NERR_InternalError); 1972 1973 resource = sa_find_resource(handle, sharename); 1974 if (resource == NULL) { 1975 smb_shr_sa_exit(); 1976 return (NERR_NetNameNotFound); 1977 } 1978 1979 share = sa_get_resource_parent(resource); 1980 if (share == NULL) { 1981 smb_shr_sa_exit(); 1982 return (NERR_InternalError); 1983 } 1984 1985 status = smb_shr_sa_load(share, resource); 1986 1987 smb_shr_sa_exit(); 1988 return (status); 1989 } 1990 1991 /* 1992 * ============================================ 1993 * Share publishing functions 1994 * 1995 * All the functions are private 1996 * ============================================ 1997 */ 1998 1999 static void 2000 smb_shr_publish(const char *sharename, const char *container) 2001 { 2002 smb_shr_publisher_queue(sharename, container, SMB_SHR_PUBLISH); 2003 } 2004 2005 static void 2006 smb_shr_unpublish(const char *sharename, const char *container) 2007 { 2008 smb_shr_publisher_queue(sharename, container, SMB_SHR_UNPUBLISH); 2009 } 2010 2011 /* 2012 * In domain mode, put a share on the publisher queue. 2013 * This is a no-op if the smb service is in Workgroup mode. 2014 */ 2015 static void 2016 smb_shr_publisher_queue(const char *sharename, const char *container, char op) 2017 { 2018 smb_shr_pitem_t *item = NULL; 2019 2020 if (container == NULL || *container == '\0') 2021 return; 2022 2023 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 2024 return; 2025 2026 (void) mutex_lock(&ad_queue.spq_mtx); 2027 switch (ad_queue.spq_state) { 2028 case SMB_SHR_PQS_READY: 2029 case SMB_SHR_PQS_PUBLISHING: 2030 break; 2031 default: 2032 (void) mutex_unlock(&ad_queue.spq_mtx); 2033 return; 2034 } 2035 (void) mutex_unlock(&ad_queue.spq_mtx); 2036 2037 if ((item = malloc(sizeof (smb_shr_pitem_t))) == NULL) 2038 return; 2039 2040 item->spi_op = op; 2041 (void) strlcpy(item->spi_name, sharename, sizeof (item->spi_name)); 2042 (void) strlcpy(item->spi_container, container, 2043 sizeof (item->spi_container)); 2044 2045 (void) mutex_lock(&ad_queue.spq_mtx); 2046 list_insert_tail(&ad_queue.spq_list, item); 2047 (void) cond_signal(&ad_queue.spq_cv); 2048 (void) mutex_unlock(&ad_queue.spq_mtx); 2049 } 2050 2051 /* 2052 * Publishing won't be activated if the smb service is running in 2053 * Workgroup mode. 2054 */ 2055 static int 2056 smb_shr_publisher_start(void) 2057 { 2058 pthread_t publish_thr; 2059 pthread_attr_t tattr; 2060 int rc; 2061 2062 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 2063 return (0); 2064 2065 (void) mutex_lock(&ad_queue.spq_mtx); 2066 if (ad_queue.spq_state != SMB_SHR_PQS_NOQUEUE) { 2067 (void) mutex_unlock(&ad_queue.spq_mtx); 2068 errno = EINVAL; 2069 return (-1); 2070 } 2071 2072 list_create(&ad_queue.spq_list, sizeof (smb_shr_pitem_t), 2073 offsetof(smb_shr_pitem_t, spi_lnd)); 2074 ad_queue.spq_state = SMB_SHR_PQS_READY; 2075 (void) mutex_unlock(&ad_queue.spq_mtx); 2076 2077 (void) pthread_attr_init(&tattr); 2078 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 2079 rc = pthread_create(&publish_thr, &tattr, smb_shr_publisher, 0); 2080 (void) pthread_attr_destroy(&tattr); 2081 2082 return (rc); 2083 } 2084 2085 static void 2086 smb_shr_publisher_stop(void) 2087 { 2088 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 2089 return; 2090 2091 (void) mutex_lock(&ad_queue.spq_mtx); 2092 switch (ad_queue.spq_state) { 2093 case SMB_SHR_PQS_READY: 2094 case SMB_SHR_PQS_PUBLISHING: 2095 ad_queue.spq_state = SMB_SHR_PQS_STOPPING; 2096 (void) cond_signal(&ad_queue.spq_cv); 2097 break; 2098 default: 2099 break; 2100 } 2101 (void) mutex_unlock(&ad_queue.spq_mtx); 2102 } 2103 2104 /* 2105 * This is the publisher daemon thread. While running, the thread waits 2106 * on a conditional variable until notified that a share needs to be 2107 * [un]published or that the thread should be terminated. 2108 * 2109 * Entries may remain in the outgoing queue if the Active Directory 2110 * service is inaccessible, in which case the thread wakes up every 60 2111 * seconds to retry. 2112 */ 2113 /*ARGSUSED*/ 2114 static void * 2115 smb_shr_publisher(void *arg) 2116 { 2117 smb_ads_handle_t *ah; 2118 smb_shr_pitem_t *shr; 2119 list_t publist; 2120 timestruc_t pubretry; 2121 char hostname[MAXHOSTNAMELEN]; 2122 2123 (void) mutex_lock(&ad_queue.spq_mtx); 2124 if (ad_queue.spq_state != SMB_SHR_PQS_READY) { 2125 (void) mutex_unlock(&ad_queue.spq_mtx); 2126 return (NULL); 2127 } 2128 ad_queue.spq_state = SMB_SHR_PQS_PUBLISHING; 2129 (void) mutex_unlock(&ad_queue.spq_mtx); 2130 2131 (void) smb_gethostname(hostname, MAXHOSTNAMELEN, 2132 SMB_CASE_PRESERVE); 2133 2134 list_create(&publist, sizeof (smb_shr_pitem_t), 2135 offsetof(smb_shr_pitem_t, spi_lnd)); 2136 2137 for (;;) { 2138 (void) mutex_lock(&ad_queue.spq_mtx); 2139 2140 while (list_is_empty(&ad_queue.spq_list) && 2141 (ad_queue.spq_state == SMB_SHR_PQS_PUBLISHING)) { 2142 if (list_is_empty(&publist)) { 2143 (void) cond_wait(&ad_queue.spq_cv, 2144 &ad_queue.spq_mtx); 2145 } else { 2146 pubretry.tv_sec = 60; 2147 pubretry.tv_nsec = 0; 2148 (void) cond_reltimedwait(&ad_queue.spq_cv, 2149 &ad_queue.spq_mtx, &pubretry); 2150 break; 2151 } 2152 } 2153 2154 if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) { 2155 (void) mutex_unlock(&ad_queue.spq_mtx); 2156 break; 2157 } 2158 2159 /* 2160 * Transfer queued items to the local list so that 2161 * the mutex can be released. 2162 */ 2163 while ((shr = list_head(&ad_queue.spq_list)) != NULL) { 2164 list_remove(&ad_queue.spq_list, shr); 2165 list_insert_tail(&publist, shr); 2166 } 2167 2168 (void) mutex_unlock(&ad_queue.spq_mtx); 2169 2170 if ((ah = smb_ads_open()) != NULL) { 2171 smb_shr_publisher_send(ah, &publist, hostname); 2172 smb_ads_close(ah); 2173 } 2174 } 2175 2176 (void) mutex_lock(&ad_queue.spq_mtx); 2177 smb_shr_publisher_flush(&ad_queue.spq_list); 2178 list_destroy(&ad_queue.spq_list); 2179 ad_queue.spq_state = SMB_SHR_PQS_NOQUEUE; 2180 (void) mutex_unlock(&ad_queue.spq_mtx); 2181 2182 smb_shr_publisher_flush(&publist); 2183 list_destroy(&publist); 2184 return (NULL); 2185 } 2186 2187 /* 2188 * Remove items from the specified queue and [un]publish them. 2189 */ 2190 static void 2191 smb_shr_publisher_send(smb_ads_handle_t *ah, list_t *publist, const char *host) 2192 { 2193 smb_shr_pitem_t *shr; 2194 2195 while ((shr = list_head(publist)) != NULL) { 2196 (void) mutex_lock(&ad_queue.spq_mtx); 2197 if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) { 2198 (void) mutex_unlock(&ad_queue.spq_mtx); 2199 return; 2200 } 2201 (void) mutex_unlock(&ad_queue.spq_mtx); 2202 2203 list_remove(publist, shr); 2204 2205 if (shr->spi_op == SMB_SHR_PUBLISH) 2206 (void) smb_ads_publish_share(ah, shr->spi_name, 2207 NULL, shr->spi_container, host); 2208 else 2209 (void) smb_ads_remove_share(ah, shr->spi_name, 2210 NULL, shr->spi_container, host); 2211 2212 free(shr); 2213 } 2214 } 2215 2216 /* 2217 * Flush all remaining items from the specified list/queue. 2218 */ 2219 static void 2220 smb_shr_publisher_flush(list_t *lst) 2221 { 2222 smb_shr_pitem_t *shr; 2223 2224 while ((shr = list_head(lst)) != NULL) { 2225 list_remove(lst, shr); 2226 free(shr); 2227 } 2228 } 2229 2230 /* 2231 * If the share path refers to a ZFS file system, add the 2232 * .zfs/shares/<share> object and add or remove the special 2233 * directory and file telling clients about quota support. 2234 */ 2235 static void 2236 smb_shr_zfs_add(smb_share_t *si) 2237 { 2238 libzfs_handle_t *libhd; 2239 zfs_handle_t *zfshd; 2240 int ret; 2241 char buf[MAXPATHLEN]; /* dataset or mountpoint */ 2242 2243 if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0) 2244 return; 2245 2246 if ((libhd = libzfs_init()) == NULL) 2247 return; 2248 2249 if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) { 2250 libzfs_fini(libhd); 2251 return; 2252 } 2253 2254 errno = 0; 2255 ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name); 2256 if (ret != 0 && errno != EAGAIN && errno != EEXIST) 2257 syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n", 2258 si->shr_name, strerror(errno)); 2259 2260 ret = zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, 2261 buf, MAXPATHLEN, NULL, NULL, 0, B_FALSE); 2262 if (ret != 0) { 2263 syslog(LOG_INFO, "share: failed to get mountpoint: " 2264 "%s\n", si->shr_name); 2265 } else { 2266 if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) { 2267 smb_quota_add_fs(buf); 2268 } else { 2269 smb_quota_remove_fs(buf); 2270 } 2271 } 2272 2273 zfs_close(zfshd); 2274 libzfs_fini(libhd); 2275 } 2276 2277 /* 2278 * If the share path refers to a ZFS file system, remove the 2279 * .zfs/shares/<share> object. 2280 */ 2281 static void 2282 smb_shr_zfs_remove(smb_share_t *si) 2283 { 2284 libzfs_handle_t *libhd; 2285 int ret; 2286 char buf[MAXPATHLEN]; /* dataset or mountpoint */ 2287 2288 if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0) 2289 return; 2290 2291 if ((libhd = libzfs_init()) == NULL) 2292 return; 2293 2294 errno = 0; 2295 ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name); 2296 if (ret != 0 && errno != EAGAIN) 2297 syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n", 2298 si->shr_name, strerror(errno)); 2299 2300 /* 2301 * We could remove the quotas directory here, but that adds 2302 * significantly to the time required for a zpool export, 2303 * so just leave it here and fixup when we share next. 2304 */ 2305 2306 libzfs_fini(libhd); 2307 } 2308 2309 /* 2310 * If the share path refers to a ZFS file system, rename the 2311 * .zfs/shares/<share> object. 2312 */ 2313 static void 2314 smb_shr_zfs_rename(smb_share_t *from, smb_share_t *to) 2315 { 2316 libzfs_handle_t *libhd; 2317 zfs_handle_t *zfshd; 2318 int ret; 2319 char dataset[MAXPATHLEN]; 2320 2321 if (smb_getdataset(from->shr_path, dataset, MAXPATHLEN) != 0) 2322 return; 2323 2324 if ((libhd = libzfs_init()) == NULL) 2325 return; 2326 2327 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) { 2328 libzfs_fini(libhd); 2329 return; 2330 } 2331 2332 errno = 0; 2333 ret = zfs_smb_acl_rename(libhd, dataset, from->shr_path, 2334 from->shr_name, to->shr_name); 2335 if (ret != 0 && errno != EAGAIN) 2336 syslog(LOG_INFO, "share: failed to rename ACL object: %s: %s\n", 2337 from->shr_name, strerror(errno)); 2338 2339 zfs_close(zfshd); 2340 libzfs_fini(libhd); 2341 } 2342 2343 /* 2344 * Enable all privileges in the inheritable set to execute command. 2345 */ 2346 static int 2347 smb_shr_enable_all_privs(void) 2348 { 2349 priv_set_t *pset; 2350 2351 pset = priv_allocset(); 2352 if (pset == NULL) 2353 return (-1); 2354 2355 if (getppriv(PRIV_LIMIT, pset)) { 2356 priv_freeset(pset); 2357 return (-1); 2358 } 2359 2360 if (setppriv(PRIV_ON, PRIV_INHERITABLE, pset)) { 2361 priv_freeset(pset); 2362 return (-1); 2363 } 2364 2365 priv_freeset(pset); 2366 return (0); 2367 } 2368 2369 /* 2370 * Tokenizes the command string and returns the list of tokens in an array. 2371 * 2372 * Returns NULL if there are no tokens. 2373 */ 2374 static char ** 2375 smb_shr_tokenize_cmd(char *cmdstr) 2376 { 2377 char *cmd, *buf, *bp, *value; 2378 char **argv, **ap; 2379 int argc, i; 2380 2381 if (cmdstr == NULL || *cmdstr == '\0') 2382 return (NULL); 2383 2384 if ((buf = malloc(MAXPATHLEN)) == NULL) 2385 return (NULL); 2386 2387 (void) strlcpy(buf, cmdstr, MAXPATHLEN); 2388 2389 for (argc = 2, bp = cmdstr; *bp != '\0'; ++bp) 2390 if (*bp == ' ') 2391 ++argc; 2392 2393 if ((argv = calloc(argc, sizeof (char *))) == NULL) { 2394 free(buf); 2395 return (NULL); 2396 } 2397 2398 ap = argv; 2399 for (bp = buf, i = 0; i < argc; ++i) { 2400 do { 2401 if ((value = strsep(&bp, " ")) == NULL) 2402 break; 2403 } while (*value == '\0'); 2404 2405 if (value == NULL) 2406 break; 2407 2408 *ap++ = value; 2409 } 2410 2411 /* get the filename of the command from the path */ 2412 if ((cmd = strrchr(argv[0], '/')) != NULL) 2413 (void) strlcpy(argv[0], ++cmd, strlen(argv[0])); 2414 2415 return (argv); 2416 } 2417 2418 /* 2419 * Expands the command string for the following substitution tokens: 2420 * 2421 * %U - Windows username 2422 * %D - Name of the domain or workgroup of %U 2423 * %h - The server hostname 2424 * %M - The client hostname 2425 * %L - The server NetBIOS name 2426 * %m - The client NetBIOS name. This option is only valid for NetBIOS 2427 * connections (port 139). 2428 * %I - The IP address of the client machine 2429 * %i - The local IP address to which the client is connected 2430 * %S - The name of the share 2431 * %P - The root directory of the share 2432 * %u - The UID of the Unix user 2433 * 2434 * Returns 0 on success. Otherwise -1. 2435 */ 2436 static int 2437 smb_shr_expand_subs(char **cmd_toks, smb_share_t *si, smb_shr_execinfo_t *subs) 2438 { 2439 char *fmt, *sub_chr, *ptr; 2440 boolean_t unknown; 2441 char hostname[MAXHOSTNAMELEN]; 2442 char ip_str[INET6_ADDRSTRLEN]; 2443 char name[SMB_PI_MAX_HOST]; 2444 smb_wchar_t wbuf[SMB_PI_MAX_HOST]; 2445 int i; 2446 2447 if (cmd_toks == NULL || *cmd_toks == NULL) 2448 return (-1); 2449 2450 for (i = 1; cmd_toks[i]; i++) { 2451 fmt = cmd_toks[i]; 2452 if (*fmt == '%') { 2453 sub_chr = fmt + 1; 2454 unknown = B_FALSE; 2455 2456 switch (*sub_chr) { 2457 case 'U': 2458 ptr = strdup(subs->e_winname); 2459 break; 2460 case 'D': 2461 ptr = strdup(subs->e_userdom); 2462 break; 2463 case 'h': 2464 if (gethostname(hostname, MAXHOSTNAMELEN) != 0) 2465 unknown = B_TRUE; 2466 else 2467 ptr = strdup(hostname); 2468 break; 2469 case 'M': 2470 if (smb_getnameinfo(&subs->e_cli_ipaddr, 2471 hostname, sizeof (hostname), 0) != 0) 2472 unknown = B_TRUE; 2473 else 2474 ptr = strdup(hostname); 2475 break; 2476 case 'L': 2477 if (smb_getnetbiosname(hostname, 2478 NETBIOS_NAME_SZ) != 0) 2479 unknown = B_TRUE; 2480 else 2481 ptr = strdup(hostname); 2482 break; 2483 case 'm': 2484 if (*subs->e_cli_netbiosname == '\0') 2485 unknown = B_TRUE; 2486 else { 2487 (void) smb_mbstowcs(wbuf, 2488 subs->e_cli_netbiosname, 2489 SMB_PI_MAX_HOST - 1); 2490 2491 if (ucstooem(name, wbuf, 2492 SMB_PI_MAX_HOST, OEM_CPG_850) == 0) 2493 (void) strlcpy(name, 2494 subs->e_cli_netbiosname, 2495 SMB_PI_MAX_HOST); 2496 2497 ptr = strdup(name); 2498 } 2499 break; 2500 case 'I': 2501 if (smb_inet_ntop(&subs->e_cli_ipaddr, ip_str, 2502 SMB_IPSTRLEN(subs->e_cli_ipaddr.a_family)) 2503 != NULL) 2504 ptr = strdup(ip_str); 2505 else 2506 unknown = B_TRUE; 2507 break; 2508 case 'i': 2509 if (smb_inet_ntop(&subs->e_srv_ipaddr, ip_str, 2510 SMB_IPSTRLEN(subs->e_srv_ipaddr.a_family)) 2511 != NULL) 2512 ptr = strdup(ip_str); 2513 else 2514 unknown = B_TRUE; 2515 break; 2516 case 'S': 2517 ptr = strdup(si->shr_name); 2518 break; 2519 case 'P': 2520 ptr = strdup(si->shr_path); 2521 break; 2522 case 'u': 2523 (void) snprintf(name, sizeof (name), "%u", 2524 subs->e_uid); 2525 ptr = strdup(name); 2526 break; 2527 default: 2528 /* unknown sub char */ 2529 unknown = B_TRUE; 2530 break; 2531 } 2532 2533 if (unknown) 2534 ptr = strdup(""); 2535 2536 } else /* first char of cmd's arg is not '%' char */ 2537 ptr = strdup(""); 2538 2539 cmd_toks[i] = ptr; 2540 2541 if (ptr == NULL) { 2542 for (i = 1; cmd_toks[i]; i++) 2543 free(cmd_toks[i]); 2544 2545 return (-1); 2546 } 2547 } 2548 2549 return (0); 2550 } 2551 2552 /*ARGSUSED*/ 2553 static void 2554 smb_shr_sig_abnormal_term(int sig_val) 2555 { 2556 /* 2557 * Calling _exit() prevents parent process from getting SIGTERM/SIGINT 2558 * signal. 2559 */ 2560 _exit(-1); 2561 } 2562 2563 /*ARGSUSED*/ 2564 static void 2565 smb_shr_sig_child(int sig_val) 2566 { 2567 /* 2568 * Catch the signal and allow the exit status of the child process 2569 * to be available for reaping. 2570 */ 2571 } 2572 2573 /* 2574 * This is a temporary function which converts the given smb_share_t 2575 * structure to the nvlist format that will be provided by libsharev2 2576 */ 2577 static int 2578 smb_shr_encode(smb_share_t *si, nvlist_t **nvlist) 2579 { 2580 nvlist_t *list; 2581 nvlist_t *share; 2582 nvlist_t *smb; 2583 char *csc; 2584 int rc = 0; 2585 2586 *nvlist = NULL; 2587 2588 if ((rc = nvlist_alloc(&list, NV_UNIQUE_NAME, 0)) != 0) 2589 return (rc); 2590 2591 if ((rc = nvlist_alloc(&share, NV_UNIQUE_NAME, 0)) != 0) { 2592 nvlist_free(list); 2593 return (rc); 2594 } 2595 2596 if ((rc = nvlist_alloc(&smb, NV_UNIQUE_NAME, 0)) != 0) { 2597 nvlist_free(share); 2598 nvlist_free(list); 2599 return (rc); 2600 } 2601 2602 /* global share properties */ 2603 rc |= nvlist_add_string(share, "name", si->shr_name); 2604 rc |= nvlist_add_string(share, "path", si->shr_path); 2605 rc |= nvlist_add_string(share, "desc", si->shr_cmnt); 2606 2607 /* smb protocol properties */ 2608 rc = nvlist_add_string(smb, SHOPT_AD_CONTAINER, si->shr_container); 2609 if ((si->shr_flags & SMB_SHRF_ACC_NONE) != 0) 2610 rc |= nvlist_add_string(smb, SHOPT_NONE, si->shr_access_none); 2611 if ((si->shr_flags & SMB_SHRF_ACC_RO) != 0) 2612 rc |= nvlist_add_string(smb, SHOPT_RO, si->shr_access_ro); 2613 if ((si->shr_flags & SMB_SHRF_ACC_RW) != 0) 2614 rc |= nvlist_add_string(smb, SHOPT_RW, si->shr_access_rw); 2615 2616 if ((si->shr_flags & SMB_SHRF_ABE) != 0) 2617 rc |= nvlist_add_string(smb, SHOPT_ABE, "true"); 2618 if ((si->shr_flags & SMB_SHRF_CATIA) != 0) 2619 rc |= nvlist_add_string(smb, SHOPT_CATIA, "true"); 2620 if ((si->shr_flags & SMB_SHRF_GUEST_OK) != 0) 2621 rc |= nvlist_add_string(smb, SHOPT_GUEST, "true"); 2622 if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) 2623 rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true"); 2624 if ((si->shr_flags & SMB_SHRF_CA) != 0) 2625 rc |= nvlist_add_string(smb, SHOPT_CA, "true"); 2626 if ((si->shr_flags & SMB_SHRF_FSO) != 0) 2627 rc |= nvlist_add_string(smb, SHOPT_FSO, "true"); 2628 if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) 2629 rc |= nvlist_add_string(smb, SHOPT_QUOTAS, "true"); 2630 2631 if (si->shr_encrypt == SMB_CONFIG_REQUIRED) 2632 rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "required"); 2633 else if (si->shr_encrypt == SMB_CONFIG_ENABLED) 2634 rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "enabled"); 2635 else 2636 rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "disabled"); 2637 2638 if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) { 2639 rc |= nvlist_add_string(smb, SHOPT_AUTOHOME, "true"); 2640 rc |= nvlist_add_uint32(smb, "uid", si->shr_uid); 2641 rc |= nvlist_add_uint32(smb, "gid", si->shr_gid); 2642 } 2643 2644 if ((csc = smb_shr_sa_csc_name(si)) != NULL) 2645 rc |= nvlist_add_string(smb, SHOPT_CSC, csc); 2646 2647 rc |= nvlist_add_uint32(smb, "type", si->shr_type); 2648 2649 rc |= nvlist_add_nvlist(share, "smb", smb); 2650 rc |= nvlist_add_nvlist(list, si->shr_name, share); 2651 2652 nvlist_free(share); 2653 nvlist_free(smb); 2654 2655 if (rc != 0) 2656 nvlist_free(list); 2657 else 2658 *nvlist = list; 2659 2660 return (rc); 2661 } 2662