1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22c5866007SKeyur Desai * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23*12b65585SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 2689dc44ceSjose borrego #include <sys/param.h> 27da6c28aaSamw #include <string.h> 28da6c28aaSamw #include <stdlib.h> 29da6c28aaSamw #include <stdio.h> 30da6c28aaSamw #include <pwd.h> 31c5866007SKeyur Desai #include <nss_dbdefs.h> 323ad684d6Sjb150015 #include <assert.h> 333ad684d6Sjb150015 #include <strings.h> 34da6c28aaSamw #include <sys/stat.h> 35c5866007SKeyur Desai #include <sys/idmap.h> 36da6c28aaSamw #include <smbsrv/libsmb.h> 37da6c28aaSamw #include <smbsrv/libmlsvc.h> 38da6c28aaSamw #include <smbsrv/smbinfo.h> 39da6c28aaSamw 40da6c28aaSamw #define SMB_AUTOHOME_KEYSIZ 128 41da6c28aaSamw #define SMB_AUTOHOME_MAXARG 4 42da6c28aaSamw #define SMB_AUTOHOME_BUFSIZ 2048 43da6c28aaSamw 44da6c28aaSamw typedef struct smb_autohome_info { 45da6c28aaSamw struct smb_autohome_info *magic1; 46da6c28aaSamw FILE *fp; 47da6c28aaSamw smb_autohome_t autohome; 48da6c28aaSamw char buf[SMB_AUTOHOME_BUFSIZ]; 49da6c28aaSamw char *argv[SMB_AUTOHOME_MAXARG]; 50da6c28aaSamw int lineno; 51da6c28aaSamw struct smb_autohome_info *magic2; 52da6c28aaSamw } smb_autohome_info_t; 53da6c28aaSamw 54da6c28aaSamw static smb_autohome_info_t smb_ai; 55da6c28aaSamw 56da6c28aaSamw static smb_autohome_t *smb_autohome_make_entry(smb_autohome_info_t *); 57da6c28aaSamw static char *smb_autohome_keysub(const char *, char *, int); 58da6c28aaSamw static smb_autohome_info_t *smb_autohome_getinfo(void); 593ad684d6Sjb150015 static smb_autohome_t *smb_autohome_lookup(const char *); 603ad684d6Sjb150015 static void smb_autohome_setent(void); 613ad684d6Sjb150015 static void smb_autohome_endent(void); 623ad684d6Sjb150015 static smb_autohome_t *smb_autohome_getent(const char *); 6389dc44ceSjose borrego static void smb_autohome_parse_options(smb_share_t *); 64c5866007SKeyur Desai static int smb_autohome_add_private(const char *, uid_t, gid_t); 65da6c28aaSamw 66da6c28aaSamw /* 67da6c28aaSamw * Add an autohome share. See smb_autohome(4) for details. 68da6c28aaSamw * 69da6c28aaSamw * If share directory contains backslash path separators, they will 70da6c28aaSamw * be converted to forward slash to support NT/DOS path style for 71da6c28aaSamw * autohome shares. 729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * We need to serialize calls to smb_autohome_lookup because it 749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * operates on the global smb_ai structure. 75da6c28aaSamw */ 763ad684d6Sjb150015 void 77fe1c642dSBill Krier smb_autohome_add(const smb_token_t *token) 78da6c28aaSamw { 79da6c28aaSamw 80c5866007SKeyur Desai char *username; 81c5866007SKeyur Desai struct passwd pw; 82c5866007SKeyur Desai char buf[NSS_LINELEN_PASSWD]; 83c5866007SKeyur Desai uid_t uid; 84c5866007SKeyur Desai gid_t gid; 85c5866007SKeyur Desai 86*12b65585SGordon Ross if (token->tkn_flags & SMB_ATF_ANON) 87*12b65585SGordon Ross return; 88*12b65585SGordon Ross 89c5866007SKeyur Desai uid = token->tkn_user.i_id; 90c5866007SKeyur Desai gid = token->tkn_primary_grp.i_id; 91c5866007SKeyur Desai 92c5866007SKeyur Desai if (IDMAP_ID_IS_EPHEMERAL(uid)) { 93c5866007SKeyur Desai username = token->tkn_account_name; 943ad684d6Sjb150015 assert(username); 95c5866007SKeyur Desai } else { 96c5866007SKeyur Desai if (getpwuid_r(uid, &pw, buf, sizeof (buf)) == NULL) { 97c5866007SKeyur Desai syslog(LOG_ERR, "unable to determine name for " \ 98c5866007SKeyur Desai "UID: %u\n", uid); 993db3f65cSamw return; 1003db3f65cSamw } 101c5866007SKeyur Desai username = pw.pw_name; 1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 103da6c28aaSamw 104c5866007SKeyur Desai if (smb_autohome_add_private(username, uid, gid) != NERR_Success) { 105c5866007SKeyur Desai if (!smb_isstrlwr(username)) { 106c5866007SKeyur Desai (void) smb_strlwr(username); 107c5866007SKeyur Desai (void) smb_autohome_add_private(username, uid, gid); 108c5866007SKeyur Desai } 109c5866007SKeyur Desai } 110da6c28aaSamw } 111da6c28aaSamw 112da6c28aaSamw /* 113da6c28aaSamw * Remove an autohome share. 114da6c28aaSamw */ 1153ad684d6Sjb150015 void 116da6c28aaSamw smb_autohome_remove(const char *username) 117da6c28aaSamw { 1183db3f65cSamw smb_share_t si; 119da6c28aaSamw 1203ad684d6Sjb150015 assert(username); 121da6c28aaSamw 1223db3f65cSamw if (smb_shr_get((char *)username, &si) == NERR_Success) { 123c8ec8eeaSjose borrego if (si.shr_flags & SMB_SHRF_AUTOHOME) 124b89a8333Snatalie li - Sun Microsystems - Irvine United States (void) smb_shr_remove((char *)username); 125da6c28aaSamw } 126da6c28aaSamw } 127da6c28aaSamw 128da6c28aaSamw /* 129c5866007SKeyur Desai * An autohome share is not created if a static share using the same name 130c5866007SKeyur Desai * already exists. Autohome shares will be added for each login attempt. 131c5866007SKeyur Desai * 132c5866007SKeyur Desai * Calling smb_shr_get() may return the first argument in all lower case so 133c5866007SKeyur Desai * a copy is passed in instead. 134c5866007SKeyur Desai * 135c5866007SKeyur Desai * We need to serialize calls to smb_autohome_lookup because it 136c5866007SKeyur Desai * operates on the global smb_ai structure. 137c5866007SKeyur Desai */ 138c5866007SKeyur Desai static int 139c5866007SKeyur Desai smb_autohome_add_private(const char *username, uid_t uid, gid_t gid) 140c5866007SKeyur Desai { 141c5866007SKeyur Desai static mutex_t autohome_mutex; 142c5866007SKeyur Desai smb_share_t si; 143c5866007SKeyur Desai smb_autohome_t *ai; 144c5866007SKeyur Desai char shr_name[MAXNAMELEN]; 145c5866007SKeyur Desai 146c5866007SKeyur Desai (void) strlcpy(shr_name, username, sizeof (shr_name)); 147c5866007SKeyur Desai 148c5866007SKeyur Desai if (smb_shr_get(shr_name, &si) == NERR_Success) { 149c5866007SKeyur Desai if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0) 150c5866007SKeyur Desai return (NERR_Success); 151c5866007SKeyur Desai 152c5866007SKeyur Desai (void) smb_shr_add(&si); 153c5866007SKeyur Desai return (NERR_Success); 154c5866007SKeyur Desai } 155c5866007SKeyur Desai 156c5866007SKeyur Desai (void) mutex_lock(&autohome_mutex); 157c5866007SKeyur Desai 158c5866007SKeyur Desai if ((ai = smb_autohome_lookup(username)) == NULL) { 159c5866007SKeyur Desai (void) mutex_unlock(&autohome_mutex); 160c5866007SKeyur Desai return (NERR_ItemNotFound); 161c5866007SKeyur Desai } 162c5866007SKeyur Desai 163c5866007SKeyur Desai bzero(&si, sizeof (smb_share_t)); 164c5866007SKeyur Desai (void) strlcpy(si.shr_path, ai->ah_path, MAXPATHLEN); 165c5866007SKeyur Desai (void) strsubst(si.shr_path, '\\', '/'); 166c5866007SKeyur Desai 167c5866007SKeyur Desai (void) strlcpy(si.shr_name, username, MAXNAMELEN); 168c5866007SKeyur Desai (void) strlcpy(si.shr_container, ai->ah_container, MAXPATHLEN); 169c5866007SKeyur Desai (void) strlcpy(si.shr_cmnt, "Autohome", SMB_SHARE_CMNT_MAX); 170c5866007SKeyur Desai smb_autohome_parse_options(&si); 171c5866007SKeyur Desai si.shr_flags |= SMB_SHRF_TRANS | SMB_SHRF_AUTOHOME; 172c5866007SKeyur Desai si.shr_uid = uid; 173c5866007SKeyur Desai si.shr_gid = gid; 174c5866007SKeyur Desai 175c5866007SKeyur Desai (void) mutex_unlock(&autohome_mutex); 176c5866007SKeyur Desai 177c5866007SKeyur Desai return (smb_shr_add(&si)); 178c5866007SKeyur Desai } 179c5866007SKeyur Desai 180c5866007SKeyur Desai /* 181da6c28aaSamw * Search the autohome database for the specified name. The name cannot 182da6c28aaSamw * be an empty string or begin with * or +. 183da6c28aaSamw * 1. Search the file for the specified name. 184da6c28aaSamw * 2. Check for the wildcard rule and, if present, treat it as a match. 185da6c28aaSamw * 3. Check for the nsswitch rule and, if present, lookup the name 186da6c28aaSamw * via the name services. Note that the nsswitch rule will never 187da6c28aaSamw * be applied if the wildcard rule is present. 188da6c28aaSamw * 189da6c28aaSamw * Returns a pointer to the entry on success or null on failure. 190da6c28aaSamw */ 1913ad684d6Sjb150015 static smb_autohome_t * 192da6c28aaSamw smb_autohome_lookup(const char *name) 193da6c28aaSamw { 194da6c28aaSamw struct passwd *pw; 1953ad684d6Sjb150015 smb_autohome_t *ah = NULL; 196da6c28aaSamw 197da6c28aaSamw if (name == NULL) 198da6c28aaSamw return (NULL); 199da6c28aaSamw 200da6c28aaSamw if (*name == '\0' || *name == '*' || *name == '+') 201da6c28aaSamw return (NULL); 202da6c28aaSamw 203da6c28aaSamw smb_autohome_setent(); 204da6c28aaSamw 205da6c28aaSamw while ((ah = smb_autohome_getent(name)) != NULL) { 206da6c28aaSamw if (strcasecmp(ah->ah_name, name) == 0) 207da6c28aaSamw break; 208da6c28aaSamw } 209da6c28aaSamw 210da6c28aaSamw if (ah == NULL) { 211da6c28aaSamw smb_autohome_setent(); 212da6c28aaSamw 213da6c28aaSamw while ((ah = smb_autohome_getent(name)) != NULL) { 214da6c28aaSamw if (strcasecmp(ah->ah_name, "*") == 0) { 215da6c28aaSamw ah->ah_name = (char *)name; 216da6c28aaSamw break; 217da6c28aaSamw } 218da6c28aaSamw } 219da6c28aaSamw } 220da6c28aaSamw 221da6c28aaSamw if (ah == NULL) { 222da6c28aaSamw smb_autohome_setent(); 223da6c28aaSamw 224da6c28aaSamw while ((ah = smb_autohome_getent("+nsswitch")) != NULL) { 225da6c28aaSamw if (strcasecmp("+nsswitch", ah->ah_name) != 0) 226da6c28aaSamw continue; 227da6c28aaSamw if ((pw = getpwnam(name)) == NULL) { 2283ad684d6Sjb150015 ah = NULL; 229da6c28aaSamw break; 230da6c28aaSamw } 231da6c28aaSamw 232da6c28aaSamw ah->ah_name = pw->pw_name; 233da6c28aaSamw 234da6c28aaSamw if (ah->ah_path) 235da6c28aaSamw ah->ah_container = ah->ah_path; 236da6c28aaSamw 237da6c28aaSamw ah->ah_path = pw->pw_dir; 238da6c28aaSamw break; 239da6c28aaSamw } 240da6c28aaSamw } 241da6c28aaSamw 242da6c28aaSamw smb_autohome_endent(); 243da6c28aaSamw return (ah); 244da6c28aaSamw } 245da6c28aaSamw 246da6c28aaSamw /* 247da6c28aaSamw * Open or rewind the autohome database. 248da6c28aaSamw */ 2493ad684d6Sjb150015 static void 250da6c28aaSamw smb_autohome_setent(void) 251da6c28aaSamw { 252da6c28aaSamw smb_autohome_info_t *si; 253dc20a302Sas200622 char path[MAXNAMELEN]; 254da6c28aaSamw char filename[MAXNAMELEN]; 255dc20a302Sas200622 int rc; 256da6c28aaSamw 257da6c28aaSamw if ((si = smb_autohome_getinfo()) != 0) { 258da6c28aaSamw (void) fseek(si->fp, 0L, SEEK_SET); 259da6c28aaSamw si->lineno = 0; 260da6c28aaSamw return; 261da6c28aaSamw } 262da6c28aaSamw 263da6c28aaSamw if ((si = &smb_ai) == 0) 264da6c28aaSamw return; 265da6c28aaSamw 266dc20a302Sas200622 rc = smb_config_getstr(SMB_CI_AUTOHOME_MAP, path, sizeof (path)); 267dc20a302Sas200622 if (rc != SMBD_SMF_OK) 268dc20a302Sas200622 return; 269dc20a302Sas200622 270dc20a302Sas200622 (void) snprintf(filename, MAXNAMELEN, "%s/%s", path, 271da6c28aaSamw SMB_AUTOHOME_FILE); 272da6c28aaSamw 273da6c28aaSamw if ((si->fp = fopen(filename, "r")) == NULL) 274da6c28aaSamw return; 275da6c28aaSamw 276da6c28aaSamw si->magic1 = si; 277da6c28aaSamw si->magic2 = si; 278da6c28aaSamw si->lineno = 0; 279da6c28aaSamw } 280da6c28aaSamw 281da6c28aaSamw /* 282da6c28aaSamw * Close the autohome database and invalidate the autohome info. 283da6c28aaSamw * We can't zero the whole info structure because the application 284da6c28aaSamw * should still have access to the data after the file is closed. 285da6c28aaSamw */ 2863ad684d6Sjb150015 static void 287da6c28aaSamw smb_autohome_endent(void) 288da6c28aaSamw { 289da6c28aaSamw smb_autohome_info_t *si; 290da6c28aaSamw 291da6c28aaSamw if ((si = smb_autohome_getinfo()) != 0) { 292da6c28aaSamw (void) fclose(si->fp); 293da6c28aaSamw si->fp = 0; 294da6c28aaSamw si->magic1 = 0; 295da6c28aaSamw si->magic2 = 0; 296da6c28aaSamw } 297da6c28aaSamw } 298da6c28aaSamw 299da6c28aaSamw /* 300da6c28aaSamw * Return the next entry in the autohome database, opening the file 301da6c28aaSamw * if necessary. Returns null on EOF or error. 302da6c28aaSamw * 303da6c28aaSamw * Note that we are not looking for the specified name. The name is 304da6c28aaSamw * only used for key substitution, so that the caller sees the entry 305da6c28aaSamw * in expanded form. 306da6c28aaSamw */ 3073ad684d6Sjb150015 static smb_autohome_t * 308da6c28aaSamw smb_autohome_getent(const char *name) 309da6c28aaSamw { 310da6c28aaSamw smb_autohome_info_t *si; 311da6c28aaSamw char *bp; 312da6c28aaSamw 313da6c28aaSamw if ((si = smb_autohome_getinfo()) == 0) { 314da6c28aaSamw smb_autohome_setent(); 315da6c28aaSamw 316da6c28aaSamw if ((si = smb_autohome_getinfo()) == 0) 317da6c28aaSamw return (0); 318da6c28aaSamw } 319da6c28aaSamw 320da6c28aaSamw /* 321da6c28aaSamw * Find the next non-comment, non-empty line. 322da6c28aaSamw * Anything after a # is a comment and can be discarded. 323da6c28aaSamw * Discard a newline to avoid it being included in the parsing 324da6c28aaSamw * that follows. 325da6c28aaSamw * Leading and training whitespace is discarded, and replicated 326da6c28aaSamw * whitespace is compressed to simplify the token parsing, 327da6c28aaSamw * although strsep() deals with that better than strtok(). 328da6c28aaSamw */ 329da6c28aaSamw do { 330da6c28aaSamw if (fgets(si->buf, SMB_AUTOHOME_BUFSIZ, si->fp) == 0) 331da6c28aaSamw return (0); 332da6c28aaSamw 333da6c28aaSamw ++si->lineno; 334da6c28aaSamw 335da6c28aaSamw if ((bp = strpbrk(si->buf, "#\r\n")) != 0) 336da6c28aaSamw *bp = '\0'; 337da6c28aaSamw 338da6c28aaSamw (void) trim_whitespace(si->buf); 339da6c28aaSamw bp = strcanon(si->buf, " \t"); 340da6c28aaSamw } while (*bp == '\0'); 341da6c28aaSamw 342da6c28aaSamw (void) smb_autohome_keysub(name, si->buf, SMB_AUTOHOME_BUFSIZ); 343da6c28aaSamw return (smb_autohome_make_entry(si)); 344da6c28aaSamw } 345da6c28aaSamw 346da6c28aaSamw /* 347da6c28aaSamw * Set up an autohome entry from the line buffer. The line should just 348da6c28aaSamw * contain tokens separated by single whitespace. The line format is: 349da6c28aaSamw * <username> <home-dir-path> <ADS container> 350da6c28aaSamw */ 351da6c28aaSamw static smb_autohome_t * 352da6c28aaSamw smb_autohome_make_entry(smb_autohome_info_t *si) 353da6c28aaSamw { 354da6c28aaSamw char *bp; 355da6c28aaSamw int i; 356da6c28aaSamw 357da6c28aaSamw bp = si->buf; 358da6c28aaSamw 359da6c28aaSamw for (i = 0; i < SMB_AUTOHOME_MAXARG; ++i) 36089dc44ceSjose borrego si->argv[i] = NULL; 361da6c28aaSamw 362da6c28aaSamw for (i = 0; i < SMB_AUTOHOME_MAXARG; ++i) { 363da6c28aaSamw do { 36489dc44ceSjose borrego if ((si->argv[i] = strsep(&bp, " \t")) == NULL) 365da6c28aaSamw break; 366da6c28aaSamw } while (*(si->argv[i]) == '\0'); 367da6c28aaSamw 36889dc44ceSjose borrego if (si->argv[i] == NULL) 369da6c28aaSamw break; 370da6c28aaSamw } 371da6c28aaSamw 372da6c28aaSamw if ((si->autohome.ah_name = si->argv[0]) == NULL) { 373da6c28aaSamw /* 374da6c28aaSamw * Sanity check: the name could be an empty 375da6c28aaSamw * string but it can't be a null pointer. 376da6c28aaSamw */ 377da6c28aaSamw return (0); 378da6c28aaSamw } 379da6c28aaSamw 380da6c28aaSamw if ((si->autohome.ah_path = si->argv[1]) == NULL) 381da6c28aaSamw si->autohome.ah_path = ""; 382da6c28aaSamw 383da6c28aaSamw if ((si->autohome.ah_container = si->argv[2]) == NULL) 384da6c28aaSamw si->autohome.ah_container = ""; 385da6c28aaSamw 386da6c28aaSamw return (&si->autohome); 387da6c28aaSamw } 388da6c28aaSamw 389da6c28aaSamw /* 390da6c28aaSamw * Substitute the ? and & map keys. 391da6c28aaSamw * ? is replaced by the first character of the name 392da6c28aaSamw * & is replaced by the whole name. 393da6c28aaSamw */ 394da6c28aaSamw static char * 395da6c28aaSamw smb_autohome_keysub(const char *name, char *buf, int buflen) 396da6c28aaSamw { 397da6c28aaSamw char key[SMB_AUTOHOME_KEYSIZ]; 398da6c28aaSamw char *ampersand; 399da6c28aaSamw char *tmp; 40055bf511dSas200622 int bufsize = buflen; 401da6c28aaSamw 402da6c28aaSamw (void) strlcpy(key, buf, SMB_AUTOHOME_KEYSIZ); 403da6c28aaSamw 404da6c28aaSamw if ((tmp = strpbrk(key, " \t")) == NULL) 405da6c28aaSamw return (NULL); 406da6c28aaSamw 407da6c28aaSamw *tmp = '\0'; 408da6c28aaSamw 40955bf511dSas200622 /* 41055bf511dSas200622 * Substitution characters are not allowed in the key. 41155bf511dSas200622 */ 41255bf511dSas200622 if (strpbrk(key, "?&") != NULL) 41355bf511dSas200622 return (NULL); 41455bf511dSas200622 415da6c28aaSamw if (strcmp(key, "*") == 0 && name != NULL) 416da6c28aaSamw (void) strlcpy(key, name, SMB_AUTOHOME_KEYSIZ); 417da6c28aaSamw 418da6c28aaSamw (void) strsubst(buf, '?', *key); 419da6c28aaSamw 420da6c28aaSamw while ((ampersand = strchr(buf, '&')) != NULL) { 421da6c28aaSamw if ((tmp = strdup(ampersand + 1)) == NULL) 422da6c28aaSamw return (0); 423da6c28aaSamw 42455bf511dSas200622 bufsize = buflen - (ampersand - buf); 42555bf511dSas200622 (void) strlcpy(ampersand, key, bufsize); 42655bf511dSas200622 (void) strlcat(ampersand, tmp, bufsize); 427da6c28aaSamw free(tmp); 428da6c28aaSamw } 429da6c28aaSamw 430da6c28aaSamw return (buf); 431da6c28aaSamw } 432da6c28aaSamw 433da6c28aaSamw /* 434da6c28aaSamw * Get a pointer to the context buffer and validate it. 435da6c28aaSamw */ 436da6c28aaSamw static smb_autohome_info_t * 437da6c28aaSamw smb_autohome_getinfo(void) 438da6c28aaSamw { 439da6c28aaSamw smb_autohome_info_t *si; 440da6c28aaSamw 441da6c28aaSamw if ((si = &smb_ai) == 0) 442da6c28aaSamw return (0); 443da6c28aaSamw 444da6c28aaSamw if ((si->magic1 == si) && (si->magic2 == si) && (si->fp != NULL)) 445da6c28aaSamw return (si); 446da6c28aaSamw 447da6c28aaSamw return (0); 448da6c28aaSamw } 44989dc44ceSjose borrego 45089dc44ceSjose borrego /* 45189dc44ceSjose borrego * Parse the options string, which contains a comma separated list of 45289dc44ceSjose borrego * name-value pairs. One of the options may be an AD container, which 45389dc44ceSjose borrego * is also a comma separated list of name-value pairs. For example, 45489dc44ceSjose borrego * dn=ad,dn=sun,dn=com,ou=users 45589dc44ceSjose borrego * 45689dc44ceSjose borrego * All options other than the AD container will be extracted from 45789dc44ceSjose borrego * shr_container and used to set share properties. 45889dc44ceSjose borrego * On return, shr_container will contain the AD container string. 45989dc44ceSjose borrego */ 46089dc44ceSjose borrego static void 46189dc44ceSjose borrego smb_autohome_parse_options(smb_share_t *si) 46289dc44ceSjose borrego { 46389dc44ceSjose borrego char buf[MAXPATHLEN]; 46489dc44ceSjose borrego char **argv; 46589dc44ceSjose borrego char **ap; 46689dc44ceSjose borrego char *bp; 46789dc44ceSjose borrego char *value; 46889dc44ceSjose borrego boolean_t separator = B_FALSE; 46989dc44ceSjose borrego int argc; 47089dc44ceSjose borrego int i; 47189dc44ceSjose borrego 47289dc44ceSjose borrego if (strlcpy(buf, si->shr_container, MAXPATHLEN) == 0) 47389dc44ceSjose borrego return; 47489dc44ceSjose borrego 47589dc44ceSjose borrego for (argc = 1, bp = si->shr_container; *bp != '\0'; ++bp) 47689dc44ceSjose borrego if (*bp == ',') 47789dc44ceSjose borrego ++argc; 47889dc44ceSjose borrego 47989dc44ceSjose borrego if ((argv = calloc(argc + 1, sizeof (char *))) == NULL) 48089dc44ceSjose borrego return; 48189dc44ceSjose borrego 48289dc44ceSjose borrego ap = argv; 48389dc44ceSjose borrego for (bp = buf, i = 0; i < argc; ++i) { 48489dc44ceSjose borrego do { 48589dc44ceSjose borrego if ((value = strsep(&bp, ",")) == NULL) 48689dc44ceSjose borrego break; 48789dc44ceSjose borrego } while (*value == '\0'); 48889dc44ceSjose borrego 48989dc44ceSjose borrego if (value == NULL) 49089dc44ceSjose borrego break; 49189dc44ceSjose borrego 49289dc44ceSjose borrego *ap++ = value; 49389dc44ceSjose borrego } 49489dc44ceSjose borrego *ap = NULL; 49589dc44ceSjose borrego 49689dc44ceSjose borrego si->shr_container[0] = '\0'; 49789dc44ceSjose borrego bp = si->shr_container; 49889dc44ceSjose borrego 49989dc44ceSjose borrego for (ap = argv; *ap != NULL; ++ap) { 50089dc44ceSjose borrego value = *ap; 50189dc44ceSjose borrego 5028b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (strncasecmp(value, "catia=", 6) == 0) { 5039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_setflag((value + 6), si, SMB_SHRF_CATIA); 5048b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States continue; 5058b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 5068b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 50789dc44ceSjose borrego if (strncasecmp(value, "csc=", 4) == 0) { 50889dc44ceSjose borrego smb_shr_sa_csc_option((value + 4), si); 50989dc44ceSjose borrego continue; 51089dc44ceSjose borrego } 51189dc44ceSjose borrego 512e3f2c991SKeyur Desai if (strncasecmp(value, "abe=", 4) == 0) { 5139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_setflag((value + 4), si, SMB_SHRF_ABE); 514e3f2c991SKeyur Desai continue; 515e3f2c991SKeyur Desai } 516e3f2c991SKeyur Desai 51789dc44ceSjose borrego if (strncasecmp(value, "description=", 12) == 0) { 51889dc44ceSjose borrego (void) strlcpy(si->shr_cmnt, (value + 12), 51989dc44ceSjose borrego SMB_SHARE_CMNT_MAX); 52089dc44ceSjose borrego continue; 52189dc44ceSjose borrego } 52289dc44ceSjose borrego 523148c5f43SAlan Wright if (strncasecmp(value, "rw=", 3) == 0) { 524148c5f43SAlan Wright (void) strlcpy(si->shr_access_rw, (value + 3), 525148c5f43SAlan Wright sizeof (si->shr_access_rw)); 526148c5f43SAlan Wright continue; 527148c5f43SAlan Wright } 528148c5f43SAlan Wright 529148c5f43SAlan Wright if (strncasecmp(value, "ro=", 3) == 0) { 530148c5f43SAlan Wright (void) strlcpy(si->shr_access_ro, (value + 3), 531148c5f43SAlan Wright sizeof (si->shr_access_ro)); 532148c5f43SAlan Wright continue; 533148c5f43SAlan Wright } 534148c5f43SAlan Wright 535148c5f43SAlan Wright if (strncasecmp(value, "none=", 5) == 0) { 536148c5f43SAlan Wright (void) strlcpy(si->shr_access_none, (value + 5), 537148c5f43SAlan Wright sizeof (si->shr_access_none)); 538148c5f43SAlan Wright continue; 539148c5f43SAlan Wright } 540148c5f43SAlan Wright 54189dc44ceSjose borrego if (separator) 54289dc44ceSjose borrego (void) strlcat(bp, ",", MAXPATHLEN); 54389dc44ceSjose borrego (void) strlcat(bp, value, MAXPATHLEN); 54489dc44ceSjose borrego separator = B_TRUE; 54589dc44ceSjose borrego } 54689dc44ceSjose borrego 54789dc44ceSjose borrego free(argv); 54889dc44ceSjose borrego } 549