]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
OPENAFS-SA-2018-001 Add auditing to butc server RPC implementations
authorBenjamin Kaduk <kaduk@mit.edu>
Sun, 9 Sep 2018 16:49:03 +0000 (11:49 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sun, 9 Sep 2018 23:35:26 +0000 (18:35 -0500)
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.

(cherry picked from commit c43169fd36348783b1a5a55c5bb05317e86eef82)

Change-Id: Ia90c355bfded24820ae3b5c014e948e28eac6356

doc/man-pages/pod8/butc.pod
src/audit/audit.h
src/butc/Makefile.in
src/butc/butc_prototypes.h
src/butc/tcmain.c
src/butc/tcprocs.c
src/butc/tcstatus.c

index 730ce839756b064b817519e934120ac3d000e0d2..e836d3940838d4e3b3c18e43f48d0b28e0f02ac7 100644 (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
index 599620a2be28d65a6ad2ec3b7593f55f06b69e18..6188cf60ddf15549bdba8377eba034fc1122fa13 100644 (file)
 #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, ...);
index 4648f96b7afe32f52229d48882ccd3a4d226f1c2..5d942222e78f5b43695b8a19df27e4e1ec6cecfc 100644 (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 \
index 1c62c34b4d01e9ff21327a9f0e26ffe8fa5d2e55..a1d7712e85e74f388187beabccab33b3ac31c6c6 100644 (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
 
index 89b711a5611816b231027991c45ea7d691d246b1..7f79fa751676be7de01ce85ee7bb4b01faa47a08 100644 (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)) {
index cc19e532d524b637e4041e2fb73d84dc95130791..7f0e40c86e8d6b9d45f8dff546dd40e5bbf3da59 100644 (file)
 #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
index db06b514fe765c476f3eccc3355a8f7ce47df482..b67ae1eee405ec0a59503446783e840ccf0cccfd 100644 (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;