/** * '$RCSfile$' * Copyright: 2013 Regents of the University of California and the * National Center for Ecological Analysis and Synthesis * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.ucsb.nceas.metacat.authentication; import java.io.Console; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.util.HashMap; import java.util.List; import java.util.Vector; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.ucsb.nceas.metacat.AuthInterface; import edu.ucsb.nceas.metacat.AuthLdap; import edu.ucsb.nceas.metacat.properties.PropertyService; import edu.ucsb.nceas.metacat.util.SystemUtil; import edu.ucsb.nceas.utilities.PropertyNotFoundException; /** * This an authentication class base on a username/password file. * It is an alternative authentication mechanism of the ldap authentication. * The password file looks like: * * * * * ******* * foo@foo.com * Smith * John * NCEAS * nceas-dev * * * * * developers at NCEAS * * * * http://commons.apache.org/proper/commons-configuration/userguide/howto_xml.html * @author tao * */ public class AuthFile implements AuthInterface { private static final String ORGANIZATIONNAME = "Unknown"; private static final String ORGANIZATION = "organization"; private static final String NAME = "name"; private static final String DN = "dn"; private static final String DESCRIPTION = "description"; private static final String PASSWORD = "password"; private static final String SLASH = "/"; private static final String AT = "@"; private static final String SUBJECTS = "subjects"; private static final String USERS = "users"; private static final String USER = "user"; private static final String GROUPS = "groups"; private static final String GROUP = "group"; private static final String EMAIL = "email"; private static final String SURNAME = "surName"; private static final String GIVENNAME = "givenName"; private static final String MEMBEROF = "memberof"; private static final String INITCONTENT = "\n"+ "<"+SUBJECTS+">\n"+"<"+USERS+">\n"+"\n"+"<"+GROUPS+">\n"+"\n"+"\n"; private static Log log = LogFactory.getLog(AuthFile.class); private static XMLConfiguration userpassword = null; private String authURI = null; private static String passwordFilePath = null; private static AuthFileHashInterface hashClass = null; private boolean readPathFromProperty = true; /** * Get the instance of the AuthFile * @return * @throws AuthenticationException */ /*public static AuthFile getInstance() throws AuthenticationException { if(authFile == null) { authFile = new AuthFile(); } return authFile; }*/ /** * Get the instance of the AuthFile from specified password file * @return * @throws AuthenticationException */ /*public static AuthFile getInstance(String passwordFile) throws AuthenticationException { passwordFilePath = passwordFile; if(authFile == null) { authFile = new AuthFile(); } return authFile; }*/ /** * Constructor */ public AuthFile() throws AuthenticationException { try { init(); } catch (Exception e) { e.printStackTrace(); throw new AuthenticationException(e.getMessage()); } } /** * * @param passwordFile * @throws AuthenticationException */ public AuthFile (String passwordFile) throws AuthenticationException { passwordFilePath = passwordFile; readPathFromProperty = false; try { init(); } catch (Exception e) { e.printStackTrace(); throw new AuthenticationException(e.getMessage()); } } /* * Initialize the user/password configuration */ private void init() throws PropertyNotFoundException, IOException, ConfigurationException, ClassNotFoundException, InstantiationException, IllegalAccessException { if(readPathFromProperty || passwordFilePath == null) { passwordFilePath = PropertyService.getProperty("auth.file.path"); } //System.out.println("the password file path is ======================= "+passwordFilePath); File passwordFile = new File(passwordFilePath); authURI = SystemUtil.getContextURL(); String hashClassName = PropertyService.getProperty("auth.file.hashClassName"); Class classDefinition = Class.forName(hashClassName); Object object = classDefinition.newInstance(); hashClass = (AuthFileHashInterface) object; //if the password file doesn't exist, create a new one and set the initial content if(!passwordFile.exists()) { File parent = passwordFile.getParentFile(); if(!parent.exists()) { boolean success = false; try { success = parent.mkdirs(); } catch (Exception e) { throw new IOException("AuthFile.init - couldn't create the directory "+parent.getAbsolutePath()+ " since "+e.getMessage()); } if(!success) { throw new IOException("AuthFile.init - couldn't create the directory "+parent.getAbsolutePath()+ ", probably since the metacat doesn't have the write permission."); } } boolean success = false; try { success = passwordFile.createNewFile(); } catch (Exception e) { throw new IOException("AuthFile.init - couldn't create the file "+passwordFile.getAbsolutePath()+ " since "+e.getMessage()); } if(!success) { throw new IOException("AuthFile.init - couldn't create the file "+parent.getAbsolutePath()+ ", probably since the metacat doesn't have the write permission."); } OutputStreamWriter writer = null; FileOutputStream output = null; try { output = new FileOutputStream(passwordFile); writer = new OutputStreamWriter(output, "UTF-8"); writer.write(INITCONTENT); } finally { writer.close(); output.close(); } } userpassword = new XMLConfiguration(passwordFile); userpassword.setExpressionEngine(new XPathExpressionEngine()); userpassword.setAutoSave(true); userpassword.setDelimiterParsingDisabled(true); userpassword.setAttributeSplittingDisabled(true); } @Override public boolean authenticate(String user, String password) throws AuthenticationException { boolean match = false; String passwordRecord = userpassword.getString(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+PASSWORD); if(passwordRecord != null) { try { match = hashClass.match(password, passwordRecord); } catch (Exception e) { throw new AuthenticationException(e.getMessage()); } } return match; } @Override /** * Get all users. This is two-dimmention array. Each row is a user. The first element of * a row is the user name. The second element is common name. The third one is the organization name (null). * The fourth one is the organization unit name (null). The fifth one is the email address. */ public String[][] getUsers(String user, String password) throws ConnectException { List users = userpassword.getList(USERS+SLASH+USER+SLASH+AT+DN); if(users != null && users.size() > 0) { String[][] usersArray = new String[users.size()][5]; for(int i=0; i surNames = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+SURNAME); if(surNames != null && !surNames.isEmpty()) { surname = (String)surNames.get(0); } aUser.setSurName(surname); String givenName = null; List givenNames = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+GIVENNAME); if(givenNames != null && !givenNames.isEmpty()) { givenName = (String)givenNames.get(0); } aUser.setGivenName(givenName); userinfo[AuthInterface.USERINFOCNINDEX] = aUser.getCn();//common name String organization = null; List organizations = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+ORGANIZATION); if(organizations != null && !organizations.isEmpty()) { organization = (String)organizations.get(0); } userinfo[AuthInterface.USERINFOORGANIDEX] = organization;//organization name. aUser.setOrganization(organization); List emails = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+user+"']"+SLASH+EMAIL); String email = null; if(emails != null && !emails.isEmpty() ) { email = (String)emails.get(0); } aUser.setEmail(email); userinfo[AuthInterface.USERINFOEMAILINDEX] = email; return userinfo; } @Override /** * Get the users for a particular group from the authentication service * The null will return if there is no user. * @param user * the user for authenticating against the service * @param password * the password for authenticating against the service * @param group * the group whose user list should be returned * @returns string array of the user names belonging to the group */ public String[] getUsers(String user, String password, String group) throws ConnectException { List users = userpassword.getList(USERS+SLASH+USER+"["+MEMBEROF+"='"+group+"']"+SLASH+AT+DN); if(users != null && users.size() > 0) { String[] usersArray = new String[users.size()]; for(int i=0; i groups = userpassword.getList(GROUPS+SLASH+GROUP+SLASH+AT+NAME); if(groups!= null && groups.size() >0) { String[][] groupsArray = new String[groups.size()][2]; for(int i=0; idescriptions = userpassword.getList(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+SLASH+DESCRIPTION); if(descriptions != null && !descriptions.isEmpty()) { description = (String)descriptions.get(0); } groupsArray[i][AuthInterface.GROUPDESINDEX] = description; } return groupsArray; } return null; } @Override /** * Get groups from a specified user. It returns two dimmension array. Each row is a * group. The first column is the group name. The null will return if no group found. */ public String[][] getGroups(String user, String password, String foruser) throws ConnectException { List groups = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+foruser+"']"+SLASH+MEMBEROF); if(groups != null && groups.size() > 0) { String[][] groupsArray = new String[groups.size()][2]; for(int i=0; idescriptions = userpassword.getList(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+SLASH+DESCRIPTION); if(descriptions != null && !descriptions.isEmpty()) { description = (String)descriptions.get(0); } groupsArray[i][AuthInterface.GROUPDESINDEX] = description; } return groupsArray; } return null; } @Override public HashMap> getAttributes(String foruser) throws ConnectException { //we only check if the user exists or not. if(!userExists(foruser)) { throw new ConnectException("NameNotFoundException - the user "+foruser+" doesn't exist in the password file."); } return null; } @Override public HashMap> getAttributes(String user, String password, String foruser) throws ConnectException { // TODO Auto-generated method stub return null; } @Override public String getPrincipals(String user, String password) throws ConnectException { StringBuffer out = new StringBuffer(); out.append("\n"); out.append("\n"); out.append(" \n"); // get all groups for directory context String[][] groups = getGroups(user, password); String[][] users = getUsers(user, password); int userIndex = 0; // for the groups and users that belong to them if (groups != null && users != null && groups.length > 0) { for (int i = 0; i < groups.length; i++) { out.append(" \n"); out.append(" " + groups[i][AuthInterface.GROUPNAMEINDEX] + "\n"); if(groups[i].length > 1) { out.append(" " + groups[i][AuthInterface.GROUPDESINDEX] + "\n"); } String[] usersForGroup = getUsers(user, password, groups[i][0]); if(usersForGroup != null) { for (int j = 0; j < usersForGroup.length; j++) { userIndex = AuthLdap.searchUser(usersForGroup[j], users); out.append(" \n"); if (userIndex < 0) { out.append(" " + usersForGroup[j] + "\n"); } else { out.append(" " + users[userIndex][0] + "\n"); if(users[userIndex][AuthInterface.USERCNINDEX] != null) { out.append(" " + users[userIndex][AuthInterface.USERCNINDEX] + "\n"); } if(users[userIndex][AuthInterface.USERORGINDEX] != null) { out.append(" " + users[userIndex][AuthInterface.USERORGINDEX] + "\n"); } if(users[userIndex][AuthInterface.USERORGUNITINDEX] != null) { out.append(" " + users[userIndex][AuthInterface.USERORGUNITINDEX] + "\n"); } if(users[userIndex][AuthInterface.USEREMAILINDEX] != null) { out.append(" " + users[userIndex][AuthInterface.USEREMAILINDEX] + "\n"); } } out.append(" \n"); } } out.append(" \n"); } } if (users != null) { // for the users not belonging to any grou8p for (int j = 0; j < users.length; j++) { out.append(" \n"); out.append(" " + users[j][0] + "\n"); if(users[j][AuthInterface.USERCNINDEX] != null) { out.append(" " + users[j][AuthInterface.USERCNINDEX] + "\n"); } if(users[j][AuthInterface.USERORGINDEX] != null) { out.append(" " + users[j][AuthInterface.USERORGINDEX] + "\n"); } if(users[j][AuthInterface.USERORGUNITINDEX] != null) { out.append(" " + users[j][AuthInterface.USERORGUNITINDEX] + "\n"); } if(users[j][AuthInterface.USEREMAILINDEX] != null) { out.append(" " + users[j][AuthInterface.USEREMAILINDEX] + "\n"); } out.append(" \n"); } } out.append(" \n"); out.append(""); return out.toString(); } /** * Add a user to the file * @param userName the name of the user * @param groups the groups the user belong to. The group should exist in the file * @param password the password of the user */ public void addUser(String dn, String[] groups, String plainPass, String hashedPass, String email, String surName, String givenName, String organization) throws AuthenticationException{ User user = new User(); user.setDN(dn); user.setGroups(groups); user.setPlainPass(plainPass); user.setHashedPass(hashedPass); user.setEmail(email); user.setSurName(surName); user.setGivenName(givenName); user.setOrganization(organization); user.serialize(); } /** * Add a group into the file * @param groupName the name of group */ public void addGroup(String groupName, String description) throws AuthenticationException{ if(groupName == null || groupName.trim().equals("")) { throw new AuthenticationException("AuthFile.addGroup - can't add a group whose name is null or blank."); } if(!groupExists(groupName)) { if(userpassword != null) { userpassword.addProperty(GROUPS+" "+GROUP+AT+NAME, groupName); if(description != null && !description.trim().equals("")) { userpassword.addProperty(GROUPS+SLASH+GROUP+"["+AT+NAME+"='"+groupName+"']"+" "+DESCRIPTION, description); } //userpassword.reload(); } } else { throw new AuthenticationException("AuthFile.addGroup - can't add the group "+groupName+" since it already exists."); } } /** * Change the password of the user to the new one which is hashed * @param usrName the specified user. * @param newPassword the new password which will be set */ public void modifyPassWithHash(String userName, String newHashPassword) throws AuthenticationException { User user = new User(); user.setDN(userName); user.modifyHashPass(newHashPassword); } /** * Change the password of the user to the new one which is plain. However, only the hashed version will be serialized. * @param usrName the specified user. * @param newPassword the new password which will be set */ public void modifyPassWithPlain(String userName, String newPlainPassword) throws AuthenticationException { User user = new User(); user.setDN(userName); user.modifyPlainPass(newPlainPassword); } /** * Add a user to a group * @param userName the name of the user. the user should already exist * @param group the name of the group. the group should already exist */ public void addUserToGroup(String userName, String group) throws AuthenticationException { User user = new User(); user.setDN(userName); user.addToGroup(group); } /** * Remove a user from a group. * @param userName the name of the user. the user should already exist. * @param group the name of the group */ public void removeUserFromGroup(String userName, String group) throws AuthenticationException{ User user = new User(); user.setDN(userName); user.removeFromGroup(group); } /** * If the specified user name exist or not * @param userName the name of the user * @return true if the user eixsit */ private synchronized boolean userExists(String userName) throws AuthenticationException{ if(userName == null || userName.trim().equals("")) { throw new AuthenticationException("AuthFile.userExist - can't judge if a user exists when its name is null or blank."); } List users = userpassword.getList(USERS+SLASH+USER+SLASH+AT+DN); if(users != null && users.contains(userName)) { return true; } else { return false; } } /** * If the specified group exist or not * @param groupName the name of the group * @return true if the user exists */ private synchronized boolean groupExists(String groupName) throws AuthenticationException{ if(groupName == null || groupName.trim().equals("")) { throw new AuthenticationException("AuthFile.groupExist - can't judge if a group exists when its name is null or blank."); } List groups = userpassword.getList(GROUPS+SLASH+GROUP+SLASH+AT+NAME); if(groups != null && groups.contains(groupName)) { return true; } else { return false; } } /* * Encrypt a plain text */ private static String encrypt(String plain) { return hashClass.hash(plain); } /** * A method is used to help administrator to manage users and groups * @param argus * @throws Exception */ public static void main(String[] argus) throws Exception { String USERADD = "useradd"; String USERMOD = "usermod"; String GROUPADD = "groupadd"; String USAGE = "usage"; if(argus == null || argus.length ==0) { System.out.println("Please make sure that there are two arguments - \"$BASE_WEB_INF\" and\" $@\" after the class name edu.ucsb.nceas.metacat.authentication.AuthFile in the script file."); System.exit(1); } else if(argus.length ==1) { printUsage(); System.exit(1); } PropertyService.getInstance(argus[0]); AuthFile authFile = new AuthFile(); if(argus[1] != null && argus[1].equals(GROUPADD)) { handleGroupAdd(authFile,argus); } else if (argus[1] != null && argus[1].equals(USERADD)) { handleUserAdd(authFile,argus); } else if (argus[1] != null && argus[1].equals(USERMOD)) { handleUserMod(authFile, argus); } else if (argus[1] != null && argus[1].equals(USAGE)) { printUsage(); } else { System.out.print("Error: the unknown action "+argus[1]); } } /* * Handle the groupAdd action in the main method */ private static void handleGroupAdd(AuthFile authFile, String[]argus) throws AuthenticationException { HashMap map = null; String G = "-g"; String D = "-d"; Vector pairedOptions = new Vector(); pairedOptions.add(G); pairedOptions.add(D); int startIndex = 2; try { map = parseArgus(startIndex, argus, pairedOptions, null); } catch (Exception e ) { System.out.println("Error in the groupadd command: "+e.getMessage()); System.exit(1); } String groupName = null; String description = null; if(map.keySet().size() == 0) { System.out.println("Error in the groupadd command: the \""+G+" group-name\" is required."); System.exit(1); } else if(map.keySet().size() ==1 || map.keySet().size() ==2) { groupName = map.get(G); if(groupName == null || groupName.trim().equals("")) { System.out.println("Error in the groupadd command : the \""+G+" group-name\" is required."); System.exit(1); } description = map.get(D); authFile.addGroup(groupName, description); System.out.println("Successfully added a group \""+groupName+"\" to the file authentication system"); } else { printError(argus); System.exit(1); } } /* * Handle the userAdd action in the main method */ private static void handleUserAdd(AuthFile authFile,String[]argus) throws UnsupportedEncodingException, AuthenticationException{ String I = "-i"; String H = "-h"; String DN = "-dn"; String G = "-g"; String E = "-e"; String S = "-s"; String F = "-f"; String O = "-o"; Vector pairedOptions = new Vector(); pairedOptions.add(H); pairedOptions.add(DN); pairedOptions.add(G); pairedOptions.add(E); pairedOptions.add(S); pairedOptions.add(F); pairedOptions.add(O); Vector singleOptions = new Vector(); singleOptions.add(I); HashMap map = new HashMap(); int startIndex = 2; try { map = parseArgus(startIndex, argus, pairedOptions, singleOptions); } catch (Exception e) { System.out.println("Error in the useradd command: "+e.getMessage()); System.exit(1); } String dn = map.get(DN); if(dn == null || dn.trim().equals("")) { System.out.println("The \"-dn user-distinguish-name\" is requried in the useradd command ."); System.exit(1); } String plainPassword = null; String hashedPassword = null; String input = map.get(I); String passHash = map.get(H); if(input != null && passHash != null) { System.out.println("Error in the useradd command: you only can choose either \"-i\" (input a password) or \"-h hashed-password\" (pass through a hashed passwword)."); System.exit(1); } else if (input == null && passHash == null) { System.out.println("Error in the useradd command: you must choose either \"-i\" (input a password) or \"-h hashed-password\" (pass through a hashed password)."); System.exit(1); } else if(input != null) { plainPassword = inputPassword(); //System.out.println("============the plain password is "+plainPassword); } else if(passHash != null) { hashedPassword = passHash; } String group = map.get(G); //System.out.println("the groups name is "+group); String[] groups = null; if(group != null && !group.trim().equals("")) { groups = new String[1]; groups[0]=group; //System.out.println("set the first element of the groups to "+groups[0]); } String email = map.get(E); String surname = map.get(S); String givenname = map.get(F); String organization = map.get(O); authFile.addUser(dn, groups, plainPassword, hashedPassword, email, surname, givenname, organization); System.out.println("Successfully added a user \""+dn+"\" to the file authentication system "); } /* * Handle modify a user's password or group information. */ private static void handleUserMod(AuthFile authFile, String[] argus) throws AuthenticationException, UnsupportedEncodingException { String PASSWORD = "-password"; String GROUP = "-group"; if(argus.length < 3) { System.out.println("Error: the sub action \"-password\" or \"-group\" should follow the action \"usermod\""); System.exit(1); } else { if(argus[2] != null && argus[2].equals(PASSWORD)) { handleModifyPass(authFile, argus); } else if (argus[2] != null && argus[2].equals(GROUP)) { handleModifyGroup(authFile, argus); } else { System.out.println("Error: the sub action \""+argus[2]+"\" is unkown in the action \"usermod\""); System.exit(1); } } } /* * Handle the action to modify the password of a user */ private static void handleModifyPass(AuthFile authFile, String[] argus) throws UnsupportedEncodingException, AuthenticationException { String DN = "-dn"; String I = "-i"; String H = "-h"; Vector pairedOptions = new Vector(); pairedOptions.add(H); pairedOptions.add(DN); Vector singleOptions = new Vector(); singleOptions.add(I); HashMap map = new HashMap(); int startIndex = 3; try { map = parseArgus(startIndex, argus, pairedOptions, singleOptions); } catch (Exception e) { System.out.println("Error in the usermod -password command: "+e.getMessage()); System.exit(1); } String dn = map.get(DN); if(dn == null || dn.trim().equals("")) { System.out.println("Error in the usermod -password command: The \"-dn user-distinguish-name\" is requried."); System.exit(1); } String plainPassword = null; String hashedPassword = null; String input = map.get(I); String passHash = map.get(H); if(input != null && passHash != null) { System.out.println("Error in the usermod -password command: you only can choose either \"-i\" (input a password) or \"-h hashed-password\" (pass through a hashed password)."); System.exit(1); } else if (input == null && passHash == null) { System.out.println("Error in the usermod -password command: you must choose either \"-i\" (input a password) or \"-h hashed-password\" (pass through a hashed password)."); System.exit(1); } else if(input != null) { plainPassword = inputPassword(); //System.out.println("============the plain password is "+plainPassword); authFile.modifyPassWithPlain(dn, plainPassword); System.out.println("Successfully modified the password for the user \""+dn+"\"."); } else if(passHash != null) { hashedPassword = passHash; authFile.modifyPassWithHash(dn, hashedPassword); System.out.println("Successfully modified the password for the user "+dn+"\"."); } } /* * Handle the action adding/removing a user to/from a group */ private static void handleModifyGroup(AuthFile authFile, String[] argus) throws AuthenticationException { String DN = "-dn"; String A = "-a"; String R = "-r"; String G = "-g"; Vector pairedOptions = new Vector(); pairedOptions.add(G); pairedOptions.add(DN); Vector singleOptions = new Vector(); singleOptions.add(A); singleOptions.add(R); HashMap map = new HashMap(); int startIndex = 3; try { map = parseArgus(startIndex, argus, pairedOptions, singleOptions); } catch (Exception e) { System.out.println("Error in the usermod -group command: "+e.getMessage()); System.exit(1); } String add = map.get(A); String remove = map.get(R); String group = map.get(G); String dn = map.get(DN); if(dn == null || dn.trim().equals("")) { System.out.println("Error in the usermod -group command: the \"-dn user-distinguish-name\" is required."); System.exit(1); } if(group == null || group.trim().equals("")) { System.out.println("Error in the usermod -group command: the \"-g group-name\" is required."); System.exit(1); } if(add != null && remove!= null) { System.out.println("Error in the usermod -group command: You can only choose either \"-a\" (add the user to the group) or \"-r\" (remove the user from the group)."); System.exit(1); } else if (add == null && remove == null) { System.out.println("Error in the usermod -group command: You must choose either \"-a\" (add the user to the group) or \"-r\" (remove the user from the group)."); System.exit(1); } else if (remove != null) { authFile.removeUserFromGroup(dn, group); System.out.println("Successfully removed the user "+dn+" from the group \""+group+"\"."); } else { authFile.addUserToGroup(dn, group); System.out.println("Successfully added the user "+dn+" to the group \""+group+"\"."); } } /** * Parse the arguments to get the pairs of option/value. If it is a single option (it doesn't need a value), the pair will be switch/switch. * @param startIndex the index of arguments where we will start. * @param argus the arguments array will be parsed. * @param pairedOptions the known options which should be a pair * @param singleOptions the know options which just has a single value * @return the empty map if there is no pairs were found * @throws Exception if there is an illegal argument. */ private static HashMap parseArgus(int startIndex, String[]argus, VectorpairedOptions, VectorsingleOptions) throws Exception { HashMap map = new HashMap(); if(argus != null) { for(int i=startIndex; i [-g -e -s -f -o ]\n" + "./authFileManager.sh useradd -h -dn [-g -e -s -f -o ]\n"+ "./authFileManager.sh groupadd -g group-name [-d description]\n" + "./authFileManager.sh usermod -password -dn -i\n"+ "./authFileManager.sh usermod -password -dn -h \n"+ "./authFileManager.sh usermod -group -a -dn -g \n" + "./authFileManager.sh usermod -group -r -dn -g \n"+ "Note:\n"+"1. Metacat currently uses Bcrypt algorithm to hash the password. The hashed password following the \"-h\" should be generated by a Bcrypt algorithm.\n"+ " The hash string usually has $ signs which can interfere with the command line arguments. You should use two SINGLE quotes to wrap the entire hashed string.\n"+ "2. The user-distinguish-name must look like \"uid=john,o=something,dc=something,dc=something\" and the group-name must look like \"cn=dev,o=something,dc=something,dc=something\".\n"+ "3. if a value of an option has spaces, the value should be enclosed by the double quotes.\n"+ " For example: ./authFileManager.sh groupadd -g cn=dev,o=something,dc=something,dc=something -d \"Developers at NCEAS\"\n"+ "4. \"-d description\" in the \"groupadd\" command is optional; \"-g groupname -e email-address -s surname -f given-name -o organizationName\" in the \"useradd\" command are optional as well."); } /* * Print out the statement to say it is a illegal command */ private static void printError(String[] argus) { if(argus != null) { System.out.println("Error: it is an illegal command (probably with some illegal options): "); for(int i=0; i existingGroups = userpassword.getList(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+SLASH+MEMBEROF); if(existingGroups != null && existingGroups.contains(group)) { throw new AuthenticationException("AuthFile.User.addUserToGroup - the user "+dn+ " already is the memember of the group "+group); } userpassword.addProperty(USERS+SLASH+USER+"["+AT+DN+"='"+dn+"']"+" "+MEMBEROF, group); //add information to the memory if(groups == null) { if(existingGroups == null || existingGroups.isEmpty()) { groups = new String[1]; groups[0] = group; } else { groups = new String[existingGroups.size()+1]; for(int i=0; i existingGroups = userpassword.getList(key); if(!existingGroups.contains(group)) { throw new AuthenticationException("AuthFile.User.removeUserFromGroup - the user "+dn+ " isn't the memember of the group "+group); } else { userpassword.clearProperty(key+"[.='"+group+"']"); } //change the value in the memory. if(groups != null) { boolean contains = false; for(int i=0; i