/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.zookeeper.server.command; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.HashSet; import java.util.Set; import java.util.Arrays; /** * This class contains constants for all the four letter commands */ public class FourLetterCommands { /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int confCmd = ByteBuffer.wrap("conf".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int consCmd = ByteBuffer.wrap("cons".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int crstCmd = ByteBuffer.wrap("crst".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int dirsCmd = ByteBuffer.wrap("dirs".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int dumpCmd = ByteBuffer.wrap("dump".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int enviCmd = ByteBuffer.wrap("envi".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int getTraceMaskCmd = ByteBuffer.wrap("gtmk".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int ruokCmd = ByteBuffer.wrap("ruok".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int setTraceMaskCmd = ByteBuffer.wrap("stmk".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int srvrCmd = ByteBuffer.wrap("srvr".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int srstCmd = ByteBuffer.wrap("srst".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int statCmd = ByteBuffer.wrap("stat".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int wchcCmd = ByteBuffer.wrap("wchc".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int wchpCmd = ByteBuffer.wrap("wchp".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int wchsCmd = ByteBuffer.wrap("wchs".getBytes()).getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int mntrCmd = ByteBuffer.wrap("mntr".getBytes()) .getInt(); /* * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands"> * Zk Admin</a>. this link is for all the commands. */ public final static int isroCmd = ByteBuffer.wrap("isro".getBytes()) .getInt(); /* * The control sequence sent by the telnet program when it closes a * connection. Include simply to keep the logs cleaner (the server would * close the connection anyway because it would parse this as a negative * length). */ public final static int telnetCloseCmd = 0xfff4fffd; private static final String ZOOKEEPER_4LW_COMMANDS_WHITELIST = "zookeeper.4lw.commands.whitelist"; private static final Logger LOG = LoggerFactory.getLogger(FourLetterCommands.class); private static final Map<Integer, String> cmd2String = new HashMap<Integer, String>(); private static final Set<String> whiteListedCommands = new HashSet<String>(); private static boolean whiteListInitialized = false; // @VisibleForTesting public synchronized static void resetWhiteList() { whiteListInitialized = false; whiteListedCommands.clear(); } /** * Return the string representation of the specified command code. */ public static String getCommandString(int command) { return cmd2String.get(command); } /** * Check if the specified command code is from a known command. * * @param command The integer code of command. * @return true if the specified command is known, false otherwise. */ public static boolean isKnown(int command) { return cmd2String.containsKey(command); } /** * Check if the specified command is enabled. * * In ZOOKEEPER-2693 we introduce a configuration option to only * allow a specific set of white listed commands to execute. * A command will only be executed if it is also configured * in the white list. * * @param command The command string. * @return true if the specified command is enabled */ public synchronized static boolean isEnabled(String command) { if (whiteListInitialized) { return whiteListedCommands.contains(command); } String commands = System.getProperty(ZOOKEEPER_4LW_COMMANDS_WHITELIST); if (commands != null) { String[] list = commands.split(","); for (String cmd : list) { if (cmd.trim().equals("*")) { for (Map.Entry<Integer, String> entry : cmd2String.entrySet()) { whiteListedCommands.add(entry.getValue()); } break; } if (!cmd.trim().isEmpty()) { whiteListedCommands.add(cmd.trim()); } } } // It is sad that isro and srvr are used by ZooKeeper itself. Need fix this // before deprecating 4lw. if (System.getProperty("readonlymode.enabled", "false").equals("true")) { whiteListedCommands.add("isro"); } // zkServer.sh depends on "srvr". whiteListedCommands.add("srvr"); whiteListInitialized = true; LOG.info("The list of known four letter word commands is : {}", Arrays.asList(cmd2String)); LOG.info("The list of enabled four letter word commands is : {}", Arrays.asList(whiteListedCommands)); return whiteListedCommands.contains(command); } // specify all of the commands that are available static { cmd2String.put(confCmd, "conf"); cmd2String.put(consCmd, "cons"); cmd2String.put(crstCmd, "crst"); cmd2String.put(dirsCmd, "dirs"); cmd2String.put(dumpCmd, "dump"); cmd2String.put(enviCmd, "envi"); cmd2String.put(getTraceMaskCmd, "gtmk"); cmd2String.put(ruokCmd, "ruok"); cmd2String.put(setTraceMaskCmd, "stmk"); cmd2String.put(srstCmd, "srst"); cmd2String.put(srvrCmd, "srvr"); cmd2String.put(statCmd, "stat"); cmd2String.put(wchcCmd, "wchc"); cmd2String.put(wchpCmd, "wchp"); cmd2String.put(wchsCmd, "wchs"); cmd2String.put(mntrCmd, "mntr"); cmd2String.put(isroCmd, "isro"); cmd2String.put(telnetCloseCmd, "telnet close"); } }