RestrictedQuery feature
authorGergely Risko <gergely@risko.hu>
Wed, 19 Mar 2014 09:56:26 +0000 (10:56 +0100)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 21 May 2014 00:39:12 +0000 (20:39 -0400)
Make vlserver and volserver suppport a new command line parameter,
"-restricted_query admin".  When this is on, the query RPCs that
are not needed for normal cache manager operations are restricted
to administrators listed in UserList.  This is off by default.

Change-Id: I2a23a4e99cabd46b19ed491a6520773731a5994e
Reviewed-on: http://gerrit.openafs.org/10927
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Reviewed-by: D Brashear <shadow@your-file-system.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

15 files changed:
doc/man-pages/pod8/fragments/volserver-options.pod
doc/man-pages/pod8/fragments/volserver-synopsis.pod
doc/man-pages/pod8/vlserver.pod
src/auth/cellconfig.p.h
src/auth/liboafs_auth.la.sym
src/auth/userok.c
src/libafsauthent/afsauthent.def
src/libafsauthent/afsauthent.exp
src/libafsauthent/libafsauthent.la.sym
src/libafsauthent/mapfile
src/packaging/Debian/libafsauthent1.symbols
src/vlserver/vlprocs.c
src/vlserver/vlserver.c
src/volser/volmain.c
src/volser/volprocs.c

index a3ddf78..49e43c5 100644 (file)
@@ -122,6 +122,13 @@ This option is obsolete, and is now only accepted for compatibility with older
 releases. All it does now is log a warning message about how the option is
 obsolete.
 
+=item B<-restricted_query> (anyuser | admin)
+
+Restrict RPCs that query information about volumes to a specific group
+of users. You can use C<admin> to restrict to AFS administrators.  The
+C<anyuser> option doesn't restrict the RPCs and leaves it open for all
+users including unauthenticated users, this is the default.
+
 =item B<-help>
 
 Prints the online help for this command. All other valid options are
index ebcee46..82f6786 100644 (file)
@@ -13,4 +13,5 @@ B<volserver>
     [B<-rxbind>]
     [B<-syslog>[=<I<FACILITY>]]
     [B<-sleep> <I<sleep time>/I<run time>>]
+    [B<-restricted_query> (anyuser | admin)]
     [B<-help>]
index 82c60b8..df86281 100644 (file)
@@ -21,6 +21,7 @@ vlserver [B<-noauth>] [B<-smallmem>]
     [B<-enable_peer_stats>] [B<-enable_process_stats>]
     S<<< [B<-auditlog> <I<log path>>] >>>
     S<<< [B<-audit-interface> (file | sysvmq)] >>>
+    S<<< [B<-restricted_query> (anyuser | admin)] >>>
     [B<-help>]
 
 =for html
@@ -188,6 +189,16 @@ service. In a typical configuration this will be F</usr/afs/etc> - this
 option allows the use of alternative configuration locations for testing
 purposes.
 
+=item B<-restricted_query> (anyuser | admin)
+
+Restrict RPCs that query information about volumes to a specific group
+of users. Only the RPCs that are not used by cache managers will be
+restricted, since cache manager connections to the Volume Server are
+always unauthenticated. You can use C<admin> to restrict to AFS
+administrators.  The C<anyuser> option doesn't restrict the RPCs and
+leaves it open for all users including unauthenticated users, this is
+the default.
+
 =item B<-help>
 
 Prints the online help for this command. All other valid options are
index c641fc3..3b91e01 100644 (file)
@@ -254,6 +254,18 @@ extern int afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall,
 extern int afsconf_SuperIdentity(struct afsconf_dir *, struct rx_call *,
                                 struct rx_identity **);
 extern int afsconf_IsSuperIdentity(struct afsconf_dir *, struct rx_identity *);
+extern int afsconf_CheckRestrictedQuery(struct afsconf_dir *adir,
+                                       struct rx_call *acall,
+                                       int needed_level);
+
+/*
+ * Level constants for the -restricted_query option used by vlserver
+ * and volser.  Once we have vlserver and volserver to ptserver
+ * connection, we can add more access levels, like AUTHUSER or
+ * AUTHANDFOREIGNUSER.
+ */
+#define RESTRICTED_QUERY_ANYUSER  0
+#define RESTRICTED_QUERY_ADMIN    1
 
 /* realms.c */
 extern int afsconf_SetLocalRealm(const char *realm);
index 1d08b24..6ed4220 100644 (file)
@@ -7,6 +7,7 @@ afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_ClientAuthToken
 afsconf_Close
+afsconf_CheckRestrictedQuery
 afsconf_DeleteKey
 afsconf_GetAfsdbInfo
 afsconf_GetAllKeys
index 326a736..d0f68d2 100644 (file)
@@ -804,3 +804,30 @@ afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall,
 
     return ret;
 }
+
+/*!
+ * Check whether the user authenticated on a given RX call is
+ * compatible with the access specified by needed_level.
+ *
+ * @param[in] adir
+ *     The configuration directory currently in use
+ * @param[in] acall
+ *     The RX call whose authenticated identity is being checked
+ * @param[in] needed_level
+ *     Either RESTRICTED_QUERY_ANYUSER for allowing any access or
+ *     RESTRICTED_QUERY_ADMIN for allowing super user only.
+ * @returns
+ *     True if the user is compatible with needed_level.
+ *      Otherwise, false.
+ */
+
+int
+afsconf_CheckRestrictedQuery(struct afsconf_dir *adir,
+                            struct rx_call *acall,
+                            int needed_level)
+{
+    if (needed_level == RESTRICTED_QUERY_ANYUSER)
+       return 1;
+
+    return afsconf_SuperIdentity(adir, acall, NULL);
+}
index 31809cd..40186f0 100644 (file)
@@ -165,3 +165,4 @@ EXPORTS
         afsconf_AddTypedKey                             @164
         afsconf_typedKey_values                         @165
         afsconf_GetAllKeys                              @166
+       afsconf_CheckRestrictedQuery                    @167
index b5f8247..fc617ce 100644 (file)
@@ -2,6 +2,7 @@ afsconf_AddKey
 afsconf_AddUser
 afsconf_CellApply
 afsconf_CheckAuth
+afsconf_CheckRestrictedQuery
 afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_Close
index 50f5e83..928f1dc 100644 (file)
@@ -6,6 +6,7 @@ afsconf_CheckAuth
 afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_Close
+afsconf_CheckRestrictedQuery
 afsconf_DeleteKey
 afsconf_DeleteUser
 afsconf_GetCellInfo
index ddf03f0..e3ec9e1 100644 (file)
@@ -14,6 +14,7 @@
        afsconf_ClientAuth;
        afsconf_ClientAuthSecure;
        afsconf_Close;
+       afsconf_CheckRestrictedQuery;
        afsconf_DeleteKey;
        afsconf_DeleteUser;
        afsconf_GetCellInfo;
index 2b71c12..34e84fa 100644 (file)
@@ -6,6 +6,7 @@ libafsauthent.so.1 libafsauthent1 #MINVER#
  afsconf_ClientAuth@Base 1.5.75
  afsconf_ClientAuthSecure@Base 1.5.75
  afsconf_Close@Base 1.5.75
+ afsconf_CheckRestrictedQuery@Base 1.5.75
  afsconf_DeleteKey@Base 1.5.75
  afsconf_DeleteUser@Base 1.5.75
  afsconf_GetCellInfo@Base 1.5.75
index b7a20c4..7d4cb75 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 extern int smallMem;
+extern int restrictedQueryLevel;
 extern int extent_mod;
 extern struct afsconf_dir *vldb_confdir;
 extern struct ubik_dbase *VL_dbase;
@@ -1192,6 +1193,11 @@ SVL_ListEntry(struct rx_call *rxcall, afs_int32 previous_index,
     char rxstr[AFS_RXINFO_LEN];
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
        goto end;
     VLog(25, ("OListEntry index=%d %s\n", previous_index,
@@ -1227,6 +1233,11 @@ SVL_ListEntryN(struct rx_call *rxcall, afs_int32 previous_index,
     char rxstr[AFS_RXINFO_LEN];
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
        goto end;
     VLog(25, ("ListEntry index=%d %s\n", previous_index, rxinfo(rxstr, rxcall)));
@@ -1268,6 +1279,11 @@ SVL_ListAttributes(struct rx_call *rxcall,
     char rxstr[AFS_RXINFO_LEN];
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     vldbentries->bulkentries_val = 0;
     vldbentries->bulkentries_len = *nentries = 0;
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
@@ -1401,6 +1417,11 @@ SVL_ListAttributesN(struct rx_call *rxcall,
     char rxstr[AFS_RXINFO_LEN];
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     vldbentries->nbulkentries_val = 0;
     vldbentries->nbulkentries_len = *nentries = 0;
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
@@ -1550,6 +1571,11 @@ SVL_ListAttributesN2(struct rx_call *rxcall,
 #endif
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     vldbentries->nbulkentries_val = 0;
     vldbentries->nbulkentries_len = 0;
     *nentries = 0;
@@ -1816,6 +1842,11 @@ SVL_LinkedList(struct rx_call *rxcall,
     int pollcount = 0;
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
        goto end;
 
@@ -1955,6 +1986,11 @@ SVL_LinkedListN(struct rx_call *rxcall,
     int pollcount = 0;
 
     countRequest(this_op);
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
        goto end;
 
@@ -2092,13 +2128,11 @@ SVL_GetStats(struct rx_call *rxcall,
     char rxstr[AFS_RXINFO_LEN];
 
     countRequest(this_op);
-#ifdef notdef
-    /* Allow users to get statistics freely */
-    if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) {      /* Must be in 'UserList' to use */
-       code = VL_PERM;
-       goto end;
-    }
-#endif
+
+    if (!afsconf_CheckRestrictedQuery(vldb_confdir, rxcall,
+                                     restrictedQueryLevel))
+       END(VL_PERM);
+
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
        goto end;
     VLog(5, ("GetStats %s\n", rxinfo(rxstr, rxcall)));
index 02aeecc..7ae8e88 100644 (file)
@@ -50,6 +50,7 @@ afs_uint32 wr_HostAddress[MAXSERVERID + 1];
 static void *CheckSignal(void*);
 int LogLevel = 0;
 int smallMem = 0;
+int restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER;
 int rxJumbograms = 0;          /* default is to not send and receive jumbo grams */
 int rxMaxMTU = -1;
 afs_int32 rxBind = 0;
@@ -150,7 +151,8 @@ enum optionsList {
     OPT_rxbind,
     OPT_rxmaxmtu,
     OPT_trace,
-    OPT_dotted
+    OPT_dotted,
+    OPT_restricted_query
 };
 
 int
@@ -179,6 +181,8 @@ main(int argc, char **argv)
     char *interface = NULL;
     char *optstring = NULL;
 
+    char *restricted_query_parameter = NULL;
+
 #ifdef AFS_AIX32_ENV
     /*
      * The following signal action for AIX is necessary so that in case of a
@@ -257,6 +261,9 @@ main(int argc, char **argv)
                        CMD_OPTIONAL, "maximum MTU for RX");
     cmd_AddParmAtOffset(opts, OPT_trace, "-trace", CMD_SINGLE,
                        CMD_OPTIONAL, "rx trace file");
+    cmd_AddParmAtOffset(opts, OPT_restricted_query, "-restricted_query",
+                       CMD_SINGLE, CMD_OPTIONAL, "anyuser | admin");
+
 
     /* rxkad options */
     cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals",
@@ -332,6 +339,21 @@ main(int argc, char **argv)
     /* rxkad options */
     cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck);
 
+    /* restricted query */
+    if (cmd_OptionAsString(opts, OPT_restricted_query,
+                          &restricted_query_parameter) == 0) {
+       if (strcmp(restricted_query_parameter, "anyuser") == 0)
+           restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER;
+       else if (strcmp(restricted_query_parameter, "admin") == 0)
+           restrictedQueryLevel = RESTRICTED_QUERY_ADMIN;
+       else {
+           printf("invalid argument for -restricted_query: %s\n",
+                  restricted_query_parameter);
+           return -1;
+       }
+       free(restricted_query_parameter);
+    }
+
     if (auditFileName) {
        osi_audit_file(auditFileName);
     }
index f8bbd2f..166ee2a 100644 (file)
@@ -70,6 +70,7 @@ int debuglevel = 0;
 #define MAXLWP 128
 int lwps = 9;
 int udpBufSize = 0;            /* UDP buffer size for receive */
+int restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER;
 
 int rxBind = 0;
 int rxkadDisableDotCheck = 0;
@@ -235,7 +236,8 @@ enum optionsList {
     OPT_sync,
     OPT_syslog,
     OPT_logfile,
-    OPT_config
+    OPT_config,
+    OPT_restricted_query
 };
 
 static int
@@ -246,6 +248,7 @@ ParseArgs(int argc, char **argv) {
     struct cmd_syndesc *opts;
     char *sleepSpec = NULL;
     char *sync_behavior = NULL;
+    char *restricted_query_parameter = NULL;
 
     opts = cmd_CreateSyntax(NULL, NULL, NULL, NULL);
     cmd_AddParmAtOffset(opts, OPT_log, "-log", CMD_FLAG, CMD_OPTIONAL,
@@ -288,6 +291,8 @@ ParseArgs(int argc, char **argv) {
           CMD_OPTIONAL, "location of log file");
     cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE,
           CMD_OPTIONAL, "configuration location");
+    cmd_AddParmAtOffset(opts, OPT_restricted_query, "-restricted_query",
+           CMD_SINGLE, CMD_OPTIONAL, "anyuser | admin");
 
     code = cmd_Parse(argc, argv, &opts);
     if (code == CMD_HELP) {
@@ -350,6 +355,19 @@ ParseArgs(int argc, char **argv) {
     }
     cmd_OptionAsString(opts, OPT_logfile, &logFile);
     cmd_OptionAsString(opts, OPT_config, &configDir);
+    if (cmd_OptionAsString(opts, OPT_restricted_query,
+                          &restricted_query_parameter) == 0) {
+       if (strcmp(restricted_query_parameter, "anyuser") == 0)
+           restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER;
+       else if (strcmp(restricted_query_parameter, "admin") == 0)
+           restrictedQueryLevel = RESTRICTED_QUERY_ADMIN;
+       else {
+           printf("invalid argument for -restricted_query: %s\n",
+                  restricted_query_parameter);
+           return -1;
+       }
+       free(restricted_query_parameter);
+    }
 
     return 0;
 }
index 2e483f3..5555ca4 100644 (file)
@@ -60,6 +60,7 @@
 extern int DoLogging;
 extern struct afsconf_dir *tdir;
 extern int DoPreserveVolumeStats;
+extern int restrictedQueryLevel;
 
 extern void LogError(afs_int32 errcode);
 
@@ -448,6 +449,9 @@ VolPartitionInfo(struct rx_call *acid, char *pname, struct diskPartition64
 {
     struct DiskPartition64 *dp;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     VResetDiskUsage();
     dp = VGetPartition(pname, 0);
     if (dp) {
@@ -1123,6 +1127,9 @@ static afs_int32
 VolGetNthVolume(struct rx_call *acid, afs_int32 aindex, afs_uint32 *avolume,
                    afs_int32 *apart)
 {
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     Log("1 Volser: GetNthVolume: Not yet implemented\n");
     return VOLSERNO_OP;
 }
@@ -1145,6 +1152,9 @@ VolGetFlags(struct rx_call *acid, afs_int32 atid, afs_int32 *aflags)
 {
     struct volser_trans *tt;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     tt = FindTrans(atid);
     if (!tt)
        return ENOENT;
@@ -1650,6 +1660,8 @@ VolGetStatus(struct rx_call *acid, afs_int32 atrans,
     struct VolumeDiskData *td;
     struct volser_trans *tt;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
 
     tt = FindTrans(atrans);
     if (!tt)
@@ -1771,6 +1783,9 @@ VolGetName(struct rx_call *acid, afs_int32 atrans, char **aname)
     struct volser_trans *tt;
     int len;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     /* We need to at least fill it in */
     *aname = malloc(1);
     if (!*aname)
@@ -1835,6 +1850,9 @@ VolListPartitions(struct rx_call *acid, struct pIDs *partIds)
     char namehead[9];
     int i;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     strcpy(namehead, "/vicep");        /*7 including null terminator */
 
     /* Just return attached partitions. */
@@ -1867,6 +1885,9 @@ XVolListPartitions(struct rx_call *acid, struct partEntries *pEntries)
     struct DiskPartition64 *dp;
     int i, j = 0;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     strcpy(namehead, "/vicep");        /*7 including null terminator */
 
     /* Only report attached partitions */
@@ -2342,6 +2363,9 @@ VolListOneVolume(struct rx_call *acid, afs_int32 partid,
     int found = 0;
     volint_info_handle_t handle;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     volumeInfo->volEntries_val = calloc(1, sizeof(volintInfo));
     if (!volumeInfo->volEntries_val)
        return ENOMEM;
@@ -2432,6 +2456,9 @@ VolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID,
     int found = 0;             /*Did we find the volume we need? */
     volint_info_handle_t handle;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, a_rxCidP, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     /*
      * Set up our pointers for action, marking our structure to hold exactly
      * one entry.  Also, assume we'll fail in our quest.
@@ -2530,6 +2557,9 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags,
     int code;
     volint_info_handle_t handle;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     volumeInfo->volEntries_val = calloc(allocSize, sizeof(volintInfo));
     if (!volumeInfo->volEntries_val)
        return ENOMEM;
@@ -2640,6 +2670,9 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID,
     int code;
     volint_info_handle_t handle;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, a_rxCidP, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     /*
      * Allocate a large array of extended volume info structures, then
      * set it up for action.
@@ -2756,6 +2789,9 @@ VolMonitor(struct rx_call *acid, transDebugEntries *transInfo)
     afs_int32 allocSize = 50;
     struct volser_trans *tt, *nt, *allTrans;
 
+    if (!afsconf_CheckRestrictedQuery(tdir, acid, restrictedQueryLevel))
+        return VOLSERBAD_ACCESS;
+
     transInfo->transDebugEntries_val =
        malloc(allocSize * sizeof(transDebugInfo));
     if (!transInfo->transDebugEntries_val)