Lines 49-54
__FBSDID("$FreeBSD: head/usr.sbin/mountd
Link Here
|
49 |
|
49 |
|
50 |
#include <sys/param.h> |
50 |
#include <sys/param.h> |
51 |
#include <sys/fcntl.h> |
51 |
#include <sys/fcntl.h> |
|
|
52 |
#include <sys/fnv_hash.h> |
52 |
#include <sys/linker.h> |
53 |
#include <sys/linker.h> |
53 |
#include <sys/module.h> |
54 |
#include <sys/module.h> |
54 |
#include <sys/mount.h> |
55 |
#include <sys/mount.h> |
Lines 114-123
struct dirlist {
Link Here
|
114 |
struct exportlist { |
115 |
struct exportlist { |
115 |
struct dirlist *ex_dirl; |
116 |
struct dirlist *ex_dirl; |
116 |
struct dirlist *ex_defdir; |
117 |
struct dirlist *ex_defdir; |
|
|
118 |
struct grouplist *ex_grphead; |
117 |
int ex_flag; |
119 |
int ex_flag; |
118 |
fsid_t ex_fs; |
120 |
fsid_t ex_fs; |
119 |
char *ex_fsdir; |
121 |
char *ex_fsdir; |
120 |
char *ex_indexfile; |
122 |
char *ex_indexfile; |
|
|
123 |
struct xucred ex_defanon; |
124 |
int ex_defexflags; |
121 |
int ex_numsecflavors; |
125 |
int ex_numsecflavors; |
122 |
int ex_secflavors[MAXSECFLAVORS]; |
126 |
int ex_secflavors[MAXSECFLAVORS]; |
123 |
int ex_defnumsecflavors; |
127 |
int ex_defnumsecflavors; |
Lines 127-132
struct exportlist {
Link Here
|
127 |
}; |
131 |
}; |
128 |
/* ex_flag bits */ |
132 |
/* ex_flag bits */ |
129 |
#define EX_LINKED 0x1 |
133 |
#define EX_LINKED 0x1 |
|
|
134 |
#define EX_DONE 0x2 |
135 |
|
136 |
SLIST_HEAD(exportlisthead, exportlist); |
130 |
|
137 |
|
131 |
struct netmsk { |
138 |
struct netmsk { |
132 |
struct sockaddr_storage nt_net; |
139 |
struct sockaddr_storage nt_net; |
Lines 143-148
struct grouplist {
Link Here
|
143 |
int gr_type; |
150 |
int gr_type; |
144 |
union grouptypes gr_ptr; |
151 |
union grouptypes gr_ptr; |
145 |
struct grouplist *gr_next; |
152 |
struct grouplist *gr_next; |
|
|
153 |
struct xucred gr_anon; |
154 |
int gr_exflags; |
155 |
int gr_flag; |
146 |
int gr_numsecflavors; |
156 |
int gr_numsecflavors; |
147 |
int gr_secflavors[MAXSECFLAVORS]; |
157 |
int gr_secflavors[MAXSECFLAVORS]; |
148 |
}; |
158 |
}; |
Lines 153-158
struct grouplist {
Link Here
|
153 |
#define GT_DEFAULT 0x3 |
163 |
#define GT_DEFAULT 0x3 |
154 |
#define GT_IGNORE 0x5 |
164 |
#define GT_IGNORE 0x5 |
155 |
|
165 |
|
|
|
166 |
/* Group flags */ |
167 |
#define GR_FND 0x1 |
168 |
|
156 |
struct hostlist { |
169 |
struct hostlist { |
157 |
int ht_flag; /* Uses DP_xx bits */ |
170 |
int ht_flag; /* Uses DP_xx bits */ |
158 |
struct grouplist *ht_grp; |
171 |
struct grouplist *ht_grp; |
Lines 185-201
static void complete_service(struct netc
Link Here
|
185 |
static void clearout_service(void); |
198 |
static void clearout_service(void); |
186 |
static void del_mlist(char *hostp, char *dirp); |
199 |
static void del_mlist(char *hostp, char *dirp); |
187 |
static struct dirlist *dirp_search(struct dirlist *, char *); |
200 |
static struct dirlist *dirp_search(struct dirlist *, char *); |
|
|
201 |
static int do_export_mount(struct exportlist *, struct statfs *); |
188 |
static int do_mount(struct exportlist *, struct grouplist *, int, |
202 |
static int do_mount(struct exportlist *, struct grouplist *, int, |
189 |
struct xucred *, char *, int, struct statfs *); |
203 |
struct xucred *, char *, int, struct statfs *); |
190 |
static int do_opt(char **, char **, struct exportlist *, |
204 |
static int do_opt(char **, char **, struct exportlist *, |
191 |
struct grouplist *, int *, int *, struct xucred *); |
205 |
struct grouplist *, int *, int *, struct xucred *); |
192 |
static struct exportlist *ex_search(fsid_t *); |
206 |
static struct exportlist *ex_search(fsid_t *, struct exportlisthead *); |
193 |
static struct exportlist *get_exp(void); |
207 |
static struct exportlist *get_exp(void); |
194 |
static void free_dir(struct dirlist *); |
208 |
static void free_dir(struct dirlist *); |
195 |
static void free_exp(struct exportlist *); |
209 |
static void free_exp(struct exportlist *); |
196 |
static void free_grp(struct grouplist *); |
210 |
static void free_grp(struct grouplist *); |
197 |
static void free_host(struct hostlist *); |
211 |
static void free_host(struct hostlist *); |
198 |
static void get_exportlist(void); |
212 |
static void free_v4rootexp(void); |
|
|
213 |
static void get_exportlist_one(int); |
214 |
static void get_exportlist(int); |
215 |
static void insert_exports(struct exportlist *, struct exportlisthead *); |
216 |
static void free_exports(struct exportlisthead *); |
217 |
static void read_exportfile(int); |
218 |
static int compare_nmount_exportlist(struct iovec *, int, char *); |
219 |
static int compare_export(struct exportlist *, struct exportlist *); |
220 |
static int compare_cred(struct xucred *, struct xucred *); |
221 |
static int compare_secflavor(int *, int *, int); |
222 |
static void delete_export(struct iovec *, int, struct statfs *, char *); |
199 |
static int get_host(char *, struct grouplist *, struct grouplist *); |
223 |
static int get_host(char *, struct grouplist *, struct grouplist *); |
200 |
static struct hostlist *get_ht(void); |
224 |
static struct hostlist *get_ht(void); |
201 |
static int get_line(void); |
225 |
static int get_line(void); |
Lines 204-210
static int get_net(char *, struct netmsk
Link Here
|
204 |
static void getexp_err(struct exportlist *, struct grouplist *, const char *); |
228 |
static void getexp_err(struct exportlist *, struct grouplist *, const char *); |
205 |
static struct grouplist *get_grp(void); |
229 |
static struct grouplist *get_grp(void); |
206 |
static void hang_dirp(struct dirlist *, struct grouplist *, |
230 |
static void hang_dirp(struct dirlist *, struct grouplist *, |
207 |
struct exportlist *, int); |
231 |
struct exportlist *, int, struct xucred *, int); |
208 |
static void huphandler(int sig); |
232 |
static void huphandler(int sig); |
209 |
static int makemask(struct sockaddr_storage *ssp, int bitlen); |
233 |
static int makemask(struct sockaddr_storage *ssp, int bitlen); |
210 |
static void mntsrv(struct svc_req *, SVCXPRT *); |
234 |
static void mntsrv(struct svc_req *, SVCXPRT *); |
Lines 227-235
static int xdr_fhs(XDR *, caddr_t);
Link Here
|
227 |
static int xdr_mlist(XDR *, caddr_t); |
251 |
static int xdr_mlist(XDR *, caddr_t); |
228 |
static void terminate(int); |
252 |
static void terminate(int); |
229 |
|
253 |
|
230 |
static SLIST_HEAD(, exportlist) exphead = SLIST_HEAD_INITIALIZER(exphead); |
254 |
#define EXPHASH(f) (fnv_32_buf((f), sizeof(fsid_t), 0) % exphashsize) |
231 |
static SLIST_HEAD(, mountlist) mlhead = SLIST_HEAD_INITIALIZER(mlhead); |
255 |
static struct exportlisthead *exphead = NULL; |
232 |
static struct grouplist *grphead; |
256 |
static struct exportlisthead *oldexphead = NULL; |
|
|
257 |
static int exphashsize = 0; |
258 |
static SLIST_HEAD(, mountlist) mlhead = SLIST_HEAD_INITIALIZER(&mlhead); |
233 |
static char *exnames_default[2] = { _PATH_EXPORTS, NULL }; |
259 |
static char *exnames_default[2] = { _PATH_EXPORTS, NULL }; |
234 |
static char **exnames; |
260 |
static char **exnames; |
235 |
static char **hosts = NULL; |
261 |
static char **hosts = NULL; |
Lines 260-265
static int have_v6 = 1;
Link Here
|
260 |
|
286 |
|
261 |
static int v4root_phase = 0; |
287 |
static int v4root_phase = 0; |
262 |
static char v4root_dirpath[PATH_MAX + 1]; |
288 |
static char v4root_dirpath[PATH_MAX + 1]; |
|
|
289 |
static struct exportlist *v4root_ep = NULL; |
290 |
static struct grouplist *v4root_grp = NULL; |
263 |
static int has_publicfh = 0; |
291 |
static int has_publicfh = 0; |
264 |
|
292 |
|
265 |
static struct pidfh *pfh = NULL; |
293 |
static struct pidfh *pfh = NULL; |
Lines 368-376
main(int argc, char **argv)
Link Here
|
368 |
in_port_t svcport; |
396 |
in_port_t svcport; |
369 |
int c, k, s; |
397 |
int c, k, s; |
370 |
int maxrec = RPC_MAXDATASIZE; |
398 |
int maxrec = RPC_MAXDATASIZE; |
371 |
int attempt_cnt, port_len, port_pos, ret; |
399 |
int attempt_cnt, passno, port_len, port_pos, ret; |
372 |
char **port_list; |
400 |
char **port_list; |
373 |
|
401 |
|
|
|
402 |
passno = 0; |
374 |
/* Check that another mountd isn't already running. */ |
403 |
/* Check that another mountd isn't already running. */ |
375 |
pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &otherpid); |
404 |
pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &otherpid); |
376 |
if (pfh == NULL) { |
405 |
if (pfh == NULL) { |
Lines 385-391
main(int argc, char **argv)
Link Here
|
385 |
else |
414 |
else |
386 |
close(s); |
415 |
close(s); |
387 |
|
416 |
|
388 |
while ((c = getopt(argc, argv, "2deh:lnp:rS")) != -1) |
417 |
while ((c = getopt(argc, argv, "2deh:Ilnp:rS")) != -1) |
389 |
switch (c) { |
418 |
switch (c) { |
390 |
case '2': |
419 |
case '2': |
391 |
force_v2 = 1; |
420 |
force_v2 = 1; |
Lines 437-442
main(int argc, char **argv)
Link Here
|
437 |
case 'S': |
466 |
case 'S': |
438 |
suspend_nfsd = 1; |
467 |
suspend_nfsd = 1; |
439 |
break; |
468 |
break; |
|
|
469 |
case 'I': |
470 |
passno = 1; |
471 |
break; |
440 |
default: |
472 |
default: |
441 |
usage(); |
473 |
usage(); |
442 |
} |
474 |
} |
Lines 449-455
main(int argc, char **argv)
Link Here
|
449 |
|
481 |
|
450 |
argc -= optind; |
482 |
argc -= optind; |
451 |
argv += optind; |
483 |
argv += optind; |
452 |
grphead = (struct grouplist *)NULL; |
|
|
453 |
if (argc > 0) |
484 |
if (argc > 0) |
454 |
exnames = argv; |
485 |
exnames = argv; |
455 |
else |
486 |
else |
Lines 457-463
main(int argc, char **argv)
Link Here
|
457 |
openlog("mountd", LOG_PID, LOG_DAEMON); |
488 |
openlog("mountd", LOG_PID, LOG_DAEMON); |
458 |
if (debug) |
489 |
if (debug) |
459 |
warnx("getting export list"); |
490 |
warnx("getting export list"); |
460 |
get_exportlist(); |
491 |
get_exportlist(0); |
461 |
if (debug) |
492 |
if (debug) |
462 |
warnx("getting mount list"); |
493 |
warnx("getting mount list"); |
463 |
get_mountlist(); |
494 |
get_mountlist(); |
Lines 628-634
main(int argc, char **argv)
Link Here
|
628 |
/* Expand svc_run() here so that we can call get_exportlist(). */ |
659 |
/* Expand svc_run() here so that we can call get_exportlist(). */ |
629 |
for (;;) { |
660 |
for (;;) { |
630 |
if (got_sighup) { |
661 |
if (got_sighup) { |
631 |
get_exportlist(); |
662 |
get_exportlist(passno); |
632 |
got_sighup = 0; |
663 |
got_sighup = 0; |
633 |
} |
664 |
} |
634 |
readfds = svc_fdset; |
665 |
readfds = svc_fdset; |
Lines 1087-1093
mntsrv(struct svc_req *rqstp, SVCXPRT *t
Link Here
|
1087 |
if (bad) |
1118 |
if (bad) |
1088 |
ep = NULL; |
1119 |
ep = NULL; |
1089 |
else |
1120 |
else |
1090 |
ep = ex_search(&fsb.f_fsid); |
1121 |
ep = ex_search(&fsb.f_fsid, exphead); |
1091 |
hostset = defset = 0; |
1122 |
hostset = defset = 0; |
1092 |
if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset, |
1123 |
if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset, |
1093 |
&numsecflavors, &secflavorsp) || |
1124 |
&numsecflavors, &secflavorsp) || |
Lines 1302-1322
xdr_explist_common(XDR *xdrsp, caddr_t c
Link Here
|
1302 |
int false = 0; |
1333 |
int false = 0; |
1303 |
int putdef; |
1334 |
int putdef; |
1304 |
sigset_t sighup_mask; |
1335 |
sigset_t sighup_mask; |
|
|
1336 |
int i; |
1305 |
|
1337 |
|
1306 |
sigemptyset(&sighup_mask); |
1338 |
sigemptyset(&sighup_mask); |
1307 |
sigaddset(&sighup_mask, SIGHUP); |
1339 |
sigaddset(&sighup_mask, SIGHUP); |
1308 |
sigprocmask(SIG_BLOCK, &sighup_mask, NULL); |
1340 |
sigprocmask(SIG_BLOCK, &sighup_mask, NULL); |
1309 |
|
1341 |
|
1310 |
SLIST_FOREACH(ep, &exphead, entries) { |
1342 |
for (i = 0; i < exphashsize; i++) |
1311 |
putdef = 0; |
1343 |
SLIST_FOREACH(ep, &exphead[i], entries) { |
1312 |
if (put_exlist(ep->ex_dirl, xdrsp, ep->ex_defdir, |
1344 |
putdef = 0; |
1313 |
&putdef, brief)) |
1345 |
if (put_exlist(ep->ex_dirl, xdrsp, ep->ex_defdir, |
1314 |
goto errout; |
1346 |
&putdef, brief)) |
1315 |
if (ep->ex_defdir && putdef == 0 && |
1347 |
goto errout; |
1316 |
put_exlist(ep->ex_defdir, xdrsp, (struct dirlist *)NULL, |
1348 |
if (ep->ex_defdir && putdef == 0 && |
1317 |
&putdef, brief)) |
1349 |
put_exlist(ep->ex_defdir, xdrsp, NULL, |
1318 |
goto errout; |
1350 |
&putdef, brief)) |
1319 |
} |
1351 |
goto errout; |
|
|
1352 |
} |
1320 |
sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); |
1353 |
sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); |
1321 |
if (!xdr_bool(xdrsp, &false)) |
1354 |
if (!xdr_bool(xdrsp, &false)) |
1322 |
return (0); |
1355 |
return (0); |
Lines 1416-1422
static FILE *exp_file;
Link Here
|
1416 |
* Get the export list from one, currently open file |
1449 |
* Get the export list from one, currently open file |
1417 |
*/ |
1450 |
*/ |
1418 |
static void |
1451 |
static void |
1419 |
get_exportlist_one(void) |
1452 |
get_exportlist_one(int passno) |
1420 |
{ |
1453 |
{ |
1421 |
struct exportlist *ep; |
1454 |
struct exportlist *ep; |
1422 |
struct grouplist *grp, *tgrp; |
1455 |
struct grouplist *grp, *tgrp; |
Lines 1540-1546
get_exportlist_one(void)
Link Here
|
1540 |
* See if this directory is already |
1573 |
* See if this directory is already |
1541 |
* in the list. |
1574 |
* in the list. |
1542 |
*/ |
1575 |
*/ |
1543 |
ep = ex_search(&fsb.f_fsid); |
1576 |
ep = ex_search(&fsb.f_fsid, exphead); |
1544 |
if (ep == (struct exportlist *)NULL) { |
1577 |
if (ep == (struct exportlist *)NULL) { |
1545 |
ep = get_exp(); |
1578 |
ep = get_exp(); |
1546 |
ep->ex_fs = fsb.f_fsid; |
1579 |
ep->ex_fs = fsb.f_fsid; |
Lines 1653-1663
get_exportlist_one(void)
Link Here
|
1653 |
* Loop through hosts, pushing the exports into the kernel. |
1686 |
* Loop through hosts, pushing the exports into the kernel. |
1654 |
* After loop, tgrp points to the start of the list and |
1687 |
* After loop, tgrp points to the start of the list and |
1655 |
* grp points to the last entry in the list. |
1688 |
* grp points to the last entry in the list. |
|
|
1689 |
* Do not do the do_mount() for passno == 1, since the |
1690 |
* second pass will do it, as required. |
1656 |
*/ |
1691 |
*/ |
1657 |
grp = tgrp; |
1692 |
grp = tgrp; |
1658 |
do { |
1693 |
do { |
1659 |
if (do_mount(ep, grp, exflags, &anon, dirp, dirplen, |
1694 |
grp->gr_exflags = exflags; |
1660 |
&fsb)) { |
1695 |
grp->gr_anon = anon; |
|
|
1696 |
if (passno != 1 && do_mount(ep, grp, exflags, &anon, |
1697 |
dirp, dirplen, &fsb)) { |
1661 |
getexp_err(ep, tgrp, NULL); |
1698 |
getexp_err(ep, tgrp, NULL); |
1662 |
goto nextline; |
1699 |
goto nextline; |
1663 |
} |
1700 |
} |
Lines 1668-1682
get_exportlist_one(void)
Link Here
|
1668 |
*/ |
1705 |
*/ |
1669 |
if (v4root_phase > 0 && v4root_phase <= 2) { |
1706 |
if (v4root_phase > 0 && v4root_phase <= 2) { |
1670 |
/* |
1707 |
/* |
1671 |
* Since these structures aren't used by mountd, |
1708 |
* These structures are used for the "-I" reload, |
|
|
1709 |
* so save them for that case. Otherwise, just |
1672 |
* free them up now. |
1710 |
* free them up now. |
1673 |
*/ |
1711 |
*/ |
1674 |
if (ep != NULL) |
1712 |
if (passno == 1) { |
1675 |
free_exp(ep); |
1713 |
if (v4root_ep != NULL) { |
1676 |
while (tgrp != NULL) { |
1714 |
getexp_err(ep, tgrp, |
1677 |
grp = tgrp; |
1715 |
"multiple V4 lines"); |
1678 |
tgrp = tgrp->gr_next; |
1716 |
goto nextline; |
1679 |
free_grp(grp); |
1717 |
} |
|
|
1718 |
v4root_ep = ep; |
1719 |
v4root_grp = tgrp; |
1720 |
} else { |
1721 |
if (ep != NULL) |
1722 |
free_exp(ep); |
1723 |
while (tgrp != NULL) { |
1724 |
grp = tgrp; |
1725 |
tgrp = tgrp->gr_next; |
1726 |
free_grp(grp); |
1727 |
} |
1680 |
} |
1728 |
} |
1681 |
goto nextline; |
1729 |
goto nextline; |
1682 |
} |
1730 |
} |
Lines 1685-1701
get_exportlist_one(void)
Link Here
|
1685 |
* Success. Update the data structures. |
1733 |
* Success. Update the data structures. |
1686 |
*/ |
1734 |
*/ |
1687 |
if (has_host) { |
1735 |
if (has_host) { |
1688 |
hang_dirp(dirhead, tgrp, ep, opt_flags); |
1736 |
hang_dirp(dirhead, tgrp, ep, opt_flags, &anon, exflags); |
1689 |
grp->gr_next = grphead; |
1737 |
grp->gr_next = ep->ex_grphead; |
1690 |
grphead = tgrp; |
1738 |
ep->ex_grphead = tgrp; |
1691 |
} else { |
1739 |
} else { |
1692 |
hang_dirp(dirhead, (struct grouplist *)NULL, ep, |
1740 |
hang_dirp(dirhead, (struct grouplist *)NULL, ep, |
1693 |
opt_flags); |
1741 |
opt_flags, &anon, exflags); |
1694 |
free_grp(grp); |
1742 |
free_grp(grp); |
1695 |
} |
1743 |
} |
1696 |
dirhead = (struct dirlist *)NULL; |
1744 |
dirhead = (struct dirlist *)NULL; |
1697 |
if ((ep->ex_flag & EX_LINKED) == 0) { |
1745 |
if ((ep->ex_flag & EX_LINKED) == 0) { |
1698 |
SLIST_INSERT_HEAD(&exphead, ep, entries); |
1746 |
insert_exports(ep, exphead); |
1699 |
|
1747 |
|
1700 |
ep->ex_flag |= EX_LINKED; |
1748 |
ep->ex_flag |= EX_LINKED; |
1701 |
} |
1749 |
} |
Lines 1712-1756
nextline:
Link Here
|
1712 |
* Get the export list from all specified files |
1760 |
* Get the export list from all specified files |
1713 |
*/ |
1761 |
*/ |
1714 |
static void |
1762 |
static void |
1715 |
get_exportlist(void) |
1763 |
get_exportlist(int passno) |
1716 |
{ |
1764 |
{ |
1717 |
struct exportlist *ep, *ep2; |
|
|
1718 |
struct grouplist *grp, *tgrp; |
1719 |
struct export_args export; |
1765 |
struct export_args export; |
1720 |
struct iovec *iov; |
1766 |
struct iovec *iov; |
1721 |
struct statfs *fsp, *mntbufp; |
1767 |
struct statfs *mntbufp; |
1722 |
struct xvfsconf vfc; |
|
|
1723 |
char errmsg[255]; |
1768 |
char errmsg[255]; |
1724 |
int num, i; |
1769 |
int num, i; |
1725 |
int iovlen; |
1770 |
int iovlen; |
1726 |
int done; |
|
|
1727 |
struct nfsex_args eargs; |
1771 |
struct nfsex_args eargs; |
1728 |
|
1772 |
|
1729 |
if (suspend_nfsd != 0) |
1773 |
syslog(LOG_ERR, "passno=%d", passno); |
1730 |
(void)nfssvc(NFSSVC_SUSPENDNFSD, NULL); |
|
|
1731 |
v4root_dirpath[0] = '\0'; |
1774 |
v4root_dirpath[0] = '\0'; |
|
|
1775 |
free_v4rootexp(); |
1776 |
if (passno == 1) { |
1777 |
/* |
1778 |
* Save the current lists as old ones, so that the new lists |
1779 |
* can be compared with the old ones in the 2nd pass. |
1780 |
*/ |
1781 |
for (i = 0; i < exphashsize; i++) { |
1782 |
SLIST_FIRST(&oldexphead[i]) = SLIST_FIRST(&exphead[i]); |
1783 |
SLIST_INIT(&exphead[i]); |
1784 |
} |
1785 |
|
1786 |
/* Read the export file(s) and process them */ |
1787 |
read_exportfile(passno); |
1788 |
syslog(LOG_ERR, "readexp1"); |
1789 |
} else { |
1790 |
/* |
1791 |
* Just make the old lists empty. |
1792 |
* exphashsize == 0 for the first call, before oldexphead |
1793 |
* has been initialized-->loop won't be executed. |
1794 |
*/ |
1795 |
for (i = 0; i < exphashsize; i++) |
1796 |
SLIST_INIT(&oldexphead[i]); |
1797 |
} |
1798 |
|
1732 |
bzero(&export, sizeof(export)); |
1799 |
bzero(&export, sizeof(export)); |
1733 |
export.ex_flags = MNT_DELEXPORT; |
1800 |
export.ex_flags = MNT_DELEXPORT; |
1734 |
iov = NULL; |
1801 |
iov = NULL; |
1735 |
iovlen = 0; |
1802 |
iovlen = 0; |
1736 |
bzero(errmsg, sizeof(errmsg)); |
1803 |
bzero(errmsg, sizeof(errmsg)); |
1737 |
|
1804 |
|
1738 |
/* |
1805 |
if (suspend_nfsd != 0) |
1739 |
* First, get rid of the old list |
1806 |
(void)nfssvc(NFSSVC_SUSPENDNFSD, NULL); |
1740 |
*/ |
|
|
1741 |
SLIST_FOREACH_SAFE(ep, &exphead, entries, ep2) { |
1742 |
SLIST_REMOVE(&exphead, ep, exportlist, entries); |
1743 |
free_exp(ep); |
1744 |
} |
1745 |
|
1746 |
grp = grphead; |
1747 |
while (grp) { |
1748 |
tgrp = grp; |
1749 |
grp = grp->gr_next; |
1750 |
free_grp(tgrp); |
1751 |
} |
1752 |
grphead = (struct grouplist *)NULL; |
1753 |
|
1754 |
/* |
1807 |
/* |
1755 |
* and the old V4 root dir. |
1808 |
* and the old V4 root dir. |
1756 |
*/ |
1809 |
*/ |
Lines 1765-1826
get_exportlist(void)
Link Here
|
1765 |
*/ |
1818 |
*/ |
1766 |
has_publicfh = 0; |
1819 |
has_publicfh = 0; |
1767 |
|
1820 |
|
|
|
1821 |
build_iovec(&iov, &iovlen, "fstype", NULL, 0); |
1822 |
build_iovec(&iov, &iovlen, "fspath", NULL, 0); |
1823 |
build_iovec(&iov, &iovlen, "from", NULL, 0); |
1824 |
build_iovec(&iov, &iovlen, "update", NULL, 0); |
1825 |
build_iovec(&iov, &iovlen, "export", &export, |
1826 |
sizeof(export)); |
1827 |
build_iovec(&iov, &iovlen, "errmsg", errmsg, |
1828 |
sizeof(errmsg)); |
1829 |
|
1768 |
/* |
1830 |
/* |
1769 |
* And delete exports that are in the kernel for all local |
1831 |
* For passno == 1, compare the old and new lists updating the kernel |
1770 |
* filesystems. |
1832 |
* exports for any cases that have changed. |
1771 |
* XXX: Should know how to handle all local exportable filesystems. |
1833 |
* This call is doing the second pass through the lists. |
|
|
1834 |
* If it fails, fall back on the bulk reload. |
1772 |
*/ |
1835 |
*/ |
1773 |
num = getmntinfo(&mntbufp, MNT_NOWAIT); |
1836 |
if (passno == 1 && compare_nmount_exportlist(iov, iovlen, errmsg) == |
1774 |
|
1837 |
0) { |
1775 |
if (num > 0) { |
1838 |
syslog(LOG_ERR, "compareok"); |
1776 |
build_iovec(&iov, &iovlen, "fstype", NULL, 0); |
1839 |
/* Free up the old lists. */ |
1777 |
build_iovec(&iov, &iovlen, "fspath", NULL, 0); |
1840 |
free_exports(oldexphead); |
1778 |
build_iovec(&iov, &iovlen, "from", NULL, 0); |
1841 |
} else { |
1779 |
build_iovec(&iov, &iovlen, "update", NULL, 0); |
1842 |
syslog(LOG_ERR, "doin passno=0"); |
1780 |
build_iovec(&iov, &iovlen, "export", &export, sizeof(export)); |
1843 |
/* exphead == NULL if not yet allocated (first call). */ |
1781 |
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg)); |
1844 |
if (exphead != NULL) { |
1782 |
} |
1845 |
/* |
1783 |
|
1846 |
* First, get rid of the old lists. |
1784 |
for (i = 0; i < num; i++) { |
1847 |
*/ |
1785 |
fsp = &mntbufp[i]; |
1848 |
free_exports(exphead); |
1786 |
if (getvfsbyname(fsp->f_fstypename, &vfc) != 0) { |
1849 |
free_exports(oldexphead); |
1787 |
syslog(LOG_ERR, "getvfsbyname() failed for %s", |
|
|
1788 |
fsp->f_fstypename); |
1789 |
continue; |
1790 |
} |
1850 |
} |
|
|
1851 |
free_v4rootexp(); |
1791 |
|
1852 |
|
1792 |
/* |
1853 |
/* |
1793 |
* We do not need to delete "export" flag from |
1854 |
* And delete exports that are in the kernel for all local |
1794 |
* filesystems that do not have it set. |
1855 |
* filesystems. |
1795 |
*/ |
1856 |
* XXX: Should know how to handle all local exportable |
1796 |
if (!(fsp->f_flags & MNT_EXPORTED)) |
1857 |
* filesystems. |
1797 |
continue; |
1858 |
*/ |
1798 |
/* |
1859 |
num = getmntinfo(&mntbufp, MNT_NOWAIT); |
1799 |
* Do not delete export for network filesystem by |
1860 |
|
1800 |
* passing "export" arg to nmount(). |
1861 |
/* Allocate hash tables, for first call. */ |
1801 |
* It only makes sense to do this for local filesystems. |
1862 |
if (exphead == NULL) { |
1802 |
*/ |
1863 |
/* Target an average linked list length of 20. */ |
1803 |
if (vfc.vfc_flags & VFCF_NETWORK) |
1864 |
exphashsize = num / 10; |
1804 |
continue; |
1865 |
if (exphashsize < 1) |
1805 |
|
1866 |
exphashsize = 1; |
1806 |
iov[1].iov_base = fsp->f_fstypename; |
1867 |
else if (exphashsize > 100000) |
1807 |
iov[1].iov_len = strlen(fsp->f_fstypename) + 1; |
1868 |
exphashsize = 100000; |
1808 |
iov[3].iov_base = fsp->f_mntonname; |
1869 |
exphead = malloc(exphashsize * sizeof(*exphead)); |
1809 |
iov[3].iov_len = strlen(fsp->f_mntonname) + 1; |
1870 |
oldexphead = malloc(exphashsize * sizeof(*oldexphead)); |
1810 |
iov[5].iov_base = fsp->f_mntfromname; |
1871 |
if (exphead == NULL || oldexphead == NULL) |
1811 |
iov[5].iov_len = strlen(fsp->f_mntfromname) + 1; |
1872 |
errx(1, "Can't malloc hash tables"); |
1812 |
errmsg[0] = '\0'; |
1873 |
|
1813 |
|
1874 |
for (i = 0; i < exphashsize; i++) { |
1814 |
/* |
1875 |
SLIST_INIT(&exphead[i]); |
1815 |
* EXDEV is returned when path exists but is not a |
1876 |
SLIST_INIT(&oldexphead[i]); |
1816 |
* mount point. May happens if raced with unmount. |
1877 |
} |
1817 |
*/ |
|
|
1818 |
if (nmount(iov, iovlen, fsp->f_flags) < 0 && |
1819 |
errno != ENOENT && errno != ENOTSUP && errno != EXDEV) { |
1820 |
syslog(LOG_ERR, |
1821 |
"can't delete exports for %s: %m %s", |
1822 |
fsp->f_mntonname, errmsg); |
1823 |
} |
1878 |
} |
|
|
1879 |
|
1880 |
for (i = 0; i < num; i++) |
1881 |
delete_export(iov, iovlen, &mntbufp[i], errmsg); |
1882 |
|
1883 |
|
1884 |
/* Read the export file(s) and process them */ |
1885 |
read_exportfile(0); |
1886 |
syslog(LOG_ERR, "readexp0"); |
1824 |
} |
1887 |
} |
1825 |
|
1888 |
|
1826 |
if (iov != NULL) { |
1889 |
if (iov != NULL) { |
Lines 1838-1843
get_exportlist(void)
Link Here
|
1838 |
} |
1901 |
} |
1839 |
|
1902 |
|
1840 |
/* |
1903 |
/* |
|
|
1904 |
* If there was no public fh, clear any previous one set. |
1905 |
*/ |
1906 |
if (has_publicfh == 0) |
1907 |
(void) nfssvc(NFSSVC_NOPUBLICFH, NULL); |
1908 |
|
1909 |
/* Resume the nfsd. If they weren't suspended, this is harmless. */ |
1910 |
(void)nfssvc(NFSSVC_RESUMENFSD, NULL); |
1911 |
syslog(LOG_ERR, "eo get_exportlist"); |
1912 |
} |
1913 |
|
1914 |
/* |
1915 |
* Insert an export entry in the appropriate list. |
1916 |
*/ |
1917 |
static void |
1918 |
insert_exports(struct exportlist *ep, struct exportlisthead *exhp) |
1919 |
{ |
1920 |
uint32_t i; |
1921 |
|
1922 |
i = EXPHASH(&ep->ex_fs); |
1923 |
syslog(LOG_ERR, "fs=%s hash=%i", ep->ex_fsdir, i); |
1924 |
SLIST_INSERT_HEAD(&exhp[i], ep, entries); |
1925 |
} |
1926 |
|
1927 |
/* |
1928 |
* Free up the exports lists passed in as arguments. |
1929 |
*/ |
1930 |
static void |
1931 |
free_exports(struct exportlisthead *exhp) |
1932 |
{ |
1933 |
struct exportlist *ep, *ep2; |
1934 |
int i; |
1935 |
|
1936 |
for (i = 0; i < exphashsize; i++) { |
1937 |
SLIST_FOREACH_SAFE(ep, &exhp[i], entries, ep2) { |
1938 |
SLIST_REMOVE(&exhp[i], ep, exportlist, entries); |
1939 |
free_exp(ep); |
1940 |
} |
1941 |
SLIST_INIT(&exhp[i]); |
1942 |
} |
1943 |
} |
1944 |
|
1945 |
/* |
1946 |
* Read the exports file(s) and call get_exportlist_one() for each line. |
1947 |
*/ |
1948 |
static void |
1949 |
read_exportfile(int passno) |
1950 |
{ |
1951 |
int done, i; |
1952 |
|
1953 |
/* |
1841 |
* Read in the exports file and build the list, calling |
1954 |
* Read in the exports file and build the list, calling |
1842 |
* nmount() as we go along to push the export rules into the kernel. |
1955 |
* nmount() as we go along to push the export rules into the kernel. |
1843 |
*/ |
1956 |
*/ |
Lines 1849-1855
get_exportlist(void)
Link Here
|
1849 |
syslog(LOG_WARNING, "can't open %s", exnames[i]); |
1962 |
syslog(LOG_WARNING, "can't open %s", exnames[i]); |
1850 |
continue; |
1963 |
continue; |
1851 |
} |
1964 |
} |
1852 |
get_exportlist_one(); |
1965 |
get_exportlist_one(passno); |
1853 |
fclose(exp_file); |
1966 |
fclose(exp_file); |
1854 |
done++; |
1967 |
done++; |
1855 |
} |
1968 |
} |
Lines 1857-1871
get_exportlist(void)
Link Here
|
1857 |
syslog(LOG_ERR, "can't open any exports file"); |
1970 |
syslog(LOG_ERR, "can't open any exports file"); |
1858 |
exit(2); |
1971 |
exit(2); |
1859 |
} |
1972 |
} |
|
|
1973 |
} |
1974 |
|
1975 |
/* |
1976 |
* Compare the export lists against the old ones and do nmount() operations |
1977 |
* for any cases that have changed. This avoids doing nmount() for entries |
1978 |
* that have not changed. |
1979 |
* Return 0 upon success, 1 otherwise. |
1980 |
*/ |
1981 |
static int |
1982 |
compare_nmount_exportlist(struct iovec *iov, int iovlen, char *errmsg) |
1983 |
{ |
1984 |
struct exportlist *ep, *oep; |
1985 |
struct grouplist *grp; |
1986 |
struct statfs fs, ofs; |
1987 |
int i, ret; |
1860 |
|
1988 |
|
1861 |
/* |
1989 |
/* |
1862 |
* If there was no public fh, clear any previous one set. |
1990 |
* Loop through the current list and look for an entry in the old |
|
|
1991 |
* list. |
1992 |
* If found, check to see if it the same. |
1993 |
* If it is not the same, delete and re-export. |
1994 |
* Then mark it done on the old list. |
1995 |
* else (not found) |
1996 |
* export it. |
1997 |
* Any entries left in the old list after processing must have their |
1998 |
* exports deleted. |
1863 |
*/ |
1999 |
*/ |
1864 |
if (has_publicfh == 0) |
2000 |
for (i = 0; i < exphashsize; i++) |
1865 |
(void) nfssvc(NFSSVC_NOPUBLICFH, NULL); |
2001 |
SLIST_FOREACH(ep, &exphead[i], entries) { |
|
|
2002 |
syslog(LOG_ERR, "foreach ep"); |
2003 |
oep = ex_search(&ep->ex_fs, oldexphead); |
2004 |
if (oep != NULL) { |
2005 |
/* |
2006 |
* Check the mount paths are the same. |
2007 |
* If not, return 1 so that the reload of the |
2008 |
* exports will be done in bulk, the |
2009 |
* passno == 0 way. |
2010 |
*/ |
2011 |
syslog(LOG_ERR, "fnd ex"); |
2012 |
if (strcmp(ep->ex_fsdir, oep->ex_fsdir) != 0) |
2013 |
return (1); |
2014 |
/* |
2015 |
* Test to see if the entry is the same. |
2016 |
* If not the same delete exports and |
2017 |
* re-export. |
2018 |
*/ |
2019 |
syslog(LOG_ERR, "at compare"); |
2020 |
if (compare_export(ep, oep) != 0) { |
2021 |
if (statfs(ep->ex_fsdir, &fs) < 0) |
2022 |
return (1); |
2023 |
syslog(LOG_ERR, "changed fsv0=%d fsv1=%d", fs.f_fsid.val[0], fs.f_fsid.val[1]); |
2024 |
delete_export(iov, iovlen, &fs, errmsg); |
2025 |
ret = do_export_mount(ep, &fs); |
2026 |
if (ret != 0) |
2027 |
return (ret); |
2028 |
} |
2029 |
oep->ex_flag |= EX_DONE; |
2030 |
syslog(LOG_ERR, "exdone"); |
2031 |
} else { |
2032 |
syslog(LOG_ERR, "not fnd so ex"); |
2033 |
/* Not found, so do export. */ |
2034 |
if (statfs(ep->ex_fsdir, &fs) < 0) |
2035 |
return (1); |
2036 |
syslog(LOG_ERR, "not fnd fsv0=%d fsv1=%d", fs.f_fsid.val[0], fs.f_fsid.val[1]); |
2037 |
ret = do_export_mount(ep, &fs); |
2038 |
if (ret != 0) |
2039 |
return (ret); |
2040 |
} |
2041 |
} |
1866 |
|
2042 |
|
1867 |
/* Resume the nfsd. If they weren't suspended, this is harmless. */ |
2043 |
/* Delete exports not done. */ |
1868 |
(void)nfssvc(NFSSVC_RESUMENFSD, NULL); |
2044 |
for (i = 0; i < exphashsize; i++) |
|
|
2045 |
SLIST_FOREACH(oep, &oldexphead[i], entries) { |
2046 |
if ((oep->ex_flag & EX_DONE) == 0) { |
2047 |
syslog(LOG_ERR, "not done delete"); |
2048 |
if (statfs(oep->ex_fsdir, &ofs) >= 0 && |
2049 |
oep->ex_fs.val[0] == ofs.f_fsid.val[0] && |
2050 |
oep->ex_fs.val[1] == ofs.f_fsid.val[1]) { |
2051 |
syslog(LOG_ERR, "do delete"); |
2052 |
delete_export(iov, iovlen, &ofs, errmsg); |
2053 |
} |
2054 |
} |
2055 |
} |
2056 |
|
2057 |
/* Do the V4 root exports, as required. */ |
2058 |
grp = v4root_grp; |
2059 |
v4root_phase = 2; |
2060 |
while (v4root_ep != NULL && grp != NULL) { |
2061 |
syslog(LOG_ERR, "v4ex path=%s gr_type=0x%x gr_exflags=0x%x", v4root_dirpath, grp->gr_type, grp->gr_exflags); |
2062 |
syslog(LOG_ERR, "v4rootd=%s", v4root_dirpath); |
2063 |
ret = do_mount(v4root_ep, grp, grp->gr_exflags, &grp->gr_anon, |
2064 |
v4root_dirpath, strlen(v4root_dirpath), &fs); |
2065 |
if (ret != 0) { |
2066 |
v4root_phase = 0; |
2067 |
return (ret); |
2068 |
} |
2069 |
grp = grp->gr_next; |
2070 |
} |
2071 |
v4root_phase = 0; |
2072 |
free_v4rootexp(); |
2073 |
return (0); |
2074 |
} |
2075 |
|
2076 |
/* |
2077 |
* Compare old and current exportlist entries for the fsid and return 0 |
2078 |
* if they are the same, 1 otherwise. |
2079 |
*/ |
2080 |
static int |
2081 |
compare_export(struct exportlist *ep, struct exportlist *oep) |
2082 |
{ |
2083 |
struct grouplist *grp, *ogrp; |
2084 |
|
2085 |
if (strcmp(ep->ex_fsdir, oep->ex_fsdir) != 0) |
2086 |
return (1); |
2087 |
if ((ep->ex_defdir != NULL && oep->ex_defdir == NULL) || |
2088 |
(ep->ex_defdir == NULL && oep->ex_defdir != NULL)) |
2089 |
return (1); |
2090 |
if (ep->ex_defdir != NULL) { |
2091 |
if ((ep->ex_defdir->dp_flag & DP_DEFSET) != 0) { |
2092 |
if ((oep->ex_defdir->dp_flag & DP_DEFSET) == 0) |
2093 |
return (1); |
2094 |
if (ep->ex_defnumsecflavors != |
2095 |
oep->ex_defnumsecflavors || |
2096 |
ep->ex_defexflags != oep->ex_defexflags || |
2097 |
compare_cred(&ep->ex_defanon, &oep->ex_defanon) != |
2098 |
0 || compare_secflavor(ep->ex_defsecflavors, |
2099 |
oep->ex_defsecflavors, ep->ex_defnumsecflavors) != |
2100 |
0) |
2101 |
return (1); |
2102 |
} |
2103 |
} |
2104 |
|
2105 |
/* Now, check all the groups. */ |
2106 |
for (ogrp = oep->ex_grphead; ogrp != NULL; ogrp = ogrp->gr_next) |
2107 |
ogrp->gr_flag = 0; |
2108 |
for (grp = ep->ex_grphead; grp != NULL; grp = grp->gr_next) { |
2109 |
for (ogrp = oep->ex_grphead; ogrp != NULL; ogrp = |
2110 |
ogrp->gr_next) |
2111 |
if ((ogrp->gr_flag & GR_FND) == 0 && |
2112 |
grp->gr_numsecflavors == ogrp->gr_numsecflavors && |
2113 |
grp->gr_exflags == ogrp->gr_exflags && |
2114 |
compare_cred(&grp->gr_anon, &ogrp->gr_anon) == 0 && |
2115 |
compare_secflavor(grp->gr_secflavors, |
2116 |
ogrp->gr_secflavors, grp->gr_numsecflavors) == 0) |
2117 |
break; |
2118 |
if (ogrp != NULL) |
2119 |
ogrp->gr_flag |= GR_FND; |
2120 |
else |
2121 |
return (1); |
2122 |
} |
2123 |
for (ogrp = oep->ex_grphead; ogrp != NULL; ogrp = ogrp->gr_next) |
2124 |
if ((ogrp->gr_flag & GR_FND) == 0) |
2125 |
return (1); |
2126 |
return (0); |
2127 |
} |
2128 |
|
2129 |
/* |
2130 |
* Compare to struct xucred's. Return 0 if the same and 1 otherwise. |
2131 |
* This algorithm is O(N**2) but fortunately N is always small. |
2132 |
*/ |
2133 |
static int |
2134 |
compare_cred(struct xucred *cr0, struct xucred *cr1) |
2135 |
{ |
2136 |
int i, j; |
2137 |
|
2138 |
if (cr0->cr_uid != cr1->cr_uid || cr0->cr_ngroups != cr1->cr_ngroups) |
2139 |
return (1); |
2140 |
for (i = 0; i < cr0->cr_ngroups; i++) { |
2141 |
for (j = 0; j < cr0->cr_ngroups; j++) |
2142 |
if (cr0->cr_groups[i] == cr1->cr_groups[j]) |
2143 |
break; |
2144 |
if (j == cr0->cr_ngroups) |
2145 |
return (1); |
2146 |
} |
2147 |
return (0); |
2148 |
} |
2149 |
|
2150 |
/* |
2151 |
* Compare two lists of security flavors. Return 0 if the same and 1 otherwise. |
2152 |
* This algorithm is O(N**2) but fortunately N is always small. |
2153 |
*/ |
2154 |
static int |
2155 |
compare_secflavor(int *sec1, int *sec2, int nsec) |
2156 |
{ |
2157 |
int i, j; |
2158 |
|
2159 |
for (i = 0; i < nsec; i++) { |
2160 |
for (j = 0; j < nsec; j++) |
2161 |
if (sec1[i] == sec2[j]) |
2162 |
break; |
2163 |
if (j == nsec) |
2164 |
return (1); |
2165 |
} |
2166 |
return (0); |
2167 |
} |
2168 |
|
2169 |
/* |
2170 |
* Delete an exports entry. |
2171 |
*/ |
2172 |
static void |
2173 |
delete_export(struct iovec *iov, int iovlen, struct statfs *fsp, char *errmsg) |
2174 |
{ |
2175 |
struct xvfsconf vfc; |
2176 |
|
2177 |
if (getvfsbyname(fsp->f_fstypename, &vfc) != 0) { |
2178 |
syslog(LOG_ERR, "getvfsbyname() failed for %s", |
2179 |
fsp->f_fstypename); |
2180 |
return; |
2181 |
} |
2182 |
|
2183 |
/* |
2184 |
* We do not need to delete "export" flag from |
2185 |
* filesystems that do not have it set. |
2186 |
*/ |
2187 |
if (!(fsp->f_flags & MNT_EXPORTED)) |
2188 |
return; |
2189 |
/* |
2190 |
* Do not delete export for network filesystem by |
2191 |
* passing "export" arg to nmount(). |
2192 |
* It only makes sense to do this for local filesystems. |
2193 |
*/ |
2194 |
if (vfc.vfc_flags & VFCF_NETWORK) |
2195 |
return; |
2196 |
|
2197 |
iov[1].iov_base = fsp->f_fstypename; |
2198 |
iov[1].iov_len = strlen(fsp->f_fstypename) + 1; |
2199 |
iov[3].iov_base = fsp->f_mntonname; |
2200 |
iov[3].iov_len = strlen(fsp->f_mntonname) + 1; |
2201 |
iov[5].iov_base = fsp->f_mntfromname; |
2202 |
iov[5].iov_len = strlen(fsp->f_mntfromname) + 1; |
2203 |
errmsg[0] = '\0'; |
2204 |
|
2205 |
/* |
2206 |
* EXDEV is returned when path exists but is not a |
2207 |
* mount point. May happens if raced with unmount. |
2208 |
*/ |
2209 |
if (nmount(iov, iovlen, fsp->f_flags) < 0 && errno != ENOENT && |
2210 |
errno != ENOTSUP && errno != EXDEV) { |
2211 |
syslog(LOG_ERR, |
2212 |
"can't delete exports for %s: %m %s", |
2213 |
fsp->f_mntonname, errmsg); |
2214 |
} |
1869 |
} |
2215 |
} |
1870 |
|
2216 |
|
1871 |
/* |
2217 |
/* |
Lines 1924-1934
getexp_err(struct exportlist *ep, struct
Link Here
|
1924 |
* Search the export list for a matching fs. |
2270 |
* Search the export list for a matching fs. |
1925 |
*/ |
2271 |
*/ |
1926 |
static struct exportlist * |
2272 |
static struct exportlist * |
1927 |
ex_search(fsid_t *fsid) |
2273 |
ex_search(fsid_t *fsid, struct exportlisthead *exhp) |
1928 |
{ |
2274 |
{ |
1929 |
struct exportlist *ep; |
2275 |
struct exportlist *ep; |
|
|
2276 |
uint32_t i; |
1930 |
|
2277 |
|
1931 |
SLIST_FOREACH(ep, &exphead, entries) { |
2278 |
i = EXPHASH(fsid); |
|
|
2279 |
SLIST_FOREACH(ep, &exhp[i], entries) { |
1932 |
if (ep->ex_fs.val[0] == fsid->val[0] && |
2280 |
if (ep->ex_fs.val[0] == fsid->val[0] && |
1933 |
ep->ex_fs.val[1] == fsid->val[1]) |
2281 |
ep->ex_fs.val[1] == fsid->val[1]) |
1934 |
return (ep); |
2282 |
return (ep); |
Lines 1965-1971
add_expdir(struct dirlist **dpp, char *c
Link Here
|
1965 |
*/ |
2313 |
*/ |
1966 |
static void |
2314 |
static void |
1967 |
hang_dirp(struct dirlist *dp, struct grouplist *grp, struct exportlist *ep, |
2315 |
hang_dirp(struct dirlist *dp, struct grouplist *grp, struct exportlist *ep, |
1968 |
int flags) |
2316 |
int flags, struct xucred *anoncrp, int exflags) |
1969 |
{ |
2317 |
{ |
1970 |
struct hostlist *hp; |
2318 |
struct hostlist *hp; |
1971 |
struct dirlist *dp2; |
2319 |
struct dirlist *dp2; |
Lines 1982-1987
hang_dirp(struct dirlist *dp, struct gro
Link Here
|
1982 |
if (ep->ex_numsecflavors > 0) |
2330 |
if (ep->ex_numsecflavors > 0) |
1983 |
memcpy(ep->ex_defsecflavors, ep->ex_secflavors, |
2331 |
memcpy(ep->ex_defsecflavors, ep->ex_secflavors, |
1984 |
sizeof(ep->ex_secflavors)); |
2332 |
sizeof(ep->ex_secflavors)); |
|
|
2333 |
ep->ex_defanon = *anoncrp; |
2334 |
ep->ex_defexflags = exflags; |
1985 |
} else while (grp) { |
2335 |
} else while (grp) { |
1986 |
hp = get_ht(); |
2336 |
hp = get_ht(); |
1987 |
hp->ht_grp = grp; |
2337 |
hp->ht_grp = grp; |
Lines 2403-2408
get_host(char *cp, struct grouplist *grp
Link Here
|
2403 |
static void |
2753 |
static void |
2404 |
free_exp(struct exportlist *ep) |
2754 |
free_exp(struct exportlist *ep) |
2405 |
{ |
2755 |
{ |
|
|
2756 |
struct grouplist *grp, *tgrp; |
2406 |
|
2757 |
|
2407 |
if (ep->ex_defdir) { |
2758 |
if (ep->ex_defdir) { |
2408 |
free_host(ep->ex_defdir->dp_hosts); |
2759 |
free_host(ep->ex_defdir->dp_hosts); |
Lines 2413-2422
free_exp(struct exportlist *ep)
Link Here
|
2413 |
if (ep->ex_indexfile) |
2764 |
if (ep->ex_indexfile) |
2414 |
free(ep->ex_indexfile); |
2765 |
free(ep->ex_indexfile); |
2415 |
free_dir(ep->ex_dirl); |
2766 |
free_dir(ep->ex_dirl); |
|
|
2767 |
grp = ep->ex_grphead; |
2768 |
while (grp) { |
2769 |
tgrp = grp; |
2770 |
grp = grp->gr_next; |
2771 |
free_grp(tgrp); |
2772 |
} |
2416 |
free((caddr_t)ep); |
2773 |
free((caddr_t)ep); |
2417 |
} |
2774 |
} |
2418 |
|
2775 |
|
2419 |
/* |
2776 |
/* |
|
|
2777 |
* Free up the v4root exports. |
2778 |
*/ |
2779 |
static void |
2780 |
free_v4rootexp(void) |
2781 |
{ |
2782 |
struct grouplist *grp, *tgrp; |
2783 |
|
2784 |
if (v4root_ep != NULL) { |
2785 |
free_exp(v4root_ep); |
2786 |
v4root_ep = NULL; |
2787 |
} |
2788 |
tgrp = v4root_grp; |
2789 |
v4root_grp = NULL; |
2790 |
while (tgrp != NULL) { |
2791 |
grp = tgrp; |
2792 |
tgrp = tgrp->gr_next; |
2793 |
free_grp(grp); |
2794 |
} |
2795 |
} |
2796 |
|
2797 |
/* |
2420 |
* Free hosts. |
2798 |
* Free hosts. |
2421 |
*/ |
2799 |
*/ |
2422 |
static void |
2800 |
static void |
Lines 2456-2461
out_of_mem(void)
Link Here
|
2456 |
} |
2834 |
} |
2457 |
|
2835 |
|
2458 |
/* |
2836 |
/* |
|
|
2837 |
* Call do_mount() from the struct exportlist, for each case needed. |
2838 |
*/ |
2839 |
static int |
2840 |
do_export_mount(struct exportlist *ep, struct statfs *fsp) |
2841 |
{ |
2842 |
struct dirlist *dp; |
2843 |
struct grouplist *grp, defgrp; |
2844 |
int ret; |
2845 |
size_t dirlen; |
2846 |
|
2847 |
syslog(LOG_ERR, "do_mount_export=%s", ep->ex_fsdir); |
2848 |
dirlen = strlen(ep->ex_fsdir); |
2849 |
dp = ep->ex_defdir; |
2850 |
if (dp != NULL && (dp->dp_flag & DP_DEFSET) != 0) { |
2851 |
defgrp.gr_type = GT_DEFAULT; |
2852 |
defgrp.gr_next = NULL; |
2853 |
/* We have an entry for all other hosts/nets. */ |
2854 |
syslog(LOG_ERR, "ex_defexflags=0x%x", ep->ex_defexflags); |
2855 |
ret = do_mount(ep, &defgrp, ep->ex_defexflags, &ep->ex_defanon, |
2856 |
ep->ex_fsdir, dirlen, fsp); |
2857 |
if (ret != 0) |
2858 |
return (ret); |
2859 |
} |
2860 |
|
2861 |
/* Do a mount for each group. */ |
2862 |
grp = ep->ex_grphead; |
2863 |
while (grp != NULL) { |
2864 |
syslog(LOG_ERR, "do mount gr_type=0x%x gr_exflags=0x%x", grp->gr_type, grp->gr_exflags); |
2865 |
ret = do_mount(ep, grp, grp->gr_exflags, &grp->gr_anon, |
2866 |
ep->ex_fsdir, dirlen, fsp); |
2867 |
if (ret != 0) |
2868 |
return (ret); |
2869 |
grp = grp->gr_next; |
2870 |
} |
2871 |
return (0); |
2872 |
} |
2873 |
|
2874 |
/* |
2459 |
* Do the nmount() syscall with the update flag to push the export info into |
2875 |
* Do the nmount() syscall with the update flag to push the export info into |
2460 |
* the kernel. |
2876 |
* the kernel. |
2461 |
*/ |
2877 |
*/ |
Lines 2487-2492
do_mount(struct exportlist *ep, struct g
Link Here
|
2487 |
bzero(errmsg, sizeof(errmsg)); |
2903 |
bzero(errmsg, sizeof(errmsg)); |
2488 |
eap->ex_flags = exflags; |
2904 |
eap->ex_flags = exflags; |
2489 |
eap->ex_anon = *anoncrp; |
2905 |
eap->ex_anon = *anoncrp; |
|
|
2906 |
syslog(LOG_ERR, "do_exflags=0x%x", exflags); |
2490 |
eap->ex_indexfile = ep->ex_indexfile; |
2907 |
eap->ex_indexfile = ep->ex_indexfile; |
2491 |
if (grp->gr_type == GT_HOST) |
2908 |
if (grp->gr_type == GT_HOST) |
2492 |
ai = grp->gr_ptr.gt_addrinfo; |
2909 |
ai = grp->gr_ptr.gt_addrinfo; |
Lines 2824-2841
static void
Link Here
|
2824 |
nextfield(char **cp, char **endcp) |
3241 |
nextfield(char **cp, char **endcp) |
2825 |
{ |
3242 |
{ |
2826 |
char *p; |
3243 |
char *p; |
|
|
3244 |
char quot = 0; |
2827 |
|
3245 |
|
2828 |
p = *cp; |
3246 |
p = *cp; |
2829 |
while (*p == ' ' || *p == '\t') |
3247 |
while (*p == ' ' || *p == '\t') |
2830 |
p++; |
3248 |
p++; |
2831 |
if (*p == '\n' || *p == '\0') |
3249 |
*cp = p; |
2832 |
*cp = *endcp = p; |
3250 |
while (*p != '\0') { |
2833 |
else { |
3251 |
if (quot) { |
2834 |
*cp = p++; |
3252 |
if (*p == quot) |
2835 |
while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') |
3253 |
quot = 0; |
2836 |
p++; |
3254 |
} else { |
2837 |
*endcp = p; |
3255 |
if (*p == '\\' && *(p + 1) != '\0') |
2838 |
} |
3256 |
p++; |
|
|
3257 |
else if (*p == '\'' || *p == '"') |
3258 |
quot = *p; |
3259 |
else if (*p == ' ' || *p == '\t') |
3260 |
break; |
3261 |
} |
3262 |
p++; |
3263 |
}; |
3264 |
*endcp = p; |
2839 |
} |
3265 |
} |
2840 |
|
3266 |
|
2841 |
/* |
3267 |
/* |
Lines 2907-2914
parsecred(char *namelist, struct xucred
Link Here
|
2907 |
/* |
3333 |
/* |
2908 |
* Get the user's password table entry. |
3334 |
* Get the user's password table entry. |
2909 |
*/ |
3335 |
*/ |
2910 |
names = strsep_quote(&namelist, " \t\n"); |
3336 |
names = namelist; |
2911 |
name = strsep(&names, ":"); |
3337 |
name = strsep_quote(&names, ":"); |
2912 |
/* Bug? name could be NULL here */ |
3338 |
/* Bug? name could be NULL here */ |
2913 |
if (isdigit(*name) || *name == '-') |
3339 |
if (isdigit(*name) || *name == '-') |
2914 |
pw = getpwuid(atoi(name)); |
3340 |
pw = getpwuid(atoi(name)); |
Lines 2952-2958
parsecred(char *namelist, struct xucred
Link Here
|
2952 |
} |
3378 |
} |
2953 |
cr->cr_ngroups = 0; |
3379 |
cr->cr_ngroups = 0; |
2954 |
while (names != NULL && *names != '\0' && cr->cr_ngroups < XU_NGROUPS) { |
3380 |
while (names != NULL && *names != '\0' && cr->cr_ngroups < XU_NGROUPS) { |
2955 |
name = strsep(&names, ":"); |
3381 |
name = strsep_quote(&names, ":"); |
2956 |
if (isdigit(*name) || *name == '-') { |
3382 |
if (isdigit(*name) || *name == '-') { |
2957 |
cr->cr_groups[cr->cr_ngroups++] = atoi(name); |
3383 |
cr->cr_groups[cr->cr_ngroups++] = atoi(name); |
2958 |
} else { |
3384 |
} else { |