pax_global_header 0000666 0000000 0000000 00000000064 13672703240 0014516 g ustar 00root root 0000000 0000000 52 comment=c7d868e8b343ff04b8fa9ab7cb00e80375002d32
.gitignore 0000664 0000000 0000000 00000000124 13672703240 0013047 0 ustar 00root root 0000000 0000000 aklog-kafs
kafs-check-config
kafs-preload
kafs-dns
*.o
*.os
libkafs_client.so*
TAGS
LICENCE.GPL 0000664 0000000 0000000 00000043115 13672703240 0012474 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C) 19yy
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
Makefile 0000664 0000000 0000000 00000011063 13672703240 0012523 0 ustar 00root root 0000000 0000000 CFLAGS = -g -O2 -Wall -Wsign-compare
MKDIR = mkdir
INSTALL = install
DESTDIR =
ETCDIR = /etc
BINDIR = /usr/bin
LIBEXECDIR = /usr/libexec
MANDIR = /usr/share/man
DATADIR = /usr/share/kafs-client
UNITDIR = /usr/lib/systemd/system
SPECFILE = redhat/kafs-client.spec
LNS := ln -sf
###############################################################################
#
# Determine the current package version from the specfile
#
###############################################################################
VERSION := $(word 2,$(shell grep "^Version:" $(SPECFILE)))
TARBALL := kafs-client-$(VERSION).tar
ZTARBALL := $(TARBALL).bz2
###############################################################################
#
# Guess at the appropriate word size
#
###############################################################################
BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
ifeq ($(BUILDFOR),32-bit)
CFLAGS += -m32
else
ifeq ($(BUILDFOR),64-bit)
CFLAGS += -m64
endif
endif
###############################################################################
#
# Build stuff
#
###############################################################################
all:
$(MAKE) -C src all
###############################################################################
#
# Install everything
#
###############################################################################
MAN1 := $(MANDIR)/man1
MAN5 := $(MANDIR)/man5
MAN7 := $(MANDIR)/man7
MAN8 := $(MANDIR)/man8
install: all
$(MAKE) -C src install
$(MKDIR) -p -m755 $(DESTDIR)$(MAN1)/
$(MKDIR) -p -m755 $(DESTDIR)$(MAN5)/
$(MKDIR) -p -m755 $(DESTDIR)$(MAN7)/
$(MKDIR) -p -m755 $(DESTDIR)$(MAN8)/
$(INSTALL) -D -m 0644 man/*.1 $(DESTDIR)$(MAN1)/
$(INSTALL) -D -m 0644 man/*.5 $(DESTDIR)$(MAN5)/
$(INSTALL) -D -m 0644 man/*.7 $(DESTDIR)$(MAN7)/
$(INSTALL) -D -m 0644 man/*.8 $(DESTDIR)$(MAN8)/
$(INSTALL) -D -m 0644 conf/cellservdb.conf $(DESTDIR)$(DATADIR)/cellservdb.conf
$(INSTALL) -D -m 0644 conf/client.conf $(DESTDIR)$(ETCDIR)/kafs/client.conf
$(INSTALL) -D -m 0644 conf/kafs_dns.conf $(DESTDIR)$(ETCDIR)/request-key.d/kafs_dns.conf
$(INSTALL) -D -m 0644 conf/kafs-config.service $(DESTDIR)$(UNITDIR)/kafs-config.service
$(INSTALL) -D -m 0644 conf/afs.mount $(DESTDIR)$(UNITDIR)/afs.mount
$(MKDIR) -m755 $(DESTDIR)$(ETCDIR)/kafs/client.d
###############################################################################
#
# Clean up
#
###############################################################################
clean:
$(MAKE) -C src clean
$(RM) debugfiles.list debugsources.list
distclean: clean
$(MAKE) -C src distclean
$(RM) -r rpmbuild $(TARBALL)
###############################################################################
#
# Generate a tarball
#
###############################################################################
$(ZTARBALL):
git archive --prefix=kafs-client-$(VERSION)/ --format tar HEAD | \
bzip2 -9 >$(ZTARBALL)
tarball: $(ZTARBALL)
###############################################################################
#
# Generate an RPM
#
###############################################################################
SRCBALL := rpmbuild/SOURCES/$(TARBALL)
ZSRCBALL := rpmbuild/SOURCES/$(ZTARBALL)
BUILDID := .local
rpmver0 := $(shell rpmspec -q ./redhat/kafs-client.spec --define "buildid $(BUILDID)")
rpmver1 := $(word 1,$(rpmver0))
rpmver2 := $(subst ., ,$(rpmver1))
rpmver3 := $(lastword $(rpmver2))
rpmver4 := $(patsubst %.$(rpmver3),%,$(rpmver1))
rpmver := $(patsubst kafs-client-%,%,$(rpmver4))
SRPM := rpmbuild/SRPMS/kafs-client-$(rpmver).src.rpm
RPMBUILDDIRS := \
--define "_srcrpmdir $(CURDIR)/rpmbuild/SRPMS" \
--define "_rpmdir $(CURDIR)/rpmbuild/RPMS" \
--define "_sourcedir $(CURDIR)/rpmbuild/SOURCES" \
--define "_specdir $(CURDIR)/rpmbuild/SPECS" \
--define "_builddir $(CURDIR)/rpmbuild/BUILD" \
--define "_buildrootdir $(CURDIR)/rpmbuild/BUILDROOT"
RPMFLAGS := \
--define "buildid $(BUILDID)"
rpm: tarball
mkdir -p rpmbuild
chmod ug-s rpmbuild
mkdir -p rpmbuild/{SPECS,SOURCES,BUILD,BUILDROOT,RPMS,SRPMS}
cp $(ZTARBALL) $(ZSRCBALL)
rpmbuild -ts $(ZSRCBALL) --define "_srcrpmdir rpmbuild/SRPMS" $(RPMFLAGS)
rpmbuild --rebuild $(SRPM) $(RPMBUILDDIRS) $(RPMFLAGS)
rpmlint: rpm
rpmlint $(SRPM) $(CURDIR)/rpmbuild/RPMS/*/kafs-client-{,debuginfo-}$(rpmver).*.rpm
.PHONY: rpmlint rpm tarball $(ZTARBALL)
###############################################################################
#
# Build debugging
#
###############################################################################
show_vars:
@echo VERSION=$(VERSION)
@echo TARBALL=$(TARBALL)
@echo BUILDFOR=$(BUILDFOR)
README 0000664 0000000 0000000 00000001363 13672703240 0011745 0 ustar 00root root 0000000 0000000 ===========
kAFS CLIENT
===========
Contents:
(*) Overview.
========
OVERVIEW
========
The kafs-client package provides the basics for using the kAFS filesystem in
the Linux kernel. It provides:
(*) The aklog-kafs program that can be used to authenticate with Kerberos so
that the kAFS filesystem can perform authenticated and encrypted
communications with an AFS fileserver.
(*) A dynamic mount on /afs so that the roots of arbitrary cells can be
mounted automatically, using the DNS to look up their details. This needs
to be enabled by:
systemctl enable afs.mount
and can then be accessed by referring to cell names in the /afs/
directory, for example:
ls /afs/grand.central.org/
SUBMITTING_PATCHES 0000664 0000000 0000000 00000003525 13672703240 0013646 0 ustar 00root root 0000000 0000000 ==================
SUBMITTING PATCHES
==================
Patches can be sent to the linux-afs@lists.infradead.org mailing list or
directly to David Howells , the author, in a private
email.
When sending patches to be included in kafs-utils, please certify that your
patch meets the criteria below by including include a sign-off line in your
email which looks like this:
Signed-off-by: Random J Developer
This confirms that you are permitted to submit the patch for inclusion in
kafs-utils under the GPLv2 licence. The full text of the certificate is as
follows:
Developer's Certificate of Origin v1.1
======================================
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source licences
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
licence and I have the right under that licence to submit that
work with modifications, whether created in whole or in part
by me, under the same open source licence (unless I am
permitted to submit under a different licence), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
and also that:
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source licence(s) involved.
conf/ 0000775 0000000 0000000 00000000000 13672703240 0012007 5 ustar 00root root 0000000 0000000 conf/afs.mount 0000664 0000000 0000000 00000000276 13672703240 0013651 0 ustar 00root root 0000000 0000000 [Unit]
Description=kAFS Dynamic Root mount
ConditionPathExists=/afs
Wants=kafs-config.service
[Mount]
What=none
Where=/afs
Type=afs
Options=_netdev,dyn
[Install]
WantedBy=remote-fs.target
conf/cellservdb.conf 0000664 0000000 0000000 00000131332 13672703240 0015006 0 ustar 00root root 0000000 0000000 # AuristorFS cellservdb client configuration
# 8 October 2017
#
# This file should be placed in the yfs-client.conf.d directory
# or beincluded within the yfs-client.conf file.
[cells]
# grand.central.org imported from DNS SRV
grand.central.org = {
description = "Grand Central Org"
use_dns = yes
kerberos_realm = GRAND.CENTRAL.ORG
servers = {
grand.mit.edu = {
address = 18.9.48.14
}
grand-old-opry.central.org = {
address = 128.2.13.219
}
}
}
# wu-wien.ac.at imported from DNS AFSDB
wu-wien.ac.at = {
description = "University of Economics, Vienna, Austria"
use_dns = yes
servers = {
heimdal.wu-wien.ac.at = {
address = 137.208.7.37
}
caravaggio.wu-wien.ac.at = {
address = 137.208.7.57
}
vermeer.wu-wien.ac.at = {
address = 137.208.8.14
}
goya.wu-wien.ac.at = {
address = 137.208.3.33
}
}
}
# hephy.at imported from DNS SRV
hephy.at = {
description = "hephy-vienna"
use_dns = yes
servers = {
afs01.hephy.oeaw.ac.at = {
address = 193.170.243.10
}
afs02.hephy.oeaw.ac.at = {
address = 193.170.243.12
}
afs03.hephy.oeaw.ac.at = {
address = 193.170.243.14
}
}
}
# cgv.tugraz.at imported from DNS SRV
cgv.tugraz.at = {
description = "CGV cell"
use_dns = yes
servers = {
phobos.cgv.tugraz.at = {
address = 129.27.218.30
}
deimos.cgv.tugraz.at = {
address = 129.27.218.31
}
trinculo.cgv.tugraz.at = {
address = 129.27.218.32
}
}
}
# itp.tugraz.at imported from GCO Public CellServDB 01 Jan 2016
itp.tugraz.at = {
description = "Institute of Theoretical and Computational Physics, TU Graz, Aus"
use_dns = yes
servers = {
faepafs1.tu-graz.ac.at = {
address = 129.27.161.7
}
faepafs2.tu-graz.ac.at = {
address = 129.27.161.15
}
faepafs3.tu-graz.ac.at = {
address = 129.27.161.114
}
}
}
# ualberta.ca imported from GCO Public CellServDB 01 Jan 2016
ualberta.ca = {
description = "University of Alberta"
use_dns = yes
servers = {
file13.ucs.ualberta.ca = {
address = 129.128.1.131
}
mystery.ucs.ualberta.ca = {
address = 129.128.98.17
}
drake.ucs.ualberta.ca = {
address = 129.128.125.40
}
}
}
# cern.ch imported from DNS AFSDB
cern.ch = {
description = "European Laboratory for Particle Physics, Geneva"
use_dns = yes
servers = {
afsdb1.cern.ch = {
address = 137.138.128.148
}
afsdb3.cern.ch = {
address = 137.138.246.50
}
afsdb2.cern.ch = {
address = 137.138.246.51
}
}
}
# psi.ch imported from DNS AFSDB
psi.ch = {
description = "Paul Scherrer Institut - Villigen, Switzerland"
use_dns = yes
servers = {
afs00.psi.ch = {
address = 129.129.190.140
}
afs01.psi.ch = {
address = 129.129.190.141
}
afs02.psi.ch = {
address = 129.129.190.142
}
}
}
# freedaemon.com imported from GCO Public CellServDB 01 Jan 2016
freedaemon.com = {
description = "Free Daemon Consulting, Oklahoma City, OK, USA"
use_dns = yes
servers = {
afs0.freedaemon.com = {
address = 66.210.104.254
}
afs1.freedaemon.com = {
address = 78.46.227.213
}
afs2.freedaemon.com = {
address = 208.79.89.92
}
}
}
# nilcons.com imported from DNS SRV
nilcons.com = {
description = "nilcons.com"
use_dns = yes
servers = {
files.nilcons.com = {
address = 5.9.14.177
}
}
}
# ics.muni.cz updated 8 Oct 2017 via udebug
ics.muni.cz = {
description = "Masaryk university, Czech Republic"
use_dns = yes
servers = {
afs-plzen.meta.zcu.cz = {
address = 147.228.240.30
}
smaug2.ics.muni.cz = {
address = 147.251.9.9
}
tarkil-xen.cesnet.cz = {
address = 195.113.214.4
}
}
}
# zcu.cz imported from AFSDB
zcu.cz = {
description = "University of West Bohemia, Czech Republic"
use_dns = yes
servers = {
sauron.zcu.cz = {
address = 147.228.10.18
}
oknos.zcu.cz = {
address = 147.228.52.10
}
nic.zcu.cz = {
address = 147.228.52.17
}
}
}
# desy.de imported from AFSDB
desy.de = {
description = "Deutsches Elektronen-Synchrotron"
use_dns = yes
servers = {
afsdb2.desy.de = {
address = 131.169.2.19
}
afsdb3.desy.de = {
address = 131.169.2.20
}
solar00.desy.de = {
address = 131.169.244.60
}
afsdb5.desy.de = {
address = 131.169.2.42
}
}
}
# naf.desy.de imported from GCO Public CellServDB 01 Jan 2016
naf.desy.de = {
description = "National Analysis Facility at DESY"
use_dns = yes
servers = {
tcsh1-vm1.naf.desy.de = {
address = 141.34.220.32
}
tcsh2-vm1.naf.desy.de = {
address = 141.34.230.33
}
tcsh3-vm1.naf.desy.de = {
address = 141.34.230.34
}
}
}
# gppc.de update 8 Oct 2017 via udebug
gppc.de = {
description = "GPP Chemnitz mbH"
use_dns = yes
servers = {
gpp1.gppc.de = {
address = 213.187.92.33
}
tyr.gppc.de = {
address = 213.187.92.39
}
rhea.gppc.de = {
address = 213.187.92.36
}
}
}
# cms.hu-berlin.de imported from GCO Public CellServDB 01 Jan 2016
cms.hu-berlin.de = {
description = "Humboldt University Berlin"
use_dns = yes
servers = {
commodus.cms.hu-berlin.de = {
address = 141.20.1.65
}
faustinus.cms.hu-berlin.de = {
address = 141.20.1.66
}
marcellus.cms.hu-berlin.de = {
address = 141.20.1.67
}
}
}
# ifh.de imported from AFSDB
ifh.de = {
description = "DESY Zeuthen"
use_dns = yes
servers = {
romulus.ifh.de = {
address = 141.34.22.10
}
remus.ifh.de = {
address = 141.34.22.11
}
hekate.ifh.de = {
address = 141.34.22.29
}
}
}
# integra-ev.de update 8 Oct 2017 via udebug
integra-ev.de = {
description = "INTEGRA e.V."
use_dns = yes
servers = {
afsdb2.integra-ev.de = {
address = 134.155.48.14
}
afsdb1.integra-ev.de = {
address = 134.155.48.8
}
}
}
# ipp-garching.mpg.de imported from DNS SRV
ipp-garching.mpg.de = {
description = "Institut fuer Plasmaphysik"
use_dns = yes
servers = {
afs-db1.rzg.mpg.de = {
address = 130.183.9.5
}
afs-db3.bc.rzg.mpg.de = {
address = 130.183.14.14
}
afs-db2.aug.ipp-garching.mpg.de = {
address = 130.183.100.10
}
}
}
# mpe.mpg.de imported from GCO Public CellServDB 01 Jan 2016
mpe.mpg.de = {
description = "MPE cell"
use_dns = yes
servers = {
irafs1.mpe-garching.mpg.de = {
address = 130.183.130.7
}
irafs2.mpe-garching.mpg.de = {
address = 130.183.134.20
}
}
}
# nicsys.de imported from GCO Public CellServDB 01 Jan 2016
nicsys.de = {
description = "NICsys GbR"
use_dns = yes
servers = {
attila.nicsys.de = {
address = 213.187.80.3
}
}
}
# tu-berlin.de imported from DNS SRV
tu-berlin.de = {
description = "TU Berlin"
use_dns = yes
servers = {
afsc-pr-1.tubit.tu-berlin.de = {
address = 130.149.204.10
}
afsc-pr-2.tubit.tu-berlin.de = {
address = 130.149.204.11
}
afsc-ba-1.tubit.tu-berlin.de = {
address = 130.149.204.70
}
}
}
# tu-chemnitz.de imported from DNS SRV
tu-chemnitz.de = {
description = "Technische Universitaet Chemnitz, Germany"
use_dns = yes
servers = {
zuse.hrz.tu-chemnitz.de = {
address = 134.109.2.1
}
andrew.hrz.tu-chemnitz.de = {
address = 134.109.2.2
}
phoenix.hrz.tu-chemnitz.de = {
address = 134.109.2.15
}
}
}
# physik.uni-bonn.de imported from DNS SRV
physik.uni-bonn.de = {
description = "Institute of Physics, University of Bonn, Germany"
use_dns = yes
servers = {
afsdb1.physik.uni-bonn.de = {
address = 131.220.166.33
}
afsdb2.physik.uni-bonn.de = {
address = 131.220.166.34
}
afsdb3.physik.uni-bonn.de = {
address = 131.220.166.35
}
}
}
# atlass01.physik.uni-bonn.de imported from GCO Public CellServDB 01 Jan 2016
atlass01.physik.uni-bonn.de = {
description = "Bonn ATLAS"
use_dns = yes
servers = {
atlass01.physik.uni-bonn.de = {
address = 131.220.165.43
}
}
}
# uni-freiburg.de imported from AFSDB
uni-freiburg.de = {
description = "Albert-Ludwigs-Universitat Freiburg"
use_dns = yes
servers = {
sv8.ruf.uni-freiburg.de = {
address = 132.230.6.237
}
sv7.ruf.uni-freiburg.de = {
address = 132.230.6.236
}
}
}
# physik.uni-freiburg.de updated 8 Oct 2017 via udebug
physik.uni-freiburg.de = {
description = "Institute of Physics, University Freiburg, Germany"
use_dns = yes
servers = {
sherlock.physik.uni-freiburg.de = {
address = 132.230.77.12
}
}
}
# math.uni-hamburg.de imported from AFSDB
math.uni-hamburg.de = {
description = "Department of Mathematics Uni Hamburg"
use_dns = yes
servers = {
afs-core.math.uni-hamburg.de = {
address = 134.100.223.3
}
afs-core2.math.uni-hamburg.de = {
address = 134.100.223.6
}
afs-core3.math.uni-hamburg.de = {
address = 134.100.223.9
}
}
}
# physnet.uni-hamburg.de imported from AFSDB
physnet.uni-hamburg.de = {
description = "PHYSnet-Rechenzentrum university of hamburg"
use_dns = yes
servers = {
afs-core.physnet.uni-hamburg.de = {
address = 134.100.106.44
}
afs-core2.physnet.uni-hamburg.de = {
address = 134.100.106.45
}
afs-core3.physnet.uni-hamburg.de = {
address = 134.100.106.47
}
}
}
# iqo.uni-hannover.de imported from AFSDB
iqo.uni-hannover.de = {
description = "Institut fuer Quantenoptik Hannover"
use_dns = yes
servers = {
afs1.iqo.uni-hannover.de = {
address = 130.75.103.221
}
afs2.iqo.uni-hannover.de = {
address = 130.75.103.223
}
}
}
# mathi.uni-heidelberg.de imported from AFDDB
mathi.uni-heidelberg.de = {
description = "Uni Heidelberg (Mathematisches Institut)"
use_dns = yes
servers = {
hactar.mathi.uni-heidelberg.de = {
address = 129.206.26.241
}
}
}
# urz.uni-heidelberg.de imported from GCO Public CellServDB 01 Jan 2016
urz.uni-heidelberg.de = {
description = "Uni Heidelberg (Rechenzentrum)"
use_dns = yes
servers = {
afsdb.urz.uni-heidelberg.de = {
address = 129.206.119.10
}
afsdb1.urz.uni-heidelberg.de = {
address = 129.206.119.16
}
afsdb2.urz.uni-heidelberg.de = {
address = 129.206.119.17
}
}
}
# uni-hohenheim.de imported from AFSDB
uni-hohenheim.de = {
description = "University of Hohenheim"
use_dns = yes
servers = {
rs13.serv.uni-hohenheim.de = {
address = 144.41.2.2
}
rs14.serv.uni-hohenheim.de = {
address = 144.41.2.3
}
rs15.serv.uni-hohenheim.de = {
address = 144.41.2.4
}
}
}
# rz.uni-jena.de imported from SRV
rz.uni-jena.de = {
description = "Rechenzentrum University of Jena, Germany"
use_dns = yes
servers = {
afs00.rz.uni-jena.de = {
address = 141.35.2.180
}
afs01.rz.uni-jena.de = {
address = 141.35.2.181
}
afs02.rz.uni-jena.de = {
address = 141.35.2.182
}
}
}
# rrz.uni-koeln.de imported from SRV
rrz.uni-koeln.de = {
description = "University of Cologne - Reg Comp Center"
use_dns = yes
servers = {
afsdb1.rrz.uni-koeln.de = {
address = 134.95.19.3
}
afsdb2.rrz.uni-koeln.de = {
address = 134.95.19.4
}
lyra.rrz.uni-koeln.de = {
address = 134.95.19.10
}
afs.thp.uni-koeln.de = {
address = 134.95.67.97
}
ladon.rrz.uni-koeln.de = {
address = 134.95.112.8
}
}
}
# mathematik.uni-stuttgart.de updated 8 Oct 2017 via udebug
mathematik.uni-stuttgart.de = {
description = "University of Stuttgart, Math Dept."
use_dns = yes
servers = {
fbm01.mathematik.uni-stuttgart.de = {
address = 129.69.61.1
}
fbm02.mathematik.uni-stuttgart.de = {
address = 129.69.61.2
}
fbm03.mathematik.uni-stuttgart.de = {
address = 129.69.61.3
}
}
}
# stud.mathematik.uni-stuttgart.de updated 8 Oct 2017 via udebug
stud.mathematik.uni-stuttgart.de = {
description = "CIP-Pool of Math. Dept, University of Stuttgart"
use_dns = yes
servers = {
omni.mathematik.uni-stuttgart.de = {
address = 129.69.61.28
}
stud00.mathematik.uni-stuttgart.de = {
address = 129.69.116.200
}
stud01.mathematik.uni-stuttgart.de = {
address = 129.69.116.201
}
stud02.mathematik.uni-stuttgart.de = {
address = 129.69.116.202
}
stud03.mathematik.uni-stuttgart.de = {
address = 129.69.116.203
}
stud60.mathematik.uni-stuttgart.de = {
address = 129.69.116.210
}
}
}
# s-et.aau.dk imported from GCO Public CellServDB 01 Jan 2016
s-et.aau.dk = {
description = "Aalborg Univ., The Student Society, Denmark"
use_dns = yes
servers = {
afs.s-et.aau.dk = {
address = 130.225.196.22
}
}
}
# ies.auc.dk imported from SRV
ies.auc.dk = {
description = "Aalborg Univ., Inst. of Electronic Systems, Denmark"
use_dns = yes
servers = {
afsdb1.kom.auc.dk = {
address = 130.225.51.73
}
afsdb2.kom.auc.dk = {
address = 130.225.51.74
}
afsdb3.kom.auc.dk = {
address = 130.225.51.85
}
}
}
# asu.edu imported from SRV
asu.edu = {
description = "Arizona State University"
use_dns = yes
servers = {
authen2.asu.edu = {
address = 129.219.10.69
}
authen1.asu.edu = {
address = 129.219.10.70
}
authen3.asu.edu = {
address = 129.219.10.72
}
authen4.asu.edu = {
address = 129.219.110.104
}
}
}
# andrew.cmu.edu imported from SRV
andrew.cmu.edu = {
description = "Carnegie Mellon University - Computing Services Cell"
use_dns = yes
servers = {
afsdb-02.andrew.cmu.edu = {
address = 128.2.10.7
}
afsdb-03.andrew.cmu.edu = {
address = 128.2.10.11
}
}
}
# club.cc.cmu.edu imported from AFSDB
club.cc.cmu.edu = {
description = "Carnegie Mellon University Computer Club"
use_dns = yes
servers = {
barium.club.cc.cmu.edu = {
address = 128.2.204.149
}
sodium.club.cc.cmu.edu = {
address = 128.237.157.11
}
potassium.club.cc.cmu.edu = {
address = 128.237.157.13
}
}
}
# cs.cmu.edu imported from AFSDB
cs.cmu.edu = {
description = "Carnegie Mellon University - School of Comp. Sci."
use_dns = yes
servers = {
date.srv.cs.cmu.edu = {
address = 128.2.172.58
}
fig.srv.cs.cmu.edu = {
address = 128.2.172.60
}
watermelon.srv.cs.cmu.edu = {
address = 128.2.200.97
}
}
}
# ece.cmu.edu imported from AFSDB
ece.cmu.edu = {
description = "Carnegie Mellon University - Elec. Comp. Eng. Dept."
use_dns = yes
servers = {
porok.ece.cmu.edu = {
address = 128.2.129.7
}
vicio.ece.cmu.edu = {
address = 128.2.129.8
}
e-xing.ece.cmu.edu = {
address = 128.2.129.9
}
}
}
# qatar.cmu.edu imported from AFSDB
qatar.cmu.edu = {
description = "Carnegie Mellon University - Qatar"
use_dns = yes
servers = {
afs1.qatar.cmu.edu = {
address = 86.36.46.6
}
afs2.qatar.cmu.edu = {
address = 86.36.46.7
}
afsdb-03.qatar.cmu.edu = {
address = 86.36.46.9
}
}
}
# cnf.cornell.edu imported from AFDSB
cnf.cornell.edu = {
description = "CNF"
use_dns = yes
kerberos_realm = CIT.CORNELL.EDU
servers = {
hole.cnf.cornell.edu = {
address = 128.253.198.9
}
smoke.cnf.cornell.edu = {
address = 128.253.198.27
}
mist.cnf.cornell.edu = {
address = 128.253.198.231
}
}
}
# math.cornell.edu imported from GCO Public CellServDB 01 Jan 2016
math.cornell.edu = {
description = "Cornell Math Dept"
use_dns = yes
servers = {
pooh.math.cornell.edu = {
address = 128.84.234.12
}
bernoulli.math.cornell.edu = {
address = 128.84.234.16
}
dyno.math.cornell.edu = {
address = 128.84.234.162
}
}
}
# msc.cornell.edu imported from AFSDB
msc.cornell.edu = {
description = "Cornell University Materials Science Center"
use_dns = yes
servers = {
miranda.ccmr.cornell.edu = {
address = 128.84.231.242
}
co.ccmr.cornell.edu = {
address = 128.84.241.35
}
dax.ccmr.cornell.edu = {
address = 128.84.249.78
}
}
}
# dbic.dartmouth.edu imported from SRV
dbic.dartmouth.edu = {
description = "Dartmouth Brain Imaging Center"
use_dns = yes
servers = {
dbicafs1.dartmouth.edu = {
address = 129.170.30.143
}
dbicafs2.dartmouth.edu = {
address = 129.170.30.144
}
dbicafs3.dartmouth.edu = {
address = 129.170.30.145
}
}
}
# northstar.dartmouth.edu imported SRV
northstar.dartmouth.edu = {
description = "Dartmouth College Research Computing"
use_dns = yes
servers = {
halley.dartmouth.edu = {
address = 129.170.16.22
}
andromeda.dartmouth.edu = {
address = 129.170.16.26
}
cygnusx1.dartmouth.edu = {
address = 129.170.16.43
}
kuiper.dartmouth.edu = {
address = 129.170.199.250
}
}
}
# cs.hm.edu imported from GCO Public CellServDB 01 Jan 2016
cs.hm.edu = {
description = "Department Computer Science Munich University Of Applied Science"
use_dns = yes
servers = {
afs1.cs.hm.edu = {
address = 129.187.208.31
}
}
}
# iastate.edu imported from GCO Public CellServDB 01 Jan 2016
iastate.edu = {
description = "Iowa State University"
use_dns = yes
servers = {
afsdb-1.iastate.edu = {
address = 129.186.1.243
}
afsdb-2.iastate.edu = {
address = 129.186.6.243
}
afsdb-3.iastate.edu = {
address = 129.186.142.243
}
}
}
# athena.mit.edu imported from AFSDB
athena.mit.edu = {
description = "MIT/Athena cell"
use_dns = yes
kerberos_realm = ATHENA.MIT.EDU
servers = {
leda.mit.edu = {
address = 18.7.45.11
}
castor.mit.edu = {
address = 18.9.48.11
}
pollux.mit.edu = {
address = 18.9.48.12
}
}
}
# csail.mit.edu imported from AFSDB
csail.mit.edu = {
description = "MIT Computer Science & Artificial Intelligence Lab"
use_dns = yes
servers = {
titanic.csail.mit.edu = {
address = 128.30.2.13
}
vasa.csail.mit.edu = {
address = 128.30.2.31
}
maine.csail.mit.edu = {
address = 128.30.2.75
}
}
}
# lns.mit.edu imported from AFSDB
lns.mit.edu = {
description = "MIT/LNS Cell"
use_dns = yes
servers = {
afs2.lns.mit.edu. = {
address = 198.125.160.134
}
afsdbserv1.lns.mit.edu. = {
address = 198.125.160.217
}
afsdbserv2.lns.mit.edu. = {
address = 198.125.160.218
}
}
}
# net.mit.edu imported from AFSDB
net.mit.edu = {
description = "MIT/Network Group cell"
use_dns = yes
kerberos_realm = ATHENA.MIT.EDU
servers = {
willy.mit.edu = {
address = 18.7.62.60
}
moby.mit.edu = {
address = 18.9.48.15
}
springer.mit.edu = {
address = 18.9.48.16
}
}
}
# ops.mit.edu imported from AFSDB
ops.mit.edu = {
description = "MIT/Operations Group cell"
use_dns = yes
kerberos_realm = ATHENA.MIT.EDU
servers = {
despair.mit.edu = {
address = 18.9.68.42
}
heartbreak.mit.edu = {
address = 18.9.68.41
}
bitterness.mit.edu = {
address = 18.9.68.31
}
}
}
# sipb.mit.edu imported from AFSDB
sipb.mit.edu = {
description = "MIT/SIPB cell"
use_dns = yes
kerberos_realm = ATHENA.MIT.EDU
servers = {
reynelda.mit.edu = {
address = 18.181.0.19
}
rosebud2.mit.edu = {
address = 18.181.0.22
}
ronald-ann.mit.edu = {
address = 18.181.0.23
}
}
}
# zone.mit.edu imported from AFSDB
zone.mit.edu = {
description = "MIT/ZONE cell"
use_dns = yes
kerberos_realm = ATHENA.MIT.EDU
servers = {
casio.mit.edu = {
address = 18.1.41.29
}
timex.mit.edu = {
address = 18.1.41.30
}
seiko.mit.edu = {
address = 18.1.41.31
}
}
}
# msu.edu imported from GCO Public CellServDB 01 Jan 2016
msu.edu = {
description = "Michigan State University Main Cell"
use_dns = yes
servers = {
afsdb0.cl.msu.edu = {
address = 35.9.7.10
}
}
}
# crc.nd.edu imported from GCO Public CellServDB 01 Jan 2016
crc.nd.edu = {
description = "University of Notre Dame - Center for Research Computing"
use_dns = yes
servers = {
afsdb1.crc.nd.edu = {
address = 129.74.85.34
}
afsdb2.crc.nd.edu = {
address = 129.74.85.35
}
afsdb3.crc.nd.edu = {
address = 129.74.85.36
}
}
}
# pitt.edu update 8 Oct 2017 via udebug
pitt.edu = {
description = "University of Pittsburgh"
use_dns = yes
servers = {
afs-db-01.cssd.pitt.edu = {
address = 136.142.8.15
}
afs-db-02.cssd.pitt.edu = {
address = 136.142.8.20
}
afs-db-03.cssd.pitt.edu = {
address = 136.142.8.21
}
}
}
# cs.pitt.edu imported from SRV
cs.pitt.edu = {
description = "University of Pittsburgh - Computer Science"
use_dns = yes
servers = {
afs01.cs.pitt.edu = {
address = 136.142.22.5
}
afs02.cs.pitt.edu = {
address = 136.142.22.6
}
afs03.cs.pitt.edu = {
address = 136.142.22.7
}
}
}
# psc.edu imported from SRV
psc.edu = {
description = "PSC (Pittsburgh Supercomputing Center)"
use_dns = yes
servers = {
shaggy.psc.edu = {
address = 128.182.59.182
}
velma.psc.edu = {
address = 128.182.66.184
}
daphne.psc.edu = {
address = 128.182.66.185
}
}
}
# rose-hulman.edu imported from GCO Public CellServDB 01 Jan 2016
rose-hulman.edu = {
description = "Rose-Hulman Institute of Technology"
use_dns = yes
servers = {
afs1.rose-hulman.edu = {
address = 137.112.7.11
}
afs2.rose-hulman.edu = {
address = 137.112.7.12
}
afs3.rose-hulman.edu = {
address = 137.112.7.13
}
}
}
# rpi.edu imported from AFSDB
rpi.edu = {
description = "Rensselaer Polytechnic Institute"
use_dns = yes
servers = {
saul.server.rpi.edu = {
address = 128.113.22.11
}
joab.server.rpi.edu = {
address = 128.113.22.12
}
korah.server.rpi.edu = {
address = 128.113.22.13
}
achan.server.rpi.edu = {
address = 128.113.22.14
}
}
}
# cs.stanford.edu imported from AFSDB
cs.stanford.edu = {
description = "Stanford University Computer Science Department"
use_dns = yes
servers = {
cs-afs-1.Stanford.EDU = {
address = 171.64.64.10
}
cs-afs-2.stanford.edu = {
address = 171.64.64.66
}
cs-afs-3.stanford.edu = {
address = 171.64.64.69
}
}
}
# ir.stanford.edu imported from SRV
ir.stanford.edu = {
description = "Stanford University"
use_dns = yes
servers = {
afsdb1.stanford.edu = {
address = 171.64.7.222
}
afsdb2.stanford.edu = {
address = 171.64.7.234
}
afsdb3.stanford.edu = {
address = 171.64.7.246
}
}
}
# slac.stanford.edu imported from AFSDB
slac.stanford.edu = {
description = "Stanford Linear Accelerator Center"
use_dns = yes
servers = {
afsdb1.slac.stanford.edu = {
address = 134.79.18.25
}
afsdb2.slac.stanford.edu = {
address = 134.79.18.26
}
afsdb3.slac.stanford.edu = {
address = 134.79.18.27
}
}
}
# cats.ucsc.edu imported from SRV
cats.ucsc.edu = {
description = "University of California, Santa Cruz"
use_dns = yes
servers = {
afs-prod-front-1.ucsc.edu = {
address = 128.114.123.8
}
afs-prod-front-2.ucsc.edu = {
address = 128.114.123.9
}
afs-prod-front-3.ucsc.edu = {
address = 128.114.123.10
}
}
}
# ncsa.uiuc.edu imported from SRV
ncsa.uiuc.edu = {
description = "National Center for Supercomputing Applications at Illinois"
use_dns = yes
servers = {
nile-vm.ncsa.uiuc.edu = {
address = 141.142.192.66
}
congo-vm.ncsa.uiuc.edu = {
address = 141.142.192.143
}
kaskaskia-vm.ncsa.uiuc.edu = {
address = 141.142.192.144
}
}
}
# umbc.edu imported from AFSDB
umbc.edu = {
description = "University of Maryland, Baltimore County"
use_dns = yes
servers = {
db2.afs.umbc.edu = {
address = 130.85.24.23
}
db3.afs.umbc.edu = {
address = 130.85.24.87
}
db1.afs.umbc.edu = {
address = 130.85.24.101
}
}
}
# glue.umd.edu imported from AFSDB
glue.umd.edu = {
description = "University of Maryland - Project Glue"
use_dns = yes
servers = {
olmec.umd.edu = {
address = 128.8.70.11
}
egypt.umd.edu = {
address = 128.8.236.4
}
babylon.umd.edu = {
address = 128.8.236.230
}
}
}
# wam.umd.edu imported from AFSDB
wam.umd.edu = {
description = "University of Maryland Network WAM Project"
use_dns = yes
servers = {
csc-srv.wam.umd.edu = {
address = 128.8.70.9
}
avw-srv.wam.umd.edu = {
address = 128.8.236.5
}
ptx-srv.wam.umd.edu = {
address = 128.8.236.231
}
}
}
# umich.edu imported from AFSDB
umich.edu = {
description = "University of Michigan - Campus"
use_dns = yes
servers = {
fear.ifs.umich.edu = {
address = 141.211.1.32
}
surprise.ifs.umich.edu = {
address = 141.211.1.33
}
ruthless.ifs.umich.edu = {
address = 141.211.1.34
}
}
}
# atlas.umich.edu imported from GCO Public CellServDB 01 Jan 2016
atlas.umich.edu = {
description = "ATLAS group cell in physics at University of Michigan"
use_dns = yes
servers = {
linat02.grid.umich.edu = {
address = 141.211.43.102
}
linat03.grid.umich.edu = {
address = 141.211.43.103
}
linat04.grid.umich.edu = {
address = 141.211.43.104
}
}
}
# citi.umich.edu imported from AFSDB
citi.umich.edu = {
description = "University of Michigan - Center for Information Technology Integ"
use_dns = yes
servers = {
babylon.citi.umich.edu = {
address = 141.212.112.5
}
}
}
# cs.uwm.edu imported from GCO Public CellServDB 01 Jan 2016
cs.uwm.edu = {
description = "University of Wisconsin--Milwaukee"
use_dns = yes
servers = {
solomons.cs.uwm.edu = {
address = 129.89.38.124
}
filip.cs.uwm.edu = {
address = 129.89.143.71
}
}
}
# cs.wisc.edu imported from SRV
cs.wisc.edu = {
description = "Univ. of Wisconsin-Madison, Computer Sciences Dept."
use_dns = yes
servers = {
vldba.cs.wisc.edu = {
address = 128.105.9.18
}
vldbb.cs.wisc.edu = {
address = 128.105.9.19
}
vldbc.cs.wisc.edu = {
address = 128.105.9.20
}
timon.cs.wisc.edu = {
address = 128.105.132.14
}
pumbaa.cs.wisc.edu = {
address = 128.105.132.15
}
zazu.cs.wisc.edu = {
address = 128.105.132.16
}
}
}
# hep.wisc.edu imported from AFSDB
hep.wisc.edu = {
description = "University of Wisconsin -- High Energy Physics"
use_dns = yes
servers = {
anise.hep.wisc.edu = {
address = 128.104.28.219
}
rosemary.hep.wisc.edu = {
address = 144.92.180.7
}
fennel.hep.wisc.edu = {
address = 144.92.180.30
}
}
}
# physics.wisc.edu imported from AFSDB
physics.wisc.edu = {
description = "Univ. of Wisconsin-Madison, Physics Department"
use_dns = yes
servers = {
kendra.physics.wisc.edu = {
address = 128.104.160.13
}
fray.physics.wisc.edu = {
address = 128.104.160.14
}
buffy.physics.wisc.edu = {
address = 128.104.160.15
}
}
}
# ciemat.es updated 8 Oct 2017 via udebug
ciemat.es = {
description = "Ciemat, Madrid, Spain"
use_dns = yes
servers = {
afsdb1.ciemat.es = {
address = 192.101.165.10
}
afsdb2.ciemat.es = {
address = 192.101.165.11
}
}
}
# ific.uv.es imported from GCO Public CellServDB 01 Jan 2016
ific.uv.es = {
description = "Instituto de Fisica Corpuscular, Valencia, Spain"
use_dns = yes
servers = {
alpha.ific.uv.es = {
address = 147.156.163.11
}
}
}
# alteholz.eu imported from GCO Public CellServDB 01 Jan 2016
alteholz.eu = {
description = "alteholz.eu"
use_dns = yes
servers = {
krb1eu.afs.alteholz.net = {
address = 78.47.192.125
}
}
}
# in2p3.fr imported from GCO Public CellServDB 01 Jan 2016
in2p3.fr = {
description = "IN2P3"
use_dns = yes
servers = {
ccafsdb01.in2p3.fr = {
address = 134.158.104.11
}
ccafsdb02.in2p3.fr = {
address = 134.158.104.12
}
ccafsdb03.in2p3.fr = {
address = 134.158.104.13
}
}
}
# mcc.ac.gb imported from GCO Public CellServDB 01 Jan 2016
mcc.ac.gb = {
description = "University of Manchester"
use_dns = yes
servers = {
nevis.mc.man.ac.uk = {
address = 130.88.203.41
}
eryri.mc.man.ac.uk = {
address = 130.88.203.144
}
scafell.mc.man.ac.uk = {
address = 130.88.203.145
}
}
}
# rhic.bnl.gov imported from GCO Public CellServDB 01 Jan 2016
rhic.bnl.gov = {
description = "Relativistic Heavy Ion Collider"
use_dns = yes
servers = {
rafs03.rcf.bnl.gov = {
address = 130.199.6.51
}
rafs02.rcf.bnl.gov = {
address = 130.199.6.52
}
rafs01.rcf.bnl.gov = {
address = 130.199.6.69
}
}
}
# usatlas.bnl.gov imported from AFSDB
usatlas.bnl.gov = {
description = "US Atlas Tier 1 Facility at BNL"
use_dns = yes
servers = {
aafs01.usatlas.bnl.gov = {
address = 130.199.48.32
}
aafs02.usatlas.bnl.gov = {
address = 130.199.48.33
}
aafs03.usatlas.bnl.gov = {
address = 130.199.48.34
}
}
}
# jpl.nasa.gov imported from AFSDB
jpl.nasa.gov = {
description = "Jet Propulsion Laboratory"
use_dns = yes
servers = {
afsdb08.jpl.nasa.gov = {
address = 137.78.160.21
}
afsdb09.jpl.nasa.gov = {
address = 137.78.160.22
}
afsdb10.jpl.nasa.gov = {
address = 137.78.160.23
}
}
}
# bme.hu imported from AFSDB
bme.hu = {
description = "Budapest University of Technology and Economics"
use_dns = yes
servers = {
zero.eik.bme.hu = {
address = 152.66.115.2
}
}
}
# kfki.hu imported from AFSDB
kfki.hu = {
description = "Wigner Research Centre for Physics - Budapest, Hungary"
use_dns = yes
servers = {
afs0.kfki.hu = {
address = 148.6.2.109
}
}
}
# rnd.ru.is imported from AFSDB
rnd.ru.is = {
description = "Reykjavik University Research and Development Network"
use_dns = yes
servers = {
lithium.rnd.ru.is. = {
address = 130.208.242.66
}
beryllium.rnd.ru.is. = {
address = 130.208.242.67
}
boron.rnd.ru.is. = {
address = 130.208.242.68
}
}
}
# enea.it updated 8 Oct 2017 via udebug
enea.it = {
description = "ENEA New Tech. Energy & Environment Agency, Italy"
use_dns = yes
servers = {
aixfs.frascati.enea.it = {
address = 192.107.54.5
}
rs2ced.frascati.enea.it = {
address = 192.107.54.11
}
43p.frascati.enea.it = {
address = 192.107.54.12
}
afsdb.portici.enea.it = {
address = 192.107.70.49
}
afsdb1.portici.enea.it = {
address = 192.107.70.51
}
serverinfo02.bologna.enea.it = {
address = 192.107.61.235
}
glauco.casaccia.enea.it = {
address = 192.107.71.6
}
riscdb.trisaia.enea.it = {
address = 192.107.96.233
}
}
}
# fusione.it imported from GCO Public CellServDB 01 Jan 2016
fusione.it = {
description = "Assoz. FUSIONE/Euratom, ENEA, Frascati-Italy"
use_dns = yes
servers = {
fusafs1.frascati.enea.it = {
address = 192.107.90.2
}
fusafs2.frascati.enea.it = {
address = 192.107.90.3
}
fusafs3.frascati.enea.it = {
address = 192.107.90.4
}
}
}
# ictp.it updated 8 Oct 2017 via udebug; AFSDB records are wrong
ictp.it = {
description = "The Abdus Salam International Centre for Theoretical Physics (IC"
use_dns = no
servers = {
afsdb1.ictp.it = {
address = 140.105.34.7
}
afsdb2.ictp.it = {
address = 140.105.34.8
}
afsdb3.ictp.it = {
address = 140.105.34.205
}
}
}
# infn.it imported from GCO Public CellServDB 01 Jan 2016
infn.it = {
description = "Istituto Nazionale di Fisica Nucleare (INFN), Italia"
use_dns = yes
servers = {
afscnaf.infn.it = {
address = 131.154.1.7
}
afsrm1.roma1.infn.it = {
address = 141.108.26.75
}
afsna.na.infn.it = {
address = 192.84.134.75
}
}
}
# ba.infn.it imported from GCO Public CellServDB 01 Jan 2016
ba.infn.it = {
description = "INFN, Sezione di Bari"
use_dns = yes
servers = {
baafsserver.ba.infn.it = {
address = 193.206.185.235
}
debsrv.ba.infn.it = {
address = 193.206.185.236
}
}
}
# kloe.infn.it imported from GCO Public CellServDB 01 Jan 2016
kloe.infn.it = {
description = "INFN, KLOE experiment at Laboratori di Frascati"
use_dns = yes
servers = {
kloeafs1.lnf.infn.it = {
address = 192.135.25.111
}
kloeafs2.lnf.infn.it = {
address = 192.135.25.112
}
}
}
# le.infn.it imported from GCO Public CellServDB 01 Jan 2016
le.infn.it = {
description = "INFN, Sezione di Lecce"
use_dns = yes
servers = {
afs01.le.infn.it = {
address = 192.84.152.40
}
afs02.le.infn.it = {
address = 192.84.152.148
}
}
}
# lnf.infn.it imported from AFSDB
lnf.infn.it = {
description = "INFN, Laboratori Nazionali di Frascati"
use_dns = yes
servers = {
afs1.lnf.infn.it = {
address = 193.206.84.121
}
afs2.lnf.infn.it = {
address = 193.206.84.122
}
afs3.lnf.infn.it = {
address = 193.206.84.123
}
}
}
# lngs.infn.it imported from GCO Public CellServDB 01 Jan 2016
lngs.infn.it = {
description = "INFN, Laboratori Nazionali del Gran Sasso"
use_dns = yes
servers = {
afs1.lngs.infn.it = {
address = 192.84.135.21
}
afs2.lngs.infn.it = {
address = 192.84.135.133
}
}
}
# pi.infn.it imported from AFSDB
pi.infn.it = {
description = "INFN, Sezione di Pisa"
use_dns = yes
servers = {
aix1.pi.infn.it = {
address = 192.84.133.50
}
afs1.pi.infn.it = {
address = 212.189.152.6
}
afs2.pi.infn.it = {
address = 212.189.152.7
}
}
}
# roma3.infn.it imported from GCO Public CellServDB 01 Jan 2016
roma3.infn.it = {
description = "Istituto Nazionale di Fisica Nucleare (INFN), Italia"
use_dns = yes
servers = {
afsrm3.roma3.infn.it = {
address = 193.205.159.17
}
}
}
# psm.it imported from GCO Public CellServDB 01 Jan 2016
psm.it = {
description = "Progetto San Marco, Universita' di Roma-1"
use_dns = yes
servers = {
atlante.psm.uniroma1.it = {
address = 151.100.1.65
}
}
}
# math.unifi.it imported from GCO Public CellServDB 01 Jan 2016
math.unifi.it = {
description = "math.unifi.it"
use_dns = yes
servers = {
xeno.math.unifi.it = {
address = 150.217.34.182
}
}
}
# dia.uniroma3.it imported from AFSDB
dia.uniroma3.it = {
description = "University Roma Tre - DIA"
use_dns = yes
servers = {
srv.dia.uniroma3.it = {
address = 193.204.161.67
}
aux.dia.uniroma3.it = {
address = 193.204.161.79
}
afs.dia.uniroma3.it = {
address = 193.204.161.118
}
}
}
# vn.uniroma3.it imported from GCO Public CellServDB 01 Jan 2016
vn.uniroma3.it = {
description = "University Roma Tre, area Vasca Navale"
use_dns = yes
servers = {
alfa2.dia.uniroma3.it = {
address = 193.205.219.59
}
beta2.dia.uniroma3.it = {
address = 193.205.219.60
}
gamma2.dia.uniroma3.it = {
address = 193.205.219.61
}
}
}
# ictp.trieste.it imported from AFSDB
ictp.trieste.it = {
description = "Abdus Salam International Centre for Theoretical Physics"
use_dns = yes
servers = {
fs2.ictp.trieste.it = {
address = 140.105.16.9
}
}
}
# cmf.nrl.navy.mil imported from AFSDB
cmf.nrl.navy.mil = {
description = "Naval Research Laboratory - Center for Computational Science"
use_dns = yes
servers = {
picard.cmf.nrl.navy.mil = {
address = 134.207.12.68
}
riker.cmf.nrl.navy.mil = {
address = 134.207.12.69
}
kirk.cmf.nrl.navy.mil = {
address = 134.207.12.70
}
}
}
# lcp.nrl.navy.mil imported from GCO Public CellServDB 01 Jan 2016
lcp.nrl.navy.mil = {
description = "Naval Research Lab - Lab for Computational Physics"
use_dns = yes
servers = {
afs1.lcp.nrl.navy.mil = {
address = 132.250.114.2
}
afs2.lcp.nrl.navy.mil = {
address = 132.250.114.4
}
afs3.lcp.nrl.navy.mil = {
address = 132.250.114.6
}
}
}
# crossproduct.net imported from SRV
crossproduct.net = {
description = "crossproduct.net"
use_dns = yes
servers = {
prism.crossproduct.net = {
address = 136.248.125.67
}
}
}
# epitech.net imported from GCO Public CellServDB 01 Jan 2016
epitech.net = {
description = "EPITECH, France"
use_dns = yes
servers = {
afs-db-1.epitech.net = {
address = 163.5.255.41
}
afs-db-2.epitech.net = {
address = 163.5.255.42
}
}
}
# es.net imported from GCO Public CellServDB 01 Jan 2016
es.net = {
description = "Energy Sciences Net"
use_dns = yes
servers = {
fs1.es.net = {
address = 198.128.3.21
}
fs2.es.net = {
address = 198.128.3.22
}
fs3.es.net = {
address = 198.128.3.23
}
}
}
# sinenomine.net imported from AFSDB
sinenomine.net = {
description = "Sine Nomine Associates"
use_dns = yes
servers = {
afsdb5.sinenomine.net = {
address = 207.89.43.110
}
afsdb3.sinenomine.net = {
address = 207.89.43.108
}
afsdb4.sinenomine.net = {
address = 207.89.43.109
}
}
}
# slackers.net imported from AFSDB
slackers.net = {
description = "The Slackers' Network"
use_dns = yes
servers = {
alexandria.slackers.net = {
address = 199.4.150.159
}
}
}
# tproa.net imported from SRV
tproa.net = {
description = "The People's Republic of Ames"
use_dns = yes
servers = {
service-3.tproa.net = {
address = 204.11.35.83
}
service-4.tproa.net = {
address = 204.11.35.84
}
service-5.tproa.net = {
address = 204.11.35.85
}
}
}
# nikhef.nl imported from GCO Public CellServDB 01 Jan 2016
nikhef.nl = {
description = "The Dutch National Institute for High Energy Physics"
use_dns = yes
servers = {
afs1.nikhef.nl = {
address = 192.16.185.26
}
afs2.nikhef.nl = {
address = 192.16.185.27
}
}
}
# adrake.org imported from SRV
adrake.org = {
description = "adrake.org"
use_dns = yes
servers = {
afs-vldb.adrake.org = {
address = 128.2.98.241
}
}
}
# coed.org imported from SRV
coed.org = {
description = "Adam Pennington's Cell"
use_dns = yes
servers = {
vice1.coed.org = {
address = 108.48.124.91
}
}
}
# dementia.org imported from GCO Public CellServDB 01 Jan 2016
dementia.org = {
description = "Dementia Unlimited (old)"
use_dns = no
kerberos_realm = DEMENTIX.ORG
servers = {
dedlock.dementix.org = {
address = 128.2.13.209
}
vorkana.dementix.org = {
address = 128.2.234.204
}
}
}
# dementix.org imported from GCO Public CellServDB 01 Jan 2016
dementix.org = {
description = "Dementia Unlimited"
use_dns = yes
servers = {
dedlock.dementix.org = {
address = 128.2.13.209
}
vorkana.dementix.org = {
address = 128.2.234.204
}
}
}
# hpc2n.umu.se imported from SRV
hpc2n.umu.se = {
description = "High Performance Computing Center North - Ume University"
use_dns = yes
servers = {
zenith.hpc2n.umu.se = {
address = 130.239.45.214
}
blackjack.hpc2n.umu.se = {
address = 130.239.45.220
}
mamba.hpc2n.umu.se = {
address = 130.239.45.228
}
}
}
# ltu.se imported from SRV
ltu.se = {
description = "Lule tekniska universitet"
use_dns = yes
servers = {
afsdb2.its.ltu.se = {
address = 130.240.42.223
}
afsdb3.its.ltu.se = {
address = 130.240.42.222
}
afsdb1.its.ltu.se = {
address = 130.240.42.224
}
}
}
# pfriedma.org imported from DNS
pfriedma.org = {
description = "pfriedma.org"
use_dns = yes
servers = {
vice.pfriedma.org = {
address = 50.198.62.99
}
}
}
# kth.se imported from AFSDB
kth.se = {
description = "Royal Institute of Technology, Stockholm, Sweden"
use_dns = yes
servers = {
sonen.e.kth.se = {
address = 130.237.32.145
}
anden.e.kth.se = {
address = 130.237.48.7
}
fadern.e.kth.se = {
address = 130.237.48.244
}
}
}
# ict.kth.se imported from SRV
ict.kth.se = {
description = "Royal Institute of Technology, Information and Communication tec"
use_dns = yes
servers = {
afsdb1.ict.kth.se = {
address = 130.237.216.11
}
afsdb2.ict.kth.se = {
address = 130.237.216.12
}
afsdb3.ict.kth.se = {
address = 130.237.216.13
}
}
}
# it.kth.se imported from SRV
it.kth.se = {
description = "Royal Institute of Technology, Teleinformatics, Kista"
use_dns = yes
servers = {
afsdb1.it.kth.se = {
address = 130.237.216.14
}
afsdb2.it.kth.se = {
address = 130.237.216.15
}
afsdb3.it.kth.se = {
address = 130.237.216.16
}
}
}
# mech.kth.se imported from AFSDB
mech.kth.se = {
description = "Royal Institute of Technology, MECH"
use_dns = yes
servers = {
matterhorn.mech.kth.se = {
address = 130.237.233.142
}
castor.mech.kth.se = {
address = 130.237.233.143
}
pollux.mech.kth.se = {
address = 130.237.233.144
}
}
}
# nada.kth.se imported from AFSDB
nada.kth.se = {
description = "Royal Institute of Technology, NADA"
use_dns = yes
servers = {
afsdb-1.csc.kth.se = {
address = 130.237.222.20
}
afsdb-2.csc.kth.se = {
address = 130.237.223.12
}
afsdb-3.csc.kth.se = {
address = 130.237.224.78
}
afsdb-4.csc.kth.se = {
address = 130.237.227.23
}
afsdb-5.csc.kth.se = {
address = 130.237.228.28
}
}
}
# pdc.kth.se imported from AFSDB
pdc.kth.se = {
description = "Royal Institute of Technology, PDC"
use_dns = yes
servers = {
crab.pdc.kth.se = {
address = 130.237.232.29
}
anna.pdc.kth.se = {
address = 130.237.232.112
}
hokkigai.pdc.kth.se = {
address = 130.237.232.114
}
}
}
# stacken.kth.se imported from AFSDB
stacken.kth.se = {
description = "Stacken Computer Club"
use_dns = yes
servers = {
milko.stacken.kth.se = {
address = 130.237.234.3
}
hot.stacken.kth.se = {
address = 130.237.234.43
}
fishburger.stacken.kth.se = {
address = 130.237.234.101
}
}
}
# su.se imported from AFSDB
su.se = {
description = "Stockholm University"
use_dns = yes
servers = {
afsdb1.su.se = {
address = 130.237.162.81
}
afsdb2.su.se = {
address = 130.237.162.82
}
afsdb3.su.se = {
address = 130.237.162.230
}
}
}
# f9.ijs.si updated 8 Oct 2017 via udebug
f9.ijs.si = {
description = "F9, Jozef Stefan Institue"
use_dns = yes
servers = {
brenta.ijs.si = {
address = 194.249.156.1
}
f9pc00.ijs.si = {
address = 194.249.156.100
}
}
}
# p-ng.si imported from SRV
p-ng.si = {
description = "University of Nova Gorica"
use_dns = yes
servers = {
solkan.p-ng.si = {
address = 193.2.120.2
}
sabotin.p-ng.si = {
address = 193.2.120.9
}
}
}
# ihep.su imported from AFSDB
ihep.su = {
description = "Institute for High-Energy Physics"
use_dns = yes
servers = {
fs0001.ihep.su = {
address = 194.190.165.201
}
fs0002.ihep.su = {
address = 194.190.165.202
}
}
}
# inf.ed.ac.uk imported from AFSDB
inf.ed.ac.uk = {
description = "School of Informatics, University of Edinburgh"
use_dns = yes
servers = {
afsdb0.inf.ed.ac.uk = {
address = 129.215.64.16
}
afsdb1.inf.ed.ac.uk = {
address = 129.215.64.17
}
afsdb2.inf.ed.ac.uk = {
address = 129.215.64.18
}
}
}
# phas.gla.ac.uk imported from GCO Public CellServDB 01 Jan 2016
phas.gla.ac.uk = {
description = "Univeristy of Glasgow Physics And Astronomy"
use_dns = yes
servers = {
afsdb1.phas.gla.ac.uk = {
address = 194.36.1.19
}
afsdb3.phas.gla.ac.uk = {
address = 194.36.1.27
}
afsdb2.phas.gla.ac.uk = {
address = 194.36.1.33
}
}
}
# hep.man.ac.uk imported from GCO Public CellServDB 01 Jan 2016
hep.man.ac.uk = {
description = "Manchester HEP"
use_dns = yes
servers = {
afs1.hep.man.ac.uk = {
address = 194.36.2.3
}
afs2.hep.man.ac.uk = {
address = 194.36.2.4
}
afs3.hep.man.ac.uk = {
address = 194.36.2.5
}
}
}
# tlabs.ac.za imported from SRV
tlabs.ac.za = {
description = "iThemba LABS Cell"
use_dns = yes
servers = {
afs01.tlabs.ac.za = {
address = 196.24.232.1
}
afs02.tlabs.ac.za = {
address = 196.24.232.2
}
afs03.tlabs.ac.za = {
address = 196.24.232.3
}
}
}
# your-file-system.com imported from SRV
your-file-system.com = {
description = "AuriStor, Inc. formerly Your File System, Inc."
use_dns = yes
servers = {
bethlehem.auristor.com = {
address = [2001:470:30:84:20c:29ff:fe2a:fcc]
address = 204.29.154.37
}
faultline.auristor.com = {
address = [2001:470:30:84:20c:29ff:fe19:de6f]
address = 204.29.154.47
}
atwater-block.auristor.com = {
address = [2001:470:1f07:f77:20c:29ff:fe3b:c525]
address = 208.125.0.252
}
}
}
# 1ts.org imported from AFSDB
1ts.org = {
description = "1TS.ORG cell"
use_dns = yes
servers = {
vice0.1ts.org = {
address = 136.248.125.132
}
}
}
# mrow.org imported from AFSDB
mrow.org = {
description = "MROW.ORG cell"
use_dns = yes
servers = {
openafs1.tinc.ad.mrow.org = {
address = 44.44.69.195
}
hyperion.tinc.ad.mrow.org = {
address = 44.44.82.1
}
washington.tinc.ad.mrow.org = {
address = 44.44.69.97
}
}
}
# thok.org imported from AFSDB
thok.org = {
description = "THOK.ORG cell"
use_dns = yes
servers = {
curl-up-paw-over-nose.thok.org = {
address = 172.110.60.210
}
}
}
# openstack.org DNS SRV records available
openstack.org = {
description = "OpenStack Project"
use_dns = yes
servers = {
afsdb02.openstack.org = {
address = 23.253.200.228
}
afsdb01.openstack.org = {
address = 104.130.136.20
}
}
}
conf/client.conf 0000664 0000000 0000000 00000000345 13672703240 0014136 0 ustar 00root root 0000000 0000000 #
# This file stitches together the local kAFS configuration and cell database,
# which can be placed in the client.d/ directory, with the generic database.
#
includedir /etc/kafs/client.d
include /usr/share/kafs/cellservdb.conf
conf/kafs-config.service 0000664 0000000 0000000 00000000272 13672703240 0015561 0 ustar 00root root 0000000 0000000 [Unit]
Description=Preload AFS Cell Database
After=local-fs.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStartPre=/sbin/modprobe -q kafs
ExecStart=/usr/libexec/kafs-preload
conf/kafs_dns.conf 0000664 0000000 0000000 00000000111 13672703240 0014437 0 ustar 00root root 0000000 0000000 create dns_resolver afsdb:* * /usr/libexec/kafs-dns %k
man/ 0000775 0000000 0000000 00000000000 13672703240 0011635 5 ustar 00root root 0000000 0000000 man/AF_RXRPC.7 0000664 0000000 0000000 00000000014 13672703240 0013164 0 ustar 00root root 0000000 0000000 .so rxrpc.7
man/aklog-kafs.1 0000664 0000000 0000000 00000002524 13672703240 0013741 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH AKLOG-KAFS 1 "16 Apr 2019" Linux "AFS Kerberos authentication"
.SH NAME
aklog-kafs \- AFS Kerberos authentication tool
.SH SYNOPSIS
\fBaklog-kafs\fR [ []]
.P
.B
*** NOTE THE ABOVE IS PROVISIONAL AND IS LIKELY TO CHANGE ***
.R
.SH DESCRIPTION
This program is used to get an authentication ticket from Kerberos that can be
used by the in-kernel AFS filesystem (kAFS) to perform authenticated and
encrypted accesses to the server. Without this only unencrypted anonymous
accesses can be made.
.P
Before calling this, the \fBkinit\fR program or similar should be invoked to
authenticate with the appropriate Kerberos server.
.SH ARGUMENTS
.IP
This is the name of the cell with which the ticket is intended to be used. If
not given, the name of the default cell will be read from
\fB/proc/net/afs/rootcell\fR and used instead.
.IP
This is the name of the Kerberos realm from which the ticket will be obtained.
.SH ERRORS
.SH SEE ALSO
.ad l
.nh
.BR kinit (1)
man/aklog.1 0000664 0000000 0000000 00000000021 13672703240 0013005 0 ustar 00root root 0000000 0000000 .so aklog-kafs.1
man/kafs-check-config.8 0000664 0000000 0000000 00000004705 13672703240 0015176 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH KAFS-CHECK-CONFIG 1 "16 Apr 2019" Linux "AFS Config Checker"
.SH NAME
kafs-check-config \- AFS configuration check tool
.SH SYNOPSIS
\fBkafs-check-config\fR [OPTION]... []*
.P
Where options are:
.P
.RS
[-46PDvv] [-c ]* [-N ]
.RE
.SH DESCRIPTION
This program is used to check the configuration for the in-kernel AFS
filesystem (kAFS). This configuration is used when systemd mounts the
filesystem to load up the cell database and create cell automounts in the /afs
directory.
.P
The configuration is also used by the kernel name resolver upcall to provide
static configuration for some cells and to specify overrides and limits on DNS
lookups.
.P
If a list of \fB\fR arguments is given, the listed cells will be
dumped, including the sources of the Volume Location records and address
records.
.P
The available options are:
.SH ARGUMENTS
.IP -4
Only show IPv4 addresses in the dump.
.IP -6
Only show IPv6 addresses in the dump.
.IP -P
Dump the parse tree of the configuration file(s).
.IP -D
Dump the cell database extracted from the configuration.
.IP -v
Increase the verbosity of the output. This may be specified multiple times.
.IP "-c "
Specify a configuration file to read instead of the system default. This may
be specified multiple times and the configuration files are read and applied in
order.
.IP "-N "
Apply a restriction to the lookup performed for the listed cells (if any are).
Restrictions include:
.RS
.IP "-N vl-srv"
Don't use SRV records to find Volume Location servers.
.IP "-N vl-afsdb"
Don't use AFSDB records to find Volume Location servers.
.IP "-N vl-all"
Don't use SRV or AFSDB records to find Volume Location servers.
.IP "-N vl-host"
Don't look cell name up as hostname to find a Volume Location server.
.IP "-N vl-dns"
Don't do any lookups to find Volume Location servers. Use only the static
configuration.
.RE
.SH EXIT STATUS
.IP 0
If check okay and any dumping succeeded.
.IP 1
If an error occurs during processing.
.IP 2
If a command line error occurs.
.SH SEE ALSO
.ad l
.nh
.BR kafs (7),
.BR kafs\-client.conf (5)
man/kafs-client.conf.5 0000664 0000000 0000000 00000016567 13672703240 0015066 0 ustar 00root root 0000000 0000000 .\" -*- nroff -*-
.\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH KAFS-CLIENT.CONF 5 "17 Apr 2019" Linux "kAFS Configuration"
.SH NAME
/etc/kafs/client.conf
.br
/etc/kafs/client.d/ \- kAFS filesystem configuration
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH DESCRIPTION
Configuration information for the in-kernel kAFS filesystem can be provided in
the /etc/kafs/ directory. This may include the following:
.IP
- A list of cells to be preconfigured
.IP
- Fallback addresses for each cell.
.IP
- The name of the default cell (the
.B @cell
substitution).
.IP
- A list of strings for the
.BR @sys " substitution."
.PP
When the
.B afs.mount
service is started by
.BR systemd (1),
a configuration service
.RB ( kafs-config.service )
runs first and loads the configuration into the kernel from the
.B client.conf
file. This contains directives to include other things, such as the contents
of the
.B client.d/
directory and the generic public cell database.
.PP
Once the afs.mount service is started (or if an AFS volume is manually
mounted), if a mountpoint is triggered, the kernel will upcall by means of
.BR request-key (8)
to look up addresses for the Volume Location servers for the named cell. This
will also parse the configuration.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH CONFIGURATION FILE FORMAT
The file format is based on the MIT Kerberos configuration file format. There
are a couple of general directives:
.TP
.BR include " " /path/to/file
This includes the contents of the named file in the parse at this point.
.TP
.BR includedir " " /path/to/dir/
This includes the files in the named directory in the parse at this point.
Files that have names beginning with "." or ending with "~" are ignored.
.PP
Leading and trailing whitespace on a line is ignored. Any line otherwise
beginning with a "#" character is considered a comment and ignored.
.PP
Any line that contains a label bounded by square brackets, e.g. "[cells]", by
itself on that line denotes a switch to the section specified by that label.
.PP
Configuration data is specified within a named section as a series of
.BR key = value
pairs, where a value may be one of nothing, an unquoted string, a quoted
string or a braced lists containing further key=value pairs. Whitespace
either side of the "=" symbol is ignored.
.PP
For example:
.PP
.RS
.nf
[cells]
rivendell.example.com = {
description = "Last Homely Cell"
use_dns = yes
servers = {
elrond.rivendell.example.com = {
address = 192.0.2.23
}
}
}
.fi
.RE
.PP
If two or more consecutive clauses specify values for the same key sequence
(so cells:rivendell.example.com:use_dns, for example), then they are merged
together to form a single list. If a single value is expected for a
configuration item, the last element in the list is taken.
.PP
To prevent overriding by subsequent conflicting configuration, an asterisk can
be placed after the closing brace in a braced list to indicate that that list
is closed, for example:
.PP
.RS
.nf
[cells]
rivendell.example.com = {
description = "Foo"
use_dns = no
}*
.fi
.RE
.PP
Strings that are intepreted as boolean values are classed as false if they
match one of
.BR 0 ", " f ", " false ", " n ", " no " or " off ,
and classed as true if they match one off
.BR 1 ", " t ", " true ", " y ", " yes " or " on .
The match is case-independent.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH GENERAL SETTINGS
The first section contains general system-level settings shared between all
utilities and the kernel. This is denoted by the section label
"\fB[defaults]\fP".
.PP
The system settings that may be changed are configured in this section with
the following key-value pairs:
.TP
.B thiscell =
This sets the name of the local cell. This will be used to configure the
.B @cell
path substitution and will also supply the default cellname for
.BR aklog-kafs (1).
.TP
.B sysname = []*
This specifies a (potentially empty) list of strings which the kernel should
attempt to substitute in turn for "\fB@sys\fR" at the end of a filename until
a match is found.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH CELL DEFINITIONS
The second section contains a list of preconfigured cells, to be used in
preloading the cell list in /afs and also to provide fallback or override
address data for locating Volume Location servers. This is denoted by the
section label "\fB[cells]\fP".
.PP
Within the cell list, each cell is declared with a key=value pair, where the
key is the name of the cell and the value is a braced list indicating the
details, e.g.:
.PP
.RS
.nf
.B [cells]
rivendell.example.com = {
...
}
.fi
.RE
.PP
A cell definition may contain any number of key=value pairs. The keys that
are taken note of are:
.TP
.BR description " = "
This is a text description for the cell.
.TP
.BR show_cell " = "
Whether a cell should be shown in /afs.
.TP
.BR use_dns " = "
Whether address look ups for a cell may use the DNS.
.TP
.BR kerberos_realm " = "
The name of the Kerberos realm to use for a cell by default.
.TP
.BR servers " = " { " ... " }
A list of servers for the cell, where each element in the list is a key=value
pair, where the key is the name of a server and the value is a braced section
of the details for that server.
.PP
The elements in the list of server details attached to each server can
comprise the following keys:
.TP
.B type = vlserver
The server is an AFS Volume Location server. This is the default.
.TP
.B type = ptserver
The server is an AFS Protection server.
.TP
.BR address " = " [/][:]
Specify a single address for a server. The
.B address
is required and can be a single IPv4 or a single IPv6 address, and may be
brackets with square brackets (to avoid confusion with the port number, if
specified). The
.B protocol
is optional; currently only
.B udp
is supported. The
.B port
is also optional and may be specified to change the UDP port from the default
for the server type.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH EXAMPLE
.PP
.nf
.B [defaults]
thiscell = rivendell.example.com
sysname = fedora28_x86 amd64_linux
.B [cells]
corp.example.com = {
description = "Valinor Corporation cell"
use_dns = yes
servers = {
manwe.corp.example.com = {
address = 2001:db8:123::13
address = 203.0.113.19
}
ulmo.corp.example.com = {
address = [2001:db8:123::750c:1234]:6666
address = 203.0.113.3:6666
}
aule.corp.example.com = {
address = udp/[2001:db8:123::abcd:9090]
address = udp/203.0.113.189
}
namo.corp.example.com = {
type = ptserver
address = 2001:db8:123::8888
address = 203.0.113.88
}
}
}
rivendell.example.com = {
description = "Last Homely Cell"
servers = {
elrond.rivendell.example.com = {
address = 192.0.2.23
}
arwen.rivendell.example.com = {
address = 192.0.2.75
}
}
}
.fi
.PP
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SEE ALSO
.ad l
.nh
.BR kafs (7),
.BR kafs\-check\-config (8),
.BR systemd (1)
man/kafs-dns.8 0000664 0000000 0000000 00000007320 13672703240 0013436 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH KAFS-DNS 8 "9 Jun 2020" Linux "AFS kernel address resolver"
.SH NAME
kafs-dns \- AFS filesystem address resolution helper
.SH SYNOPSIS
\fB/usr/libexec/kafs-dns\fR [OPTION]...
.br
\fB/usr/libexec/kafs-dns\fR -D [OPTION]...
.br
\fB/usr/libexec/kafs-dns\fR -V
.PP
Where options are:
.PP
.RS
[-v] [-c ]* [-N ] [-o ]
.RE
.SH DESCRIPTION
This program is invoked by the
.BR request-key (8)
kernel upcall handling program to handle an address resolution request on
behalf of the in-kernel AFS filesystem driver to find the Volume Location
servers for a cell. It is capable of using static configuration, NSS and DNS
SRV and AFSDB record lookups.
.PP
Note that this program is not meant to be called directly, though it does have
a debugging mode that can be used.
.PP
The first form of the command, without the \fB-D\fR flag cannot be called
directly as it requires an under-construction kernel key as its parameter.
.PP
The debugging form, in which \fB-D\fR is given, doesn't require a key, but
must be given a proposed key description and a callout information string.
Information about what it is doing is dumped to the output. The result blob
may be binary and so is not dumped to stdout, but can be dumped to a file with
\fB-o\ \fR.
.PP
The available options are:
.SH ARGUMENTS
.IP -D
Execute in debug mode.
.IP -v
Increase the verbosity of the output. This may be specified multiple times.
.IP "-c "
Specify a configuration file to read instead of the system default. This may
be specified multiple times and the configuration files are read and applied in
order.
.IP "-N "
Apply a restriction to the lookup performed for the listed cells (if any are).
Restrictions include:
.RS
.IP "-N vl-srv"
Don't use SRV records to find Volume Location servers.
.IP "-N vl-afsdb"
Don't use AFSDB records to find Volume Location servers.
.IP "-N vl-all"
Don't use SRV or AFSDB records to find Volume Location servers.
.IP "-N vl-host"
Don't look cell name up as hostname to find a Volume Location server.
.IP "-N vl-dns"
Don't do any lookups to find Volume Location servers. Use only the static
configuration.
.RE
.IP "-o "
Specify a file in which to dump the proposed payload with which to instantiate
a resolver key.
.IP "-V"
Display version information and exit.
.PP
The key description, \fB\fR, should be the name of a cell prefixed by
"afsdb:".
.PP
The callout information string, \fB\fR, is a comma separated list
of none or more of the following items:
.IP "ipv4"
Get IPv4 addresses only.
.IP "ipv6"
Get IPv6 addresses only.
.IP "srv="
Allow the extra information that can be gleaned from SRV records to be
rendered as output format \fB\fR, where is a number.
.SH EXIT STATUS
.IP 0
On success.
.IP 1
If an error occurs during processing.
.IP 2
If a command line error occurs.
.IP 3
If bad configuration is detected.
.SH EXAMPLE
.PP
The program can be called with something like:
.PP
.RS
.nf
/usr/libexec/kafs-dns -D afsdb:example.com srv=1
.fi
.RE
.PP
The program can also be invoked indirectly with something like:
.PP
.RS
.nf
keyctl request2 dns_resolver afsdb:example.com srv=1 @s
.fi
.RE
.PP
which will return the serial number of a key that can then be displayed.
.SH SEE ALSO
.ad l
.nh
.BR kafs (7),
.BR kafs\-client.conf (5),
.BR keyctl (1),
.BR request-key (8)
man/kafs-preload.8 0000664 0000000 0000000 00000002467 13672703240 0014307 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH KAFS-PRELOAD 8 "9 Jun 2020" Linux "AFS configuration preloader"
.SH NAME
kafs-preload \- AFS filesystem configuration preloader
.SH SYNOPSIS
\fB/usr/libexec/kafs-preload [-Dv]\fR
.SH DESCRIPTION
This program loads static configuration into the AFS filesystem, such as
preloading some cells and setting the workstation cell (@cell) and the system
identifier list (@sys).
.PP
This is not intended to be called directly, but rather is intended to be called
from a systemd service unit file.
.PP
The available options are:
.IP -D
Execute in debug mode. Instead of writing to various
.BR proc (5)
files, it notes what it would do to stdout.
.IP -v
Increase the verbosity of the output. This may be specified multiple times.
.SH EXIT STATUS
.IP 0
On success.
.IP 1
If an error occurs during processing.
.IP 2
If a command line error occurs.
.IP 3
If bad configuration is detected.
.SH SEE ALSO
.ad l
.nh
.BR kafs (7),
.BR kafs\-client.conf (5),
.BR proc (5)
man/kafs.7 0000664 0000000 0000000 00000007745 13672703240 0012666 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH KAFS 7 "16 Apr 2019" Linux "In-kernel AFS filesystem"
.SH NAME
kafs \- In-kernel AFS filesystem
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH DESCRIPTION
.B kafs
is a network filesystem driver in the Linux kernel that is able to access AFS
cells and the servers contained therein to locate the logical volumes that
comprise the cell and the files contained in each volume.
.P
It supports transport over IPv4 UDP and IPv6 UDP and security based on
Kerberos. The authentication token is used to define the user for the purpose
of providing access control as well as providing communications security.
.P
The filesystem is of type "afs" and the mount command can be used to mount afs
volumes manually using the "-t" flag on
.BR mount (8).
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SETTING UP
The \fBkafs-client\fP package should be installed to so that systemd is
configured to include a mount of AFS dynamic root on /afs. Note that mounting
/afs is not enabled by default, so if it is needed, then \fIsystemd\fP should
be told to enable it. This can be done with the following step:
.P
.RS
.nf
systemctl enable afs.mount
.fi
.RE
.P
This will mount a special directory on \fB/afs\fR which will be populated by
an automount directory for each cell listed in the configuration. Doing a
pathwalk into one of these directories will result in the \fBafs.cell\fR
volume from the cell being mounted onto that directory.
.P
Local configuration should be placed in a file in the /etc/kafs/client.d/
directory. This will be included from client.conf in the next directory up.
.P
Typically in the local configuration, the local cell name would be specified
and backup details of its Volume Location server addresses would be given.
.P
Also any overrides for the @sys filename substitution would be specified. See
.BR kafs\-client.conf (5).
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH OPERATION
Once the kafs-client is set up (and if there's no local cell, this is
practically zero-conf, provided the cells to be accessed are properly set up
with AFSDB or SRV records in the DNS), the /afs directory can be accessed:
.P
.RS
.nf
ls /afs//location/within/cell
.fi
.RE
.P
For example:
.P
.RS
.nf
ls /afs/rivendell.example.com/doc
.fi
.RE
.P
The user isn't limited to cells listed in /afs, but any cell can be tried by
just substituting the name of the cell into the above formula. It does
require the target to have DNS-based configuration provided.
.P
Note that each logical volume gets a discrete superblock and links between
volumes turn into kernel mountpoints that, if stepped on, cause the
appropriate volume to be mounted over them.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SECURITY
.P
kafs supports Kerberos-based authentication and communication encryption
through the use of Kerberos. The \fBkinit\fP program can be use to
authenticate with a Kerberos server:
.P
.RS
.nf
kinit myname@RIVENDELL.EXAMPLE.COM
.fi
.RE
.P
and then the \fBaklog-kafs\fP program to get a ticket for the kernel
filesystem to use:
.P
.RS
.nf
aklog-kafs rivendell.example.com
.fi
.RE
.P
This will be placed on the caller's session keyring and can be viewed there
with:
.P
.RS
.nf
keyctl show
.fi
.RE
.P
Note that the default realm is assumed to be the same as the cell name, but in
all upper case.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SEE ALSO
.ad l
.nh
.BR aklog\-kafs (1),
.BR kafs\-client.conf (5),
.BR keyctl (1),
.BR kinit (1),
.BR rxrpc (7),
.BR session\-keyring (7),
.BR systemctl (1)
man/rxrpc.7 0000664 0000000 0000000 00000025154 13672703240 0013072 0 ustar 00root root 0000000 0000000 .\"
.\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
.\" Written by David Howells (dhowells@redhat.com)
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License
.\" as published by the Free Software Foundation; either version
.\" 2 of the License, or (at your option) any later version.
.\"
.TH AF_RXRPC 7 "16 Apr 2019" "Linux" "Linux Programmer's Manual"
.SH NAME
rxrpc \- Linux RxRPC (AFS) protocol implementation
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SYNOPSIS
.B #include
.br
.B #include
.PP
.IB socket " = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);"
.br
.IB socket " = socket(AF_RXRPC, SOCK_DGRAM, PF_INET6);"
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH DESCRIPTION
Linux optionally implements the RxRPC transport protocol, as used by the AFS
network filesystem. Both client and server ends are support - even on the same
socket - and authentication is supported at both ends.
.P
This can be used through the BSD socket interface, using the
.BR sendmsg "(2) and " recvmsg (2)
system calls with control data to multiplex calls over the socket and to
provide or retrieve call metadata.
.BR request_key (2)
is used to find the authentication keys to use in the calling process's
keyrings.
.P
The AF_RXRPC driver uses \fBudp\fR(7) sockets underneath, either IPv4-only or
IPv6 (with IPv4), for transport. Under certain circumstances, the underlying
transport sockets may be shared between client-only sockets (but are never
shared if a socket is implementing a server).
.P
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SS Address format
.in +4n
.EX
struct sockaddr_rxrpc {
sa_family_t srx_family; /* AF_RXRPC */
uint16_t srx_service; /* The service identifier */
uint16_t transport_type; /* The type of transport */
uint16_t transport_len; /* Transport address length */
union {
sa_family_t family; /* Transport address family */
struct sockaddr_in sin; /* IPv4 transport address */
struct sockaddr_in6 sin6; /* IPv6 transport address */
} transport;
};
.EE
.in
.PP
Where
.I srx_family
is always set to
.BR AF_RXRPC ;
.I srx_service
is set to the service ID of the desired service;
.I transport_type
is set to the transport type, which is always
.B SOCK_DGRAM
for now;
.I transport_len
says how big the address in
.I transport
is.
.P
Inside the transport address part, and appropriate address for the underlying
socket should be set, including things like family, port and address as
appropriate. Note that it may be permissible to use IPv4 addresses on an IPv6
socket.
.P
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SS Socket Options
AF_RXRPC provides a number of socket options that can be set with
.BR setsockopt (2)
and read with
.BR getsockopt (2).
The socket option level for IPv6 is
.BR SOL_RXRPC .
.TP
.B RXRPC_SECURITY_KEY
The option value is a string that specifies the name of a key to pass to
.BR request_key (2)
to get an appropriate authentication key. Such keys are expected to be of
\fIrxrpc\fR type.
.IP
If this isn't set, AF_RXRPC will perform an unauthenticated, unencrypted call
to the server.
.TP
.B RXRPC_SECURITY_KEYRING
The option value is a string that specifies the name of a keyring to pass to
.BR request_key (2)
to specify the keys used by the server end to authenticate connections.
.IP
The service keys in the ring should be of type rxrpc_s and their descriptions should be
of the form ":" and each should be given an 8-byte secret.
.TP
.B RXRPC_EXCLUSIVE_CONNECTION
The option value should be empty. This causes each call made on this socket to
get its own virtual connection and thus its own negotiated security context.
.TP
.B RXRPC_MIN_SECURITY_LEVEL
The option value should be a 4-byte unsigned integer. This can be one of the
following constants:
.BR RXRPC_SECURITY_PLAIN ", " RXRPC_SECURITY_AUTH " or " RXRPC_SECURITY_ENCRYPT ;
the first indicating the packets should be securely checksummed only, the
second that packets should be authenticated and the third that full encryption
should be employed.
.TP
.B RXRPC_UPGRADEABLE_SERVICE
The option value should be a 2-slot array of 2-byte unsigned integers. To use
this, the socket must be a server socket and must have been bound to more than
one address with different \fIsrx_service\fP specifiers.
.IP
Slot[0] in the array specified the service ID to upgrade from; slot[1]
specifies the service ID to upgrade to. This allows a client to find out if
there's a 'better' version of the service available on the same address, but a
different service ID.
.IP
If the client follows the correct protocol for probing an upgradeable service,
the kernel will automatically upgrade the service ID on the connection and this
will be reflected in the address returned by
.IR recvmsg "(2)."
.TP
.B RXRPC_SUPPORTED_CMSG
The option buffer should have room for a 4-byte integer. The maximum control
buffer message type supported by the kernel is written into the buffer. This
allows an application to find out what control messages it may use so that it
can avoid getting an error if it tries to use something unsupported.
.P
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SS Message flags
AF_RXRPC communicates certain information by way of the message flags passed to
and received from
.BR sendmsg "(2) and " recvmsg (2).
.TP
.B MSG_MORE
This is passed to sendmsg() to indicate that there is more data to be
transmitted as part of the request phase of a client call or the reply phase of
a service operation.
.B MSG_EOR
recvmsg() sets this to indicate that the call has been terminated (the control
messages must be parsed for information as to why) and that the kernel has
discarded the user call ID tag. The tag may now be reused.
.B MSG_PEEK
This is passed to recvmsg() to look at the front of the message queue without
removing any messages or changing the state of any outstanding calls.
.B MSG_WAITALL
This is passed to sendmsg() to instruct it not to return for a signal if it is
still loading up the message queue and progress is being made at the other side
in emptying it. This works around the problem of sendmsg() getting interrupted
after partially queuing its data, but not then being able to return how much it
has consumed.
.B MSG_DONTWAIT
This is passed to recvmsg() to indicate that it shouldn't wait if the message
queue is empty.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SS Control messages
AF_RXRPC communicates metadata to the caller through the ancillary data buffer
(\fImsg_control\fP) in the messages passed to and fro using
.BR sendmsg "(2) and " recvmsg (2).
When building a control message buffer for sendmsg(), the RXRPC_SUPPORTED_CMSG
value should be consulted to make sure that the control message type is
supported.
.TP
.B RXRPC_USER_CALL_ID
The data for this is an arbitrary long integer/pointer-sized tag that
represents the call to the kernel. It may, for example, hold a pointer to some
userspace structure representing the call to the process.
.IP
[sendmsg] This is passed to sendmsg() when the message proposed will create a
client call. It must thereafter be included in all future sendmsg() calls
pertaining to that call.
.IP
[recvmsg] recvmsg() includes the tag in all messages pertaining to a call until
the final termination message is reached - which recvmsg() will mark by setting
MSG_EOR.
.TP
.B RXRPC_ABORT
The data for this is a 32-bit integer that is the abort code.
.IP
[sendmsg] When passed to sendmsg(), this causes the operation matching the tag
to be aborted; this will be followed up by recvmsg() indicating MSG_EOR and a
local error of ECONNABORTED, thereby terminating the tag.
.IP
[recvmsg] When obtained from recvmsg(), this indicates that a remote abort was
received from the peer and the data gives the code for that abort.
.TP
.B RXRPC_ACK
[recvmsg] This conveys no data. It indicates the final acknowledgement to a
service call has been received.
.TP
.B RXRPC_NET_ERROR
[recvmsg] This conveys a 32-bit integer into which the network error that
terminated a call will have been placed.
.TP
.B RXRPC_BUSY
[recvmsg] This conveys no data. It indicates that the operation has been
rejected because the server is busy.
.TP
.B RXRPC_LOCAL_ERROR
[recvmsg] This conveys a 32-bit integer into which the local error that
terminated a call will have been placed.
.TP
.B RXRPC_NEW_CALL
[recvmsg] This conveys no data. It indicates that a new service call has
arrived at a server socket and is in need of a tag. RXRPC_ACCEPT is must be
used for that.
.TP
.B RXRPC_ACCEPT
The data for this is an arbitrary long integer/pointer-sized tag that
represents the call to the kernel with the same semantics as for
RXRPC_USER_CALL_ID.
.IP
[sendmsg] Supply a user call ID tag to a new service call.
.TP
.B RXRPC_EXCLUSIVE_CALL
[sendmsg] Indicate that this particular call should be made on its own
connection with an unshared negotiated security context. This requires no
additional data.
.TP
.B RXRPC_UPGRADE_SERVICE
[sendmsg] Indicate that this call should attempt to probe the service ID on the
other side to see if it gets upgraded. The answer can be found in the
srx_service value of the peer address recvmsg() returns for this call. This
requires no additional data.
.TP
.B RXRPC_TX_LENGTH
The data for this is a signed 64-bit integer.
.IP
[sendmsg] Specify the exact total transmit size. This allows AF_RXRPC to work
out in advance how big encrypted packets are going to be (under some
circumstances, there's a data length encrypted inside the packet).
.IP
If this is set, it may allow AF_RXRPC to be more efficient at filling packets.
If the wrong amount of data is given (too little or too much), then the call
will be aborted.
.TP
.B RXRPC_SET_CALL_TIMEOUT
The data for this is an array of 1-3 32-bit integers.
.IP
[sendmsg] Specify various call timeouts. The first timeout is the \fIhard\fP timeout
for the call in seconds: the call will be aborted if it takes longer than this
amount of time in total.
.IP
The second timeout is the \fIidle\fP timeout for the call in milliseconds: the
call will be aborted if we don't receive the next DATA packet within that
amount of time during the reception phase.
.IP
The third timeout is the \fInormal\fP timeout for the call in milliseconds: the
call will be aborted if we go for that amount of time without receiving any
type of packet pertaining to the call.
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH SEE ALSO
.ad l
.nh
.BR kafs (7),
.BR request_key (2)
redhat/ 0000775 0000000 0000000 00000000000 13672703240 0012331 5 ustar 00root root 0000000 0000000 redhat/kafs-client.spec 0000664 0000000 0000000 00000011012 13672703240 0015400 0 ustar 00root root 0000000 0000000 # % define buildid .local
%global libapivermajor 0
%global libapiversion %{libapivermajor}.1
Name: kafs-client
Version: 0.5
Release: 1%{?dist}%{?buildid}
Summary: The basic tools for kAFS and mounter for the AFS dynamic root
License: GPLv2+
URL: https://www.infradead.org/~dhowells/kafs/
Source0: https://www.infradead.org/~dhowells/kafs/kafs-client-%{version}.tar.bz2
Requires: filesystem-afs
BuildRequires: krb5-devel
BuildRequires: keyutils-libs-devel
BuildRequires: openssl-devel
BuildRequires: gcc
#
# Need this for the upcall program to do DNS lookups.
# /etc/kafs/client.conf
#
%global datadir %{_datarootdir}/kafs
# keyutils-1.6 request-key allows us to override AFSDB DNS lookups.
Requires: keyutils >= 1.6
BuildRequires: systemd-units
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
Requires: selinux-policy-base >= 3.7.19-5
%description
Provide basic AFS-compatible tools for kAFS and systemd scripts to mount the
dynamic root on /afs and preload the cell database.
%package libs
Summary: Library of routines for dealing with kAFS
Requires: %{name}%{?_isa} = %{version}-%{release}
%description libs
Provide a library of shareable routines for dealing with the kAFS
filesystem. These provide things like configuration parsing and DNS lookups.
%package libs-devel
Summary: Library of routines for dealing with kAFS
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
%description libs-devel
Provide a library of shareable routines for dealing with the kAFS
filesystem. These provide things like configuration parsing and DNS lookups.
#
# We generate a compatibility package that makes kafs look like OpenAFS, but it
# needs to be uninstalled be able to install OpenAFS or Auristor.
#
%package compat
Summary: AFS compatibility package
Requires: %{name}%{?_isa} = %{version}-%{release}
%description compat
Compatibility package providing standard AFS names for tools such as
aklog. This package must be uninstalled for kAFS to coexist with
another AFS implementation (such as OpenAFS).
%global _hardened_build 1
%global docdir %{_docdir}/kafs-client
%prep
%setup -q
%build
%make_build \
ETCDIR=%{_sysconfdir} \
BINDIR=%{_bindir} \
SBINDIR=%{_sbindir} \
DATADIR=%{datadir} \
INCLUDEDIR=%{_includedir} \
LIBDIR=%{_libdir} \
LIBEXECDIR=%{_libexecdir} \
MANDIR=%{_mandir} \
CFLAGS="-Wall -Werror $RPM_OPT_FLAGS $RPM_LD_FLAGS $ARCH_OPT_FLAGS"
%install
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_unitdir}
mkdir -p %{buildroot}%{_mandir}/man1
mkdir -p %{buildroot}%{_sysconfdir}
mkdir -p %{buildroot}%{_datarootdir}
%make_install \
ETCDIR=%{_sysconfdir} \
BINDIR=%{_bindir} \
SBINDIR=%{_sbindir} \
DATADIR=%{datadir} \
INCLUDEDIR=%{_includedir} \
LIBDIR=%{_libdir} \
LIBEXECDIR=%{_libexecdir} \
MANDIR=%{_mandir} \
CFLAGS="-Wall -Werror $RPM_OPT_FLAGS $RPM_LD_FLAGS $ARCH_OPT_FLAGS"
# Compat
ln -s aklog-kafs %{buildroot}/%{_bindir}/aklog
%ldconfig_scriptlets libs
%post
%systemd_post afs.mount
%preun
%systemd_preun afs.mount
%postun
%systemd_postun_with_restart afs.mount
%files
%doc README
%license LICENCE.GPL
%{_bindir}/aklog-kafs
%{_sbindir}/kafs-check-config
%{_unitdir}/*
%{_mandir}/man1/aklog-kafs.1*
%{_mandir}/man5/*.5*
%{_mandir}/man7/*.7*
%{_mandir}/man8/*.8*
%{_libexecdir}/kafs-preload
%{_libexecdir}/kafs-dns
%{_sysconfdir}/request-key.d/kafs_dns.conf
%files libs
%{_libdir}/libkafs_client.so.%{libapiversion}
%{_libdir}/libkafs_client.so.%{libapivermajor}
%{datadir}
%{_sysconfdir}/kafs
%config(noreplace) %{_sysconfdir}/kafs/client.conf
%config(noreplace) %{_sysconfdir}/kafs/client.d
%files libs-devel
%{_libdir}/libkafs_client.so
%{_includedir}/*
%files compat
%{_bindir}/aklog
%{_mandir}/man1/aklog.1*
%changelog
* Thu Jun 18 2020 David Howells 0.5-1
- kafs-dns: Fix the -V flag.
- kafs-dns: Fix srv[=N] callout option.
- Add manpages for kafs-dns and kafs-preload.
- kafs-preload: Fix the debugging output.
- kafs-dns: Use the right name in the help output and syslog logging.
- Rename the etc.conf source to client.conf as that's the installation name
* Wed May 20 2020 David Howells 0.4-1
- Use AF_ALG rather than OpenSSL's libcrypto.
- Move the aklog.1 manpage to the -compat rpm.
* Fri Jul 5 2019 David Howells 0.3-1
- Address Fedora packaging review comments [RH BZ 1724281].
* Tue Apr 16 2019 David Howells 0.2-1
- Improve aklog-kafs and its manpage.
- rpm: Depend on filesystem-afs for /afs dir installation.
* Fri Feb 9 2018 David Howells 0.1-1
- Initial commit
src/ 0000775 0000000 0000000 00000000000 13672703240 0011651 5 ustar 00root root 0000000 0000000 src/Makefile 0000664 0000000 0000000 00000006201 13672703240 0013310 0 ustar 00root root 0000000 0000000 CFLAGS ?= -g -Wall -Wsign-compare
include Makefile.config
all: lib progs
CPPFLAGS += -Iinclude -DETCDIR=\"$(ETCDIR)\"
###############################################################################
#
# Build a library to do config parsing and other stuff.
#
###############################################################################
lib: $(DEVELLIB)
$(DEVELLIB): $(SONAME)
$(LNS) $< $@
$(SONAME): $(LIBNAME)
$(LNS) $< $@
LIB_HEADERS := $(wildcard include/kafs/*.h)
LIB_FILES := \
lib_cell_lookup.c \
lib_cellserv.c \
lib_dns_lookup.c \
lib_object.c \
lib_profile.c
LIBVERS := -shared -Wl,-soname,$(SONAME) -Wl,--version-script,version.lds
LIB_OBJS := $(patsubst %.c,%.os,$(LIB_FILES))
%.os: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
$(LIBNAME): $(LIB_OBJS) version.lds Makefile
$(CC) $(CFLAGS) -fPIC $(LDFLAGS) $(LIBVERS) -o $@ $(LIB_OBJS) $(LIBLIBS) \
-lresolv
$(LIB_OBJS) : $(LIB_HEADERS) Makefile
LIB_DEPENDENCY := $(DEVELLIB)
LDFLAGS += -L.
#%.o: %.c $(LIB_HEADERS) Makefile
# $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
###############################################################################
#
# Build stuff
#
###############################################################################
progs: \
aklog-kafs \
kafs-check-config \
kafs-preload \
kafs-dns
aklog-kafs: aklog-kafs.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lkrb5 -lkeyutils
kafs-check-config: kafs-check-config.o $(DEVELLIB)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ kafs-check-config.o -lkafs_client
kafs-preload: preload-cells.o $(DEVELLIB)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ preload-cells.o -lkafs_client
KAFS_DNS_OBJS := dns_main.o dns_afsdb_text.o dns_afsdb_v1.o
kafs-dns: $(KAFS_DNS_OBJS) $(DEVELLIB)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(KAFS_DNS_OBJS) \
-lkafs_client -lkeyutils
kafs-check-config.o: $(LIB_HEADERS)
preload-cells.o: $(LIB_HEADERS)
$(KAFS_DNS_OBJS): $(LIB_HEADERS)
###############################################################################
#
# Install everything
#
###############################################################################
install: all
mkdir -p $(DESTDIR)$(INCLUDEDIR)/kafs
$(INSTALL) -D -m 0644 $(LIB_HEADERS) $(DESTDIR)$(INCLUDEDIR)/kafs/
$(INSTALL) -D -m 0755 $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
$(LNS) $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
$(LNS) $(LIBDIR)/$(SONAME) $(DESTDIR)$(LIBDIR)/$(DEVELLIB)
$(INSTALL) -D -m 0755 aklog-kafs $(DESTDIR)$(BINDIR)/aklog-kafs
$(INSTALL) -D -m 0755 kafs-check-config $(DESTDIR)$(SBINDIR)/kafs-check-config
$(INSTALL) -D -m 0755 kafs-preload $(DESTDIR)$(LIBEXECDIR)/kafs-preload
$(INSTALL) -D -m 0755 kafs-dns $(DESTDIR)$(LIBEXECDIR)/kafs-dns
###############################################################################
#
# Clean up
#
###############################################################################
clean:
$(RM) aklog-kafs kafs-check-config kafs-preload kafs-dns
$(RM) $(DEVELLIB) $(SONAME) $(LIBNAME)
$(RM) *.o *~ *.os
distclean: clean
###############################################################################
#
# Build debugging
#
###############################################################################
show_vars:
@echo VERSION=$(VERSION)
src/Makefile.config 0000664 0000000 0000000 00000004075 13672703240 0014563 0 ustar 00root root 0000000 0000000 INSTALL = install
DESTDIR =
ETCDIR = /etc
BINDIR = /usr/bin
LIBEXECDIR = /usr/libexec
INCLUDEDIR = /usr/include
DATADIR = /usr/share/kafs-client
SPECFILE = ../redhat/kafs-client.spec
ifeq ($(origin LIBDIR),undefined)
LIBDIR := $(shell ldd /usr/bin/make | grep '\(/libc\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!')
endif
LNS := ln -sf
###############################################################################
#
# Determine the current package version from the specfile
#
###############################################################################
VERSION := $(word 2,$(shell grep "^Version:" $(SPECFILE)))
CPPFLAGS += -DVERSION="\"$(VERSION)\""
###############################################################################
#
# Determine the current library version from the version script
#
###############################################################################
libversion := $(filter KAFS_CLIENT_%,$(shell grep ^KAFS_CLIENT_ version.lds))
libversion := $(lastword $(libversion))
libversion := $(lastword $(libversion))
APIVERSION := $(subst KAFS_CLIENT_,,$(libversion))
vernumbers := $(subst ., ,$(APIVERSION))
APIMAJOR := $(firstword $(vernumbers))
DEVELLIB := libkafs_client.so
SONAME := $(DEVELLIB).$(APIMAJOR)
LIBNAME := $(DEVELLIB).$(APIVERSION)
###############################################################################
#
# Guess at the appropriate word size
#
###############################################################################
BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
ifeq ($(BUILDFOR),32-bit)
CFLAGS += -m32
else
ifeq ($(BUILDFOR),64-bit)
CFLAGS += -m64
endif
endif
###############################################################################
#
# Guess at the appropriate lib directory and word size
#
###############################################################################
ifeq ($(origin LIBDIR),undefined)
LIBDIR := $(shell ldd /usr/bin/make | grep '\(/libc\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!')
endif
BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
src/aklog-kafs.c 0000664 0000000 0000000 00000026420 13672703240 0014040 0 ustar 00root root 0000000 0000000 /* aklog.c: description
*
* Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* Based on code:
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* Copyright (C) 2008 Chaskiel Grundman. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Kerberos-5 strong enctype support for rxkad:
* https://tools.ietf.org/html/draft-kaduk-afs3-rxkad-k5-kdf-00
*
* Invoke as: aklog-k5 []
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct rxrpc_key_sec2_v1 {
uint32_t kver; /* key payload interface version */
uint16_t security_index; /* RxRPC header security index */
uint16_t ticket_length; /* length of ticket[] */
uint32_t expiry; /* time at which expires */
uint32_t kvno; /* key version number */
uint8_t session_key[8]; /* DES session key */
uint8_t ticket[0]; /* the encrypted ticket */
};
#define MD5_DIGEST_SIZE 16
#define RXKAD_TKT_TYPE_KERBEROS_V5 256
#define OSERROR(X, Y) do { if ((long)(X) == -1) { perror(Y); exit(1); } } while(0)
#define OSZERROR(X, Y) do { if ((long)(X) == 0) { perror(Y); exit(1); } } while(0)
#define KRBERROR(X, Y) do { if ((X) != 0) { const char *msg = krb5_get_error_message(k5_ctx, (X)); fprintf(stderr, "%s: %s\n", (Y), msg); krb5_free_error_message(k5_ctx, msg); exit(1); } } while(0)
static const uint64_t des_weak_keys[16] = {
0x0101010101010101ULL,
0xFEFEFEFEFEFEFEFEULL,
0xE0E0E0E0F1F1F1F1ULL,
0x1F1F1F1F0E0E0E0EULL,
0x011F011F010E010EULL,
0x1F011F010E010E01ULL,
0x01E001E001F101F1ULL,
0xE001E001F101F101ULL,
0x01FE01FE01FE01FEULL,
0xFE01FE01FE01FE01ULL,
0x1FE01FE00EF10EF1ULL,
0xE01FE01FF10EF10EULL,
0x1FFE1FFE0EFE0EFEULL,
0xFE1FFE1FFE0EFE0EULL,
0xE0FEE0FEF1FEF1FEULL,
0xFEE0FEE0FEF1FEF1ULL
};
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
static bool des_is_weak_key(uint64_t des)
{
size_t i;
#if __BYTE_ORDER == __LITTLE_ENDIAN
des = bswap_64(des);
#endif
for (i = 0; i < ARRAY_SIZE(des_weak_keys); i++)
if (des_weak_keys[i] == des)
return true;
return false;
}
static void des_set_odd_parity(uint64_t *p)
{
uint64_t x = *p, y, z;
y = x | 0x0101010101010101ULL;
y ^= y >> 4;
y ^= y >> 2;
y ^= y >> 1;
z = x | (y & 0x0101010101010101ULL);
*p = z;
}
/*
* Strip Triple-DES parity bits from a block.
*
* Discard the parity bits and converts an 8-octet block to a 7-octet block.
*
* See [afs3-rxkad-k5-kdf-00 §4.2] and [RFC3961 §6.3.1].
*
* [These docs number the bits weirdly. Bit '8' appears to be the LSB of the
* first octet, and 1 the MSB].
*/
static void des3_strip_parity_bits(void *random, const void *key)
{
const unsigned char *k = key;
unsigned char *r = random, lsbs;
int i;
lsbs = k[7] >> 1;
for (i = 0; i < 7; i++) {
r[i] = (k[i] & 0xfe) | (lsbs & 0x1);
lsbs >>= 1;
}
}
/*
* Reverse the Triple-DES random-to-key operation, converting three 64-bit DES
* keys to 56-bit random strings and concatenate to give a 168-bit random
* string that can then be fed to the KDF.
*/
static unsigned int des3_key_to_random(void *random, const void *key, unsigned int len)
{
unsigned int new_len = 0;
while (len > 8) {
des3_strip_parity_bits(random, key);
key += 8;
random += 7;
len -= 8;
new_len += 7;
}
return new_len;
}
/*
* Do HMAC(MD5).
*/
static size_t HMAC_MD5(const void *key, size_t key_len,
const void *data, size_t data_len,
unsigned char *md, size_t md_len)
{
static struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "hash",
.salg_name = "hmac(md5)",
};
int alg, sock, ret;
alg = socket(AF_ALG, SOCK_SEQPACKET, 0);
OSERROR(alg, "AF_ALG");
OSERROR(bind(alg, (struct sockaddr *)&sa, sizeof(sa)), "bind/AF_ALG");
OSERROR(setsockopt(alg, SOL_ALG, ALG_SET_KEY, key, key_len), "setsockopt/AF_ALG");
sock = accept(alg, NULL, 0);
OSERROR(sock, "AF_ALG");
OSERROR(write(sock, data, data_len), "write/AF_ALG");
ret = read(sock, md, md_len);
OSERROR(ret, "read/AF_ALG");
close(sock);
close(alg);
return ret;
}
/*
* The data to pass into the key derivation function.
*/
struct kdf_data {
unsigned char i_2;
unsigned char Label[6];
unsigned char L_2[4];
} __attribute__((packed));
static const struct kdf_data rxkad_kdf_data = {
.Label = "rxkad", /* Including NUL separator */
.L_2 = { 0, 0, 0, 64 }, /* BE integer */
};
/*
* Derive a 64-bit key we can pass to rxkad from the ticket data. The ticket
* data is used as the key for the HMAC-MD5 algorithm, which is used as the
* PRF. We then iterate over a series of constructed source strings, passing
* each one through the PRF until we get an MD5 output that we can cut down and
* use as a substitute for the DES session key that isn't too weak.
*
* [afs3-rxkad-k5-kdf-00 §4.3]
*/
static void key_derivation_function(krb5_creds *creds, uint8_t *session_key)
{
struct kdf_data kdf_data = rxkad_kdf_data;
unsigned int i, len;
union {
unsigned char md5[MD5_DIGEST_SIZE];
uint64_t n_des;
} buf;
for (i = 1; i <= 255; i++) {
/* K(i) = PRF(Ks, [i]_2 || Label || 0x00 || [L]_2) */
kdf_data.i_2 = i;
len = HMAC_MD5(creds->keyblock.contents, creds->keyblock.length,
(unsigned char *)&kdf_data, sizeof(kdf_data),
buf.md5, sizeof(buf.md5));
if (len < sizeof(buf.n_des)) {
fprintf(stderr, "aklog: HMAC returned short result\n");
exit(1);
}
/* Overlay the DES parity. */
buf.n_des &= 0xfefefefefefefefeULL;
des_set_odd_parity(&buf.n_des);
if (!des_is_weak_key(buf.n_des))
goto success;
}
fprintf(stderr, "aklog: Unable to derive strong DES key\n");
exit(1);
success:
memcpy(session_key, &buf.n_des, sizeof(buf.n_des));
}
/*
* Extract or derive the session key.
*/
static void derive_key(krb5_creds *creds, uint8_t *session_key)
{
unsigned int length = creds->keyblock.length;
switch (creds->keyblock.enctype) {
case ENCTYPE_NULL: goto not_supported;
case ENCTYPE_DES_CBC_CRC: goto just_copy;
case ENCTYPE_DES_CBC_MD4: goto just_copy;
case ENCTYPE_DES_CBC_MD5: goto just_copy;
case ENCTYPE_DES_CBC_RAW: goto deprecated;
case ENCTYPE_DES3_CBC_SHA: goto des3_discard_parity; /* des3-cbc-md5 */
case ENCTYPE_DES3_CBC_RAW: goto deprecated;
case 7: goto des3_discard_parity; /* des3-cbc-sha1 */
case ENCTYPE_DES_HMAC_SHA1: goto deprecated;
case ENCTYPE_DSA_SHA1_CMS: goto not_supported;
case ENCTYPE_MD5_RSA_CMS: goto not_supported;
case ENCTYPE_SHA1_RSA_CMS: goto not_supported;
case ENCTYPE_RC2_CBC_ENV: goto not_supported;
case ENCTYPE_RSA_ENV: goto not_supported;
case ENCTYPE_RSA_ES_OAEP_ENV: goto not_supported;
case ENCTYPE_DES3_CBC_ENV: goto not_supported;
case ENCTYPE_DES3_CBC_SHA1: goto des3_discard_parity; /* des3-cbc-sha1-kd */
default:
if (length < 7)
goto key_too_short;
if (creds->keyblock.enctype < 0)
goto not_supported;
goto derive_key;
}
/* Strip the parity bits for 3DES then do KDF [afs3-rxkad-k5-kdf-00 §4.2]. */
des3_discard_parity:
if (length & 7) {
fprintf(stderr, "aklog: 3DES session key not multiple of 8 octets.\n");
exit(1);
}
creds->keyblock.length = des3_key_to_random(creds->keyblock.contents,
creds->keyblock.contents,
length);
goto derive_key;
/* Do KDF [afs3-rxkad-k5-kdf-00 §4.3]. */
derive_key:
key_derivation_function(creds, session_key);
return;
/* Use as-is for single-DES [afs3-rxkad-k5-kdf-00 §4.1]. */
just_copy:
if (length != 8) {
fprintf(stderr, "aklog: DES session key not 8 octets.\n");
exit(1);
}
memcpy(session_key, creds->keyblock.contents, length);
return;
deprecated:
fprintf(stderr, "aklog: Ticket contains deprecated enc type (%d)\n",
creds->keyblock.enctype);
exit(1);
not_supported:
fprintf(stderr, "aklog: Ticket contains unsupported enc type (%d)\n",
creds->keyblock.enctype);
exit(1);
key_too_short:
fprintf(stderr, "aklog: Ticket contains short key block (%u)\n", length);
exit(1);
}
/*
* Read the name of default cell.
*/
static char *get_default_cell(void)
{
static const char rootcell[] = "/proc/net/afs/rootcell";
ssize_t n;
char buf[260], *nl, *cell;
int fd;
fd = open(rootcell, O_RDONLY);
OSERROR(fd, rootcell);
n = read(fd, buf, sizeof(buf) - 2);
OSERROR(n, rootcell);
close(n);
if (n == 0)
goto unset;
buf[n] = 0;
nl = memchr(buf, '\n', n);
if (nl == buf)
goto unset;
*nl = 0;
cell = strdup(buf);
OSZERROR(cell, "strdup");
return cell;
unset:
fprintf(stderr, "error: The default cell is not set\n");
exit(1);
}
/*
*
*/
int main(int argc, char **argv)
{
char *cell, *realm, *princ, *desc, *p;
int ret;
size_t plen;
struct rxrpc_key_sec2_v1 *payload;
krb5_error_code kresult;
krb5_context k5_ctx;
krb5_ccache cc;
krb5_creds search_cred, *creds;
if (argc < 1 || argc > 3 ||
(argc == 2 && strcmp(argv[1], "--help") == 0)) {
fprintf(stderr, "Usage: aklog-kafs [ []]\n");
exit(1);
}
if (argc == 1)
cell = get_default_cell();
else
cell = argv[1];
if (argc == 3) {
realm = strdup(argv[2]);
OSZERROR(realm, "strdup");
} else {
realm = strdup(cell);
OSZERROR(realm, "strdup");
for (p = realm; *p; p++)
*p = toupper(*p);
}
for (p = cell; *p; p++)
*p = tolower(*p);
ret = asprintf(&princ, "afs/%s@%s", cell, realm);
OSERROR(ret, "asprintf");
ret = asprintf(&desc, "afs@%s", cell);
OSERROR(ret, "asprintf");
printf("CELL %s\n", cell);
printf("PRINC %s\n", princ);
kresult = krb5_init_context(&k5_ctx);
if (kresult) { fprintf(stderr, "krb5_init_context failed\n"); exit(1); }
kresult = krb5_cc_default(k5_ctx, &cc);
KRBERROR(kresult, "Getting credential cache");
memset(&search_cred, 0, sizeof(krb5_creds));
kresult = krb5_cc_get_principal(k5_ctx, cc, &search_cred.client);
KRBERROR(kresult, "Getting client principal");
kresult = krb5_parse_name(k5_ctx, princ, &search_cred.server);
KRBERROR(kresult, "Parsing server principal name");
//search_cred.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
kresult = krb5_get_credentials(k5_ctx, 0, cc, &search_cred, &creds);
KRBERROR(kresult, "Getting tickets");
plen = sizeof(*payload) + creds->ticket.length;
payload = calloc(1, plen + 4);
if (!payload) {
perror("calloc");
exit(1);
}
printf("plen=%zu tklen=%u rk=%zu\n",
plen, creds->ticket.length, sizeof(*payload));
/* use version 1 of the key data interface */
payload->kver = 1;
payload->security_index = 2;
payload->ticket_length = creds->ticket.length;
payload->expiry = creds->times.endtime;
payload->kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
derive_key(creds, payload->session_key);
memcpy(payload->ticket, creds->ticket.data, creds->ticket.length);
ret = add_key("rxrpc", desc, payload, plen, KEY_SPEC_SESSION_KEYRING);
OSERROR(ret, "add_key");
krb5_free_creds(k5_ctx, creds);
krb5_free_cred_contents(k5_ctx, &search_cred);
krb5_cc_close(k5_ctx, cc);
krb5_free_context(k5_ctx);
exit(0);
}
src/dns_afsdb.h 0000664 0000000 0000000 00000000517 13672703240 0013750 0 ustar 00root root 0000000 0000000 struct kafs_lookup_context;
extern void *kafs_generate_text_payload(void *result,
const char *cell_name,
unsigned int *_ttl,
struct kafs_lookup_context *ctx);
extern void *kafs_generate_v1_payload(void *result,
const char *cell_name,
unsigned int *_ttl,
struct kafs_lookup_context *ctx);
src/dns_afsdb_text.c 0000664 0000000 0000000 00000004304 13672703240 0015005 0 ustar 00root root 0000000 0000000 /*
* Generate a set of addresses as a text string.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include
#include
#include
#include
#include
#include "dns_afsdb.h"
static void store_char(char **_b, char n)
{
*(*_b)++ = n;
}
static void store_string(char **_b, const char *p)
{
unsigned int len = strlen(p);
memcpy(*_b, p, len);
*_b += len;
}
/*
* Generate the payload to pass to the kernel as v1 server bundle.
*/
static void emit_text_str(char **_b,
struct kafs_server_list *vls,
unsigned short default_port)
{
struct kafs_server_addr *addr;
struct kafs_server *server;
const char *p;
unsigned int i, j;
char buf[100];
bool need_sep = false;
for (i = 0; i < vls->nr_servers; i++) {
server = &vls->servers[i];
for (j = 0; j < server->nr_addrs; j++) {
addr = &server->addrs[j];
if (need_sep)
store_char(_b, ',');
need_sep = true;
switch (addr->sin.sin_family) {
case AF_INET:
p = inet_ntop(AF_INET, &addr->sin.sin_addr,
buf, sizeof(buf));
if (p) {
store_char(_b, '[');
store_string(_b, buf);
store_char(_b, ']');
}
break;
case AF_INET6:
p = inet_ntop(AF_INET6, &addr->sin6.sin6_addr,
buf, sizeof(buf));
if (p) {
store_char(_b, '[');
store_string(_b, buf);
store_char(_b, ']');
}
break;
default:
continue;
}
if (server->port && server->port != default_port) {
sprintf(buf, "%u", server->port);
store_char(_b, '+');
store_string(_b, buf);
}
}
}
store_char(_b, 0);
}
void *kafs_generate_text_payload(void *result,
const char *cell_name,
unsigned int *_ttl,
struct kafs_lookup_context *ctx)
{
struct kafs_cell *cell;
char *b = result;
ctx->report.what = cell_name;
cell = kafs_lookup_cell(cell_name, ctx);
if (!cell)
return NULL;
if (cell->vlservers)
emit_text_str(&b, cell->vlservers, 7003);
return b;
}
src/dns_afsdb_v1.c 0000664 0000000 0000000 00000004647 13672703240 0014361 0 ustar 00root root 0000000 0000000 /*
* Generate a v1 servers and addresses list.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include
#include
#include
#include
#include "dns_afsdb.h"
#include "dns_resolver.h"
static void store_u8(unsigned char **_b, unsigned char n)
{
*(*_b)++ = n;
}
static void store_u16(unsigned char **_b, unsigned short n)
{
*(*_b)++ = (n >> 0) & 0xff;
*(*_b)++ = (n >> 8) & 0xff;
}
static void store_octets(unsigned char **_b, const void *p, size_t n)
{
memcpy(*_b, p, n);
*_b += n;
}
/*
* Generate the payload to pass to the kernel as v1 server bundle.
*/
static void emit_v1(unsigned char **_b, struct kafs_server_list *vls)
{
struct kafs_server_addr *addr;
struct kafs_server *server;
unsigned int i, j, n;
store_u8 (_b, 0); /* It's not a string */
store_u8 (_b, DNS_PAYLOAD_IS_SERVER_LIST);
store_u8 (_b, 1); /* Encoding version */
store_u8 (_b, vls->source);
store_u8 (_b, vls->status);
store_u8 (_b, vls->nr_servers);
for (i = 0; i < vls->nr_servers; i++) {
server = &vls->servers[i];
n = strlen(server->name);
store_u16(_b, n);
store_u16(_b, server->pref);
store_u16(_b, server->weight);
store_u16(_b, server->port);
store_u8 (_b, server->source);
store_u8 (_b, server->status);
store_u8 (_b, server->protocol);
store_u8 (_b, server->nr_addrs);
store_octets(_b, server->name, n);
for (j = 0; j < server->nr_addrs; j++) {
addr = &server->addrs[j];
switch (addr->sin.sin_family) {
case AF_INET:
store_u8(_b, DNS_ADDRESS_IS_IPV4);
store_octets(_b, &addr->sin.sin_addr, 4);
break;
case AF_INET6:
store_u8(_b, DNS_ADDRESS_IS_IPV6);
store_octets(_b, &addr->sin6.sin6_addr, 16);
break;
default:
store_u8(_b, 0);
continue;
}
}
}
}
void *kafs_generate_v1_payload(void *result,
const char *cell_name,
unsigned int *_ttl,
struct kafs_lookup_context *ctx)
{
struct kafs_cell *cell;
unsigned char *b = result;
ctx->report.what = cell_name;
cell = kafs_lookup_cell(cell_name, ctx);
if (!cell)
return NULL;
if (_ttl)
*_ttl = cell->vlservers->ttl;
if (cell->vlservers)
emit_v1(&b, cell->vlservers);
return b;
}
src/dns_main.c 0000664 0000000 0000000 00000024011 13672703240 0013603 0 ustar 00root root 0000000 0000000 /*
* DNS Resolver Module User-space Helper for AFSDB records
*
* Copyright (C) Wang Lei (wang840925@gmail.com) 2010
* Authors: Wang Lei (wang840925@gmail.com)
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This is a userspace tool for querying AFSDB RR records in the DNS on behalf
* of the kernel, and converting the VL server addresses to IPv4 format so that
* they can be used by the kAFS filesystem.
*
* As some function like res_init() should use the static liberary, which is a
* bug of libresolv, that is the reason for cifs.upcall to reimplement.
*
* To use this program, you must tell /sbin/request-key how to invoke it. You
* need to have the keyutils package installed and something like the following
* lines added to your /etc/request-key.conf file:
*
* #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ...
* ====== ============ =========== ============ ==========================
* create dns_resolver afsdb:* * /sbin/key.dns_resolver %k
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "dns_afsdb.h"
static const char *DNS_PARSE_VERSION = "2.0";
static const char prog[] = "kafs-dns";
static const char key_type[] = "dns_resolver";
static const char afsdb_query_type[] = "afsdb:";
static key_serial_t key;
static int debug_mode;
static unsigned int output_version = 0;
/*
* Print an error to stderr or the syslog, negate the key being created and
* exit
*/
void error(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (isatty(2)) {
fputs("E: ", stderr);
vfprintf(stderr, fmt, va);
fputc('\n', stderr);
} else {
vsyslog(LOG_ERR, fmt, va);
}
va_end(va);
/*
* on error, negatively instantiate the key ourselves so that we can
* make sure the kernel doesn't hang it off of a searchable keyring
* and interfere with the next attempt to instantiate the key.
*/
if (!debug_mode)
keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
exit(1);
}
#define error(FMT, ...) error("Error: " FMT, ##__VA_ARGS__)
/*
* Just print an error to stderr or the syslog
*/
static void print_error(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (isatty(2)) {
fputs("E: ", stderr);
vfprintf(stderr, fmt, va);
fputc('\n', stderr);
} else {
vsyslog(LOG_ERR, fmt, va);
}
va_end(va);
}
/*
* Print status information
*/
static void verbose(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (isatty(1)) {
fputs("I: ", stdout);
vfprintf(stdout, fmt, va);
fputc('\n', stdout);
} else {
vsyslog(LOG_INFO, fmt, va);
}
va_end(va);
}
/*
* Print usage details,
*/
static __attribute__((noreturn))
void usage(void)
{
if (isatty(2)) {
fprintf(stderr, "Usage: %s [OPTION]... \n",
prog);
fprintf(stderr, " %s -D [OPTION]... \n",
prog);
fprintf(stderr, " %s -V\n",
prog);
fprintf(stderr, "\n");
fprintf(stderr, "Where [OPTION].. is a combination of one or more of:\n");
fprintf(stderr, "\t-c \n");
fprintf(stderr, "\t-N dns\n");
fprintf(stderr, "\t-N vls-afsdb\n");
fprintf(stderr, "\t-N vls-srv\n");
fprintf(stderr, "\t-N vls-all\n");
fprintf(stderr, "\t-N vl-host\n");
fprintf(stderr, "\t-o \n");
fprintf(stderr, "\t-v\n");
} else {
verbose("Usage: %s [-vv] ", prog);
}
exit(2);
}
/*
* Parse the callout info string.
*/
static void parse_callout(char *options, struct kafs_lookup_context *ctx)
{
char *k, *val;
ctx->want_ipv4_addrs = true;
ctx->want_ipv6_addrs = true;
if (!*options) {
/* legacy mode */
ctx->want_ipv6_addrs = false;
return;
}
do {
k = options;
options = strchr(options, ' ');
if (!options)
options = k + strlen(k);
else
*options++ = '\0';
if (!*k)
continue;
if (strchr(k, ','))
error("Option name '%s' contains a comma", k);
val = strchr(k, '=');
if (val)
*val++ = '\0';
if (ctx->report.verbose)
ctx->report.verbose("Opt %s", k);
if (strcmp(k, "ipv4") == 0) {
ctx->want_ipv4_addrs = true;
ctx->want_ipv6_addrs = false;
} else if (strcmp(k, "ipv6") == 0) {
ctx->want_ipv4_addrs = false;
ctx->want_ipv6_addrs = true;
} else if (strcmp(k, "srv") == 0) {
if (!val)
error("Option srv missing version");
output_version = atoi(val);
}
} while (*options);
}
const struct option long_options[] = {
{ "conf", 0, NULL, 'c' },
{ "debug", 0, NULL, 'D' },
{ "no", 0, NULL, 'N' },
{ "output", 0, NULL, 'o' },
{ "verbose", 0, NULL, 'v' },
{ "version", 0, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
/*
*
*/
int main(int argc, char *argv[])
{
struct kafs_lookup_context ctx = { .report.error = print_error, };
const char *dump_file = NULL;
const char *filev[10], **filep = NULL;
char *keyend, *p;
char *callout_info = NULL;
char *buf = NULL, *name, *result, *r_end;
unsigned int ttl;
size_t ktlen;
int ret, filec = 0;
if (argc > 1 && strcmp(argv[1], "--help") == 0)
usage();
openlog(prog, 0, LOG_DAEMON);
while ((ret = getopt_long(argc, argv, "Dvc:N:o:V", long_options, NULL)) != -1) {
switch (ret) {
case 'c':
if (filec >= 9) {
fprintf(stderr, "Max 9 files\n");
exit(2);
}
filev[filec++] = optarg;
break;
case 'D':
debug_mode = 1;
break;
case 'V':
printf("version: %s from %s (%s)\n",
DNS_PARSE_VERSION,
keyutils_version_string,
keyutils_build_string);
exit(0);
case 'v':
if (!ctx.report.verbose)
ctx.report.verbose = verbose;
else
ctx.report.verbose2 = verbose;
break;
case 'N':
if (strcmp(optarg, "vls-srv") == 0) {
ctx.no_vls_srv = true;
} else if (strcmp(optarg, "vls-afsdb") == 0) {
ctx.no_vls_afsdb = true;
} else if (strcmp(optarg, "vls-all") == 0) {
ctx.no_vls_srv = true;
ctx.no_vls_afsdb = true;
} else if (strcmp(optarg, "vl-host") == 0) {
ctx.no_vl_host = true;
} else if (strcmp(optarg, "dns") == 0) {
ctx.no_vls_srv = true;
ctx.no_vls_afsdb = true;
ctx.no_vl_host = true;
} else {
fprintf(stderr, "Unknown restriction '-N %s'\n", optarg);
usage();
}
break;
case 'o':
dump_file = optarg;
break;
default:
if (!isatty(2))
syslog(LOG_ERR, "unknown option: %c", ret);
usage();
}
}
argc -= optind;
argv += optind;
if (!debug_mode) {
if (argc != 1)
usage();
/* get the key ID */
if (!**argv)
error("Invalid blank key ID");
key = strtol(*argv, &p, 10);
if (*p)
error("Invalid key ID format");
/* get the key description (of the form "x;x;x;x;:") */
ret = keyctl_describe_alloc(key, &buf);
if (ret == -1)
error("keyctl_describe_alloc failed: %m");
/* get the callout_info (which can supply options) */
ret = keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY, (void **)&callout_info);
if (ret == -1)
error("Invalid key callout_info read: %m");
} else {
if (argc != 2)
usage();
ret = asprintf(&buf, "%s;-1;-1;0;%s", key_type, argv[0]);
if (ret < 0)
error("Error %m");
callout_info = argv[1];
}
ret = 1;
verbose("Key description: '%s'", buf);
verbose("Callout info: '%s'", callout_info);
p = strchr(buf, ';');
if (!p)
error("Badly formatted key description '%s'", buf);
ktlen = p - buf;
/* make sure it's the type we are expecting */
if (ktlen != sizeof(key_type) - 1 ||
memcmp(buf, key_type, ktlen) != 0)
error("Key type is not supported: '%*.*s'", ktlen, ktlen, buf);
keyend = buf + ktlen + 1;
/* the actual key description follows the last semicolon */
keyend = rindex(keyend, ';');
if (!keyend)
error("Invalid key description: %s", buf);
keyend++;
if (memcmp(keyend, afsdb_query_type, sizeof(afsdb_query_type) - 1) != 0)
error("Only 'afsdb' supported: %s", buf);
name = keyend + sizeof(afsdb_query_type) - 1;
verbose("Do AFS VL server query for:'%s' mask:'%s'", name, callout_info);
parse_callout(callout_info, &ctx);
/* Anything we create must fit into 1MiB buffer */
result = mmap(NULL, 1024 * 1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (result == MAP_FAILED)
error("mmap: %m");
if (filec > 0) {
filev[filec] = NULL;
filep = filev;
}
if (kafs_init_lookup_context(&ctx) < 0)
exit(1);
if (kafs_read_config(filep, &ctx.report) < 0)
exit(ctx.report.bad_config ? 3 : 1);
/* Generate the payload */
switch (output_version) {
case 0:
r_end = kafs_generate_text_payload(result, name, &ttl, &ctx);
break;
case 1:
default:
r_end = kafs_generate_v1_payload(result, name, &ttl, &ctx);
break;
}
if (!r_end)
error("failed");
verbose("version %u %zu", output_version, r_end - result);
if (dump_file) {
int fd = open(dump_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror(dump_file);
exit(1);
}
if (write(fd, result, r_end - result) != r_end - result) {
perror(dump_file);
exit(1);
}
close(fd);
}
/* Set the key's expiry time from the minimum TTL encountered and then
* pass the data to the key.
*/
if (!debug_mode) {
if (ttl != UINT_MAX) {
ret = keyctl_set_timeout(key, ttl);
if (ret == -1)
error("keyctl_set_timeout: %m");
}
ret = keyctl_instantiate(key, result, r_end - result, 0);
if (ret == -1)
error("keyctl_instantiate: %m");
}
verbose("Success (%zu bytes)", r_end - result);
return 0;
}
src/dns_resolver.h 0000664 0000000 0000000 00000007574 13672703240 0014544 0 ustar 00root root 0000000 0000000 /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/* DNS resolver interface definitions.
*
* Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _UAPI_LINUX_DNS_RESOLVER_H
#define _UAPI_LINUX_DNS_RESOLVER_H
#include
/*
* Type of payload.
*/
enum dns_payload_content_type {
DNS_PAYLOAD_IS_SERVER_LIST = 0, /* List of servers, requested by srv=1 */
};
/*
* Type of address that might be found in an address record.
*/
enum dns_payload_address_type {
DNS_ADDRESS_IS_IPV4 = 0, /* 4-byte AF_INET address */
DNS_ADDRESS_IS_IPV6 = 1, /* 16-byte AF_INET6 address */
};
/*
* Type of protocol used to access a server.
*/
enum dns_payload_protocol_type {
DNS_SERVER_PROTOCOL_UNSPECIFIED = 0,
DNS_SERVER_PROTOCOL_UDP = 1, /* Use UDP to talk to the server */
DNS_SERVER_PROTOCOL_TCP = 2, /* Use TCP to talk to the server */
};
/*
* Source of record included in DNS resolver payload.
*/
enum dns_record_source {
DNS_RECORD_UNAVAILABLE = 0, /* No source available (empty record) */
DNS_RECORD_FROM_CONFIG = 1, /* From local configuration data */
DNS_RECORD_FROM_DNS_A = 2, /* From DNS A or AAAA record */
DNS_RECORD_FROM_DNS_AFSDB = 3, /* From DNS AFSDB record */
DNS_RECORD_FROM_DNS_SRV = 4, /* From DNS SRV record */
DNS_RECORD_FROM_NSS = 5, /* From NSS */
NR__dns_record_source
};
/*
* Status of record included in DNS resolver payload.
*/
enum dns_lookup_status {
DNS_LOOKUP_NOT_DONE = 0, /* No lookup has been made */
DNS_LOOKUP_GOOD = 1, /* Good records obtained */
DNS_LOOKUP_GOOD_WITH_BAD = 2, /* Good records, some decoding errors */
DNS_LOOKUP_BAD = 3, /* Couldn't decode results */
DNS_LOOKUP_GOT_NOT_FOUND = 4, /* Got a "Not Found" result */
DNS_LOOKUP_GOT_LOCAL_FAILURE = 5, /* Local failure during lookup */
DNS_LOOKUP_GOT_TEMP_FAILURE = 6, /* Temporary failure during lookup */
DNS_LOOKUP_GOT_NS_FAILURE = 7, /* Name server failure */
NR__dns_lookup_status
};
/*
* Header at the beginning of binary format payload.
*/
struct dns_payload_header {
__u8 zero; /* Zero byte: marks this as not being text */
__u8 content; /* enum dns_payload_content_type */
__u8 version; /* Encoding version */
} __attribute__((packed));
/*
* Header at the beginning of a V1 server list. This is followed directly by
* the server records. Each server records begins with a struct of type
* dns_server_list_v1_server.
*/
struct dns_server_list_v1_header {
struct dns_payload_header hdr;
__u8 source; /* enum dns_record_source */
__u8 status; /* enum dns_lookup_status */
__u8 nr_servers; /* Number of server records following this */
} __attribute__((packed));
/*
* Header at the beginning of each V1 server record. This is followed by the
* characters of the name with no NUL-terminator, followed by the address
* records for that server. Each address record begins with a struct of type
* struct dns_server_list_v1_address.
*/
struct dns_server_list_v1_server {
__u16 name_len; /* Length of name (LE) */
__u16 priority; /* Priority (as SRV record) (LE) */
__u16 weight; /* Weight (as SRV record) (LE) */
__u16 port; /* UDP/TCP port number (LE) */
__u8 source; /* enum dns_record_source */
__u8 status; /* enum dns_lookup_status */
__u8 protocol; /* enum dns_payload_protocol_type */
__u8 nr_addrs;
} __attribute__((packed));
/*
* Header at the beginning of each V1 address record. This is followed by the
* bytes of the address, 4 for IPV4 and 16 for IPV6.
*/
struct dns_server_list_v1_address {
__u8 address_type; /* enum dns_payload_address_type */
} __attribute__((packed));
#endif /* _UAPI_LINUX_DNS_RESOLVER_H */
src/include/ 0000775 0000000 0000000 00000000000 13672703240 0013274 5 ustar 00root root 0000000 0000000 src/include/kafs/ 0000775 0000000 0000000 00000000000 13672703240 0014220 5 ustar 00root root 0000000 0000000 src/include/kafs/cellserv.h 0000664 0000000 0000000 00000007756 13672703240 0016227 0 ustar 00root root 0000000 0000000 /*
* kAFS config and cell database parser.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _KAFS_CELLSERV_H
#define _KAFS_CELLSERV_H
#include
#include
#include
#include "reporting.h"
struct kafs_profile;
struct kafs_profile_parse;
enum kafs_server_type {
kafs_server_is_untyped,
kafs_server_is_afs_vlserver,
kafs_server_is_afs_ptserver,
};
enum kafs_record_source {
kafs_record_unavailable,
kafs_record_from_config,
kafs_record_from_dns_a,
kafs_record_from_dns_afsdb,
kafs_record_from_dns_srv,
kafs_record_from_nss,
nr__kafs_record_source
};
enum kafs_lookup_status {
kafs_lookup_not_done,
kafs_lookup_good,
kafs_lookup_good_with_bad,
kafs_lookup_bad,
kafs_lookup_got_not_found,
kafs_lookup_got_local_failure,
kafs_lookup_got_temp_failure,
kafs_lookup_got_ns_failure,
nr__kafs_lookup_status
};
struct kafs_server_addr {
union {
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
};
struct kafs_server {
char *name;
struct kafs_server_addr *addrs;
unsigned int max_addrs;
unsigned int nr_addrs;
unsigned short port;
unsigned short pref;
unsigned short weight;
unsigned char protocol;
bool borrowed_name;
bool borrowed_addrs;
enum kafs_record_source source : 8;
enum kafs_lookup_status status : 8;
enum kafs_server_type type : 8;
};
struct kafs_server_list {
unsigned int nr_servers;
unsigned int max_servers;
unsigned int ttl;
enum kafs_record_source source : 8;
enum kafs_lookup_status status : 8;
struct kafs_server *servers;
};
struct kafs_cell {
char *name;
char *desc;
char *realm;
bool use_dns;
bool show_cell;
bool borrowed_name;
bool borrowed_desc;
bool borrowed_realm;
struct kafs_server_list *vlservers;
};
struct kafs_cell_db {
unsigned int nr_cells;
struct kafs_cell *cells[];
};
struct kafs_lookup_context {
struct kafs_report report;
struct __res_state res;
bool want_ipv4_addrs;
bool want_ipv6_addrs;
bool no_vls_afsdb;
bool no_vls_srv;
bool no_vl_host;
};
/*
* object.c
*/
extern int kafs_init_lookup_context(struct kafs_lookup_context *ctx);
extern void kafs_clear_lookup_context(struct kafs_lookup_context *ctx);
extern struct kafs_server_list *kafs_alloc_server_list(struct kafs_report *report);
extern void kafs_free_server_list(struct kafs_server_list *sl);
extern void kafs_free_cell(struct kafs_cell *cell);
extern void kafs_transfer_addresses(struct kafs_server *to,
const struct kafs_server *from);
extern int kafs_transfer_server_list(struct kafs_server_list *to,
const struct kafs_server_list *from);
extern void kafs_transfer_cell(struct kafs_cell *to,
const struct kafs_cell *from);
/*
* cellserv.c
*/
extern struct kafs_cell_db *kafs_cellserv_parse_conf(const struct kafs_profile *prof,
struct kafs_report *report);
extern void kafs_cellserv_dump(const struct kafs_cell_db *db);
extern const char *kafs_record_source(enum kafs_record_source source);
extern const char *kafs_lookup_status(enum kafs_lookup_status status);
extern void kafs_dump_cell(const struct kafs_cell *cell);
/*
* dns_lookup.c
*/
extern int kafs_dns_lookup_addresses(struct kafs_server_list *sl,
struct kafs_lookup_context *ctx);
extern int kafs_dns_lookup_vlservers(struct kafs_server_list *vsl,
const char *cell_name,
struct kafs_lookup_context *ctx);
/*
* cell_lookup.c
*/
extern struct kafs_profile kafs_config_profile;
extern struct kafs_cell_db *kafs_cellserv_db;
extern const char *kafs_this_cell;
extern const char *kafs_sysname;
extern int kafs_read_config(const char *const *files,
struct kafs_report *report);
extern struct kafs_cell *kafs_lookup_cell(const char *cell_name,
struct kafs_lookup_context *ctx);
#endif /* _KAFS_CELLSERV_H */
src/include/kafs/profile.h 0000664 0000000 0000000 00000010115 13672703240 0016027 0 ustar 00root root 0000000 0000000 /*
* Kerberos-style profile file parser.
*
* Copyright (C) 2018 David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _KAFS_PROFILE_H
#define _KAFS_PROFILE_H
#include
#include "reporting.h"
enum kafs_profile_value_type {
kafs_profile_value_is_list,
kafs_profile_value_is_string,
};
struct kafs_profile {
enum kafs_profile_value_type type : 8;
bool final;
bool dummy;
unsigned int nr_relations;
unsigned int line;
const char *file;
char *name;
char *value;
struct kafs_profile *parent;
struct kafs_profile **relations;
};
extern void kafs_profile_dump(const struct kafs_profile *p,
unsigned int depth);
extern int kafs_profile_parse_file(struct kafs_profile *prof,
const char *filename,
struct kafs_report *report);
extern int kafs_profile_parse_dir(struct kafs_profile *prof,
const char *dirname,
struct kafs_report *report);
extern const struct kafs_profile *
kafs_profile_find_first_child(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
struct kafs_report *report);
typedef int (*kafs_profile_iterator)(const struct kafs_profile *child,
void *data,
struct kafs_report *report);
extern int kafs_profile_iterate(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
kafs_profile_iterator iterator,
void *data,
struct kafs_report *report);
extern int kafs_profile_count(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
unsigned int *_nr);
/*
* Constant matching.
*/
struct kafs_constant_table {
const char *name;
int value;
};
extern int kafs_lookup_constant2(const struct kafs_constant_table tbl[],
size_t tbl_size,
const char *name,
int not_found);
#define kafs_lookup_constant(t, n, nf) \
kafs_lookup_constant2(t, sizeof(t)/sizeof(t[0]), (n), (nf))
extern int kafs_lookup_bool(const char *name, int not_found);
/*
* Convenience relation parsers.
*/
static inline const char *kafs_profile_get_string(const struct kafs_profile *prof,
const char *name,
struct kafs_report *report)
{
const struct kafs_profile *p;
p = kafs_profile_find_first_child(prof, kafs_profile_value_is_string, name,
report);
return p ? p->value : NULL;
}
static inline bool kafs_profile_get_bool(const struct kafs_profile *prof,
const char *name,
struct kafs_report *report)
{
const struct kafs_profile *p;
int tmp;
p = kafs_profile_find_first_child(prof, kafs_profile_value_is_string, name,
report);
if (!p || !p->value)
return false;
tmp = kafs_lookup_bool(p->value, -1);
if (tmp == -1) {
report->error("%s:%u: Invalid bool value", p->file, p->line);
return false;
}
return tmp;
}
static inline int kafs_profile_iterate_list(const struct kafs_profile *prof,
const char *name,
kafs_profile_iterator iterator,
void *data,
struct kafs_report *report)
{
return kafs_profile_iterate(prof, kafs_profile_value_is_list,
name, iterator, data, report);
}
static inline int kafs_profile_count_list(const struct kafs_profile *prof,
const char *name,
unsigned int *_nr)
{
return kafs_profile_count(prof, kafs_profile_value_is_list,
name, _nr);
}
static inline int kafs_profile_iterate_strings(const struct kafs_profile *prof,
const char *name,
kafs_profile_iterator iterator,
void *data,
struct kafs_report *report)
{
return kafs_profile_iterate(prof, kafs_profile_value_is_string,
name, iterator, data, report);
}
static inline int kafs_profile_count_strings(const struct kafs_profile *prof,
const char *name,
unsigned int *_nr)
{
return kafs_profile_count(prof, kafs_profile_value_is_string,
name, _nr);
}
#endif /* _KAFS_PROFILE_H */
src/include/kafs/reporting.h 0000664 0000000 0000000 00000001603 13672703240 0016402 0 ustar 00root root 0000000 0000000 /*
* Error reporting context.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _KAFS_REPORTING_H
#define _KAFS_REPORTING_H
struct kafs_report {
void (*error)(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void (*verbose)(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void (*verbose2)(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
const char *what;
int line;
bool bad_config; /* T if bad config encountered */
bool bad_error; /* T if fatal system error encountered */
bool abandon_alloc; /* T to not clean up on error */
};
#endif /* _KAFS_REPORTING_H */
src/kafs-check-config.c 0000664 0000000 0000000 00000006521 13672703240 0015263 0 ustar 00root root 0000000 0000000 /*
* kAFS filesystem configuration checker.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include
#include
#include
#include
#include
#include
#include
static void error_report(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
fputc('\n', stderr);
va_end(va);
}
static void verbose(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
printf("[V] ");
vprintf(fmt, va);
putchar('\n');
va_end(va);
}
static __attribute__((noreturn))
void usage(const char *prog)
{
fprintf(stderr,
"Usage: %s [-46PDvv] [-c ]* [-N ] []*\n",
prog);
fprintf(stderr, "\n");
fprintf(stderr, "Where restrictions are one or more of:\n");
fprintf(stderr, "\t-N dns\n");
fprintf(stderr, "\t-N vls-afsdb\n");
fprintf(stderr, "\t-N vls-srv\n");
fprintf(stderr, "\t-N vls-all\n");
fprintf(stderr, "\t-N vl-host\n");
exit(2);
}
int main(int argc, char *argv[])
{
struct kafs_lookup_context ctx = {
.report.error = error_report,
.want_ipv4_addrs = true,
.want_ipv6_addrs = true,
};
const char *filev[10], **filep = NULL;
bool dump_profile = false, dump_db = false;
int opt, filec = 0;
if (argc > 1 && strcmp(argv[1], "--help") == 0)
usage(argv[0]);
while (opt = getopt(argc, argv, "46PDc:vN:"),
opt != -1) {
switch (opt) {
case 'c':
if (filec >= 9) {
fprintf(stderr, "Max 9 files\n");
exit(2);
}
filev[filec++] = optarg;
break;
case 'v':
if (!ctx.report.verbose)
ctx.report.verbose = verbose;
else
ctx.report.verbose2 = verbose;
break;
case 'P':
dump_profile = true;
break;
case 'D':
dump_db = true;
break;
case '4':
ctx.want_ipv4_addrs = true;
ctx.want_ipv6_addrs = false;
break;
case '6':
ctx.want_ipv4_addrs = false;
ctx.want_ipv6_addrs = true;
break;
case 'N':
if (strcmp(optarg, "vl-srv") == 0) {
ctx.no_vls_srv = true;
} else if (strcmp(optarg, "vl-afsdb") == 0) {
ctx.no_vls_afsdb = true;
} else if (strcmp(optarg, "vl-all") == 0) {
ctx.no_vls_srv = true;
ctx.no_vls_afsdb = true;
} else if (strcmp(optarg, "vl-host") == 0) {
ctx.no_vl_host = true;
} else if (strcmp(optarg, "dns") == 0) {
ctx.no_vls_srv = true;
ctx.no_vls_afsdb = true;
ctx.no_vl_host = true;
} else {
fprintf(stderr, "Unknown restriction '-N %s'\n", optarg);
usage(argv[0]);
}
break;
default:
usage(argv[0]);
}
}
argc -= optind;
argv += optind;
if (filec > 0) {
filev[filec] = NULL;
filep = filev;
}
if (kafs_init_lookup_context(&ctx) < 0)
exit(1);
if (kafs_read_config(filep, &ctx.report) < 0)
exit(ctx.report.bad_config ? 3 : 1);
if (dump_profile)
kafs_profile_dump(&kafs_config_profile, 0);
if (dump_db)
kafs_cellserv_dump(kafs_cellserv_db);
for (; *argv; argv++) {
struct kafs_cell *cell;
cell = kafs_lookup_cell(*argv, &ctx);
if (cell) {
printf("\n");
printf("=== Found cell %s ===\n", cell->name);
kafs_dump_cell(cell);
}
}
kafs_clear_lookup_context(&ctx);
return 0;
}
src/lib_cell_lookup.c 0000664 0000000 0000000 00000013406 13672703240 0015157 0 ustar 00root root 0000000 0000000 /*
* Cell database access.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include
#include
#include
#include
#include
#include
#include
#include
static const char *const kafs_std_config[] = {
ETCDIR "/kafs/client.conf",
NULL
};
struct kafs_profile kafs_config_profile = { .name = "" };
struct kafs_cell_db *kafs_cellserv_db;
const char *kafs_this_cell;
const char *kafs_sysname;
#define verbose(r, fmt, ...) \
do { \
if ((r)->verbose) \
(r)->verbose(fmt, ## __VA_ARGS__); \
} while(0)
/*
* Allocate a cell record.
*/
struct kafs_cell *kafs_alloc_cell(const char *cell_name,
struct kafs_lookup_context *ctx)
{
struct kafs_cell *cell;
cell = calloc(1, sizeof(*cell));
if (!cell)
goto error;
cell->name = strdup(cell_name);
if (!cell->name)
goto error;
return cell;
error:
ctx->report.error("%m");
return NULL;
}
/*
* Read the [defaults] section.
*/
static void kafs_read_defaults(struct kafs_profile *prof, struct kafs_report *report)
{
const struct kafs_profile *def;
const char *p;
def = kafs_profile_find_first_child(prof, kafs_profile_value_is_list, "defaults", report);
if (!def) {
verbose(report, "Cannot find [defaults] section");
return;
}
/* Find the current cell name (thiscell = ) */
p = kafs_profile_get_string(def, "thiscell", report);
if (p)
kafs_this_cell = p;
/* Find the @sys substitutions (sysname = ...) */
p = kafs_profile_get_string(def, "sysname", report);
if (p)
kafs_sysname = p;
}
/*
* Read the configuration and initialise the cell database.
*/
int kafs_read_config(const char *const *files, struct kafs_report *report)
{
if (!files)
files = kafs_std_config;
for (; *files; files++)
if (kafs_profile_parse_file(&kafs_config_profile, *files, report) == -1)
return -1;
kafs_cellserv_db = kafs_cellserv_parse_conf(&kafs_config_profile, report);
if (!kafs_cellserv_db)
return -1;
kafs_read_defaults(&kafs_config_profile, report);
return 0;
}
/*
* Deal with an unconfigured cell.
*/
static int kafs_unconfigured_cell(struct kafs_cell *cell,
struct kafs_lookup_context *ctx)
{
struct kafs_server_list *vsl;
verbose(&ctx->report, "%s: Cell not found in config", cell->name);
vsl = kafs_alloc_server_list(&ctx->report);
if (!vsl)
return -1;
cell->vlservers = vsl;
if (kafs_dns_lookup_vlservers(vsl, cell->name, ctx) < 0 ||
kafs_dns_lookup_addresses(vsl, ctx) < 0)
return -1;
verbose(&ctx->report, "DNS query AFSDB RR results:%u ttl:%u",
vsl->nr_servers, vsl->ttl);
return 0;
}
/*
* Look up a cell in configuration and DNS.
*
* The rules are:
*
* (*) Look up the cell in the configuration first.
*
* (*) If there's no cell in the config, we have to try and build it entirely
* from the DNS.
*
* (*) Else:
*
* (*) We look at the configured no_dns setting:
*
* (*) If true, we use the list of servers listed in the config
*
* (*) If false, we try to replace that with one derived from the DNS.
*
* (*) For each server:
*
* (*) we try to look up a list of addresses in NSS/DNS.
*
* (*) If that fails, we use the list of addresses from the config.
*/
struct kafs_cell *kafs_lookup_cell(const char *cell_name,
struct kafs_lookup_context *ctx)
{
const struct kafs_server_list *cvsl;
struct kafs_server_list *vsl;
const struct kafs_cell *conf_cell;
struct kafs_cell *cell;
unsigned int i, j;
if (!kafs_cellserv_db && kafs_read_config(NULL, &ctx->report) < 0)
return NULL;
cell = kafs_alloc_cell(cell_name, ctx);
if (!cell)
return NULL;
for (i = 0; i < kafs_cellserv_db->nr_cells; i++) {
conf_cell = kafs_cellserv_db->cells[i];
if (strcmp(cell_name, conf_cell->name) == 0)
goto cell_is_configured;
}
if (kafs_unconfigured_cell(cell, ctx) < 0)
goto error;
return cell;
/* Deal with the case where we have a configuration. */
cell_is_configured:
verbose(&ctx->report, "%s: Found cell in config", cell_name);
kafs_transfer_cell(cell, conf_cell);
vsl = kafs_alloc_server_list(&ctx->report);
if (!vsl)
goto error;
cell->vlservers = vsl;
/* The DNS overrides the configuration if indicated. */
if (conf_cell->use_dns) {
verbose(&ctx->report, "Query DNS for server list");
if (kafs_dns_lookup_vlservers(vsl, cell_name, ctx) < 0)
goto error;
verbose(&ctx->report, "Looked up %u VL servers [%s, %s]",
vsl->nr_servers,
kafs_lookup_status(vsl->status),
kafs_record_source(vsl->source));
}
/* If we didn't get any servers, copy the server list from the
* configuration.
*/
if (vsl->nr_servers == 0) {
verbose(&ctx->report, "Use configured server list");
if (kafs_transfer_server_list(vsl, conf_cell->vlservers) < 0)
goto error;
}
/* Try and look up addresses for all the servers in the list. */
if (kafs_dns_lookup_addresses(vsl, ctx) < 0)
goto error;
/* Borrow addresses from the config for any server that didn't find any
* in the DNS.
*/
cvsl = conf_cell->vlservers;
if (cvsl) {
for (i = 0; i < vsl->nr_servers; i++) {
struct kafs_server *srv = &vsl->servers[i];
if (srv->nr_addrs)
continue;
verbose(&ctx->report, "Borrow addresses for '%s'", srv->name);
for (j = 0; j < cvsl->nr_servers; j++) {
const struct kafs_server *csrv = &cvsl->servers[j];
if (strcmp(srv->name, csrv->name) == 0) {
verbose(&ctx->report, "From '%s' %u",
csrv->name, csrv->nr_addrs);
kafs_transfer_addresses(srv, csrv);
break;
}
}
}
}
return cell;
error:
if (!ctx->report.abandon_alloc)
kafs_free_cell(cell);
return NULL;
}
src/lib_cellserv.c 0000664 0000000 0000000 00000023673 13672703240 0014475 0 ustar 00root root 0000000 0000000 /*
* Parse the profile tree into a cell server database
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include "dns_resolver.h"
#define report_error(r, fmt, ...) \
({ \
r->error(fmt, ## __VA_ARGS__); \
-1; \
})
#define parse_error(r, fmt, ...) \
({ \
r->bad_config = true; \
r->error("%s:%u: " fmt, r->what, r->line, ## __VA_ARGS__); \
-1; \
})
#define verbose(r, fmt, ...) \
do { \
if (r->verbose) \
r->verbose(fmt, ## __VA_ARGS__); \
} while(0)
#define verbose2(r, fmt, ...) \
do { \
if (r->verbose2) \
r->verbose2(fmt, ## __VA_ARGS__); \
} while(0)
/*
* Parse an address.
*/
static int cellserv_parse_address(const struct kafs_profile *child,
void *data,
struct kafs_report *report)
{
struct kafs_server *server = data;
struct kafs_server_addr *addr = &server->addrs[server->nr_addrs];
const char *v = child->value;
if (server->nr_addrs >= server->max_addrs) {
report_error(report, "%s: Address list overrun", server->name);
return 0;
}
if (inet_pton(AF_INET, v, &addr->sin.sin_addr) == 1) {
addr->sin.sin_family = AF_INET;
addr->sin.sin_port = htons(server->port);
server->nr_addrs++;
return 0;
}
if (v[0] == '[') {
char *p;
v++;
p = strchr(v, ']');
if (!p || p[1])
goto invalid;
p[0] = 0;
}
if (inet_pton(AF_INET6, v, &addr->sin6.sin6_addr) == 1) {
addr->sin6.sin6_family = AF_INET6;
addr->sin6.sin6_port = htons(server->port);
server->nr_addrs++;
return 0;
}
invalid:
parse_error(report, "%s:%u: Invalid address '%s'",
child->file, child->line, child->value);
return 0;
}
/*
* Parse a server definition.
*/
static int cellserv_parse_server(const struct kafs_profile *child,
void *data,
struct kafs_report *report)
{
struct kafs_server_list *vsl = data;
struct kafs_server *server = &vsl->servers[vsl->nr_servers];
unsigned long tmp;
unsigned int max_addrs = 0;
const char *p;
char *q;
if (vsl->nr_servers >= vsl->max_servers) {
report_error(report, "%s: Server list overrun", server->name);
return 0;
}
memset(server, 0, sizeof(*server));
server->source = kafs_record_from_config;
/* Strip off any protocol indicator */
server->name = child->name;
if (strncmp(server->name, "udp/", 4) == 0) {
server->protocol = DNS_SERVER_PROTOCOL_UDP;
server->name += 4;
} else if (strncmp(server->name, "tcp/", 4) == 0) {
server->protocol = DNS_SERVER_PROTOCOL_TCP;
server->name += 4;
}
if (!server->name[0])
return 0;
/* Strip any port number and square brackets */
if (server->name[0] == '[') {
server->name++;
p = strchr(server->name, ']');
if (!*p)
return 0;
*(char *)p = 0;
p++;
if (*p) {
if (*p != ':')
return 0;
p++;
goto extract_port;
}
}
/* Look for foo.com:port or 1.2.3.4:port, but dodge 1:2:3:4 */
p = strchr(server->name, ':');
if (!p)
goto no_port;
*(char *)p = 0;
p++;
if (strchr(p, ':'))
goto no_port;
extract_port:
tmp = strtoul(p, &q, 0);
if (*q)
goto unparseable;
if (tmp > 65536)
goto unparseable;
server->port = tmp;
no_port:
p = kafs_profile_get_string(child, "port", report);
if (p) {
tmp = strtoul(p, &q, 0);
if (*q)
goto unparseable;
if (tmp > 65536)
goto unparseable;
server->port = tmp;
}
/* Generate a list of addresses */
if (kafs_profile_count_strings(child, "address", &max_addrs) < 0)
return -1;
server->addrs = calloc(max_addrs, sizeof(struct kafs_server));
if (!server->addrs)
return -1;
server->max_addrs = max_addrs;
if (kafs_profile_iterate_strings(child, "address",
cellserv_parse_address, server,
report) < 0)
return -1;
p = kafs_profile_get_string(child, "type", report);
if (p) {
if (strcmp(p, "vlserver") == 0)
server->type = kafs_server_is_afs_vlserver;
else if (strcmp(p, "ptserver") == 0)
server->type = kafs_server_is_afs_ptserver;
else
fprintf(stderr, "Unknown type '%s'\n", p);
}
vsl->nr_servers++;
return 0;
unparseable:
parse_error(report, "%s:%u: Invalid address\n", child->file, child->line);
return 0;
}
/*
* Find any Volume Location servers listed for a cell.
*/
static int kafs_cellserv_parse_vl(const struct kafs_profile *child,
struct kafs_cell *cell,
struct kafs_report *report)
{
const struct kafs_profile *servers;
struct kafs_server_list *vsl;
unsigned int max_servers = 0;
/* Find any Volume Location servers listed for that cell */
servers = kafs_profile_find_first_child(child, kafs_profile_value_is_list,
"servers", report);
if (!servers) {
verbose(report, "%s: No servers list", child->name);
return 0;
}
if (kafs_profile_count_list(servers, NULL, &max_servers) < 0)
return -1;
vsl = calloc(1, sizeof(*vsl));
if (!vsl)
return -1;
vsl->source = kafs_record_from_config;
cell->vlservers = vsl;
vsl->servers = calloc(max_servers, sizeof(struct kafs_server));
if (!vsl->servers)
return -1;
vsl->max_servers = max_servers;
return kafs_profile_iterate_list(servers, NULL, cellserv_parse_server,
vsl, report);
}
/*
* Parse a cell definition.
*/
static int kafs_cellserv_parse_cell(const struct kafs_profile *child,
void *data,
struct kafs_report *report)
{
struct kafs_cell_db *db = data;
struct kafs_cell *cell;
cell = calloc(1, sizeof(*cell));
if (!cell)
return -1;
cell->name = child->name;
cell->show_cell = kafs_profile_get_bool(child, "show_cell", report);
cell->use_dns = kafs_profile_get_bool(child, "use_dns", report);
cell->desc = (char *)kafs_profile_get_string(child, "description", report);
cell->realm = (char *)kafs_profile_get_string(child, "kerberos_realm", report);
cell->borrowed_name = true;
cell->borrowed_desc = true;
cell->borrowed_realm = true;
verbose2(report, "CELL: %s: %s", cell->name, cell->desc);
db->cells[db->nr_cells] = cell;
db->nr_cells++;
return kafs_cellserv_parse_vl(child, cell, report);
}
/*
* Extract cell information from a kafs_profile parse tree.
*/
struct kafs_cell_db *kafs_cellserv_parse_conf(const struct kafs_profile *prof,
struct kafs_report *report)
{
const struct kafs_profile *cells;
struct kafs_cell_db *db;
unsigned int nr_cells = 0;
cells = kafs_profile_find_first_child(prof, kafs_profile_value_is_list, "cells", report);
if (!cells) {
report_error(report, "Cannot find [cells] section");
return NULL;
}
if (kafs_profile_count_list(cells, NULL, &nr_cells) < 0)
return NULL;
db = calloc(1, sizeof(*db) + nr_cells * sizeof(struct kafs_cell *));
if (!db)
return NULL;
if (!nr_cells)
return db;
if (kafs_profile_iterate_list(cells, NULL,
kafs_cellserv_parse_cell, db,
report) == -1)
return NULL;
return db;
}
static const char *const kafs_record_sources[nr__kafs_record_source] = {
[kafs_record_unavailable] = "unavailable",
[kafs_record_from_config] = "config",
[kafs_record_from_dns_a] = "A",
[kafs_record_from_dns_afsdb] = "AFSDB",
[kafs_record_from_dns_srv] = "SRV",
[kafs_record_from_nss] = "nss",
};
static const char *const kafs_lookup_statuses[nr__kafs_lookup_status] = {
[kafs_lookup_not_done] = "no-lookup",
[kafs_lookup_good] = "good",
[kafs_lookup_good_with_bad] = "good/bad",
[kafs_lookup_bad] = "bad",
[kafs_lookup_got_not_found] = "not-found",
[kafs_lookup_got_local_failure] = "local-failure",
[kafs_lookup_got_temp_failure] = "temp-failure",
[kafs_lookup_got_ns_failure] = "ns-failure",
};
const char *kafs_record_source(enum kafs_record_source source)
{
if (source >= nr__kafs_record_source)
return "unknown";
return kafs_record_sources[source] ?: "unknown";
}
const char *kafs_lookup_status(enum kafs_lookup_status status)
{
if (status >= nr__kafs_lookup_status)
return "unknown";
return kafs_lookup_statuses[status] ?: "unknown";
}
/*
* Dump a server set.
*/
void kafs_dump_server_list(const struct kafs_server_list *sl,
const char *server_type)
{
unsigned int j, k;
const char *p;
char buf[100];
for (j = 0; j < sl->nr_servers; j++) {
const struct kafs_server *srv = &sl->servers[j];
printf(" - %s %s [%s; %s]\n",
server_type, srv->name,
kafs_lookup_status(srv->status),
kafs_record_source(srv->source));
if (srv->type)
printf(" - %s\n",
srv->type == kafs_server_is_afs_vlserver ?
"VLServer" : "PTServer");
if (srv->protocol)
printf(" - %s\n",
srv->protocol == DNS_SERVER_PROTOCOL_UDP ? "udp" : "tcp");
if (srv->port || srv->pref || srv->weight)
printf(" - port %u, pref %u, weight %u\n",
srv->port, srv->pref, srv->weight);
for (k = 0; k < srv->nr_addrs; k++) {
const struct kafs_server_addr *addr = &srv->addrs[k];
switch (addr->sin.sin_family) {
case AF_INET:
p = inet_ntop(AF_INET, &addr->sin.sin_addr,
buf, sizeof(buf));
break;
case AF_INET6:
p = inet_ntop(AF_INET6, &addr->sin6.sin6_addr,
buf, sizeof(buf));
break;
default:
p = NULL;
break;
}
if (p)
printf(" - address %s\n", p);
}
}
}
/*
* Dump a cell.
*/
void kafs_dump_cell(const struct kafs_cell *cell)
{
const struct kafs_server_list *vsl = cell->vlservers;
if (!cell->use_dns)
printf(" - use-dns=no\n");
if (!cell->show_cell)
printf(" - show-cell=no\n");
if (vsl) {
printf(" - status: %s, from %s\n",
kafs_lookup_status(vsl->status),
kafs_record_source(vsl->source));
kafs_dump_server_list(vsl, "VLSERVER");
}
}
/*
* Dump the parsed afs database.
*/
void kafs_cellserv_dump(const struct kafs_cell_db *db)
{
unsigned int i;
for (i = 0; i < db->nr_cells; i++) {
const struct kafs_cell *cell = db->cells[i];
printf("CELL %s\n", cell->name);
kafs_dump_cell(cell);
}
}
src/lib_dns_lookup.c 0000664 0000000 0000000 00000035064 13672703240 0015030 0 ustar 00root root 0000000 0000000 /*
* Build a cell VL address set based on DNS records.
*
* Copyright (C) Wang Lei (wang840925@gmail.com) 2010
* Authors: Wang Lei (wang840925@gmail.com)
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This is a userspace tool for querying AFSDB RR records in the DNS on behalf
* of the kernel, and converting the VL server addresses to IPv4 format so that
* they can be used by the kAFS filesystem.
*
* As some function like res_init() should use the static liberary, which is a
* bug of libresolv, that is the reason for cifs.upcall to reimplement.
*
* To use this program, you must tell /sbin/request-key how to invoke it. You
* need to have the keyutils package installed and something like the following
* lines added to your /etc/request-key.conf file:
*
* #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ...
* ====== ============ =========== ============ ==========================
* create dns_resolver afsdb:* * /sbin/key.dns_resolver %k
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "dns_resolver.h"
#define AFS_VL_PORT 7003 /* volume location service port */
#define verbose(fmt, ...) \
do { \
if (ctx->report.verbose) \
ctx->report.verbose(fmt, ## __VA_ARGS__); \
} while(0)
/*
* Perform address resolution on a hostname and add the resulting address as a
* string to the list of payload segments.
*/
static int kafs_resolve_addrs(struct kafs_server *server,
int socktype,
struct kafs_lookup_context *ctx)
{
struct kafs_server_addr *addr;
struct addrinfo hints, *addrs, *ai;
int ret, count = 0;
verbose("Resolve '%s'", server->name);
server->source = kafs_record_from_nss;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = socktype;
if (ctx->want_ipv4_addrs && !ctx->want_ipv6_addrs)
hints.ai_family = AF_INET;
else if (ctx->want_ipv6_addrs && !ctx->want_ipv4_addrs)
hints.ai_family = AF_INET6;
/* resolve name to ip */
ret = getaddrinfo(server->name, NULL, &hints, &addrs);
if (ret) {
verbose("%s: getaddrinfo() = %d", server->name, ret);
switch (ret) {
case EAI_MEMORY:
case EAI_SYSTEM:
ctx->report.error("%s: getaddrinfo(): %m", server->name);
goto system_error;
case EAI_FAMILY:
case EAI_SOCKTYPE:
ctx->report.bad_error = true;
server->status = kafs_lookup_got_local_failure;
goto fail;
default:
server->status = kafs_lookup_got_local_failure;
/* Fall through. */
fail:
ctx->report.error("%s: %s", server->name, gai_strerror(ret));
return 0;
case EAI_FAIL:
#ifdef EAI_NODATA
case EAI_NODATA:
#endif
case EAI_NONAME:
case EAI_SERVICE:
server->status = kafs_lookup_got_not_found;
goto fail;
case EAI_AGAIN:
server->status = kafs_lookup_got_temp_failure;
goto fail;
}
}
for (ai = addrs; ai; ai = ai->ai_next)
count++;
server->addrs = calloc(count, sizeof(*addr));
if (!server->addrs) {
ctx->report.error("%m");
goto system_error;
}
server->max_addrs = count;
server->source = kafs_record_from_nss;
server->status = kafs_lookup_good;
for (ai = addrs; ai; ai = ai->ai_next) {
addr = &server->addrs[server->nr_addrs];
verbose("RR: %x,%x,%x,%x,%x,%s",
ai->ai_flags, ai->ai_family,
ai->ai_socktype, ai->ai_protocol,
ai->ai_addrlen, ai->ai_canonname);
/* convert address to string */
switch (ai->ai_family) {
case AF_INET:
if (!ctx->want_ipv4_addrs)
continue;
memcpy(&addr->sin, (struct sockaddr_in *)ai->ai_addr,
sizeof(addr->sin));
server->nr_addrs++;
break;
case AF_INET6:
if (!ctx->want_ipv6_addrs)
continue;
memcpy(&addr->sin6, (struct sockaddr_in *)ai->ai_addr,
sizeof(addr->sin6));
server->nr_addrs++;
break;
default:
verbose("Address of unknown family %u", ai->ai_family);
continue;
}
}
freeaddrinfo(addrs);
return 0;
system_error:
ctx->report.bad_error = true;
return -1;
}
/*
* Go through all the servers records and look up addresses for them.
*/
int kafs_dns_lookup_addresses(struct kafs_server_list *ss,
struct kafs_lookup_context *ctx)
{
struct kafs_server *server;
unsigned int i;
int ret;
if (ss) {
verbose("NR_SERVERS %u", ss->nr_servers);
if (ctx->no_vl_host) {
verbose("Use of DNS for FS server lookup is disabled.");
return 0;
}
for (i = 0; i < ss->nr_servers; i++) {
server = &ss->servers[i];
/* Turn the hostname into IP addresses */
ret = kafs_resolve_addrs(server, SOCK_DGRAM, ctx);
if (ret)
verbose("AFSDB RR can't resolve. subtype:1, server name:%s",
server->name);
else
verbose("NR_ADDRS %u", server->nr_addrs);
}
}
return 0;
}
/*
* Convert the outcome of an AFSDB record lookup into a set of server records.
*/
static int kafs_parse_afsdb(struct kafs_server_list *vsl,
const char *cell_name,
unsigned short subtype,
ns_msg handle,
ns_sect section,
struct kafs_lookup_context *ctx)
{
struct kafs_server *server;
unsigned int rr_ttl, max_servers = 0, i;
ns_rr rr;
char buf[MAXDNAME];
int rrnum, rr_subtype;
verbose("AFSDB RR count is %d", ns_msg_count(handle, section));
/* Count the number of afsdb records */
for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) {
if (ns_parserr(&handle, section, rrnum, &rr)) {
ctx->report.error("%s: afsdb parse failed", cell_name);
continue;
}
if (ns_rr_type(rr) != ns_t_afsdb)
continue;
rr_subtype = ns_get16(ns_rr_rdata(rr));
if (rr_subtype != subtype)
continue;
max_servers++;
}
verbose("NR_SERVER %u", max_servers);
vsl->max_servers = max_servers;
vsl->servers = calloc(max_servers, sizeof(struct kafs_server));
if (!vsl->servers)
goto system_error;
/* Look at all the resource records in this section. */
for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) {
server = &vsl->servers[vsl->nr_servers];
/* Expand the resource record number rrnum into rr. */
if (ns_parserr(&handle, section, rrnum, &rr)) {
ctx->report.error("%s: afsdb parse failed", cell_name);
vsl->status = kafs_lookup_bad;
continue;
}
/* We're only interested in AFSDB records */
if (ns_rr_type(rr) != ns_t_afsdb)
continue;
rr_subtype = ns_get16(ns_rr_rdata(rr));
if (rr_subtype != subtype)
continue;
/* Expand the name server's domain name */
if (ns_name_uncompress(ns_msg_base(handle),
ns_msg_end(handle),
ns_rr_rdata(rr) + 2,
buf,
MAXDNAME) < 0) {
ctx->report.error("%s: afsdb uncompress failed", cell_name);
vsl->status = kafs_lookup_bad;
continue;
}
rr_ttl = ns_rr_ttl(rr);
if (vsl->ttl > rr_ttl)
vsl->ttl = rr_ttl;
/* Check the domain name we've just unpacked and add it to
* the list of VL servers if it is not a duplicate.
* If it is a duplicate, just ignore it.
*/
for (i = 0; i < vsl->nr_servers; i++)
if (strcasecmp(buf, vsl->servers[i].name) == 0)
continue;
server->name = strdup(buf);
if (!server->name)
goto system_error;
server->port = AFS_VL_PORT;
server->protocol = DNS_SERVER_PROTOCOL_UDP;
verbose("SERVER[%u] %s", vsl->nr_servers, server->name);
vsl->nr_servers++;
}
if (vsl->nr_servers > 0 && vsl->status == kafs_lookup_bad)
vsl->status = kafs_lookup_good_with_bad;
if (vsl->nr_servers == 0 && vsl->status == kafs_lookup_good_with_bad)
vsl->status = kafs_lookup_got_not_found;
return 0;
system_error:
ctx->report.bad_error = true;
ctx->report.error("%m");
return -1;
}
/*
* Look up an AFSDB record to get the VL server addresses.
*/
static int dns_query_AFSDB(struct kafs_server_list *vsl,
const char *cell_name,
unsigned short subtype,
struct kafs_lookup_context *ctx)
{
int response_len; /* buffer length */
ns_msg handle; /* handle for response message */
union {
HEADER hdr;
u_char buf[NS_PACKETSZ];
} response; /* response buffers */
verbose("Get AFSDB RR for cell name:'%s'", cell_name);
/* query the dns for an AFSDB resource record */
response_len = res_nquery(&ctx->res,
cell_name,
ns_c_in,
ns_t_afsdb,
response.buf,
sizeof(response));
if (response_len < 0) {
ctx->report.error("%s: %s", cell_name, hstrerror(h_errno));
switch (h_errno) {
case HOST_NOT_FOUND:
case NO_DATA:
default:
vsl->status = kafs_lookup_got_not_found;
break;
case NO_RECOVERY:
vsl->status = kafs_lookup_got_ns_failure;
break;
case TRY_AGAIN:
vsl->status = kafs_lookup_got_temp_failure;
break;
}
return 0;
}
vsl->source = kafs_record_from_dns_afsdb;
if (ns_initparse(response.buf, response_len, &handle) < 0) {
ctx->report.error("%s: ns_initparse: %s",
cell_name, hstrerror(h_errno));
vsl->status = kafs_lookup_bad;
return 0;
}
/* look up the hostnames we've obtained to get the actual addresses */
vsl->status = kafs_lookup_good;
return kafs_parse_afsdb(vsl, cell_name, subtype, handle, ns_s_an, ctx);
}
/*
* Convert the outcome of an SRV record lookup into a set of server records.
*/
static int kafs_parse_srv(struct kafs_server_list *vsl,
const char *domain_name,
ns_msg handle,
ns_sect section,
enum dns_payload_protocol_type protocol,
struct kafs_lookup_context *ctx)
{
struct kafs_server *server;
unsigned int max_servers = 0, rr_ttl, i;
ns_rr rr;
char buf[MAXDNAME];
int rrnum;
verbose("SRV RR count is %d", ns_msg_count(handle, section));
/* Count the number of srv records */
for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) {
if (ns_parserr(&handle, section, rrnum, &rr)) {
ctx->report.error("%s: ns_parserr", domain_name);
continue;
}
if (ns_rr_type(rr) != ns_t_srv)
continue;
max_servers++;
}
verbose("NR_SERVER %u", max_servers);
vsl->max_servers = max_servers;
vsl->servers = calloc(max_servers, sizeof(struct kafs_server));
if (!vsl->servers)
goto system_error;
for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) {
server = &vsl->servers[vsl->nr_servers];
/* Expand the resource record number rrnum into rr. */
if (ns_parserr(&handle, section, rrnum, &rr)) {
ctx->report.error("%s: ns_parserr", domain_name);
vsl->status = kafs_lookup_bad;
continue;
}
if (ns_rr_type(rr) != ns_t_srv)
continue;
ns_get16(ns_rr_rdata(rr)); /* subtype */
/* Expand the name server's domain name */
if (ns_name_uncompress(ns_msg_base(handle),
ns_msg_end(handle),
ns_rr_rdata(rr) + 6,
buf,
MAXDNAME) < 0) {
ctx->report.error("%s: ns_name_uncompress", domain_name);
vsl->status = kafs_lookup_bad;
continue;
}
rr_ttl = ns_rr_ttl(rr);
if (vsl->ttl > rr_ttl)
vsl->ttl = rr_ttl;
server->pref = ns_get16(ns_rr_rdata(rr));
server->weight = ns_get16(ns_rr_rdata(rr) + 2);
server->port = ns_get16(ns_rr_rdata(rr) + 4);
verbose("rdata %u %u %u", server->pref, server->weight, server->port);
/* Check the domain name we've just unpacked and add it to
* the list of VL servers if it is not a duplicate.
* If it is a duplicate, just ignore it.
*/
for (i = 0; i < vsl->nr_servers; i++)
if (strcasecmp(buf, vsl->servers[i].name) == 0)
continue;
server->name = strdup(buf);
if (!server->name)
goto system_error;
server->port = AFS_VL_PORT;
server->protocol = protocol;
verbose("SERVER[%u] %s", vsl->nr_servers, server->name);
vsl->nr_servers++;
}
if (vsl->nr_servers > 0 && vsl->status == kafs_lookup_bad)
vsl->status = kafs_lookup_good_with_bad;
if (vsl->nr_servers == 0 && vsl->status == kafs_lookup_good_with_bad)
vsl->status = kafs_lookup_got_not_found;
return 0;
system_error:
ctx->report.bad_error = true;
ctx->report.error("%m");
return -1;
}
/*
* Look up an SRV record to get the VL server addresses [RFC 5864].
*/
static int dns_query_SRV(struct kafs_server_list *vsl,
const char *domain_name,
const char *service_name,
const char *proto_name,
struct kafs_lookup_context *ctx)
{
int response_len; /* buffer length */
ns_msg handle; /* handle for response message */
union {
HEADER hdr;
u_char buf[NS_PACKETSZ];
} response;
enum dns_payload_protocol_type protocol;
char name[1024];
snprintf(name, sizeof(name), "_%s._%s.%s",
service_name, proto_name, domain_name);
verbose("Get SRV RR for name:'%s'", name);
response_len = res_nquery(&ctx->res,
name,
ns_c_in,
ns_t_srv,
response.buf,
sizeof(response));
if (response_len < 0) {
ctx->report.error("%s: dns: %s",
domain_name, hstrerror(h_errno));
switch (h_errno) {
case HOST_NOT_FOUND:
case NO_DATA:
vsl->status = kafs_lookup_got_not_found;
break;
case NO_RECOVERY:
vsl->status = kafs_lookup_got_ns_failure;
break;
case TRY_AGAIN:
vsl->status = kafs_lookup_got_temp_failure;
break;
}
return 0;
}
vsl->source = kafs_record_from_dns_srv;
if (ns_initparse(response.buf, response_len, &handle) < 0) {
ctx->report.error("%s: ns_initparse: %s",
domain_name, hstrerror(h_errno));
vsl->status = kafs_lookup_bad;
return 0;
}
if (strcmp(proto_name, "udp") == 0)
protocol = DNS_SERVER_PROTOCOL_UDP;
else if (strcmp(proto_name, "tcp") == 0)
protocol = DNS_SERVER_PROTOCOL_TCP;
else
protocol = DNS_SERVER_PROTOCOL_UNSPECIFIED;
vsl->status = kafs_lookup_good;
return kafs_parse_srv(vsl, domain_name, handle, ns_s_an, protocol, ctx);
}
/*
* Look up a cell by name in the DNS.
*/
int kafs_dns_lookup_vlservers(struct kafs_server_list *vsl,
const char *cell_name,
struct kafs_lookup_context *ctx)
{
int ret;
vsl->status = kafs_lookup_not_done;
if (!ctx->no_vls_srv) {
ret = dns_query_SRV(vsl, cell_name, "afs3-vlserver", "udp", ctx);
if (ret == 0 && vsl->nr_servers > 0)
return 0;
} else {
verbose("Use of DNS/SRV for VL server lookup is disabled.");
}
if (!ctx->no_vls_afsdb) {
ret = dns_query_AFSDB(vsl, cell_name, 1, ctx);
if (ret == 0 && vsl->nr_servers > 0)
return 0;
} else {
verbose("Use of DNS/AFSDB for VL server lookup is disabled.");
}
return 0;
}
src/lib_object.c 0000664 0000000 0000000 00000006374 13672703240 0014123 0 ustar 00root root 0000000 0000000 /*
* Object creation/destruction.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
/*
* Initialise state in a lookup context.
*/
int kafs_init_lookup_context(struct kafs_lookup_context *ctx)
{
memset(&ctx->res, 0, sizeof(ctx->res));
if (res_ninit(&ctx->res) < 0) {
ctx->report.bad_error = true;
ctx->report.error("%m");
return -1;
}
return 0;
}
/*
* Clear state in a lookup context.
*/
void kafs_clear_lookup_context(struct kafs_lookup_context *ctx)
{
res_nclose(&ctx->res);
}
/*
* Allocate a blank server list.
*/
struct kafs_server_list *kafs_alloc_server_list(struct kafs_report *report)
{
struct kafs_server_list *sl;
sl = calloc(1, sizeof(*sl));
if (!sl) {
report->bad_error = true;
report->error("%m");
return NULL;
}
sl->ttl = UINT_MAX;
return sl;
}
/*
* Free a server list.
*/
void kafs_free_server_list(struct kafs_server_list *sl)
{
unsigned int i;
if (sl->servers) {
for (i = 0; i < sl->nr_servers; i++) {
struct kafs_server *s = &sl->servers[i];
if (!s->borrowed_name)
free(s->name);
if (!s->borrowed_addrs)
free(s->addrs);
}
free(sl->servers);
}
free(sl);
}
/*
* Free a cell.
*/
void kafs_free_cell(struct kafs_cell *cell)
{
if (!cell->borrowed_name) free(cell->name);
if (!cell->borrowed_desc) free(cell->desc);
if (!cell->borrowed_realm) free(cell->realm);
if (cell->vlservers)
kafs_free_server_list(cell->vlservers);
free(cell);
}
/*
* Transfer the addresses from one server to another.
*/
void kafs_transfer_addresses(struct kafs_server *to,
const struct kafs_server *from)
{
to->max_addrs = 0;
to->nr_addrs = from->nr_addrs;
to->addrs = from->addrs;
to->borrowed_addrs = true;
}
/*
* Transfer the list of servers from one server list to another.
*/
int kafs_transfer_server_list(struct kafs_server_list *to,
const struct kafs_server_list *from)
{
unsigned int i, nr = from->nr_servers;
to->source = from->source;
to->status = from->status;
to->nr_servers = nr;
to->max_servers = from->max_servers;
to->ttl = from->ttl;
if (nr == 0) {
to->servers = NULL;
return 0;
}
to->servers = malloc(nr * sizeof(struct kafs_server));
if (!to->servers)
return -1;
memcpy(to->servers, from->servers, nr * sizeof(struct kafs_server));
for (i = 0; i < nr; i++) {
struct kafs_server *s = &to->servers[i];
s->borrowed_name = true;
s->max_addrs = 0;
s->nr_addrs = 0;
s->addrs = NULL;
}
return 0;
}
/*
* Transfer information from one cell record to another.
*/
void kafs_transfer_cell(struct kafs_cell *to, const struct kafs_cell *from)
{
if (!to->name) {
to->name = from->name;
to->borrowed_name = true;
}
if (from->desc) {
to->desc = from->desc;
to->borrowed_desc = true;
}
if (from->realm) {
to->realm = from->realm;
to->borrowed_realm = true;
}
to->use_dns = from->use_dns;
to->show_cell = from->show_cell;
}
src/lib_profile.c 0000664 0000000 0000000 00000025564 13672703240 0014317 0 ustar 00root root 0000000 0000000 /*
* Kerberos-style profile file parser.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define report_error(r, fmt, ...) \
({ \
r->error(fmt, ## __VA_ARGS__); \
-1; \
})
#define parse_error(r, fmt, ...) \
({ \
r->bad_config = true; \
r->error("%s:%u: " fmt, r->what, r->line, ## __VA_ARGS__); \
-1; \
})
/*
* Dump a profile to stdout in tree form.
*/
void kafs_profile_dump(const struct kafs_profile *p, unsigned int depth)
{
unsigned int i;
if (p->type == kafs_profile_value_is_list) {
printf("%*s [*] '%s'%s\n",
depth, "",
p->name,
p->final ? " [final]" : "");
for (i = 0; i < p->nr_relations; i++)
kafs_profile_dump(p->relations[i], depth + 2);
} else {
printf("%*s [=] '%s' = '%s'\n", depth, "", p->name, p->value);
}
}
/*
* Find/create relation in the list to which we're contributing.
*
* If a list relation is already closed then it is replaced unless it is final,
* in which case the new stuff is ignored.
*/
static struct kafs_profile *kafs_profile_get_relation(struct kafs_profile *parent,
char *name,
enum kafs_profile_value_type type,
struct kafs_report *report)
{
struct kafs_profile *r, **list = parent->relations;
bool dummy = false;
int i, n = parent->nr_relations;
if (parent->type != kafs_profile_value_is_list) {
report->error("%s:%u: Can't insert into a non-list",
report->what, report->line);
return NULL;
}
if (type == kafs_profile_value_is_list) {
for (i = 0; i < n; i++) {
r = list[i];
if (r->type != kafs_profile_value_is_list ||
strcmp(r->name, name) != 0)
continue;
if (r->final) {
dummy = true;
goto create;
}
r->final |= parent->final;
return r;
}
}
create:
r = malloc(sizeof(*r));
if (!r)
return NULL;
memset(r, 0, sizeof(*r));
r->type = type;
r->name = name;
r->parent = parent;
r->dummy = dummy | parent->final | parent->dummy;
if (!r->dummy) {
list = realloc(list, sizeof(*list) * (n + 1));
if (!list)
return NULL;
list[n] = r;
parent->relations = list;
parent->nr_relations = n + 1;
}
return r;
}
/*
* Parse the contents of a kafs_profile file.
*/
static int kafs_profile_parse_content(struct kafs_profile *prof, const char *file,
char *p, char *end,
struct kafs_report *report)
{
struct kafs_profile *section = NULL, *list = NULL, *tmp;
unsigned int line = 0;
char *eol, *next_line = p, *key, *value;
bool at_left;
next_line:
p = next_line;
line++;
report->line = line;
at_left = p < end && !isblank(*p);
while (p < end && isblank(*p)) p++;
if (p == end)
return 0;
eol = strpbrk(p, "\n\r");
if (!eol) {
next_line = eol = end;
} else {
next_line = eol + 1;
if (next_line < end && *next_line != *eol &&
(*next_line == '\n' || *next_line == '\r'))
next_line++; /* handle CRLF and LFCR */
while (eol > p && isblank(eol[-1]))
eol--;
*eol = 0;
}
if (!*p || p[0] == '#' || p[0] == ';')
goto next_line;
/* Deal with section markers. */
if (list == section && p[0] == '[') {
if (eol - p < 3 || eol[-1] != ']')
return parse_error(report, "Bad section label");
p++;
eol--;
*eol = 0;
if (strchr(p, ']'))
return parse_error(report, "Bad section label");
section = kafs_profile_get_relation(prof, p, kafs_profile_value_is_list,
report);
if (!section)
return -1;
section->file = file;
section->line = line;
list = section;
goto next_line;
}
/* Things before the first section are either comments or inclusion
* directives.
*/
if (!section) {
if (!at_left || strncmp(p, "include", 7) != 0)
goto next_line;
p += 7;
if (isblank(*p)) {
/* It's an include directive */
while (*p && isblank(*p)) p++;
if (!*p)
return parse_error(report, "No include path");
if (kafs_profile_parse_file(prof, p, report) < 0)
return -1;
}
if (strncmp(p, "dir", 3) == 0 && (isblank(p[3]) || !p[3])) {
/* It's an includedir directive */
p += 3;
while (*p && isblank(*p)) p++;
if (!*p)
return parse_error(report, "No includedir path");
if (kafs_profile_parse_dir(prof, p, report) < 0)
return -1;
}
goto next_line;
}
/* Deal with the closure of a list */
if (p[0] == '}') {
if (list == section)
return parse_error(report, "Unmatched '}'");
p++;
if (p[0] == '*') {
list->final = true;
p++;
}
if (*p)
return parse_error(report, "Unexpected stuff after '}'");
tmp = list;
list = list->parent;
if (tmp->dummy)
free(tmp);
goto next_line;
}
/* Everything else should be a relation specifier of one of the
* following forms:
*
* x = y
* x = { .. }
*/
key = p;
p = strchr(p, '=');
if (!p)
return parse_error(report, "Missing '=' in relation");
if (p == key)
return parse_error(report, "Anonymous key in relation");
value = p + 1;
while (value < eol && isblank(*value)) value++;
p--;
while (p > key && isblank(p[-1]))
p--;
*p = 0;
/* Handle the opening of a new list-type relation */
if (value[0] == '{') {
if (value[1])
return parse_error(report, "Unexpected stuff after '{'");
list = kafs_profile_get_relation(list, key, kafs_profile_value_is_list,
report);
if (!list)
return -1;
list->file = file;
list->line = line;
goto next_line;
}
/* Handle a relation with a quoted-string value */
if (value[0] == '"') {
char *q;
value++;
if (eol <= value || eol[-1] != '"')
return parse_error(report, "Unterminated string");
eol--;
eol[0] = 0;
/* Substitute for all the escape chars in place */
for (p = q = value; p < eol;) {
char ch = *p++;
if (ch == '\\') {
if (p >= eol)
return parse_error(report, "Uncompleted '\\' escape");
ch = *p++;
switch (ch) {
case 'n': ch = '\n'; break;
case 't': ch = '\t'; break;
case 'b': ch = '\b'; break;
}
}
*q++ = ch;
}
*q = 0;
}
tmp = kafs_profile_get_relation(list, key, kafs_profile_value_is_string, report);
if (!tmp)
return -1;
tmp->file = file;
tmp->line = line;
tmp->value = value;
goto next_line;
}
/*
* Parse a kafs_profile file.
*/
int kafs_profile_parse_file(struct kafs_profile *prof, const char *file,
struct kafs_report *report)
{
const char *old_file = report->what;
struct stat st;
ssize_t n;
char *buffer;
int fd, ret;
report->what = file;
fd = open(file, O_RDONLY);
if (fd == -1)
return -1;
if (fstat(fd, &st) == -1) {
close(fd);
return -1;
}
buffer = malloc(st.st_size + 1);
if (!buffer) {
close(fd);
return -1;
}
n = read(fd, buffer, st.st_size);
close(fd);
if (n == -1) {
free(buffer);
return -1;
}
buffer[n] = 0;
ret = kafs_profile_parse_content(prof, file, buffer, buffer + n, report);
if (ret == 0)
report->what = old_file;
return ret;
}
/*
* Parse a kafs_profile directory.
*/
int kafs_profile_parse_dir(struct kafs_profile *prof,
const char *dirname,
struct kafs_report *report)
{
const char *old_file = report->what;
struct dirent *de;
char *filename;
DIR *dir;
int ret, n;
report->what = dirname;
report->line = 0;
dir = opendir(dirname);
if (!dir)
return report_error(report, "%s: %m", dirname);
while (errno = 0,
(de = readdir(dir))) {
if (de->d_name[0] == '.')
continue;
n = strlen(de->d_name);
if (n < 1 || de->d_name[n - 1] == '~')
continue;
if (asprintf(&filename, "%s/%s", dirname, de->d_name) == -1) {
closedir(dir);
return report_error(report, "%m");
}
ret = kafs_profile_parse_file(prof, filename, report);
if (ret < 0) {
closedir(dir);
return -1;
}
}
report->what = dirname;
closedir(dir);
if (errno != 0)
return -1;
report->what = old_file;
return 0;
}
/*
* Find the first child object of a type and name in the list attached to the
* given object.
*/
const struct kafs_profile *kafs_profile_find_first_child(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
struct kafs_report *report)
{
unsigned int i;
if (prof->type != kafs_profile_value_is_list) {
report_error(report, "Trying to find '%s' in relation '%s'",
name, prof->name);
return NULL;
}
for (i = 0; i < prof->nr_relations; i++) {
const struct kafs_profile *r = prof->relations[i];
if (r->type == type &&
strcmp(r->name, name) == 0)
return r;
}
return NULL;
}
/*
* Iterate over all the child objects of the given type and name in the list
* attached to the given object until the iterator function returns non-zero.
*/
int kafs_profile_iterate(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
kafs_profile_iterator iterator,
void *data,
struct kafs_report *report)
{
unsigned int i;
int ret;
if (prof->type != kafs_profile_value_is_list) {
report_error(report, "Trying to iterate over relation '%s'",
prof->name);
return -1;
}
for (i = 0; i < prof->nr_relations; i++) {
const struct kafs_profile *r = prof->relations[i];
if (r->type != type)
continue;
if (name && strcmp(r->name, name) != 0)
continue;
ret = iterator(r, data, report);
if (ret)
return ret;
}
return 0;
}
static int kafs_count_objects(const struct kafs_profile *child,
void *data,
struct kafs_report *report)
{
unsigned int *_nr = data;
*_nr += 1;
return 0;
}
/*
* Count the number of matching children of an object.
*/
int kafs_profile_count(const struct kafs_profile *prof,
enum kafs_profile_value_type type,
const char *name,
unsigned int *_nr)
{
return kafs_profile_iterate(prof, type, NULL, kafs_count_objects, _nr, NULL);
}
static int cmp_constant(const void *name, const void *entry)
{
const struct kafs_constant_table *e = entry;
return strcasecmp(name, e->name);
}
/*
* Turn a string into a constant.
*/
int kafs_lookup_constant2(const struct kafs_constant_table *tbl, size_t tbl_size,
const char *name, int not_found)
{
const struct kafs_constant_table *e;
e = bsearch(name, tbl, tbl_size, sizeof(tbl[0]), cmp_constant);
if (!e)
return not_found;
return e->value;
}
static const struct kafs_constant_table bool_names[] = {
{ "0", false },
{ "1", true },
{ "f", false },
{ "false", false },
{ "n", false },
{ "no", false },
{ "off", false },
{ "on", true },
{ "t", true },
{ "true", true },
{ "y", true },
{ "yes", true },
};
/*
* Parse a string as a bool constant.
*/
int kafs_lookup_bool(const char *name, int not_found)
{
return kafs_lookup_constant(bool_names, name, not_found);
}
src/preload-cells.c 0000664 0000000 0000000 00000010030 13672703240 0014535 0 ustar 00root root 0000000 0000000 /*
* Cell preloader for kAFS filesystem.
*
* Copyright (C) David Howells (dhowells@redhat.com) 2018
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static void verbose(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (isatty(2)) {
vprintf(fmt, va);
putchar('\n');
} else {
vsyslog(LOG_INFO, fmt, va);
}
va_end(va);
}
/*
* Just print an error to stderr or the syslog
*/
static void _error(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (isatty(2)) {
vfprintf(stderr, fmt, va);
fputc('\n', stderr);
} else {
vsyslog(LOG_ERR, fmt, va);
}
va_end(va);
}
/*
* Write a string to a proc file.
*/
static void write_to_proc(const char *file, const char *str, bool redirect_to_stdout)
{
int fd = 1, n;
if (!str)
return;
if (redirect_to_stdout) {
printf("WRITE '%s' TO %s\n", str, file);
return;
}
fd = open(file, O_WRONLY);
if (fd == -1) {
_error("Can't open %s: %m", file);
exit(1);
}
n = strlen(str);
if (write(fd, str, n) != n) {
_error("Can't write '%s' to %s: %m", str, file);
exit(1);
}
if (close(fd) == -1) {
_error("Can't close %s: %m", file);
exit(1);
}
}
/*
* Parse the cell database file
*/
int do_preload(const struct kafs_cell_db *db, bool redirect_to_stdout)
{
unsigned int i;
char buf[4096];
int fd, n;
if (!redirect_to_stdout) {
fd = open("/proc/fs/afs/cells", O_WRONLY);
if (fd == -1) {
_error("Can't open /proc/fs/afs/cells: %m");
exit(1);
}
} else {
fd = -1;
}
for (i = 0; i < db->nr_cells; i++) {
const struct kafs_cell *cell = db->cells[i];
n = snprintf(buf, sizeof(buf) - 1, "add %s", cell->name);
if (redirect_to_stdout) {
printf("WRITE '%s' TO /proc/fs/afs/cells\n", buf);
continue;
}
if (write(fd, buf, n) != n) {
if (errno != EEXIST) {
_error("Can't add cell '%s': %m", cell->name);
exit(1);
}
verbose("%s: Already exists", cell->name);
}
}
if (!redirect_to_stdout) {
if (close(fd) == -1) {
_error("Can't close /proc/fs/afs/cells: %m");
exit(1);
}
}
write_to_proc("/proc/net/afs/rootcell", kafs_this_cell, redirect_to_stdout);
write_to_proc("/proc/net/afs/sysname", kafs_sysname, redirect_to_stdout);
exit(0);
}
static __attribute__((noreturn))
void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [-Dv] [*]\n", prog);
exit(2);
}
int main(int argc, char *argv[])
{
struct kafs_report report = {};
const char *const *files;
bool redirect_to_stdout = false;
int opt;
if (argc > 1 && strcmp(argv[1], "--help") == 0)
usage(argv[0]);
while (opt = getopt(argc, argv, "Dv"),
opt != -1) {
switch (opt) {
case 'D':
redirect_to_stdout = true;
break;
case 'v':
if (!report.verbose)
report.verbose = verbose;
else
report.verbose2 = verbose;
break;
default:
usage(argv[0]);
break;
}
}
if (!redirect_to_stdout) {
openlog("kafs-preload", 0, LOG_USER);
syslog(LOG_NOTICE, "kAFS: Preloading cell database");
}
argc -= optind;
argv += optind;
files = NULL;
if (argc > 0)
files = (const char **)argv;
if (kafs_read_config(files, &report) < 0)
exit(3);
do_preload(kafs_cellserv_db, redirect_to_stdout);
return 0;
}
src/version.lds 0000664 0000000 0000000 00000001170 13672703240 0014041 0 ustar 00root root 0000000 0000000 KAFS_CLIENT_0.1 {
kafs_alloc_cell;
kafs_alloc_server_list;
kafs_cellserv_dump;
kafs_cellserv_parse_conf;
kafs_cellserv_profile;
kafs_clear_lookup_context;
kafs_dns_lookup_addresses;
kafs_dns_lookup_vlservers;
kafs_dump_cell;
kafs_dump_server_list;
kafs_free_cell;
kafs_free_server_list;
kafs_init_celldb;
kafs_init_lookup_context;
kafs_lookup_bool;
kafs_lookup_cell;
kafs_lookup_constant2;
kafs_profile_count;
kafs_profile_dump;
kafs_profile_find_first_child;
kafs_profile_iterate;
kafs_profile_parse_dir;
kafs_profile_parse_file;
kafs_transfer_addresses;
kafs_transfer_cell;
kafs_transfer_server_list;
};
| | | | |