B<butc> S<<< [B<-port> <I<port offset>>] >>> S<<< [B<-debuglevel> (0 | 1 | 2)] >>>
S<<< [B<-cell> <I<cell name>>] >>> [B<-noautoquery>] [B<-rxbind>] [B<-localauth>]
- [B<-auditlog> <I<file | sysvmq>> [B<-audit-interface> <I<interface>>]] [B<-help>]
+ [B<-auditlog> <I<file | sysvmq>> [B<-audit-interface> <I<interface>>]]
+ [B<-allow_unauthenticated>] [B<-help>]
B<butc> S<<< [B<-p> <I<port offset>>] >>> S<<< [B<-d> (0 | 1 | 2)] >>>
S<<< [B<-c> <I<cell name>>] >>> [B<-n>] [B<-r>] [B<-l>]
- [B<-auditl> <I<file | sysvmq>> [-B<-audit-i> <I<interface>>]] [B<-h>]
+ [B<-auditl> <I<file | sysvmq>> [-B<-audit-i> <I<interface>>]]
+ [B<-al>] [B<-h>]
=for html
</div>
Specifies what audit interface to use. Defaults to C<file>. See
L<fileserver(8)> for an explanation of each interface.
+=item B<-allow_unauthenticated>
+
+By default the B<butc> requires clients performing TC_ RPCs to authenticate
+themselves, behavior introduced in the fix for OPENAFS-SA-2018-001.
+This option reverts to the historical behavior of only using the rxnull
+security class for incoming connections. Use of this option is strongly
+disrecommended; it is provided only for backwards compatibility with older
+clients in environments where B<backup> and B<butc> communicate over a secure
+network that denies access to untrusted parties.
+
=item B<-help>
Prints the online help for this command. All other valid options are
afs_int32 lastLog; /* Log last pass info */
int rxBind = 0;
struct afsconf_dir *butc_confdir;
+int allow_unauth = 0;
#define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
afs_uint32 SHostAddrs[ADDRSPERSITE];
static int
WorkerBee(struct cmd_syndesc *as, void *arock)
{
- afs_int32 code;
- struct rx_securityClass *(securityObjects[1]);
+ afs_int32 code, numClasses;
+ struct rx_securityClass *(nullObjects[1]), **secObjs, **allObjs;
struct rx_service *service;
time_t tokenExpires;
char cellName[64];
localauth = (as->parms[5].items ? 1 : 0);
rxBind = (as->parms[8].items ? 1 : 0);
+ allow_unauth = (as->parms[11].items ? 1 : 0);
+
+ if (!allow_unauth && !localauth) {
+ const char *errstr = "Neither -localauth nor -allow_unauthenticated was provided; refusing to start in unintended insecure configuration\n";
+ TLog(0, "%s", (char *)errstr);
+ exit(1);
+ }
if (rxBind) {
afs_int32 ccode;
/* initialize database support, volume support, and logs */
- /* Create a single security object, in this case the null security
- * object, for unauthenticated connections, which will be used to control
- * security on connections made to this server
+ /*
+ * Create security objects for the Rx server functionality. Historically
+ * this was a single rxnull security object, since the tape controller was
+ * run by an operator that had local access to the tape device and some
+ * administrative privilege in the cell (to be able to perform volume-level
+ * accesses), but on a machine that was not necessarily trusted to hold the
+ * cell-wide key.
+ *
+ * Such a configuration is, of course, insecure because anyone can make
+ * inbound RPCs and manipulate the database, including creating bogus
+ * dumps and restoring them! Additionally, in modern usage, butc is
+ * frequently run with -localauth to authenticate its outbound connections
+ * to the volservers and budb with the cell-wide key, in which case the
+ * cell-wide key is present and could be used to authenticate incoming
+ * connections as well.
+ *
+ * If -localauth is in use, create the full barrage of server security
+ * objects, including rxkad, so that inbound connections can be verified
+ * to only be made by authenticated clients. Otherwise, only the rxnull
+ * class is in use with a single server security object. Note that butc
+ * will refuse to start in this configuration unless the
+ * "-allow_unauthenticated" flag is provided, indicating that the operator
+ * has ensured that incoming connections are appropriately restricted by
+ * firewall configuration or network topology.
*/
- securityObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject();
- if (!securityObjects[RX_SECIDX_NULL]) {
- TLog(0, "rxnull_NewServerSecurityObject");
- exit(1);
+ if (allow_unauth) {
+ nullObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject();
+ if (!nullObjects[RX_SECIDX_NULL]) {
+ TLog(0, "rxnull_NewServerSecurityObject");
+ exit(1);
+ }
+ numClasses = 1;
+ secObjs = nullObjects;
+ } else {
+ /* Must be -localauth, so the cell keys are available. */
+ afsconf_BuildServerSecurityObjects(butc_confdir, &allObjs, &numClasses);
+ secObjs = allObjs;
}
service =
- rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 1, TC_ExecuteRequest);
+ rx_NewServiceHost(host, 0, 1, "BUTC", secObjs, numClasses, TC_ExecuteRequest);
if (!service) {
TLog(0, "rx_NewService");
exit(1);
cmd_AddParm(ts, "-auditlog", CMD_SINGLE, CMD_OPTIONAL, "location of audit log");
cmd_AddParm(ts, "-audit-interface", CMD_SINGLE, CMD_OPTIONAL,
"interface to use for audit logging");
+ cmd_AddParm(ts, "-allow_unauthenticated", CMD_FLAG, CMD_OPTIONAL,
+ "allow unauthenticated inbound RPCs (requires firewalling)");
/* Initialize dirpaths */
if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {