]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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 a3ddf78e5f535b845643de8bc8af114e2e3f2bfd..49e43c51a1c3185b067bbb1f9fc440a975aed7a5 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 ebcee4686ea6ec283f0d42d31d2f7003f3758285..82f67868d71abfeba759952b55708c874dd4685b 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 82c60b855a5ec5c4bacfbeecf66f90ccebbc63b7..df86281494d7b4c86f057b20212661de3f54ba4b 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 c641fc37b1a2818faaea81f4b4b01ac0dfd9d428..3b91e01bf478334b4fd0c4c461d788a4d4261a70 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 1d08b2419d2ddfe1459c9bdb1b04547a95ad94d8..6ed42205fc6f7a6490c9a2ee0c6ca6a54d16781d 100644 (file)
@@ -7,6 +7,7 @@ afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_ClientAuthToken
 afsconf_Close
+afsconf_CheckRestrictedQuery
 afsconf_DeleteKey
 afsconf_GetAfsdbInfo
 afsconf_GetAllKeys
index 326a7362dceee9c86b3488c2f35ce61672861421..d0f68d2fbc1d0eb1a3974cd2c055cebb780a6f87 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 31809cd54204ab514dee31d8f568e64b93fb578d..40186f02a1590acf0e093d1720568f7fecf416f7 100644 (file)
@@ -165,3 +165,4 @@ EXPORTS
         afsconf_AddTypedKey                             @164
         afsconf_typedKey_values                         @165
         afsconf_GetAllKeys                              @166
+       afsconf_CheckRestrictedQuery                    @167
index b5f82474ab734dcb461d56326863afa1dddb05c5..fc617cef8840fd348521ba6e61d861376e510df7 100644 (file)
@@ -2,6 +2,7 @@ afsconf_AddKey
 afsconf_AddUser
 afsconf_CellApply
 afsconf_CheckAuth
+afsconf_CheckRestrictedQuery
 afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_Close
index 50f5e83414cf12262155ab582be02e979d72ece3..928f1dc1a52154e87731c5110a0a45c039352b15 100644 (file)
@@ -6,6 +6,7 @@ afsconf_CheckAuth
 afsconf_ClientAuth
 afsconf_ClientAuthSecure
 afsconf_Close
+afsconf_CheckRestrictedQuery
 afsconf_DeleteKey
 afsconf_DeleteUser
 afsconf_GetCellInfo
index ddf03f02bd7af881c2fc49bd7a2309ff713c8668..e3ec9e1101252e25170813cbd42f0399068aeb34 100644 (file)
@@ -14,6 +14,7 @@
        afsconf_ClientAuth;
        afsconf_ClientAuthSecure;
        afsconf_Close;
+       afsconf_CheckRestrictedQuery;
        afsconf_DeleteKey;
        afsconf_DeleteUser;
        afsconf_GetCellInfo;
index 2b71c1281f6b42d2476473f020841500545c37ca..34e84fa71ec8d1b05a75167826765f525ff1610b 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 b7a20c4341427491c8862826194baf8d893c3d62..7d4cb750663163bb52afe8e6b80394de3bf30995 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 02aeecc23d5be2813771d98ae323890322a66718..7ae8e8870536ff899c9a775c80fee93aed8ca1ec 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 f8bbd2f73e94e9de57bc9f1d828a39bf8577d364..166ee2a270cb13ecc844f728df49de8d3fa34889 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 2e483f34230dd8bd097a0c3df0a2c5d905f5f9da..5555ca42997f90684b981536a38d224cb71cf2f7 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)