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