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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27/* 28 * Portions Copyright 2007-2011 Apple Inc. 29 */ 30 31#ifndef _AUTOMOUNT_H 32#define _AUTOMOUNT_H 33 34#pragma ident "@(#)automount.h 1.69 05/09/30 SMI" 35 36#include <assert.h> 37#include <pthread.h> 38#include <sys/types.h> 39#include <sys/mount.h> /* for fsid_t */ 40#include <oncrpc/rpc.h> 41#include <netinet/in.h> /* needed for sockaddr_in declaration */ 42 43#include <mach/mach.h> 44 45#ifdef MALLOC_DEBUG 46#include <debug_alloc.h> 47#endif 48 49#include "autofs.h" 50 51#ifdef __cplusplus 52extern "C" { 53#endif 54 55#ifndef _REENTRANT 56#define fork1 vfork 57#endif 58 59 60/* 61 * OS X autofs configuration file location 62 */ 63#define AUTOFSADMIN "/etc/autofs.conf" 64 65#define MXHOSTNAMELEN 64 66#define MAXNETNAMELEN 255 67/* We can't supply names that don't fit in a "struct dirent" */ 68#define MAXFILENAMELEN (sizeof (((struct dirent *)0)->d_name) - 1) 69#define LINESZ 4096 70#define MAXOPTSLEN AUTOFS_MAXOPTSLEN 71 72#define AUTOFS_MOUNT_TIMEOUT 600 /* default min time mount will */ 73 /* remain mounted (in seconds) */ 74#define AUTOFS_RPC_TIMEOUT 60 /* secs autofs will wait for */ 75 /* automountd's reply before */ 76 /* retransmitting */ 77/* stack ops */ 78#define ERASE 0 79#define PUSH 1 80#define POP 2 81#define INIT 3 82#define STACKSIZ 30 83 84#define DIST_SELF 1 85#define DIST_MYSUB 2 86#define DIST_MYNET 3 87#define DIST_OTHER 4 88 89#define MAXIFS 32 90 91/* 92 * Retry operation related definitions. 93 */ 94#define RET_OK 0 95#define RET_RETRY 32 96#define RET_ERR 33 97#define INITDELAY 5 98#define DELAY_BACKOFF 2 99#define MAXDELAY 120 100#define DO_DELAY(delay) { \ 101 (void) sleep(delay); \ 102 delay *= DELAY_BACKOFF; \ 103 if (delay > MAXDELAY) \ 104 delay = MAXDELAY; \ 105} 106 107struct mapline { 108 char linebuf[LINESZ]; 109 char lineqbuf[LINESZ]; 110}; 111 112/* 113 * Typedefs present in Solaris but not in OS X. 114 */ 115typedef unsigned char uchar_t; 116typedef unsigned short ushort_t; 117typedef unsigned int uint_t; 118typedef uint32_t rpcprog_t; 119typedef uint32_t rpcvers_t; 120 121/* 122 * XXX - kill me if possible. 123 */ 124struct mnttab { 125 char *mnt_special; 126 char *mnt_mountp; 127 char *mnt_fstype; 128 char *mnt_mntopts; 129 char *mnt_time; 130}; 131 132/* 133 * Structure describing a host/filesystem/dir tuple in a NIS map entry 134 */ 135struct mapfs { 136 struct mapfs *mfs_next; /* next in entry */ 137 int mfs_ignore; /* ignore this entry */ 138 char *mfs_host; /* host name */ 139 char *mfs_dir; /* dir to mount */ 140 int mfs_penalty; /* mount penalty for this host */ 141 int mfs_distance; /* distance hint */ 142 struct nfs_args *mfs_args; /* nfs_args */ 143 rpcvers_t mfs_version; /* NFS version */ 144 145#define MFS_ALLOC_DIR 0x1 /* mfs_dir now points to different */ 146 /* buffer */ 147 148#define MFS_URL 0x2 /* is NFS url listed in this tuple. */ 149#define MFS_FH_VIA_WEBNFS 0x4 /* got file handle during ping phase */ 150 151 uint_t mfs_flags; 152 uint_t mfs_port; /* port# in NFS url */ 153}; 154 155/* 156 * NIS entry - lookup of name in DIR gets us this 157 */ 158struct mapent { 159 char *map_fstype; /* file system type e.g. "nfs" */ 160 char *map_mounter; /* base fs e.g. "cachefs" */ 161 char *map_root; /* path to mount root */ 162 char *map_mntpnt; /* path from mount root */ 163 char *map_mntopts; /* mount options */ 164 char *map_fsw; /* mount fs information */ 165 char *map_fswq; /* quoted mountfs information */ 166 int map_mntlevel; /* mapentry hierarchy level */ 167 bool_t map_modified; /* flags modified mapentries */ 168 bool_t map_faked; /* flags faked mapentries */ 169 int map_err; /* flags any bad entries in the map */ 170 struct mapfs *map_fs; /* list of replicas for nfs */ 171 struct mapent *map_next; 172}; 173 174 175/* 176 * Descriptor for each directory served by the automounter 177 */ 178struct autodir { 179 char *dir_name; /* mount point */ 180 char *dir_map; /* name of map for dir */ 181 char *dir_opts; /* default mount options */ 182 int dir_direct; /* direct mountpoint ? */ 183 char *dir_realpath; /* realpath() of mount point - not always set */ 184 struct autodir *dir_next; /* next entry */ 185 struct autodir *dir_prev; /* prev entry */ 186}; 187 188/* 189 * This structure is used to build an array of 190 * hostnames with associated penalties to be 191 * passed to the nfs_cast procedure 192 */ 193struct host_names { 194 char *host; 195 int penalty; 196}; 197 198/* 199 * structure used to build list of contents for a map on 200 * a readdir request 201 */ 202struct dir_entry { 203 char *name; /* name of entry */ 204 ino_t nodeid; 205 off_t offset; 206 char *line; /* map line for entry, or NULL */ 207 char *lineq; /* map quote line for entry, or NULLs */ 208 struct dir_entry *next; 209 struct dir_entry *left; /* left element in binary tree */ 210 struct dir_entry *right; /* right element in binary tree */ 211}; 212 213/* 214 * offset index table 215 */ 216struct off_tbl { 217 off_t offset; 218 struct dir_entry *first; 219 struct off_tbl *next; 220}; 221 222#ifndef NO_RDDIR_CACHE 223/* 224 * directory cache for 'map' 225 */ 226struct rddir_cache { 227 char *map; 228 struct off_tbl *offtp; 229 uint_t bucket_size; 230 time_t ttl; 231 struct dir_entry *entp; 232 pthread_mutex_t lock; /* protects 'in_use' field */ 233 int in_use; /* # threads referencing it */ 234 pthread_rwlock_t rwlock; /* protects 'full' and 'next' */ 235 int full; /* full == 1 when cache full */ 236 struct rddir_cache *next; 237}; 238 239#define RDDIR_CACHE_TIME 300 /* in seconds */ 240 241#endif /* NO_RDDIR_CACHE */ 242 243/* 244 * structure used to maintain address list for localhost 245 */ 246 247struct myaddrs { 248 struct sockaddr_in sin; 249 struct myaddrs *myaddrs_next; 250}; 251 252extern time_t timenow; /* set at start of processing of each RPC call */ 253extern char self[]; 254extern int verbose; 255extern int trace; 256extern struct autodir *dir_head; 257extern struct autodir *dir_tail; 258struct autofs_args; 259extern struct myaddrs *myaddrs_head; 260 261extern pthread_rwlock_t cache_lock; 262extern pthread_rwlock_t rddir_cache_lock; 263 264extern pthread_mutex_t cleanup_lock; 265extern pthread_cond_t cleanup_start_cv; 266extern pthread_cond_t cleanup_done_cv; 267 268/* 269 * "Safe" string operations; used with string buffers already 270 * allocated to be large enough, so we just abort if this fails. 271 */ 272#define CHECK_STRCPY(a, b, size) \ 273 assert(strlcpy(a, b, (size)) < (size)) 274 275#define CHECK_STRCAT(a, b, size) \ 276 assert(strlcat((a), (b), (size)) < (size)) 277 278/* 279 * mnttab handling routines 280 */ 281extern void free_mapent(struct mapent *); 282 283#define MNTTYPE_NFS "nfs" 284#define MNTTYPE_LOFS "lofs" 285 286/* 287 * utilities 288 */ 289extern struct mapent *parse_entry(const char *, const char *, const char *, 290 const char *, uint_t, int *, bool_t, bool_t, 291 int *); 292typedef enum { 293 MEXPAND_OK, /* expansion worked */ 294 MEXPAND_LINE_TOO_LONG, /* line too long */ 295 MEXPAND_VARNAME_TOO_LONG /* variable name too long */ 296} macro_expand_status; 297extern macro_expand_status macro_expand(const char *, char *, char *, int); 298extern void unquote(char *, char *); 299extern void trim(char *); 300extern char *get_line(FILE *, char *, char *, int); 301extern int getword(char *, char *, char **, char **, char, int); 302extern int get_retry(const char *); 303extern int str_opt(struct mnttab *, char *, char **); 304extern void dirinit(char *, char *, char *, int, char **, char ***); 305extern void pr_msg(const char *, ...) __printflike(1, 2); 306extern void trace_prt(int, char *, ...) __printflike(2, 3); 307extern void free_action_list_fields(action_list *); 308 309extern int nopt(struct mnttab *, char *, int *); 310extern int set_versrange(rpcvers_t, rpcvers_t *, rpcvers_t *); 311extern enum clnt_stat pingnfs(const char *, rpcvers_t *, rpcvers_t, 312 ushort_t, const char *, const char *); 313 314extern int self_check(char *); 315extern int host_is_us(const char *, size_t); 316extern void flush_host_name_cache(void); 317extern int we_are_a_server(void); 318extern int do_mount1(const autofs_pathname, const char *, 319 const autofs_pathname, const autofs_opts, const autofs_pathname, 320 boolean_t, boolean_t, fsid_t, uid_t, au_asid_t, fsid_t *, 321 uint32_t *, byte_buffer *, mach_msg_type_number_t *); 322extern int do_lookup1(const autofs_pathname, const char *, 323 const autofs_pathname, const autofs_opts, boolean_t, uid_t, int *); 324extern int do_unmount1(fsid_t, autofs_pathname, autofs_pathname, 325 autofs_component, autofs_opts); 326extern int do_readdir(autofs_pathname, off_t, uint32_t, off_t *, 327 boolean_t *, byte_buffer *, mach_msg_type_number_t *); 328extern int do_readsubdir(autofs_pathname, char *, autofs_pathname, 329 autofs_opts, uint32_t, off_t, uint32_t, off_t *, boolean_t *, 330 byte_buffer *, mach_msg_type_number_t *); 331extern int nfsunmount(fsid_t *, struct mnttab *); 332extern int loopbackmount(char *, char *, char *); 333extern int mount_nfs(struct mapent *, char *, char *, boolean_t, 334 fsid_t, au_asid_t, fsid_t *, uint32_t *); 335extern int mount_autofs(const char *, struct mapent *, const char *, fsid_t, 336 action_list **, const char *, const char *, const char *, fsid_t *, 337 uint32_t *); 338extern int mount_generic(char *, char *, char *, int, char *, boolean_t, 339 boolean_t, fsid_t, uid_t, au_asid_t, fsid_t *, uint32_t *); 340extern int get_triggered_mount_info(const char *, fsid_t, fsid_t *, 341 uint32_t *); 342extern enum clnt_stat nfs_cast(struct mapfs *, struct mapfs **, int); 343 344extern bool_t hasrestrictopt(const char *); 345 346extern void flush_caches(void); 347 348#ifndef NO_RDDIR_CACHE 349/* 350 * readdir handling routines 351 */ 352extern char *auto_rddir_malloc(unsigned); 353extern char *auto_rddir_strdup(const char *); 354extern struct dir_entry *btree_lookup(struct dir_entry *, const char *); 355extern void btree_enter(struct dir_entry **, struct dir_entry *); 356extern int add_dir_entry(const char *, const char *, const char *, 357 struct dir_entry **, struct dir_entry **); 358extern void *cache_cleanup(void *); 359extern struct dir_entry *rddir_entry_lookup(const char *, const char *); 360#endif /* NO_RDDIR_CACHE */ 361 362/* 363 * generic interface to specific name service functions 364 */ 365extern void ns_setup(char **, char ***); 366extern int getmapent(const char *, const char *, struct mapline *, char **, 367 char ***, bool_t *, bool_t); 368extern int getmapkeys(char *, struct dir_entry **, int *, int *, char **, 369 char ***); 370extern int loadmaster_map(char *, char *, char **, char ***); 371extern int loaddirect_map(char *, char *, char *, char **, char ***); 372 373/* 374 * Name service return statuses. 375 */ 376#define __NSW_SUCCESS 0 /* found the required data */ 377#define __NSW_NOTFOUND 1 /* the naming service returned lookup failure */ 378#define __NSW_UNAVAIL 2 /* could not call the naming service */ 379 380/* 381 * these name service specific functions should not be 382 * accessed directly, use the generic functions. 383 */ 384extern void init_files(char **, char ***); 385extern int getmapent_files(const char *, const char *, struct mapline *, 386 char **, char ***, bool_t *, bool_t); 387extern int loadmaster_files(char *, char *, char **, char ***); 388extern int loaddirect_files(char *, char *, char *, char **, char ***); 389extern int getmapkeys_files(char *, struct dir_entry **, int *, int *, 390 char **, char ***); 391extern int stack_op(int, char *, char **, char ***); 392 393extern void init_od(char **, char ***); 394extern int getmapent_od(const char *, const char *, struct mapline *, char **, 395 char ***, bool_t *, bool_t); 396extern int loadmaster_od(char *, char *, char **, char ***); 397extern int loaddirect_od(char *, char *, char *, char **, char ***); 398extern int getmapkeys_od(char *, struct dir_entry **, int *, int *, 399 char **, char ***); 400/* 401 * Node for fstab entry. 402 */ 403struct fstabnode { 404 char *fst_dir; /* directory part of fs_spec */ 405 char *fst_vfstype; /* fs_vfstype */ 406 char *fst_mntops; /* fs_mntops plus fs_type */ 407 char *fst_url; /* URL from fs_mntops, if fs_vfstype is "url" */ 408 struct fstabnode *fst_next; 409}; 410 411/* 412 * Structure for a static map entry (non-"net") in fstab. 413 */ 414struct staticmap { 415 char *dir; /* name of the directory on which to mount */ 416 char *vfstype; /* fs_vfstype */ 417 char *mntops; /* fs_mntops plus fs_type */ 418 char *host; /* host from which to mount */ 419 char *localpath; /* full path, on the server, for that item */ 420 char *spec; /* item to mount */ 421 struct staticmap *next; /* next entry in hash table bucket */ 422}; 423 424/* 425 * Look up a particular host in the fstab map hash table and, if we find it, 426 * run the callback routine on each entry in its fstab entry list. 427 */ 428extern int fstab_process_host(const char *host, 429 int (*callback)(struct fstabnode *, void *), void *callback_arg); 430 431/* 432 * Enumerate all the entries in the -fstab map. 433 * This is used by a readdir on the -fstab map; those are likely to 434 * be followed by stats on one or more of the entries in that map, so 435 * we populate the fstab map cache and return values from that. 436 */ 437extern int getfstabkeys(struct dir_entry **list, int *error, int *cache_time); 438 439/* 440 * Check whether we have any entries in the -fstab map. 441 * This is used by automount to decide whether to mount that map 442 * or not. 443 */ 444extern int havefstabkeys(void); 445 446/* 447 * Load the -static direct map. 448 */ 449extern int loaddirect_static(char *local_map, char *opts, char **stack, 450 char ***stkptr); 451 452/* 453 * Find the -static map entry corresponding to a given mount point. 454 */ 455extern struct staticmap *get_staticmap_entry(const char *dir); 456 457/* 458 * Indicate that we're done with a -static map entry returned by 459 * get_staticmap_entry(). 460 */ 461extern void release_staticmap_entry(struct staticmap *static_ent); 462 463/* 464 * Purge the fstab cache; if scheduled is true, do so only if it's 465 * stale, otherwise do it unconditionally. 466 */ 467extern void clean_fstab_cache(int scheduled); 468 469/* 470 * end of name service specific functions 471 */ 472 473/* 474 * not defined in any header file 475 */ 476extern int getnetmaskbynet(const struct in_addr, struct in_addr *); 477 478/* 479 * Hidden rpc functions 480 */ 481extern int __nis_reset_state(); 482extern int __rpc_negotiate_uid(int); 483extern int __rpc_get_local_uid(SVCXPRT *, uid_t *); 484 485#ifdef __cplusplus 486} 487#endif 488 489#endif /* _AUTOMOUNT_H */ 490