|
@@ -38,13 +38,16 @@ import com.google.common.annotations.VisibleForTesting;
|
|
|
public class ProxyUsers {
|
|
|
|
|
|
private static final String CONF_HOSTS = ".hosts";
|
|
|
+ private static final String CONF_USERS = ".users";
|
|
|
private static final String CONF_GROUPS = ".groups";
|
|
|
private static final String CONF_HADOOP_PROXYUSER = "hadoop.proxyuser.";
|
|
|
private static final String CONF_HADOOP_PROXYUSER_RE = "hadoop\\.proxyuser\\.";
|
|
|
public static final String CONF_HADOOP_PROXYSERVERS = "hadoop.proxyservers";
|
|
|
|
|
|
private static boolean init = false;
|
|
|
- // list of groups and hosts per proxyuser
|
|
|
+ //list of users, groups and hosts per proxyuser
|
|
|
+ private static Map<String, Collection<String>> proxyUsers =
|
|
|
+ new HashMap<String, Collection<String>>();
|
|
|
private static Map<String, Collection<String>> proxyGroups =
|
|
|
new HashMap<String, Collection<String>>();
|
|
|
private static Map<String, Collection<String>> proxyHosts =
|
|
@@ -53,7 +56,7 @@ public class ProxyUsers {
|
|
|
new HashSet<String>();
|
|
|
|
|
|
/**
|
|
|
- * reread the conf and get new values for "hadoop.proxyuser.*.groups/hosts"
|
|
|
+ * reread the conf and get new values for "hadoop.proxyuser.*.groups/users/hosts"
|
|
|
*/
|
|
|
public static void refreshSuperUserGroupsConfiguration() {
|
|
|
//load server side configuration;
|
|
@@ -69,11 +72,20 @@ public class ProxyUsers {
|
|
|
// remove all existing stuff
|
|
|
proxyGroups.clear();
|
|
|
proxyHosts.clear();
|
|
|
+ proxyUsers.clear();
|
|
|
proxyServers.clear();
|
|
|
+
|
|
|
+ // get all the new keys for users
|
|
|
+ String regex = CONF_HADOOP_PROXYUSER_RE+"[^.]*\\"+CONF_USERS;
|
|
|
+ Map<String,String> allMatchKeys = conf.getValByRegex(regex);
|
|
|
+ for(Entry<String, String> entry : allMatchKeys.entrySet()) {
|
|
|
+ Collection<String> users = StringUtils.getTrimmedStringCollection(entry.getValue());
|
|
|
+ proxyUsers.put(entry.getKey(), users);
|
|
|
+ }
|
|
|
|
|
|
// get all the new keys for groups
|
|
|
- String regex = CONF_HADOOP_PROXYUSER_RE+"[^.]*\\"+CONF_GROUPS;
|
|
|
- Map<String,String> allMatchKeys = conf.getValByRegex(regex);
|
|
|
+ regex = CONF_HADOOP_PROXYUSER_RE+"[^.]*\\"+CONF_GROUPS;
|
|
|
+ allMatchKeys = conf.getValByRegex(regex);
|
|
|
for(Entry<String, String> entry : allMatchKeys.entrySet()) {
|
|
|
proxyGroups.put(entry.getKey(),
|
|
|
StringUtils.getTrimmedStringCollection(entry.getValue()));
|
|
@@ -103,7 +115,17 @@ public class ProxyUsers {
|
|
|
}
|
|
|
return proxyServers.contains(remoteAddr);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns configuration key for effective users allowed for a superuser
|
|
|
+ *
|
|
|
+ * @param userName name of the superuser
|
|
|
+ * @return configuration key for superuser users
|
|
|
+ */
|
|
|
+ public static String getProxySuperuserUserConfKey(String userName) {
|
|
|
+ return ProxyUsers.CONF_HADOOP_PROXYUSER+userName+ProxyUsers.CONF_USERS;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns configuration key for effective user groups allowed for a superuser
|
|
|
*
|
|
@@ -141,27 +163,40 @@ public class ProxyUsers {
|
|
|
if (user.getRealUser() == null) {
|
|
|
return;
|
|
|
}
|
|
|
- boolean groupAuthorized = false;
|
|
|
+ boolean userAuthorized = false;
|
|
|
boolean ipAuthorized = false;
|
|
|
UserGroupInformation superUser = user.getRealUser();
|
|
|
-
|
|
|
- Collection<String> allowedUserGroups = proxyGroups.get(
|
|
|
- getProxySuperuserGroupConfKey(superUser.getShortUserName()));
|
|
|
|
|
|
- if (isWildcardList(allowedUserGroups)) {
|
|
|
- groupAuthorized = true;
|
|
|
- } else if (allowedUserGroups != null && !allowedUserGroups.isEmpty()) {
|
|
|
- for (String group : user.getGroupNames()) {
|
|
|
- if (allowedUserGroups.contains(group)) {
|
|
|
- groupAuthorized = true;
|
|
|
- break;
|
|
|
- }
|
|
|
+ Collection<String> allowedUsers = proxyUsers.get(
|
|
|
+ getProxySuperuserUserConfKey(superUser.getShortUserName()));
|
|
|
+
|
|
|
+ if (isWildcardList(allowedUsers)) {
|
|
|
+ userAuthorized = true;
|
|
|
+ } else if (allowedUsers != null && !allowedUsers.isEmpty()) {
|
|
|
+ if (allowedUsers.contains(user.getShortUserName())) {
|
|
|
+ userAuthorized = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!groupAuthorized) {
|
|
|
- throw new AuthorizationException("User: " + superUser.getUserName()
|
|
|
- + " is not allowed to impersonate " + user.getUserName());
|
|
|
+ if (!userAuthorized) {
|
|
|
+ Collection<String> allowedUserGroups = proxyGroups.get(
|
|
|
+ getProxySuperuserGroupConfKey(superUser.getShortUserName()));
|
|
|
+
|
|
|
+ if (isWildcardList(allowedUserGroups)) {
|
|
|
+ userAuthorized = true;
|
|
|
+ } else if (allowedUserGroups != null && !allowedUserGroups.isEmpty()) {
|
|
|
+ for (String group : user.getGroupNames()) {
|
|
|
+ if (allowedUserGroups.contains(group)) {
|
|
|
+ userAuthorized = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!userAuthorized) {
|
|
|
+ throw new AuthorizationException("User: " + superUser.getUserName()
|
|
|
+ + " is not allowed to impersonate " + user.getUserName());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Collection<String> ipList = proxyHosts.get(
|
|
@@ -183,7 +218,7 @@ public class ProxyUsers {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if(!ipAuthorized) {
|
|
|
+ if (!ipAuthorized) {
|
|
|
throw new AuthorizationException("Unauthorized connection for super-user: "
|
|
|
+ superUser.getUserName() + " from IP " + remoteAddress);
|
|
|
}
|
|
@@ -212,6 +247,11 @@ public class ProxyUsers {
|
|
|
(list.size() == 1) &&
|
|
|
(list.contains("*"));
|
|
|
}
|
|
|
+
|
|
|
+ @VisibleForTesting
|
|
|
+ public static Map<String, Collection<String>> getProxyUsers() {
|
|
|
+ return proxyUsers;
|
|
|
+ }
|
|
|
|
|
|
@VisibleForTesting
|
|
|
public static Map<String, Collection<String>> getProxyGroups() {
|