OPENAFS-SA-2018-001 Add auditing to butc server RPC implementations

Make the actual implementations into helper functions, with the RPC
stubs calling the helpers and doing the auditing on the results, akin
to most other server programs in the tree.  This relies on support for
some additional types having been added to the audit framework.

Change-Id: Ic872d6dfc7854fa28bd3dc2277e92c7919d0d0c0
This commit is contained in:
Benjamin Kaduk 2018-09-09 11:49:03 -05:00
parent 9ebff4c6ca
commit c43169fd36
7 changed files with 266 additions and 12 deletions

View File

@ -8,10 +8,12 @@ butc - Initializes the Tape Coordinator process
<div class="synopsis">
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<-help>]
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<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<-h>]
S<<< [B<-c> <I<cell name>>] >>> [B<-n>] [B<-r>] [B<-l>]
[B<-auditl> <I<file | sysvmq>> [-B<-audit-i> <I<interface>>]] [B<-h>]
=for html
</div>
@ -186,6 +188,19 @@ logged on to a server machine as the local superuser C<root>; client
machines do not have F</usr/afs/etc/KeyFile> or F</usr/afs/etc/KeyFileExt>
files.
=item B<-auditlog> <I<log path>>
Turns on audit logging, and sets the path for the audit log. The audit
log records information about RPC calls, including the name of the RPC
call, the host that submitted the call, the authenticated entity (user)
that issued the call, the parameters for the call, and if the call
succeeded or failed.
=item B<-audit-interface> <(file | sysvmq)>
Specifies what audit interface to use. Defaults to C<file>. See
L<fileserver(8)> for an explanation of each interface.
=item B<-help>
Prints the online help for this command. All other valid options are

View File

@ -302,6 +302,21 @@
#define SREMIORemoteGetHSMdata "AFS_RE_HSMdata"
#define SREMIOPrefetch "AFS_RE_Prefetch"
#define TC_StartEvent "AFS_TC_Start"
#define TC_LabelTapeEvent "AFS_TC_LabelTape"
#define TC_PerformDumpEvent "AFS_TC_PerformDump"
#define TC_PerformRestoreEvent "AFS_TC_PerformRestore"
#define TC_ReadLabelEvent "AFS_TC_ReadLabel"
#define TC_RestoreDbEvent "AFS_TC_RestoreDb"
#define TC_SaveDbEvent "AFS_TC_SaveDb"
#define TC_ScanDumpsEvent "AFS_TC_ScanDumps"
#define TC_TCInfoEvent "AFS_TC_TCInfo"
#define TC_DeleteDumpEvent "AFS_TC_DeleteDump"
#define TC_GetStatusEvent "AFS_TC_GetStatus"
#define TC_EndStatusEvent "AFS_TC_EndStatus"
#define TC_RequestAbortEvent "AFS_TC_RequestAbort"
#define TC_ScanStatusEvent "AFS_TC_ScanStatus"
/* prototypes for audit functions */
int osi_audit(char *audEvent, afs_int32 errCode, ...);

View File

@ -38,6 +38,7 @@ LIBS=${TOP_LIBDIR}/libbudb.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/librx.a \
${TOP_LIBDIR}/libsys.a \
${TOP_LIBDIR}/libaudit.a \
${TOP_LIBDIR}/liblwp.a \
${TOP_LIBDIR}/libcmd.a \
${TOP_LIBDIR}/libafscom_err.a \

View File

@ -32,5 +32,9 @@ extern void *saveDbToTape(void *);
extern void *restoreDbFromTape(void *);
extern void *KeepAlive(void *);
/* tcmain.c */
extern struct afsconf_dir *butc_confdir;
#endif

View File

@ -41,6 +41,7 @@
#include <afs/keys.h>
#include <afs/volser.h>
#include <ubik.h>
#include <afs/audit.h>
#include <afs/com_err.h>
#include <afs/cmd.h>
#include <afs/tcdata.h>
@ -105,6 +106,7 @@ afs_int32 BufferSize; /* Size in B stored for data */
char *centralLogFile;
afs_int32 lastLog; /* Log last pass info */
int rxBind = 0;
struct afsconf_dir *butc_confdir;
#define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
afs_uint32 SHostAddrs[ADDRSPERSITE];
@ -823,6 +825,21 @@ xbsa_shutdown(int x)
}
#endif
static int
tc_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell)
{
struct afsconf_dir *dir = (struct afsconf_dir *)rock;
afs_int32 islocal = 0; /* default to no */
int code;
code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell);
if (code) {
TLog(0, ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n",
code, name, inst, cell));
}
return islocal;
}
static int
WorkerBee(struct cmd_syndesc *as, void *arock)
{
@ -842,6 +859,8 @@ WorkerBee(struct cmd_syndesc *as, void *arock)
PROCESS dbWatcherPid;
#endif
afs_uint32 host = htonl(INADDR_ANY);
char *auditFileName = NULL;
char *auditInterface = NULL;
debugLevel = 0;
@ -987,6 +1006,30 @@ WorkerBee(struct cmd_syndesc *as, void *arock)
}
}
/* Open the configuration directory */
butc_confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
if (butc_confdir == NULL) {
TLog(0, "Failed to open server configuration directory");
exit(1);
}
/* Start auditing */
osi_audit_init();
if (as->parms[9].items) {
auditFileName = as->parms[9].items->data;
}
if (auditFileName != NULL)
osi_audit_file(auditFileName);
if (as->parms[10].items) {
auditInterface = as->parms[10].items->data;
if (osi_audit_interface(auditInterface)) {
TLog(0, "Invalid audit interface '%s'\n", auditInterface);
exit(1);
}
}
osi_audit(TC_StartEvent, 0, AUD_END);
osi_audit_set_user_check(butc_confdir, tc_IsLocalRealmMatch);
if (as->parms[1].items) {
debugLevel = SafeATOL(as->parms[1].items->data);
if (debugLevel == -1) {
@ -1186,6 +1229,9 @@ main(int argc, char **argv)
"Force multiple XBSA server support");
cmd_AddParm(ts, "-rxbind", CMD_FLAG, CMD_OPTIONAL,
"bind Rx socket");
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");
/* Initialize dirpaths */
if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {

View File

@ -33,11 +33,31 @@
#include "butc_xbsa.h"
#include "butc_prototypes.h"
#include "butc_internal.h"
#include "afs/audit.h"
static int CopyDumpDesc(struct tc_dumpDesc *, tc_dumpArray *);
static int CopyRestoreDesc(struct tc_restoreDesc *, tc_restoreArray *);
static int CopyTapeSetDesc(struct tc_tapeSet *, struct tc_tapeSet *);
/* Helpers implementing RPC backends */
static afs_int32 SLabelTape(struct rx_call *acid, struct tc_tapeLabel *label,
afs_uint32 *taskId);
static afs_int32 SPerformDump(struct rx_call *rxCallId,
struct tc_dumpInterface *tcdiPtr,
tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId);
static afs_int32 SPerformRestore(struct rx_call *acid, char *dumpSetName,
tc_restoreArray *arestores, afs_int32 *taskId);
static afs_int32 SReadLabel(struct rx_call *acid, struct tc_tapeLabel *label,
afs_uint32 *taskId);
static afs_int32 SRestoreDb(struct rx_call *rxCall, afs_uint32 *taskId);
static afs_int32 SSaveDb(struct rx_call *rxCall, Date archiveTime,
afs_uint32 *taskId);
static afs_int32 SScanDumps(struct rx_call *acid, afs_int32 addDbFlag,
afs_uint32 *taskId);
static afs_int32 STCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr);
static afs_int32 SDeleteDump(struct rx_call *acid, afs_uint32 dumpID,
afs_uint32 *taskId);
int
callPermitted(struct rx_call *call)
{
@ -129,6 +149,17 @@ CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
afs_int32
STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
afs_int32 code;
code = SLabelTape(acid, label, taskId);
osi_auditU(acid, TC_LabelTapeEvent, code,
AUD_TLBL, label, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SLabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
pthread_t pid;
@ -204,7 +235,20 @@ STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *task
*/
afs_int32
STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
STC_PerformDump(struct rx_call *call, struct tc_dumpInterface *di,
tc_dumpArray *da, afs_int32 *taskId)
{
afs_int32 code;
code = SPerformDump(call, di, da, taskId);
osi_auditU(call, TC_PerformDumpEvent, code,
AUD_TDI, di, AUD_TDA, da, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SPerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr,
tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
{
struct dumpNode *newNode = 0;
statusP statusPtr = 0;
@ -295,7 +339,20 @@ STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_d
}
afs_int32
STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
STC_PerformRestore(struct rx_call *call, char *dumpSetName,
tc_restoreArray *ra, afs_int32 *taskId)
{
afs_int32 code;
code = SPerformRestore(call, dumpSetName, ra, taskId);
osi_auditU(call, TC_PerformRestoreEvent, code,
AUD_STR, dumpSetName, AUD_TRA, ra, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SPerformRestore(struct rx_call *acid, char *dumpSetName,
tc_restoreArray *arestores, afs_int32 *taskID)
{
struct dumpNode *newNode;
statusP statusPtr;
@ -368,7 +425,18 @@ STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *are
}
afs_int32
STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
STC_ReadLabel(struct rx_call *call, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
afs_int32 code;
code = SReadLabel(call, label, taskId);
osi_auditU(call, TC_ReadLabelEvent, code,
AUD_TLBL, label, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
afs_int32 code;
@ -392,7 +460,17 @@ STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *task
*/
afs_int32
STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
STC_RestoreDb(struct rx_call *call, afs_uint32 *taskId)
{
afs_int32 code;
code = SRestoreDb(call, taskId);
osi_auditU(call, TC_RestoreDbEvent, code, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SRestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
pthread_t pid;
@ -458,7 +536,18 @@ STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
*/
afs_int32
STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
STC_SaveDb(struct rx_call *call, Date archiveTime, afs_uint32 *taskId)
{
afs_int32 code;
code = SSaveDb(call, archiveTime, taskId);
osi_auditU(call, TC_SaveDbEvent, code,
AUD_DATE, archiveTime, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SSaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
pthread_t pid;
@ -537,7 +626,18 @@ STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
*/
afs_int32
STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
STC_ScanDumps(struct rx_call *call, afs_int32 addDbFlag, afs_uint32 *taskId)
{
afs_int32 code;
code = SScanDumps(call, addDbFlag, taskId);
osi_auditU(call, TC_ScanDumpsEvent, code,
AUD_INT, addDbFlag, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
pthread_t pid;
@ -612,7 +712,17 @@ STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
*/
afs_int32
STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
STC_TCInfo(struct rx_call *call, struct tc_tcInfo *ti)
{
afs_int32 code;
code = STCInfo(call, ti);
osi_auditU(call, TC_TCInfoEvent, code, AUD_INT, ti->tcVersion, AUD_END);
return code;
}
static afs_int32
STCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
{
if (callPermitted(acid) == 0)
return (TC_NOTPERMITTED);
@ -624,7 +734,18 @@ STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
/* STC_DeleteDump
*/
afs_int32
STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
STC_DeleteDump(struct rx_call *call, afs_uint32 dumpID, afs_uint32 *taskId)
{
afs_int32 code;
code = SDeleteDump(call, dumpID, taskId);
osi_auditU(call, TC_DeleteDumpEvent, code,
AUD_DATE, dumpID, AUD_INT, *taskId, AUD_END);
return code;
}
static afs_int32
SDeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
{
afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
#ifdef xbsa

View File

@ -23,6 +23,7 @@
#include "butc_internal.h"
#include "error_macros.h"
#include "butc_xbsa.h"
#include "afs/audit.h"
/* tape coordinator - task status management */
extern afs_int32 xbsaType;
@ -31,6 +32,13 @@ dlqlinkT statusHead;
struct Lock statusQueueLock;
struct Lock cmdLineLock;
static afs_int32 SGetStatus(struct rx_call *call, afs_uint32 taskId,
struct tciStatusS *statusPtr);
static afs_int32 SEndStatus(struct rx_call *call, afs_uint32 taskId);
static afs_int32 SRequestAbort(struct rx_call *call, afs_uint32 taskId);
static afs_int32 SScanStatus(struct rx_call *call, afs_uint32 *taskId,
struct tciStatusS *statusPtr, afs_uint32 *flags);
/* STC_GetStatus
* get the status of a task
* entry:
@ -41,7 +49,19 @@ struct Lock cmdLineLock;
afs_int32
STC_GetStatus(struct rx_call *call, afs_uint32 taskId,
struct tciStatusS *statusPtr)
struct tciStatusS *status)
{
afs_int32 code;
code = SGetStatus(call, taskId, status);
osi_auditU(call, TC_GetStatusEvent, code,
AUD_INT, taskId, AUD_TSTT, status, AUD_END);
return code;
}
static afs_int32
SGetStatus(struct rx_call *call, afs_uint32 taskId,
struct tciStatusS *statusPtr)
{
statusP ptr;
int retval = 0;
@ -71,6 +91,16 @@ STC_GetStatus(struct rx_call *call, afs_uint32 taskId,
afs_int32
STC_EndStatus(struct rx_call *call, afs_uint32 taskId)
{
afs_int32 code;
code = SEndStatus(call, taskId);
osi_auditU(call, TC_EndStatusEvent, code, AUD_INT, taskId, AUD_END);
return code;
}
static afs_int32
SEndStatus(struct rx_call *call, afs_uint32 taskId)
{
statusP ptr;
int retval = 0;
@ -92,6 +122,16 @@ STC_EndStatus(struct rx_call *call, afs_uint32 taskId)
afs_int32
STC_RequestAbort(struct rx_call *call, afs_uint32 taskId)
{
afs_int32 code;
code = SRequestAbort(call, taskId);
osi_auditU(call, TC_RequestAbortEvent, code, AUD_INT, taskId, AUD_END);
return code;
}
static afs_int32
SRequestAbort(struct rx_call *call, afs_uint32 taskId)
{
statusP ptr;
int retval = 0;
@ -127,7 +167,19 @@ STC_RequestAbort(struct rx_call *call, afs_uint32 taskId)
afs_int32
STC_ScanStatus(struct rx_call *call, afs_uint32 *taskId,
struct tciStatusS *statusPtr, afs_uint32 *flags)
struct tciStatusS *status, afs_uint32 *flags)
{
afs_int32 code;
code = SScanStatus(call, taskId, status, flags);
osi_auditU(call, TC_ScanStatusEvent, code,
AUD_INT, *taskId, AUD_TSTT, status, AUD_INT, *flags, AUD_END);
return code;
}
static afs_int32
SScanStatus(struct rx_call *call, afs_uint32 *taskId,
struct tciStatusS *statusPtr, afs_uint32 *flags)
{
statusP ptr = 0;
dlqlinkP dlqPtr;