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