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