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