17052Samw /* 27052Samw * CDDL HEADER START 37052Samw * 47052Samw * The contents of this file are subject to the terms of the 57052Samw * Common Development and Distribution License (the "License"). 67052Samw * You may not use this file except in compliance with the License. 77052Samw * 87052Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97052Samw * or http://www.opensolaris.org/os/licensing. 107052Samw * See the License for the specific language governing permissions 117052Samw * and limitations under the License. 127052Samw * 137052Samw * When distributing Covered Code, include this CDDL HEADER in each 147052Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157052Samw * If applicable, add the following below this CDDL HEADER, with the 167052Samw * fields enclosed by brackets "[]" replaced with your own identifying 177052Samw * information: Portions Copyright [yyyy] [name of copyright owner] 187052Samw * 197052Samw * CDDL HEADER END 207052Samw */ 217052Samw /* 227052Samw * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237052Samw * Use is subject to license terms. 247052Samw */ 257052Samw 267052Samw /* 277052Samw * Lan Manager (SMB/CIFS) share interface implementation. This interface 287052Samw * returns Win32 error codes, usually network error values (lmerr.h). 297052Samw */ 307052Samw 317052Samw #include <errno.h> 327052Samw #include <synch.h> 337052Samw #include <stdio.h> 347052Samw #include <stdlib.h> 357052Samw #include <strings.h> 367052Samw #include <syslog.h> 377052Samw #include <thread.h> 387052Samw #include <fcntl.h> 397052Samw #include <unistd.h> 407052Samw #include <netdb.h> 417052Samw #include <synch.h> 427052Samw #include <pthread.h> 437348SJose.Borrego@Sun.COM #include <ctype.h> 447348SJose.Borrego@Sun.COM #include <assert.h> 457052Samw #include <sys/mnttab.h> 467052Samw #include <sys/stat.h> 477052Samw #include <sys/types.h> 487052Samw 497052Samw #include <smbsrv/libsmb.h> 507052Samw #include <smbsrv/libsmbns.h> 51*7588Samw@Sun.COM #include <smbsrv/libmlsvc.h> 527052Samw 537052Samw #include <libshare.h> 547052Samw 557052Samw #include <smbsrv/lm.h> 567052Samw #include <smbsrv/smb_share.h> 577052Samw #include <smbsrv/cifs.h> 587052Samw 597052Samw #include <smbsrv/ctype.h> 607052Samw #include <smbsrv/smb_vops.h> 617348SJose.Borrego@Sun.COM #include <smbsrv/nterror.h> 627052Samw 637348SJose.Borrego@Sun.COM /* 647348SJose.Borrego@Sun.COM * Cache functions and vars 657348SJose.Borrego@Sun.COM */ 667052Samw #define SMB_SHARE_HTAB_SZ 1024 677052Samw 687052Samw static HT_HANDLE *smb_shr_handle = NULL; 697052Samw static rwlock_t smb_shr_lock; 707348SJose.Borrego@Sun.COM static pthread_t smb_shr_populate_thr; 717052Samw 727052Samw static uint32_t smb_shr_cache_create(void); 737348SJose.Borrego@Sun.COM static void smb_shr_cache_destroy(void); 747052Samw static void *smb_shr_cache_populate(void *); 757348SJose.Borrego@Sun.COM static uint32_t smb_shr_cache_addent(smb_share_t *); 767348SJose.Borrego@Sun.COM static void smb_shr_cache_delent(char *); 777348SJose.Borrego@Sun.COM static uint32_t smb_shr_cache_chgent(smb_share_t *); 787348SJose.Borrego@Sun.COM static void smb_shr_cache_freent(HT_ITEM *); 797348SJose.Borrego@Sun.COM static uint32_t smb_shr_cache_loadent(sa_share_t, sa_resource_t); 807348SJose.Borrego@Sun.COM static void smb_shr_cache_loadgrp(sa_group_t); 817052Samw 827348SJose.Borrego@Sun.COM static void smb_shr_set_ahcnt(char *, int); 837348SJose.Borrego@Sun.COM static void smb_shr_set_oemname(smb_share_t *); 847348SJose.Borrego@Sun.COM static uint32_t smb_shr_create_autohome(smb_share_t *); 857348SJose.Borrego@Sun.COM static uint32_t smb_shr_create_ipc(void); 867052Samw 877348SJose.Borrego@Sun.COM /* 887348SJose.Borrego@Sun.COM * sharemgr functions 897348SJose.Borrego@Sun.COM */ 907348SJose.Borrego@Sun.COM static uint32_t smb_shr_sa_delent(smb_share_t *); 917348SJose.Borrego@Sun.COM static uint32_t smb_shr_sa_addent(smb_share_t *); 927348SJose.Borrego@Sun.COM static uint32_t smb_shr_sa_getent(sa_share_t, sa_resource_t, smb_share_t *); 937348SJose.Borrego@Sun.COM static sa_group_t smb_shr_sa_getdefgrp(sa_handle_t); 947052Samw 957052Samw /* 967348SJose.Borrego@Sun.COM * share publishing 977348SJose.Borrego@Sun.COM */ 987348SJose.Borrego@Sun.COM #define SMB_SHR_PUBLISH 0 997348SJose.Borrego@Sun.COM #define SMB_SHR_UNPUBLISH 1 1007348SJose.Borrego@Sun.COM 1017348SJose.Borrego@Sun.COM typedef struct smb_shr_pitem { 1027348SJose.Borrego@Sun.COM list_node_t spi_lnd; 1037348SJose.Borrego@Sun.COM char spi_name[MAXNAMELEN]; 1047348SJose.Borrego@Sun.COM char spi_container[MAXPATHLEN]; 1057348SJose.Borrego@Sun.COM char spi_op; 1067348SJose.Borrego@Sun.COM } smb_shr_pitem_t; 1077348SJose.Borrego@Sun.COM 1087348SJose.Borrego@Sun.COM /* 1097348SJose.Borrego@Sun.COM * publish queue states 1107348SJose.Borrego@Sun.COM */ 1117348SJose.Borrego@Sun.COM #define SMB_SHR_PQS_NOQUEUE 0 1127348SJose.Borrego@Sun.COM #define SMB_SHR_PQS_READY 1 /* the queue is ready */ 1137348SJose.Borrego@Sun.COM #define SMB_SHR_PQS_PUBLISHING 2 /* publisher thread is running */ 1147348SJose.Borrego@Sun.COM #define SMB_SHR_PQS_STOPPING 3 1157348SJose.Borrego@Sun.COM 1167348SJose.Borrego@Sun.COM /* 1177348SJose.Borrego@Sun.COM * share publishing queue 1187348SJose.Borrego@Sun.COM */ 1197348SJose.Borrego@Sun.COM typedef struct smb_shr_pqueue { 1207348SJose.Borrego@Sun.COM int spq_cnt; 1217348SJose.Borrego@Sun.COM list_t spq_list; 1227348SJose.Borrego@Sun.COM mutex_t spq_mtx; 1237348SJose.Borrego@Sun.COM cond_t spq_cv; 1247348SJose.Borrego@Sun.COM uint32_t spq_state; 1257348SJose.Borrego@Sun.COM } smb_shr_pqueue_t; 1267348SJose.Borrego@Sun.COM 1277348SJose.Borrego@Sun.COM static smb_shr_pqueue_t ad_queue; 1287348SJose.Borrego@Sun.COM static pthread_t smb_shr_publish_thr; 1297348SJose.Borrego@Sun.COM 1307348SJose.Borrego@Sun.COM static int smb_shr_publisher_start(void); 1317348SJose.Borrego@Sun.COM static void smb_shr_publisher_stop(void); 1327348SJose.Borrego@Sun.COM static void smb_shr_publisher_send(smb_ads_handle_t *, list_t *, const char *); 1337348SJose.Borrego@Sun.COM static void *smb_shr_publisher(void *); 1347348SJose.Borrego@Sun.COM static void smb_shr_publish(const char *, const char *, char); 1357348SJose.Borrego@Sun.COM 1367348SJose.Borrego@Sun.COM 1377348SJose.Borrego@Sun.COM /* 1387348SJose.Borrego@Sun.COM * smb_shr_start 1397348SJose.Borrego@Sun.COM * 1407348SJose.Borrego@Sun.COM * Starts the publisher thread and another thread which 1417348SJose.Borrego@Sun.COM * populates the share cache by share information stored 1427348SJose.Borrego@Sun.COM * by sharemgr 1437052Samw */ 1447052Samw int 1457052Samw smb_shr_start(void) 1467052Samw { 1477348SJose.Borrego@Sun.COM pthread_attr_t tattr; 1487052Samw int rc; 1497052Samw 1507348SJose.Borrego@Sun.COM if ((rc = smb_shr_publisher_start()) != 0) 1517348SJose.Borrego@Sun.COM return (rc); 1527052Samw 1537348SJose.Borrego@Sun.COM (void) pthread_attr_init(&tattr); 1547348SJose.Borrego@Sun.COM (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 1557348SJose.Borrego@Sun.COM rc = pthread_create(&smb_shr_populate_thr, &tattr, 1567052Samw smb_shr_cache_populate, 0); 1577348SJose.Borrego@Sun.COM (void) pthread_attr_destroy(&tattr); 1587052Samw 1597052Samw return (rc); 1607052Samw } 1617052Samw 1627052Samw void 1637052Samw smb_shr_stop(void) 1647052Samw { 1657348SJose.Borrego@Sun.COM smb_shr_cache_destroy(); 1667348SJose.Borrego@Sun.COM smb_shr_publisher_stop(); 1677052Samw } 1687052Samw 1697052Samw /* 1707052Samw * smb_shr_count 1717052Samw * 1727348SJose.Borrego@Sun.COM * Return the total number of shares 1737052Samw */ 1747052Samw int 1757052Samw smb_shr_count(void) 1767052Samw { 1777052Samw int n_shares; 1787052Samw 1797348SJose.Borrego@Sun.COM (void) rw_rdlock(&smb_shr_lock); 1807052Samw n_shares = ht_get_total_items(smb_shr_handle); 1817348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 1827052Samw 1837052Samw return (n_shares); 1847052Samw } 1857052Samw 1867052Samw /* 1877052Samw * smb_shr_iterinit 1887052Samw * 1897348SJose.Borrego@Sun.COM * Initialize given iterator for traversing hash table. 1907052Samw */ 1917052Samw void 1927348SJose.Borrego@Sun.COM smb_shr_iterinit(smb_shriter_t *shi) 1937052Samw { 1947052Samw bzero(shi, sizeof (smb_shriter_t)); 1957348SJose.Borrego@Sun.COM shi->si_first = B_TRUE; 1967052Samw } 1977052Samw 1987052Samw /* 1997052Samw * smb_shr_iterate 2007052Samw * 2017052Samw * Iterate on the shares in the hash table. The iterator must be initialized 2027052Samw * before the first iteration. On subsequent calls, the iterator must be 2037052Samw * passed unchanged. 2047052Samw * 2057052Samw * Returns NULL on failure or when all shares are visited, otherwise 2067052Samw * returns information of visited share. 2077052Samw */ 2087052Samw smb_share_t * 2097052Samw smb_shr_iterate(smb_shriter_t *shi) 2107052Samw { 2117052Samw HT_ITEM *item; 2127348SJose.Borrego@Sun.COM smb_share_t *share = NULL; 2137052Samw 2147052Samw if (smb_shr_handle == NULL || shi == NULL) 2157052Samw return (NULL); 2167052Samw 2177348SJose.Borrego@Sun.COM (void) rw_rdlock(&smb_shr_lock); 2187348SJose.Borrego@Sun.COM if (shi->si_first) { 2197348SJose.Borrego@Sun.COM item = ht_findfirst(smb_shr_handle, &shi->si_hashiter); 2207348SJose.Borrego@Sun.COM shi->si_first = B_FALSE; 2217348SJose.Borrego@Sun.COM } else { 2227348SJose.Borrego@Sun.COM item = ht_findnext(&shi->si_hashiter); 2237052Samw } 2247052Samw 2257348SJose.Borrego@Sun.COM if (item && item->hi_data) { 2267348SJose.Borrego@Sun.COM share = &shi->si_share; 2277348SJose.Borrego@Sun.COM bcopy(item->hi_data, share, sizeof (smb_share_t)); 2287348SJose.Borrego@Sun.COM } 2297348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 2307052Samw 2317348SJose.Borrego@Sun.COM return (share); 2327052Samw } 2337052Samw 2347052Samw /* 2357348SJose.Borrego@Sun.COM * smb_shr_create 2367052Samw * 2377348SJose.Borrego@Sun.COM * Adds the given to cache and if 'store' is B_TRUE it's also 2387348SJose.Borrego@Sun.COM * added to sharemgr 2397052Samw */ 2407052Samw uint32_t 2417348SJose.Borrego@Sun.COM smb_shr_create(smb_share_t *si, boolean_t store) 2427052Samw { 2437052Samw uint32_t status = NERR_Success; 2447348SJose.Borrego@Sun.COM int rc; 2457052Samw 2467348SJose.Borrego@Sun.COM assert(si != NULL); 2477052Samw 2487348SJose.Borrego@Sun.COM if (!smb_shr_chkname(si->shr_name)) 2497348SJose.Borrego@Sun.COM return (ERROR_INVALID_NAME); 2507052Samw 2517348SJose.Borrego@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) 2527348SJose.Borrego@Sun.COM return (smb_shr_create_autohome(si)); 2537052Samw 2547348SJose.Borrego@Sun.COM if (smb_shr_exists(si->shr_name)) 2557348SJose.Borrego@Sun.COM return (NERR_DuplicateShare); 2567052Samw 2577348SJose.Borrego@Sun.COM if ((status = smb_shr_cache_addent(si)) != NERR_Success) 2587052Samw return (status); 2597052Samw 2607348SJose.Borrego@Sun.COM if (store && (si->shr_flags & SMB_SHRF_PERM)) { 2617348SJose.Borrego@Sun.COM if ((status = smb_shr_sa_addent(si)) != NERR_Success) { 2627348SJose.Borrego@Sun.COM (void) smb_shr_cache_delent(si->shr_name); 2637052Samw return (status); 2647052Samw } 2657052Samw } 2667052Samw 267*7588Samw@Sun.COM rc = mlsvc_set_share(SMB_SHROP_ADD, si->shr_path, si->shr_name); 2687348SJose.Borrego@Sun.COM 2697348SJose.Borrego@Sun.COM if (rc == 0) { 2707348SJose.Borrego@Sun.COM smb_shr_publish(si->shr_name, si->shr_container, 2717348SJose.Borrego@Sun.COM SMB_SHR_PUBLISH); 2727348SJose.Borrego@Sun.COM return (status); 2737052Samw } 2747052Samw 2757348SJose.Borrego@Sun.COM smb_shr_cache_delent(si->shr_name); 2767348SJose.Borrego@Sun.COM if (store && (si->shr_flags & SMB_SHRF_PERM)) 2777348SJose.Borrego@Sun.COM (void) smb_shr_sa_delent(si); 2787052Samw 2797052Samw /* 2807348SJose.Borrego@Sun.COM * rc == ENOENT means the shared directory doesn't exist 2817052Samw */ 2827348SJose.Borrego@Sun.COM return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError); 2837052Samw } 2847052Samw 2857052Samw /* 2867348SJose.Borrego@Sun.COM * smb_shr_delete 2877052Samw * 2887348SJose.Borrego@Sun.COM * Removes the specified share. 2897052Samw */ 2907348SJose.Borrego@Sun.COM uint32_t 2917348SJose.Borrego@Sun.COM smb_shr_delete(char *sharename, boolean_t store) 2927052Samw { 2937348SJose.Borrego@Sun.COM smb_share_t si; 2947348SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 2957348SJose.Borrego@Sun.COM 2967348SJose.Borrego@Sun.COM assert(sharename != NULL); 2977348SJose.Borrego@Sun.COM 2987348SJose.Borrego@Sun.COM if ((status = smb_shr_get(sharename, &si)) != NERR_Success) 2997348SJose.Borrego@Sun.COM return (status); 3007052Samw 3017348SJose.Borrego@Sun.COM if (si.shr_type & STYPE_IPC) 3027348SJose.Borrego@Sun.COM return (ERROR_ACCESS_DENIED); 3037348SJose.Borrego@Sun.COM 3047348SJose.Borrego@Sun.COM if (si.shr_flags & SMB_SHRF_AUTOHOME) { 3057348SJose.Borrego@Sun.COM si.shr_refcnt--; 3067348SJose.Borrego@Sun.COM if (si.shr_refcnt > 0) { 3077348SJose.Borrego@Sun.COM smb_shr_set_ahcnt(si.shr_name, si.shr_refcnt); 3087348SJose.Borrego@Sun.COM return (status); 3097348SJose.Borrego@Sun.COM } 3107052Samw } 3117052Samw 3127348SJose.Borrego@Sun.COM if (store && (si.shr_flags & SMB_SHRF_PERM)) { 3137348SJose.Borrego@Sun.COM if (smb_shr_sa_delent(&si) != NERR_Success) 3147348SJose.Borrego@Sun.COM return (NERR_InternalError); 3157052Samw } 3167348SJose.Borrego@Sun.COM 3177348SJose.Borrego@Sun.COM smb_shr_cache_delent(si.shr_name); 3187348SJose.Borrego@Sun.COM smb_shr_publish(si.shr_name, si.shr_container, SMB_SHR_UNPUBLISH); 319*7588Samw@Sun.COM (void) mlsvc_set_share(SMB_SHROP_DELETE, si.shr_path, si.shr_name); 3207348SJose.Borrego@Sun.COM 3217052Samw return (NERR_Success); 3227052Samw } 3237052Samw 3247052Samw /* 3257348SJose.Borrego@Sun.COM * smb_shr_rename 3267052Samw * 3277052Samw * Rename a share. Check that the current name exists and the new name 3287052Samw * doesn't exist. The rename is performed by deleting the current share 3297052Samw * definition and creating a new share with the new name. 3307052Samw */ 3317052Samw uint32_t 3327348SJose.Borrego@Sun.COM smb_shr_rename(char *from_name, char *to_name) 3337052Samw { 3347052Samw smb_share_t si; 3357348SJose.Borrego@Sun.COM uint32_t status; 3367348SJose.Borrego@Sun.COM 3377348SJose.Borrego@Sun.COM assert((from_name != NULL) && (to_name != NULL)); 3387052Samw 3397348SJose.Borrego@Sun.COM if (!smb_shr_chkname(from_name) || !smb_shr_chkname(to_name)) 3407348SJose.Borrego@Sun.COM return (ERROR_INVALID_NAME); 3417052Samw 3427348SJose.Borrego@Sun.COM if (!smb_shr_exists(from_name)) 3437052Samw return (NERR_NetNameNotFound); 3447052Samw 3457052Samw if (smb_shr_exists(to_name)) 3467052Samw return (NERR_DuplicateShare); 3477052Samw 3487348SJose.Borrego@Sun.COM if ((status = smb_shr_get(from_name, &si)) != NERR_Success) 3497348SJose.Borrego@Sun.COM return (status); 3507348SJose.Borrego@Sun.COM 3517348SJose.Borrego@Sun.COM if (si.shr_type & STYPE_IPC) 3527348SJose.Borrego@Sun.COM return (ERROR_ACCESS_DENIED); 3537348SJose.Borrego@Sun.COM 3547348SJose.Borrego@Sun.COM (void) strlcpy(si.shr_name, to_name, sizeof (si.shr_name)); 3557348SJose.Borrego@Sun.COM if ((status = smb_shr_cache_addent(&si)) != NERR_Success) 3567348SJose.Borrego@Sun.COM return (status); 3577348SJose.Borrego@Sun.COM 3587348SJose.Borrego@Sun.COM smb_shr_cache_delent(from_name); 3597348SJose.Borrego@Sun.COM smb_shr_publish(from_name, si.shr_container, SMB_SHR_UNPUBLISH); 3607348SJose.Borrego@Sun.COM smb_shr_publish(to_name, si.shr_container, SMB_SHR_PUBLISH); 3617348SJose.Borrego@Sun.COM 3627348SJose.Borrego@Sun.COM return (NERR_Success); 3637348SJose.Borrego@Sun.COM } 3647348SJose.Borrego@Sun.COM 3657348SJose.Borrego@Sun.COM /* 3667348SJose.Borrego@Sun.COM * smb_shr_get 3677348SJose.Borrego@Sun.COM * 3687348SJose.Borrego@Sun.COM * Load the information for the specified share into the supplied share 3697348SJose.Borrego@Sun.COM * info structure. 3707348SJose.Borrego@Sun.COM */ 3717348SJose.Borrego@Sun.COM uint32_t 3727348SJose.Borrego@Sun.COM smb_shr_get(char *sharename, smb_share_t *si) 3737348SJose.Borrego@Sun.COM { 3747348SJose.Borrego@Sun.COM HT_ITEM *item; 3757348SJose.Borrego@Sun.COM 3767348SJose.Borrego@Sun.COM (void) utf8_strlwr(sharename); 3777348SJose.Borrego@Sun.COM 3787348SJose.Borrego@Sun.COM (void) rw_rdlock(&smb_shr_lock); 3797348SJose.Borrego@Sun.COM item = ht_find_item(smb_shr_handle, sharename); 3807348SJose.Borrego@Sun.COM if (item == NULL || item->hi_data == NULL) { 3817348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 3827348SJose.Borrego@Sun.COM return (NERR_NetNameNotFound); 3837348SJose.Borrego@Sun.COM } 3847348SJose.Borrego@Sun.COM 3857348SJose.Borrego@Sun.COM bcopy(item->hi_data, si, sizeof (smb_share_t)); 3867348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 3877348SJose.Borrego@Sun.COM 3887348SJose.Borrego@Sun.COM return (NERR_Success); 3897348SJose.Borrego@Sun.COM } 3907348SJose.Borrego@Sun.COM 3917348SJose.Borrego@Sun.COM /* 3927348SJose.Borrego@Sun.COM * smb_shr_modify 3937348SJose.Borrego@Sun.COM * 3947348SJose.Borrego@Sun.COM * Modifies an existing share. Properties that can be modified are: 3957348SJose.Borrego@Sun.COM * 3967348SJose.Borrego@Sun.COM * o comment 3977348SJose.Borrego@Sun.COM * o AD container 3987348SJose.Borrego@Sun.COM */ 3997348SJose.Borrego@Sun.COM uint32_t 4007348SJose.Borrego@Sun.COM smb_shr_modify(char *sharename, const char *cmnt, 4017348SJose.Borrego@Sun.COM const char *ad_container, boolean_t store) 4027348SJose.Borrego@Sun.COM { 4037348SJose.Borrego@Sun.COM smb_share_t si; 4047348SJose.Borrego@Sun.COM uint32_t status; 4057348SJose.Borrego@Sun.COM boolean_t cmnt_changed = B_FALSE; 4067348SJose.Borrego@Sun.COM boolean_t adc_changed = B_FALSE; 4077348SJose.Borrego@Sun.COM char shr_container[MAXPATHLEN]; 4087348SJose.Borrego@Sun.COM 4097348SJose.Borrego@Sun.COM assert(sharename != NULL); 4107348SJose.Borrego@Sun.COM 4117348SJose.Borrego@Sun.COM if ((cmnt == NULL) && (ad_container == NULL)) 4127348SJose.Borrego@Sun.COM /* no changes */ 4137348SJose.Borrego@Sun.COM return (NERR_Success); 4147052Samw 4157348SJose.Borrego@Sun.COM if ((status = smb_shr_get(sharename, &si)) != NERR_Success) 4167348SJose.Borrego@Sun.COM return (status); 4177348SJose.Borrego@Sun.COM 4187348SJose.Borrego@Sun.COM if (si.shr_type & STYPE_IPC) 4197348SJose.Borrego@Sun.COM return (ERROR_ACCESS_DENIED); 4207348SJose.Borrego@Sun.COM 4217348SJose.Borrego@Sun.COM if (cmnt) { 4227348SJose.Borrego@Sun.COM cmnt_changed = (strcmp(cmnt, si.shr_cmnt) != 0); 4237348SJose.Borrego@Sun.COM if (cmnt_changed) 4247348SJose.Borrego@Sun.COM (void) strlcpy(si.shr_cmnt, cmnt, sizeof (si.shr_cmnt)); 4257348SJose.Borrego@Sun.COM } 4267348SJose.Borrego@Sun.COM 4277348SJose.Borrego@Sun.COM if (ad_container) { 4287348SJose.Borrego@Sun.COM adc_changed = (strcmp(ad_container, si.shr_container) != 0); 4297348SJose.Borrego@Sun.COM if (adc_changed) { 4307348SJose.Borrego@Sun.COM /* save current container needed for unpublishing */ 4317348SJose.Borrego@Sun.COM (void) strlcpy(shr_container, si.shr_container, 4327348SJose.Borrego@Sun.COM sizeof (shr_container)); 4337348SJose.Borrego@Sun.COM (void) strlcpy(si.shr_container, ad_container, 4347348SJose.Borrego@Sun.COM sizeof (si.shr_container)); 4357348SJose.Borrego@Sun.COM } 4367348SJose.Borrego@Sun.COM } 4377348SJose.Borrego@Sun.COM 4387348SJose.Borrego@Sun.COM if (!cmnt_changed && !adc_changed) 4397348SJose.Borrego@Sun.COM /* no changes */ 4407348SJose.Borrego@Sun.COM return (NERR_Success); 4417348SJose.Borrego@Sun.COM 4427348SJose.Borrego@Sun.COM if (store && (si.shr_flags & SMB_SHRF_PERM)) { 4437348SJose.Borrego@Sun.COM if (smb_shr_sa_addent(&si) != NERR_Success) 4447348SJose.Borrego@Sun.COM return (NERR_InternalError); 4457348SJose.Borrego@Sun.COM } 4467348SJose.Borrego@Sun.COM 4477348SJose.Borrego@Sun.COM (void) smb_shr_cache_chgent(&si); 4487052Samw 4497348SJose.Borrego@Sun.COM if (adc_changed) { 4507348SJose.Borrego@Sun.COM smb_shr_publish(si.shr_name, shr_container, 4517348SJose.Borrego@Sun.COM SMB_SHR_UNPUBLISH); 4527348SJose.Borrego@Sun.COM smb_shr_publish(si.shr_name, si.shr_container, 4537348SJose.Borrego@Sun.COM SMB_SHR_PUBLISH); 4547348SJose.Borrego@Sun.COM } 4557348SJose.Borrego@Sun.COM 4567348SJose.Borrego@Sun.COM return (NERR_Success); 4577052Samw } 4587052Samw 4597348SJose.Borrego@Sun.COM void 4607348SJose.Borrego@Sun.COM smb_shr_list(int offset, smb_shrlist_t *list) 4617348SJose.Borrego@Sun.COM { 4627348SJose.Borrego@Sun.COM smb_shriter_t iterator; 4637348SJose.Borrego@Sun.COM smb_share_t *si; 4647348SJose.Borrego@Sun.COM int n = 0; 4657348SJose.Borrego@Sun.COM 4667348SJose.Borrego@Sun.COM bzero(list, sizeof (smb_shrlist_t)); 4677348SJose.Borrego@Sun.COM smb_shr_iterinit(&iterator); 4687348SJose.Borrego@Sun.COM 4697348SJose.Borrego@Sun.COM while ((si = smb_shr_iterate(&iterator)) != NULL) { 4707348SJose.Borrego@Sun.COM if (--offset > 0) 4717348SJose.Borrego@Sun.COM continue; 4727348SJose.Borrego@Sun.COM 4737348SJose.Borrego@Sun.COM if ((si->shr_flags & SMB_SHRF_TRANS) && 4747348SJose.Borrego@Sun.COM ((si->shr_type & STYPE_IPC) == 0)) { 4757348SJose.Borrego@Sun.COM bcopy(si, &list->sl_shares[n], sizeof (smb_share_t)); 4767348SJose.Borrego@Sun.COM if (++n == LMSHARES_PER_REQUEST) 4777348SJose.Borrego@Sun.COM break; 4787348SJose.Borrego@Sun.COM } 4797348SJose.Borrego@Sun.COM } 4807348SJose.Borrego@Sun.COM 4817348SJose.Borrego@Sun.COM list->sl_cnt = n; 4827348SJose.Borrego@Sun.COM } 4837348SJose.Borrego@Sun.COM 4847348SJose.Borrego@Sun.COM 4857052Samw /* 4867052Samw * smb_shr_exists 4877052Samw * 4887348SJose.Borrego@Sun.COM * Returns B_TRUE if the share exists. Otherwise returns B_FALSE 4897052Samw */ 4907348SJose.Borrego@Sun.COM boolean_t 4917348SJose.Borrego@Sun.COM smb_shr_exists(char *sharename) 4927052Samw { 4937348SJose.Borrego@Sun.COM boolean_t exists; 4947348SJose.Borrego@Sun.COM 4957348SJose.Borrego@Sun.COM if (sharename == NULL || *sharename == '\0') 4967348SJose.Borrego@Sun.COM return (B_FALSE); 4977052Samw 4987348SJose.Borrego@Sun.COM (void) utf8_strlwr(sharename); 4997348SJose.Borrego@Sun.COM 5007348SJose.Borrego@Sun.COM (void) rw_rdlock(&smb_shr_lock); 5017348SJose.Borrego@Sun.COM exists = (ht_find_item(smb_shr_handle, sharename) != NULL); 5027348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 5037348SJose.Borrego@Sun.COM 5047348SJose.Borrego@Sun.COM return (exists); 5057052Samw } 5067052Samw 5077052Samw /* 5087052Samw * smb_shr_is_special 5097052Samw * 5107348SJose.Borrego@Sun.COM * Special share reserved for interprocess communication (IPC$) or 5117348SJose.Borrego@Sun.COM * remote administration of the server (ADMIN$). Can also refer to 5127348SJose.Borrego@Sun.COM * administrative shares such as C$, D$, E$, and so forth. 5137052Samw */ 5147052Samw int 5157348SJose.Borrego@Sun.COM smb_shr_is_special(char *sharename) 5167052Samw { 5177052Samw int len; 5187052Samw 5197348SJose.Borrego@Sun.COM if (sharename == NULL) 5207052Samw return (0); 5217052Samw 5227348SJose.Borrego@Sun.COM if ((len = strlen(sharename)) == 0) 5237052Samw return (0); 5247052Samw 5257348SJose.Borrego@Sun.COM if (sharename[len - 1] == '$') 5267052Samw return (STYPE_SPECIAL); 5277348SJose.Borrego@Sun.COM 5287348SJose.Borrego@Sun.COM return (0); 5297052Samw } 5307052Samw 5317052Samw /* 5327052Samw * smb_shr_is_restricted 5337052Samw * 5347052Samw * Check whether or not there is a restriction on a share. Restricted 5357052Samw * shares are generally STYPE_SPECIAL, for example, IPC$. All the 5367348SJose.Borrego@Sun.COM * administration share names are restricted: C$, D$ etc. Returns B_TRUE 5377348SJose.Borrego@Sun.COM * if the share is restricted. Otherwise B_FALSE is returned to indicate 5387052Samw * that there are no restrictions. 5397052Samw */ 5407348SJose.Borrego@Sun.COM boolean_t 5417348SJose.Borrego@Sun.COM smb_shr_is_restricted(char *sharename) 5427052Samw { 5437052Samw static char *restricted[] = { 5447052Samw "IPC$" 5457052Samw }; 5467052Samw 5477052Samw int i; 5487052Samw 5497348SJose.Borrego@Sun.COM if (sharename == NULL) 5507348SJose.Borrego@Sun.COM return (B_FALSE); 5517348SJose.Borrego@Sun.COM 5527052Samw for (i = 0; i < sizeof (restricted)/sizeof (restricted[0]); i++) { 5537348SJose.Borrego@Sun.COM if (utf8_strcasecmp(restricted[i], sharename) == 0) 5547348SJose.Borrego@Sun.COM return (B_TRUE); 5557052Samw } 5567052Samw 5577348SJose.Borrego@Sun.COM return (smb_shr_is_admin(sharename)); 5587052Samw } 5597052Samw 5607052Samw /* 5617052Samw * smb_shr_is_admin 5627052Samw * 5637052Samw * Check whether or not access to the share should be restricted to 5647052Samw * administrators. This is a bit of a hack because what we're doing 5657052Samw * is checking for the default admin shares: C$, D$ etc.. There are 5667052Samw * other shares that have restrictions: see smb_shr_is_restricted(). 5677052Samw * 5687348SJose.Borrego@Sun.COM * Returns B_TRUE if the shares is an admin share. Otherwise B_FALSE 5697348SJose.Borrego@Sun.COM * is returned to indicate that there are no restrictions. 5707052Samw */ 5717348SJose.Borrego@Sun.COM boolean_t 5727348SJose.Borrego@Sun.COM smb_shr_is_admin(char *sharename) 5737052Samw { 5747348SJose.Borrego@Sun.COM if (sharename == NULL) 5757348SJose.Borrego@Sun.COM return (B_FALSE); 5767052Samw 5777348SJose.Borrego@Sun.COM if (strlen(sharename) == 2 && 5787348SJose.Borrego@Sun.COM mts_isalpha(sharename[0]) && sharename[1] == '$') { 5797348SJose.Borrego@Sun.COM return (B_TRUE); 5807052Samw } 5817052Samw 5827348SJose.Borrego@Sun.COM return (B_FALSE); 5837052Samw } 5847052Samw 5857052Samw /* 5867348SJose.Borrego@Sun.COM * smb_shr_chkname 5877052Samw * 5887052Samw * Check if any invalid char is present in share name. According to 5897052Samw * MSDN article #236388: "Err Msg: The Share Name Contains Invalid 5907052Samw * Characters", the list of invalid character is: 5917052Samw * 5927052Samw * " / \ [ ] : | < > + ; , ? * = 5937052Samw * 5947052Samw * Also rejects if control characters are embedded. 5957052Samw */ 5967348SJose.Borrego@Sun.COM boolean_t 5977348SJose.Borrego@Sun.COM smb_shr_chkname(char *sharename) 5987052Samw { 5997052Samw char *invalid = "\"/\\[]:|<>+;,?*="; 6007052Samw char *cp; 6017052Samw 6027348SJose.Borrego@Sun.COM if (sharename == NULL) 6037348SJose.Borrego@Sun.COM return (B_FALSE); 6047052Samw 6057348SJose.Borrego@Sun.COM if (strpbrk(sharename, invalid)) 6067348SJose.Borrego@Sun.COM return (B_FALSE); 6077052Samw 6087348SJose.Borrego@Sun.COM for (cp = sharename; *cp != '\0'; cp++) { 6097348SJose.Borrego@Sun.COM if (iscntrl(*cp)) 6107348SJose.Borrego@Sun.COM return (B_FALSE); 6117052Samw } 6127052Samw 6137348SJose.Borrego@Sun.COM return (B_TRUE); 6147052Samw } 6157052Samw 6167052Samw /* 6177052Samw * smb_shr_get_realpath 6187052Samw * 6197052Samw * Derive the real path of a share from the path provided by a 6207052Samw * Windows client application during the share addition. 6217052Samw * 6227052Samw * For instance, the real path of C:\ is /cvol and the 6237052Samw * real path of F:\home is /vol1/home. 6247052Samw * 6257052Samw * clipath - path provided by the Windows client is in the 6267052Samw * format of <drive letter>:\<dir> 6277052Samw * realpath - path that will be stored as the directory field of 6287052Samw * the smb_share_t structure of the share. 6297052Samw * maxlen - maximum length fo the realpath buffer 6307052Samw * 6317052Samw * Return LAN Manager network error code. 6327052Samw */ 6337052Samw /*ARGSUSED*/ 6347052Samw uint32_t 6357052Samw smb_shr_get_realpath(const char *clipath, char *realpath, int maxlen) 6367052Samw { 6377052Samw /* XXX do this translation */ 6387052Samw return (NERR_Success); 6397052Samw } 6407052Samw 6417052Samw /* 6427348SJose.Borrego@Sun.COM * ============================================ 6437348SJose.Borrego@Sun.COM * Cache management functions 6447348SJose.Borrego@Sun.COM * ============================================ 6457348SJose.Borrego@Sun.COM */ 6467348SJose.Borrego@Sun.COM 6477348SJose.Borrego@Sun.COM /* 6487348SJose.Borrego@Sun.COM * smb_shr_cache_create 6497348SJose.Borrego@Sun.COM * 6507348SJose.Borrego@Sun.COM * Create the share hash table. 6517348SJose.Borrego@Sun.COM */ 6527348SJose.Borrego@Sun.COM static uint32_t 6537348SJose.Borrego@Sun.COM smb_shr_cache_create(void) 6547348SJose.Borrego@Sun.COM { 6557348SJose.Borrego@Sun.COM if (smb_shr_handle == NULL) { 6567348SJose.Borrego@Sun.COM (void) rwlock_init(&smb_shr_lock, USYNC_THREAD, 0); 6577348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 6587348SJose.Borrego@Sun.COM 6597348SJose.Borrego@Sun.COM smb_shr_handle = ht_create_table(SMB_SHARE_HTAB_SZ, 6607348SJose.Borrego@Sun.COM MAXNAMELEN, 0); 6617348SJose.Borrego@Sun.COM if (smb_shr_handle == NULL) { 6627348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 6637348SJose.Borrego@Sun.COM return (NERR_InternalError); 6647348SJose.Borrego@Sun.COM } 6657348SJose.Borrego@Sun.COM 6667348SJose.Borrego@Sun.COM (void) ht_register_callback(smb_shr_handle, 6677348SJose.Borrego@Sun.COM smb_shr_cache_freent); 6687348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 6697348SJose.Borrego@Sun.COM } 6707348SJose.Borrego@Sun.COM 6717348SJose.Borrego@Sun.COM return (NERR_Success); 6727348SJose.Borrego@Sun.COM } 6737348SJose.Borrego@Sun.COM 6747348SJose.Borrego@Sun.COM /* 6757348SJose.Borrego@Sun.COM * smb_shr_cache_destroy 6767348SJose.Borrego@Sun.COM * 6777348SJose.Borrego@Sun.COM * Destroys the share hash table. 6787348SJose.Borrego@Sun.COM */ 6797348SJose.Borrego@Sun.COM static void 6807348SJose.Borrego@Sun.COM smb_shr_cache_destroy(void) 6817348SJose.Borrego@Sun.COM { 6827348SJose.Borrego@Sun.COM if (smb_shr_handle) { 6837348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 6847348SJose.Borrego@Sun.COM ht_destroy_table(smb_shr_handle); 6857348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 6867348SJose.Borrego@Sun.COM (void) rwlock_destroy(&smb_shr_lock); 6877348SJose.Borrego@Sun.COM smb_shr_handle = NULL; 6887348SJose.Borrego@Sun.COM } 6897348SJose.Borrego@Sun.COM } 6907348SJose.Borrego@Sun.COM 6917348SJose.Borrego@Sun.COM /* 6927348SJose.Borrego@Sun.COM * smb_shr_cache_populate 6937348SJose.Borrego@Sun.COM * 6947348SJose.Borrego@Sun.COM * Load shares from sharemgr 6957348SJose.Borrego@Sun.COM */ 6967348SJose.Borrego@Sun.COM /*ARGSUSED*/ 6977348SJose.Borrego@Sun.COM static void * 6987348SJose.Borrego@Sun.COM smb_shr_cache_populate(void *args) 6997348SJose.Borrego@Sun.COM { 7007348SJose.Borrego@Sun.COM sa_handle_t handle; 7017348SJose.Borrego@Sun.COM sa_group_t group, subgroup; 7027348SJose.Borrego@Sun.COM char *gstate; 7037348SJose.Borrego@Sun.COM boolean_t gdisabled; 7047348SJose.Borrego@Sun.COM 7057348SJose.Borrego@Sun.COM if (smb_shr_cache_create() != NERR_Success) { 7067348SJose.Borrego@Sun.COM syslog(LOG_ERR, "share: failed creating the cache"); 7077348SJose.Borrego@Sun.COM return (NULL); 7087348SJose.Borrego@Sun.COM } 7097348SJose.Borrego@Sun.COM 7107348SJose.Borrego@Sun.COM if (smb_shr_create_ipc() != NERR_Success) { 7117348SJose.Borrego@Sun.COM syslog(LOG_ERR, "share: failed creating IPC$"); 7127348SJose.Borrego@Sun.COM return (NULL); 7137348SJose.Borrego@Sun.COM } 7147348SJose.Borrego@Sun.COM 7157348SJose.Borrego@Sun.COM if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL) { 7167348SJose.Borrego@Sun.COM syslog(LOG_ERR, "share: failed connecting to backend"); 7177348SJose.Borrego@Sun.COM return (NULL); 7187348SJose.Borrego@Sun.COM } 7197348SJose.Borrego@Sun.COM 7207348SJose.Borrego@Sun.COM for (group = sa_get_group(handle, NULL); 7217348SJose.Borrego@Sun.COM group != NULL; group = sa_get_next_group(group)) { 7227348SJose.Borrego@Sun.COM gstate = sa_get_group_attr(group, "state"); 7237348SJose.Borrego@Sun.COM if (gstate == NULL) 7247348SJose.Borrego@Sun.COM continue; 7257348SJose.Borrego@Sun.COM 7267348SJose.Borrego@Sun.COM gdisabled = (strcasecmp(gstate, "disabled") == 0); 7277348SJose.Borrego@Sun.COM sa_free_attr_string(gstate); 7287348SJose.Borrego@Sun.COM if (gdisabled) 7297348SJose.Borrego@Sun.COM continue; 7307348SJose.Borrego@Sun.COM 7317348SJose.Borrego@Sun.COM smb_shr_cache_loadgrp(group); 7327348SJose.Borrego@Sun.COM for (subgroup = sa_get_sub_group(group); 7337348SJose.Borrego@Sun.COM subgroup != NULL; 7347348SJose.Borrego@Sun.COM subgroup = sa_get_next_group(subgroup)) { 7357348SJose.Borrego@Sun.COM smb_shr_cache_loadgrp(subgroup); 7367348SJose.Borrego@Sun.COM } 7377348SJose.Borrego@Sun.COM 7387348SJose.Borrego@Sun.COM } 7397348SJose.Borrego@Sun.COM 7407348SJose.Borrego@Sun.COM sa_fini(handle); 7417348SJose.Borrego@Sun.COM return (NULL); 7427348SJose.Borrego@Sun.COM } 7437348SJose.Borrego@Sun.COM 7447348SJose.Borrego@Sun.COM static uint32_t 7457348SJose.Borrego@Sun.COM smb_shr_cache_addent(smb_share_t *si) 7467348SJose.Borrego@Sun.COM { 7477348SJose.Borrego@Sun.COM smb_share_t *cache_ent; 7487348SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 7497348SJose.Borrego@Sun.COM 7507348SJose.Borrego@Sun.COM /* 7517348SJose.Borrego@Sun.COM * allocate memory for the entry that needs to be cached. 7527348SJose.Borrego@Sun.COM */ 7537348SJose.Borrego@Sun.COM if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL) 7547348SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7557348SJose.Borrego@Sun.COM 7567348SJose.Borrego@Sun.COM bcopy(si, cache_ent, sizeof (smb_share_t)); 7577348SJose.Borrego@Sun.COM 7587348SJose.Borrego@Sun.COM (void) utf8_strlwr(cache_ent->shr_name); 7597348SJose.Borrego@Sun.COM smb_shr_set_oemname(cache_ent); 7607348SJose.Borrego@Sun.COM if ((si->shr_type & STYPE_IPC) == 0) 7617348SJose.Borrego@Sun.COM cache_ent->shr_type = STYPE_DISKTREE; 7627348SJose.Borrego@Sun.COM cache_ent->shr_type |= smb_shr_is_special(cache_ent->shr_name); 7637348SJose.Borrego@Sun.COM 7647348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 7657348SJose.Borrego@Sun.COM if (ht_add_item(smb_shr_handle, cache_ent->shr_name, cache_ent) 7667348SJose.Borrego@Sun.COM == NULL) { 7677348SJose.Borrego@Sun.COM syslog(LOG_DEBUG, "share: failed adding %s to cache", 7687348SJose.Borrego@Sun.COM cache_ent->shr_name); 7697348SJose.Borrego@Sun.COM free(cache_ent); 7707348SJose.Borrego@Sun.COM status = NERR_InternalError; 7717348SJose.Borrego@Sun.COM } 7727348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 7737348SJose.Borrego@Sun.COM 7747348SJose.Borrego@Sun.COM return (status); 7757348SJose.Borrego@Sun.COM } 7767348SJose.Borrego@Sun.COM 7777348SJose.Borrego@Sun.COM static void 7787348SJose.Borrego@Sun.COM smb_shr_cache_delent(char *sharename) 7797348SJose.Borrego@Sun.COM { 7807348SJose.Borrego@Sun.COM (void) utf8_strlwr(sharename); 7817348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 7827348SJose.Borrego@Sun.COM (void) ht_remove_item(smb_shr_handle, sharename); 7837348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 7847348SJose.Borrego@Sun.COM } 7857348SJose.Borrego@Sun.COM 7867348SJose.Borrego@Sun.COM static uint32_t 7877348SJose.Borrego@Sun.COM smb_shr_cache_chgent(smb_share_t *si) 7887348SJose.Borrego@Sun.COM { 7897348SJose.Borrego@Sun.COM smb_share_t *cache_ent; 7907348SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 7917348SJose.Borrego@Sun.COM 7927348SJose.Borrego@Sun.COM /* 7937348SJose.Borrego@Sun.COM * allocate memory for the entry that needs to be cached. 7947348SJose.Borrego@Sun.COM */ 7957348SJose.Borrego@Sun.COM if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL) 7967348SJose.Borrego@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 7977348SJose.Borrego@Sun.COM 7987348SJose.Borrego@Sun.COM bcopy(si, cache_ent, sizeof (smb_share_t)); 7997348SJose.Borrego@Sun.COM (void) utf8_strlwr(cache_ent->shr_name); 8007348SJose.Borrego@Sun.COM 8017348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 8027348SJose.Borrego@Sun.COM if (ht_replace_item(smb_shr_handle, cache_ent->shr_name, cache_ent) 8037348SJose.Borrego@Sun.COM == NULL) { 8047348SJose.Borrego@Sun.COM syslog(LOG_DEBUG, "share: failed modifying %s", 8057348SJose.Borrego@Sun.COM cache_ent->shr_name); 8067348SJose.Borrego@Sun.COM free(cache_ent); 8077348SJose.Borrego@Sun.COM status = NERR_InternalError; 8087348SJose.Borrego@Sun.COM } 8097348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 8107348SJose.Borrego@Sun.COM 8117348SJose.Borrego@Sun.COM return (status); 8127348SJose.Borrego@Sun.COM } 8137348SJose.Borrego@Sun.COM 8147348SJose.Borrego@Sun.COM static uint32_t 8157348SJose.Borrego@Sun.COM smb_shr_create_autohome(smb_share_t *si) 8167348SJose.Borrego@Sun.COM { 8177348SJose.Borrego@Sun.COM uint32_t status = NERR_Success; 8187348SJose.Borrego@Sun.COM int rc; 8197348SJose.Borrego@Sun.COM 8207348SJose.Borrego@Sun.COM if (si->shr_refcnt == 0) { 8217348SJose.Borrego@Sun.COM if ((status = smb_shr_cache_addent(si)) != NERR_Success) 8227348SJose.Borrego@Sun.COM return (status); 8237348SJose.Borrego@Sun.COM 824*7588Samw@Sun.COM rc = mlsvc_set_share(SMB_SHROP_ADD, si->shr_path, si->shr_name); 8257348SJose.Borrego@Sun.COM 8267348SJose.Borrego@Sun.COM if (rc != 0) { 8277348SJose.Borrego@Sun.COM smb_shr_cache_delent(si->shr_name); 8287348SJose.Borrego@Sun.COM return ((rc == ENOENT) 8297348SJose.Borrego@Sun.COM ? NERR_UnknownDevDir : NERR_InternalError); 8307348SJose.Borrego@Sun.COM } 8317348SJose.Borrego@Sun.COM 8327348SJose.Borrego@Sun.COM smb_shr_publish(si->shr_name, si->shr_container, 8337348SJose.Borrego@Sun.COM SMB_SHR_PUBLISH); 8347348SJose.Borrego@Sun.COM } 8357348SJose.Borrego@Sun.COM 8367348SJose.Borrego@Sun.COM si->shr_refcnt++; 8377348SJose.Borrego@Sun.COM smb_shr_set_ahcnt(si->shr_name, si->shr_refcnt); 8387348SJose.Borrego@Sun.COM return (status); 8397348SJose.Borrego@Sun.COM } 8407348SJose.Borrego@Sun.COM 8417348SJose.Borrego@Sun.COM static uint32_t 8427348SJose.Borrego@Sun.COM smb_shr_create_ipc(void) 8437348SJose.Borrego@Sun.COM { 8447348SJose.Borrego@Sun.COM smb_share_t ipc; 8457348SJose.Borrego@Sun.COM 8467348SJose.Borrego@Sun.COM bzero(&ipc, sizeof (smb_share_t)); 8477348SJose.Borrego@Sun.COM (void) strcpy(ipc.shr_name, "IPC$"); 8487348SJose.Borrego@Sun.COM (void) strcpy(ipc.shr_cmnt, "Remote IPC"); 8497348SJose.Borrego@Sun.COM ipc.shr_flags = SMB_SHRF_TRANS; 8507348SJose.Borrego@Sun.COM ipc.shr_type = STYPE_IPC; 8517348SJose.Borrego@Sun.COM return (smb_shr_cache_addent(&ipc)); 8527348SJose.Borrego@Sun.COM } 8537348SJose.Borrego@Sun.COM 8547348SJose.Borrego@Sun.COM /* 8557348SJose.Borrego@Sun.COM * loads the given resource 8567348SJose.Borrego@Sun.COM */ 8577348SJose.Borrego@Sun.COM static uint32_t 8587348SJose.Borrego@Sun.COM smb_shr_cache_loadent(sa_share_t share, sa_resource_t resource) 8597348SJose.Borrego@Sun.COM { 8607348SJose.Borrego@Sun.COM smb_share_t si; 8617348SJose.Borrego@Sun.COM uint32_t status; 8627348SJose.Borrego@Sun.COM 8637348SJose.Borrego@Sun.COM if ((status = smb_shr_sa_getent(share, resource, &si)) != NERR_Success) 8647348SJose.Borrego@Sun.COM return (status); 8657348SJose.Borrego@Sun.COM 8667348SJose.Borrego@Sun.COM if ((status = smb_shr_cache_addent(&si)) == NERR_Success) 8677348SJose.Borrego@Sun.COM smb_shr_publish(si.shr_name, si.shr_container, SMB_SHR_PUBLISH); 8687348SJose.Borrego@Sun.COM 8697348SJose.Borrego@Sun.COM if (status != NERR_Success) { 8707348SJose.Borrego@Sun.COM syslog(LOG_ERR, "share: failed loading %s (%d)", si.shr_name, 8717348SJose.Borrego@Sun.COM status); 8727348SJose.Borrego@Sun.COM } 8737348SJose.Borrego@Sun.COM 8747348SJose.Borrego@Sun.COM return (status); 8757348SJose.Borrego@Sun.COM } 8767348SJose.Borrego@Sun.COM 8777348SJose.Borrego@Sun.COM /* 8787348SJose.Borrego@Sun.COM * smb_shr_cache_loadgrp 8797348SJose.Borrego@Sun.COM * 8807348SJose.Borrego@Sun.COM * Helper function for smb_shr_cache_populate. 8817348SJose.Borrego@Sun.COM * It attempts to load the shares contained in the given group. 8827348SJose.Borrego@Sun.COM * It will check to see if "smb" protocol is enabled or 8837348SJose.Borrego@Sun.COM * not on the given group. This is needed in the ZFS case where 8847348SJose.Borrego@Sun.COM * the top level ZFS group won't have "smb" protocol 8857348SJose.Borrego@Sun.COM * enabled but the sub-groups will. 8867348SJose.Borrego@Sun.COM */ 8877348SJose.Borrego@Sun.COM static void 8887348SJose.Borrego@Sun.COM smb_shr_cache_loadgrp(sa_group_t group) 8897348SJose.Borrego@Sun.COM { 8907348SJose.Borrego@Sun.COM sa_share_t share; 8917348SJose.Borrego@Sun.COM sa_resource_t resource; 8927348SJose.Borrego@Sun.COM 8937348SJose.Borrego@Sun.COM /* Don't bother if "smb" isn't set on the group */ 8947348SJose.Borrego@Sun.COM if (sa_get_optionset(group, SMB_PROTOCOL_NAME) == NULL) 8957348SJose.Borrego@Sun.COM return; 8967348SJose.Borrego@Sun.COM 8977348SJose.Borrego@Sun.COM for (share = sa_get_share(group, NULL); 8987348SJose.Borrego@Sun.COM share != NULL; share = sa_get_next_share(share)) { 8997348SJose.Borrego@Sun.COM for (resource = sa_get_share_resource(share, NULL); 9007348SJose.Borrego@Sun.COM resource != NULL; 9017348SJose.Borrego@Sun.COM resource = sa_get_next_resource(resource)) { 9027348SJose.Borrego@Sun.COM (void) smb_shr_cache_loadent(share, resource); 9037348SJose.Borrego@Sun.COM } 9047348SJose.Borrego@Sun.COM } 9057348SJose.Borrego@Sun.COM } 9067348SJose.Borrego@Sun.COM 9077348SJose.Borrego@Sun.COM /* 9087348SJose.Borrego@Sun.COM * smb_shr_cache_freent 9097348SJose.Borrego@Sun.COM * 9107348SJose.Borrego@Sun.COM * Call back to free given cache entry 9117348SJose.Borrego@Sun.COM */ 9127348SJose.Borrego@Sun.COM static void 9137348SJose.Borrego@Sun.COM smb_shr_cache_freent(HT_ITEM *item) 9147348SJose.Borrego@Sun.COM { 9157348SJose.Borrego@Sun.COM if (item && item->hi_data) 9167348SJose.Borrego@Sun.COM free(item->hi_data); 9177348SJose.Borrego@Sun.COM } 9187348SJose.Borrego@Sun.COM 9197348SJose.Borrego@Sun.COM /* 9207348SJose.Borrego@Sun.COM * smb_shr_set_ahcnt 9217348SJose.Borrego@Sun.COM * 9227348SJose.Borrego@Sun.COM * sets the autohome reference count for the given share 9237348SJose.Borrego@Sun.COM */ 9247348SJose.Borrego@Sun.COM static void 9257348SJose.Borrego@Sun.COM smb_shr_set_ahcnt(char *sharename, int refcnt) 9267348SJose.Borrego@Sun.COM { 9277348SJose.Borrego@Sun.COM smb_share_t *si; 9287348SJose.Borrego@Sun.COM HT_ITEM *item; 9297348SJose.Borrego@Sun.COM 9307348SJose.Borrego@Sun.COM (void) rw_wrlock(&smb_shr_lock); 9317348SJose.Borrego@Sun.COM item = ht_find_item(smb_shr_handle, sharename); 9327348SJose.Borrego@Sun.COM if (item == NULL || item->hi_data == NULL) { 9337348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 9347348SJose.Borrego@Sun.COM return; 9357348SJose.Borrego@Sun.COM } 9367348SJose.Borrego@Sun.COM 9377348SJose.Borrego@Sun.COM si = (smb_share_t *)item->hi_data; 9387348SJose.Borrego@Sun.COM si->shr_refcnt = refcnt; 9397348SJose.Borrego@Sun.COM (void) rw_unlock(&smb_shr_lock); 9407348SJose.Borrego@Sun.COM } 9417348SJose.Borrego@Sun.COM 9427348SJose.Borrego@Sun.COM /* 9437052Samw * smb_shr_set_oemname 9447052Samw * 9457052Samw * Generates the OEM name of the given share. If it's 9467052Samw * shorter than 13 chars it'll be saved in si->shr_oemname. 9477052Samw * Otherwise si->shr_oemname will be empty and SMB_SHRF_LONGNAME 9487052Samw * will be set in si->shr_flags. 9497052Samw */ 9507052Samw static void 9517052Samw smb_shr_set_oemname(smb_share_t *si) 9527052Samw { 9537052Samw unsigned int cpid = oem_get_smb_cpid(); 9547052Samw mts_wchar_t *unibuf; 9557052Samw char *oem_name; 9567052Samw int length; 9577052Samw 9587052Samw length = strlen(si->shr_name) + 1; 9597052Samw 9607052Samw oem_name = malloc(length); 9617052Samw unibuf = malloc(length * sizeof (mts_wchar_t)); 9627052Samw if ((oem_name == NULL) || (unibuf == NULL)) { 9637052Samw free(oem_name); 9647052Samw free(unibuf); 9657052Samw return; 9667052Samw } 9677052Samw 9687052Samw (void) mts_mbstowcs(unibuf, si->shr_name, length); 9697052Samw 9707052Samw if (unicodestooems(oem_name, unibuf, length, cpid) == 0) 9717052Samw (void) strcpy(oem_name, si->shr_name); 9727052Samw 9737052Samw free(unibuf); 9747052Samw 9757052Samw if (strlen(oem_name) + 1 > SMB_SHARE_OEMNAME_MAX) { 9767052Samw si->shr_flags |= SMB_SHRF_LONGNAME; 9777052Samw *si->shr_oemname = '\0'; 9787052Samw } else { 9797052Samw si->shr_flags &= ~SMB_SHRF_LONGNAME; 9807052Samw (void) strlcpy(si->shr_oemname, oem_name, 9817052Samw SMB_SHARE_OEMNAME_MAX); 9827052Samw } 9837052Samw 9847052Samw free(oem_name); 9857052Samw } 9867348SJose.Borrego@Sun.COM 9877348SJose.Borrego@Sun.COM /* 9887348SJose.Borrego@Sun.COM * ============================================ 9897348SJose.Borrego@Sun.COM * Interfaces to sharemgr 9907348SJose.Borrego@Sun.COM * ============================================ 9917348SJose.Borrego@Sun.COM */ 9927348SJose.Borrego@Sun.COM 9937348SJose.Borrego@Sun.COM /* 9947348SJose.Borrego@Sun.COM * Stores the given share in sharemgr 9957348SJose.Borrego@Sun.COM */ 9967348SJose.Borrego@Sun.COM static uint32_t 9977348SJose.Borrego@Sun.COM smb_shr_sa_addent(smb_share_t *si) 9987348SJose.Borrego@Sun.COM { 9997348SJose.Borrego@Sun.COM sa_handle_t handle; 10007348SJose.Borrego@Sun.COM sa_share_t share; 10017348SJose.Borrego@Sun.COM sa_group_t group; 10027348SJose.Borrego@Sun.COM sa_resource_t resource; 10037348SJose.Borrego@Sun.COM boolean_t share_created = B_FALSE; 10047348SJose.Borrego@Sun.COM int err; 10057348SJose.Borrego@Sun.COM 10067348SJose.Borrego@Sun.COM if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL) 10077348SJose.Borrego@Sun.COM return (NERR_InternalError); 10087348SJose.Borrego@Sun.COM 10097348SJose.Borrego@Sun.COM share = sa_find_share(handle, si->shr_path); 10107348SJose.Borrego@Sun.COM if (share == NULL) { 10117348SJose.Borrego@Sun.COM group = smb_shr_sa_getdefgrp(handle); 10127348SJose.Borrego@Sun.COM if (group == NULL) { 10137348SJose.Borrego@Sun.COM sa_fini(handle); 10147348SJose.Borrego@Sun.COM return (NERR_InternalError); 10157348SJose.Borrego@Sun.COM } 10167348SJose.Borrego@Sun.COM 10177348SJose.Borrego@Sun.COM share = sa_add_share(group, si->shr_path, SA_SHARE_PERMANENT, 10187348SJose.Borrego@Sun.COM &err); 10197348SJose.Borrego@Sun.COM if (share == NULL) { 10207348SJose.Borrego@Sun.COM sa_fini(handle); 10217348SJose.Borrego@Sun.COM return (NERR_InternalError); 10227348SJose.Borrego@Sun.COM } 10237348SJose.Borrego@Sun.COM share_created = B_TRUE; 10247348SJose.Borrego@Sun.COM } 10257348SJose.Borrego@Sun.COM 10267348SJose.Borrego@Sun.COM resource = sa_get_share_resource(share, si->shr_name); 10277348SJose.Borrego@Sun.COM if (resource == NULL) { 10287348SJose.Borrego@Sun.COM resource = sa_add_resource(share, si->shr_name, 10297348SJose.Borrego@Sun.COM SA_SHARE_PERMANENT, &err); 10307348SJose.Borrego@Sun.COM if (resource == NULL) 10317348SJose.Borrego@Sun.COM goto failure; 10327348SJose.Borrego@Sun.COM } 10337348SJose.Borrego@Sun.COM 10347348SJose.Borrego@Sun.COM if (sa_set_resource_attr(resource, "description", si->shr_cmnt) 10357348SJose.Borrego@Sun.COM != SA_OK) { 10367348SJose.Borrego@Sun.COM goto failure; 10377348SJose.Borrego@Sun.COM } 10387348SJose.Borrego@Sun.COM 10397348SJose.Borrego@Sun.COM if (sa_set_resource_attr(resource, SMB_SHROPT_AD_CONTAINER, 10407348SJose.Borrego@Sun.COM si->shr_container) != SA_OK) { 10417348SJose.Borrego@Sun.COM goto failure; 10427348SJose.Borrego@Sun.COM } 10437348SJose.Borrego@Sun.COM 10447348SJose.Borrego@Sun.COM sa_fini(handle); 10457348SJose.Borrego@Sun.COM return (NERR_Success); 10467348SJose.Borrego@Sun.COM 10477348SJose.Borrego@Sun.COM failure: 10487348SJose.Borrego@Sun.COM if (share_created && (share != NULL)) 10497348SJose.Borrego@Sun.COM (void) sa_remove_share(share); 10507348SJose.Borrego@Sun.COM 10517348SJose.Borrego@Sun.COM if (resource != NULL) 10527348SJose.Borrego@Sun.COM (void) sa_remove_resource(resource); 10537348SJose.Borrego@Sun.COM 10547348SJose.Borrego@Sun.COM sa_fini(handle); 10557348SJose.Borrego@Sun.COM return (NERR_InternalError); 10567348SJose.Borrego@Sun.COM } 10577348SJose.Borrego@Sun.COM 10587348SJose.Borrego@Sun.COM static uint32_t 10597348SJose.Borrego@Sun.COM smb_shr_sa_getent(sa_share_t share, sa_resource_t resource, smb_share_t *si) 10607348SJose.Borrego@Sun.COM { 10617348SJose.Borrego@Sun.COM sa_property_t prop; 10627348SJose.Borrego@Sun.COM sa_optionset_t opts; 10637348SJose.Borrego@Sun.COM char *val = NULL; 10647348SJose.Borrego@Sun.COM char *path; 10657348SJose.Borrego@Sun.COM char *rname; 10667348SJose.Borrego@Sun.COM 10677348SJose.Borrego@Sun.COM if ((path = sa_get_share_attr(share, "path")) == NULL) 10687348SJose.Borrego@Sun.COM return (NERR_InternalError); 10697348SJose.Borrego@Sun.COM 10707348SJose.Borrego@Sun.COM if ((rname = sa_get_resource_attr(resource, "name")) == NULL) { 10717348SJose.Borrego@Sun.COM sa_free_attr_string(path); 10727348SJose.Borrego@Sun.COM return (NERR_InternalError); 10737348SJose.Borrego@Sun.COM } 10747348SJose.Borrego@Sun.COM 10757348SJose.Borrego@Sun.COM bzero(si, sizeof (smb_share_t)); 10767348SJose.Borrego@Sun.COM /* Share is read from SMF so it should be permanent */ 10777348SJose.Borrego@Sun.COM si->shr_flags = SMB_SHRF_PERM; 10787348SJose.Borrego@Sun.COM 10797348SJose.Borrego@Sun.COM (void) strlcpy(si->shr_path, path, sizeof (si->shr_path)); 10807348SJose.Borrego@Sun.COM (void) strlcpy(si->shr_name, rname, sizeof (si->shr_name)); 10817348SJose.Borrego@Sun.COM 10827348SJose.Borrego@Sun.COM sa_free_attr_string(path); 10837348SJose.Borrego@Sun.COM sa_free_attr_string(rname); 10847348SJose.Borrego@Sun.COM 10857348SJose.Borrego@Sun.COM val = sa_get_resource_description(resource); 10867348SJose.Borrego@Sun.COM if (val == NULL) 10877348SJose.Borrego@Sun.COM val = sa_get_share_description(share); 10887348SJose.Borrego@Sun.COM 10897348SJose.Borrego@Sun.COM if (val != NULL) { 10907348SJose.Borrego@Sun.COM (void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt)); 10917348SJose.Borrego@Sun.COM sa_free_share_description(val); 10927348SJose.Borrego@Sun.COM } 10937348SJose.Borrego@Sun.COM 10947348SJose.Borrego@Sun.COM opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1); 10957348SJose.Borrego@Sun.COM if (opts == NULL) 10967348SJose.Borrego@Sun.COM return (NERR_Success); 10977348SJose.Borrego@Sun.COM 10987348SJose.Borrego@Sun.COM prop = (sa_property_t)sa_get_property(opts, SMB_SHROPT_AD_CONTAINER); 10997348SJose.Borrego@Sun.COM if (prop != NULL) { 11007348SJose.Borrego@Sun.COM if ((val = sa_get_property_attr(prop, "value")) != NULL) { 11017348SJose.Borrego@Sun.COM (void) strlcpy(si->shr_container, val, 11027348SJose.Borrego@Sun.COM sizeof (si->shr_container)); 11037348SJose.Borrego@Sun.COM free(val); 11047348SJose.Borrego@Sun.COM } 11057348SJose.Borrego@Sun.COM } 11067348SJose.Borrego@Sun.COM sa_free_derived_optionset(opts); 11077348SJose.Borrego@Sun.COM 11087348SJose.Borrego@Sun.COM return (NERR_Success); 11097348SJose.Borrego@Sun.COM } 11107348SJose.Borrego@Sun.COM 11117348SJose.Borrego@Sun.COM /* 11127348SJose.Borrego@Sun.COM * Removes the share from sharemgr 11137348SJose.Borrego@Sun.COM */ 11147348SJose.Borrego@Sun.COM static uint32_t 11157348SJose.Borrego@Sun.COM smb_shr_sa_delent(smb_share_t *si) 11167348SJose.Borrego@Sun.COM { 11177348SJose.Borrego@Sun.COM sa_handle_t handle; 11187348SJose.Borrego@Sun.COM sa_share_t share; 11197348SJose.Borrego@Sun.COM sa_resource_t resource; 11207348SJose.Borrego@Sun.COM 11217348SJose.Borrego@Sun.COM if ((handle = sa_init(SA_INIT_SHARE_API)) == NULL) 11227348SJose.Borrego@Sun.COM return (NERR_InternalError); 11237348SJose.Borrego@Sun.COM 11247348SJose.Borrego@Sun.COM if ((share = sa_find_share(handle, si->shr_path)) == NULL) { 11257348SJose.Borrego@Sun.COM sa_fini(handle); 11267348SJose.Borrego@Sun.COM return (NERR_InternalError); 11277348SJose.Borrego@Sun.COM } 11287348SJose.Borrego@Sun.COM 11297348SJose.Borrego@Sun.COM if ((resource = sa_get_share_resource(share, si->shr_name)) == NULL) { 11307348SJose.Borrego@Sun.COM sa_fini(handle); 11317348SJose.Borrego@Sun.COM return (NERR_InternalError); 11327348SJose.Borrego@Sun.COM } 11337348SJose.Borrego@Sun.COM 11347348SJose.Borrego@Sun.COM if (sa_remove_resource(resource) != SA_OK) { 11357348SJose.Borrego@Sun.COM sa_fini(handle); 11367348SJose.Borrego@Sun.COM return (NERR_InternalError); 11377348SJose.Borrego@Sun.COM } 11387348SJose.Borrego@Sun.COM 11397348SJose.Borrego@Sun.COM sa_fini(handle); 11407348SJose.Borrego@Sun.COM return (NERR_Success); 11417348SJose.Borrego@Sun.COM } 11427348SJose.Borrego@Sun.COM 11437348SJose.Borrego@Sun.COM /* 11447348SJose.Borrego@Sun.COM * smb_shr_sa_getdefgrp 11457348SJose.Borrego@Sun.COM * 11467348SJose.Borrego@Sun.COM * If default group for CIFS shares (i.e. "smb") exists 11477348SJose.Borrego@Sun.COM * then it will return the group handle, otherwise it will 11487348SJose.Borrego@Sun.COM * create the group and return the handle. 11497348SJose.Borrego@Sun.COM * 11507348SJose.Borrego@Sun.COM * All the shares created by CIFS clients (this is only possible 11517348SJose.Borrego@Sun.COM * via RPC) will be added to "smb" groups. 11527348SJose.Borrego@Sun.COM */ 11537348SJose.Borrego@Sun.COM static sa_group_t 11547348SJose.Borrego@Sun.COM smb_shr_sa_getdefgrp(sa_handle_t handle) 11557348SJose.Borrego@Sun.COM { 11567348SJose.Borrego@Sun.COM sa_group_t group = NULL; 11577348SJose.Borrego@Sun.COM int err; 11587348SJose.Borrego@Sun.COM 11597348SJose.Borrego@Sun.COM group = sa_get_group(handle, SMB_DEFAULT_SHARE_GROUP); 11607348SJose.Borrego@Sun.COM if (group != NULL) 11617348SJose.Borrego@Sun.COM return (group); 11627348SJose.Borrego@Sun.COM 11637348SJose.Borrego@Sun.COM group = sa_create_group(handle, SMB_DEFAULT_SHARE_GROUP, &err); 11647348SJose.Borrego@Sun.COM if (group == NULL) 11657348SJose.Borrego@Sun.COM return (NULL); 11667348SJose.Borrego@Sun.COM 11677348SJose.Borrego@Sun.COM if (sa_create_optionset(group, SMB_DEFAULT_SHARE_GROUP) == NULL) { 11687348SJose.Borrego@Sun.COM (void) sa_remove_group(group); 11697348SJose.Borrego@Sun.COM group = NULL; 11707348SJose.Borrego@Sun.COM } 11717348SJose.Borrego@Sun.COM 11727348SJose.Borrego@Sun.COM return (group); 11737348SJose.Borrego@Sun.COM } 11747348SJose.Borrego@Sun.COM 11757348SJose.Borrego@Sun.COM /* 11767348SJose.Borrego@Sun.COM * ============================================ 11777348SJose.Borrego@Sun.COM * Share publishing functions 11787348SJose.Borrego@Sun.COM * ============================================ 11797348SJose.Borrego@Sun.COM */ 11807348SJose.Borrego@Sun.COM 11817348SJose.Borrego@Sun.COM /* 11827348SJose.Borrego@Sun.COM * Put the share on publish queue. 11837348SJose.Borrego@Sun.COM */ 11847348SJose.Borrego@Sun.COM static void 11857348SJose.Borrego@Sun.COM smb_shr_publish(const char *sharename, const char *container, char op) 11867348SJose.Borrego@Sun.COM { 11877348SJose.Borrego@Sun.COM smb_shr_pitem_t *item = NULL; 11887348SJose.Borrego@Sun.COM 11897348SJose.Borrego@Sun.COM if (container == NULL || *container == '\0') 11907348SJose.Borrego@Sun.COM return; 11917348SJose.Borrego@Sun.COM 11927348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 11937348SJose.Borrego@Sun.COM switch (ad_queue.spq_state) { 11947348SJose.Borrego@Sun.COM case SMB_SHR_PQS_READY: 11957348SJose.Borrego@Sun.COM case SMB_SHR_PQS_PUBLISHING: 11967348SJose.Borrego@Sun.COM break; 11977348SJose.Borrego@Sun.COM default: 11987348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 11997348SJose.Borrego@Sun.COM return; 12007348SJose.Borrego@Sun.COM } 12017348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12027348SJose.Borrego@Sun.COM 12037348SJose.Borrego@Sun.COM if ((item = malloc(sizeof (smb_shr_pitem_t))) == NULL) { 12047348SJose.Borrego@Sun.COM syslog(LOG_DEBUG, "failed allocating share publish item"); 12057348SJose.Borrego@Sun.COM return; 12067348SJose.Borrego@Sun.COM } 12077348SJose.Borrego@Sun.COM 12087348SJose.Borrego@Sun.COM item->spi_op = op; 12097348SJose.Borrego@Sun.COM (void) strlcpy(item->spi_name, sharename, sizeof (item->spi_name)); 12107348SJose.Borrego@Sun.COM (void) strlcpy(item->spi_container, container, 12117348SJose.Borrego@Sun.COM sizeof (item->spi_container)); 12127348SJose.Borrego@Sun.COM 12137348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 12147348SJose.Borrego@Sun.COM list_insert_tail(&ad_queue.spq_list, item); 12157348SJose.Borrego@Sun.COM ad_queue.spq_cnt++; 12167348SJose.Borrego@Sun.COM (void) cond_signal(&ad_queue.spq_cv); 12177348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12187348SJose.Borrego@Sun.COM } 12197348SJose.Borrego@Sun.COM 12207348SJose.Borrego@Sun.COM static int 12217348SJose.Borrego@Sun.COM smb_shr_publisher_start(void) 12227348SJose.Borrego@Sun.COM { 12237348SJose.Borrego@Sun.COM pthread_attr_t tattr; 12247348SJose.Borrego@Sun.COM int rc; 12257348SJose.Borrego@Sun.COM 12267348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 12277348SJose.Borrego@Sun.COM if (ad_queue.spq_state != SMB_SHR_PQS_NOQUEUE) { 12287348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12297348SJose.Borrego@Sun.COM errno = EINVAL; 12307348SJose.Borrego@Sun.COM return (-1); 12317348SJose.Borrego@Sun.COM } 12327348SJose.Borrego@Sun.COM 12337348SJose.Borrego@Sun.COM list_create(&ad_queue.spq_list, sizeof (smb_shr_pitem_t), 12347348SJose.Borrego@Sun.COM offsetof(smb_shr_pitem_t, spi_lnd)); 12357348SJose.Borrego@Sun.COM ad_queue.spq_state = SMB_SHR_PQS_READY; 12367348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12377348SJose.Borrego@Sun.COM 12387348SJose.Borrego@Sun.COM (void) pthread_attr_init(&tattr); 12397348SJose.Borrego@Sun.COM (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 12407348SJose.Borrego@Sun.COM rc = pthread_create(&smb_shr_publish_thr, &tattr, 12417348SJose.Borrego@Sun.COM smb_shr_publisher, 0); 12427348SJose.Borrego@Sun.COM (void) pthread_attr_destroy(&tattr); 12437348SJose.Borrego@Sun.COM 12447348SJose.Borrego@Sun.COM return (rc); 12457348SJose.Borrego@Sun.COM } 12467348SJose.Borrego@Sun.COM 12477348SJose.Borrego@Sun.COM static void 12487348SJose.Borrego@Sun.COM smb_shr_publisher_stop(void) 12497348SJose.Borrego@Sun.COM { 12507348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 12517348SJose.Borrego@Sun.COM switch (ad_queue.spq_state) { 12527348SJose.Borrego@Sun.COM case SMB_SHR_PQS_READY: 12537348SJose.Borrego@Sun.COM case SMB_SHR_PQS_PUBLISHING: 12547348SJose.Borrego@Sun.COM ad_queue.spq_state = SMB_SHR_PQS_STOPPING; 12557348SJose.Borrego@Sun.COM (void) cond_signal(&ad_queue.spq_cv); 12567348SJose.Borrego@Sun.COM break; 12577348SJose.Borrego@Sun.COM default: 12587348SJose.Borrego@Sun.COM break; 12597348SJose.Borrego@Sun.COM } 12607348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12617348SJose.Borrego@Sun.COM } 12627348SJose.Borrego@Sun.COM 12637348SJose.Borrego@Sun.COM /* 12647348SJose.Borrego@Sun.COM * This functions waits to be signaled and once running 12657348SJose.Borrego@Sun.COM * will publish/unpublish any items in the ad_queue 12667348SJose.Borrego@Sun.COM */ 12677348SJose.Borrego@Sun.COM /*ARGSUSED*/ 12687348SJose.Borrego@Sun.COM static void * 12697348SJose.Borrego@Sun.COM smb_shr_publisher(void *arg) 12707348SJose.Borrego@Sun.COM { 12717348SJose.Borrego@Sun.COM smb_ads_handle_t *ah; 12727348SJose.Borrego@Sun.COM smb_shr_pitem_t *shr; 12737348SJose.Borrego@Sun.COM list_t publist; 12747348SJose.Borrego@Sun.COM char hostname[MAXHOSTNAMELEN]; 12757348SJose.Borrego@Sun.COM 12767348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 12777348SJose.Borrego@Sun.COM if (ad_queue.spq_state == SMB_SHR_PQS_READY) { 12787348SJose.Borrego@Sun.COM ad_queue.spq_state = SMB_SHR_PQS_PUBLISHING; 12797348SJose.Borrego@Sun.COM } else { 12807348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12817348SJose.Borrego@Sun.COM return (NULL); 12827348SJose.Borrego@Sun.COM } 12837348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12847348SJose.Borrego@Sun.COM 12857348SJose.Borrego@Sun.COM (void) smb_gethostname(hostname, MAXHOSTNAMELEN, 0); 12867348SJose.Borrego@Sun.COM list_create(&publist, sizeof (smb_shr_pitem_t), 12877348SJose.Borrego@Sun.COM offsetof(smb_shr_pitem_t, spi_lnd)); 12887348SJose.Borrego@Sun.COM 12897348SJose.Borrego@Sun.COM for (;;) { 12907348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 12917348SJose.Borrego@Sun.COM while ((ad_queue.spq_cnt == 0) && 12927348SJose.Borrego@Sun.COM (ad_queue.spq_state == SMB_SHR_PQS_PUBLISHING)) 12937348SJose.Borrego@Sun.COM (void) cond_wait(&ad_queue.spq_cv, &ad_queue.spq_mtx); 12947348SJose.Borrego@Sun.COM 12957348SJose.Borrego@Sun.COM if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) { 12967348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 12977348SJose.Borrego@Sun.COM break; 12987348SJose.Borrego@Sun.COM } 12997348SJose.Borrego@Sun.COM 13007348SJose.Borrego@Sun.COM if ((ah = smb_ads_open()) == NULL) { 13017348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 13027348SJose.Borrego@Sun.COM continue; 13037348SJose.Borrego@Sun.COM } 13047348SJose.Borrego@Sun.COM 13057348SJose.Borrego@Sun.COM /* 13067348SJose.Borrego@Sun.COM * Transfer queued items to the local list so the mutex 13077348SJose.Borrego@Sun.COM * can be quickly released 13087348SJose.Borrego@Sun.COM */ 13097348SJose.Borrego@Sun.COM while ((shr = list_head(&ad_queue.spq_list)) != NULL) { 13107348SJose.Borrego@Sun.COM list_remove(&ad_queue.spq_list, shr); 13117348SJose.Borrego@Sun.COM ad_queue.spq_cnt--; 13127348SJose.Borrego@Sun.COM list_insert_tail(&publist, shr); 13137348SJose.Borrego@Sun.COM } 13147348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 13157348SJose.Borrego@Sun.COM 13167348SJose.Borrego@Sun.COM smb_shr_publisher_send(ah, &publist, hostname); 13177348SJose.Borrego@Sun.COM smb_ads_close(ah); 13187348SJose.Borrego@Sun.COM } 13197348SJose.Borrego@Sun.COM 13207348SJose.Borrego@Sun.COM /* Remove any leftover items from publishing queue */ 13217348SJose.Borrego@Sun.COM (void) mutex_lock(&ad_queue.spq_mtx); 13227348SJose.Borrego@Sun.COM while ((shr = list_head(&ad_queue.spq_list)) != NULL) { 13237348SJose.Borrego@Sun.COM list_remove(&ad_queue.spq_list, shr); 13247348SJose.Borrego@Sun.COM free(shr); 13257348SJose.Borrego@Sun.COM } 13267348SJose.Borrego@Sun.COM ad_queue.spq_cnt = 0; 13277348SJose.Borrego@Sun.COM list_destroy(&ad_queue.spq_list); 13287348SJose.Borrego@Sun.COM ad_queue.spq_state = SMB_SHR_PQS_NOQUEUE; 13297348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 13307348SJose.Borrego@Sun.COM 13317348SJose.Borrego@Sun.COM list_destroy(&publist); 13327348SJose.Borrego@Sun.COM return (NULL); 13337348SJose.Borrego@Sun.COM } 13347348SJose.Borrego@Sun.COM 13357348SJose.Borrego@Sun.COM /* 13367348SJose.Borrego@Sun.COM * Takes item from the given list and [un]publish them one by one. 13377348SJose.Borrego@Sun.COM * In each iteration it checks the status of the publisher thread 13387348SJose.Borrego@Sun.COM * and if it's been stopped then it continues to just empty the list 13397348SJose.Borrego@Sun.COM */ 13407348SJose.Borrego@Sun.COM static void 13417348SJose.Borrego@Sun.COM smb_shr_publisher_send(smb_ads_handle_t *ah, list_t *publist, const char *host) 13427348SJose.Borrego@Sun.COM { 13437348SJose.Borrego@Sun.COM smb_shr_pitem_t *shr; 13447348SJose.Borrego@Sun.COM boolean_t publish = B_TRUE; 13457348SJose.Borrego@Sun.COM 13467348SJose.Borrego@Sun.COM while ((shr = list_head(publist)) != NULL) { 13477348SJose.Borrego@Sun.COM list_remove(publist, shr); 13487348SJose.Borrego@Sun.COM if (publish) { 13497348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 13507348SJose.Borrego@Sun.COM if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) 13517348SJose.Borrego@Sun.COM publish = B_FALSE; 13527348SJose.Borrego@Sun.COM (void) mutex_unlock(&ad_queue.spq_mtx); 13537348SJose.Borrego@Sun.COM 13547348SJose.Borrego@Sun.COM if (shr->spi_op == SMB_SHR_PUBLISH) 13557348SJose.Borrego@Sun.COM (void) smb_ads_publish_share(ah, shr->spi_name, 13567348SJose.Borrego@Sun.COM NULL, shr->spi_container, host); 13577348SJose.Borrego@Sun.COM else 13587348SJose.Borrego@Sun.COM (void) smb_ads_remove_share(ah, shr->spi_name, 13597348SJose.Borrego@Sun.COM NULL, shr->spi_container, host); 13607348SJose.Borrego@Sun.COM } 13617348SJose.Borrego@Sun.COM free(shr); 13627348SJose.Borrego@Sun.COM } 13637348SJose.Borrego@Sun.COM } 1364