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