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