package jfconfig; /** * Created : Mar 4, 2012 * * @author pquiring */ import java.io.*; import java.util.*; import javax.swing.*; import javaforce.*; import javaforce.linux.Linux; public class UsersPanel extends javax.swing.JPanel { /** * Creates new form ConfigPanel */ public UsersPanel() { initComponents(); loadUsers(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { split = new javax.swing.JSplitPane(); jScrollPane1 = new javax.swing.JScrollPane(); users = new javax.swing.JList(); jTabbedPane1 = new javax.swing.JTabbedPane(); jPanel2 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); username = new javax.swing.JTextField(); resetPasswd = new javax.swing.JButton(); jPanel1 = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); groups = new javax.swing.JList(); addGroup = new javax.swing.JButton(); deleteGroup = new javax.swing.JButton(); manageGroups = new javax.swing.JButton(); addGroupCombo = new javax.swing.JComboBox(); jToolBar1 = new javax.swing.JToolBar(); back = new javax.swing.JButton(); addUser = new javax.swing.JButton(); deleteUser = new javax.swing.JButton(); split.setDividerLocation(164); split.setResizeWeight(0.5); users.setModel(usersModel); users.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); users.addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { usersValueChanged(evt); } }); jScrollPane1.setViewportView(users); split.setLeftComponent(jScrollPane1); jLabel1.setText("Username:"); username.setEditable(false); resetPasswd.setText("Reset Password"); resetPasswd.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { resetPasswdActionPerformed(evt); } }); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(username)) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(resetPasswd) .addGap(0, 1249, Short.MAX_VALUE))) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(username, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(resetPasswd) .addContainerGap(448, Short.MAX_VALUE)) ); jTabbedPane1.addTab("General", jPanel2); groups.setModel(groupsModel); groups.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane2.setViewportView(groups); addGroup.setText("Add Group"); addGroup.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addGroupActionPerformed(evt); } }); deleteGroup.setText("Delete Group"); deleteGroup.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteGroupActionPerformed(evt); } }); manageGroups.setText("Manage Groups"); manageGroups.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { manageGroupsActionPerformed(evt); } }); addGroupCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(addGroupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(addGroup) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(deleteGroup) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 933, Short.MAX_VALUE) .addComponent(manageGroups))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 455, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(addGroup) .addComponent(deleteGroup) .addComponent(manageGroups) .addComponent(addGroupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); jTabbedPane1.addTab("Groups", jPanel1); split.setRightComponent(jTabbedPane1); jToolBar1.setFloatable(false); jToolBar1.setRollover(true); back.setText("<Back"); back.setFocusable(false); back.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); back.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); back.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backActionPerformed(evt); } }); jToolBar1.add(back); addUser.setText("Add User"); addUser.setFocusable(false); addUser.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); addUser.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); addUser.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addUserActionPerformed(evt); } }); jToolBar1.add(addUser); deleteUser.setText("Delete User"); deleteUser.setFocusable(false); deleteUser.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); deleteUser.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); deleteUser.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteUserActionPerformed(evt); } }); jToolBar1.add(deleteUser); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(split) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(split)) ); }// </editor-fold>//GEN-END:initComponents private void backActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backActionPerformed ConfigApp.This.setPanel(new MainPanel()); }//GEN-LAST:event_backActionPerformed private void addUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addUserActionPerformed UserAddDialog dialog = new UserAddDialog(ConfigApp.This, true); dialog.setVisible(true); if (!dialog.accepted) return; ShellProcess sp = new ShellProcess(); sp.log = true; ArrayList<String> cmd = new ArrayList<String>(); cmd.add("sudo"); cmd.add("useradd"); cmd.add("-s"); cmd.add("/bin/bash"); cmd.add("-m"); cmd.add("-U"); //create group with same name if (dialog.getAdmin()) { switch (Linux.distro) { case Ubuntu: // cmd.add("-G"); // cmd.add("admin"); //allows sudo (Ubuntu 11.10) cmd.add("-G"); cmd.add("sudo"); //allows sudo (Ubuntu 12.04) break; case Fedora: cmd.add("-G"); cmd.add("wheel"); break; } } cmd.add("-c"); cmd.add("\"" + dialog.getFullName() + "\""); cmd.add(dialog.getUserName()); String output = sp.run(cmd, false); if (output == null) { JF.showError("Error", "Failed to create new user."); return; } sp = new ShellProcess(); sp.addResponse("Enter new UNIX password:", dialog.getPassWord() + "\n", true); sp.addResponse("Retype new UNIX password:", dialog.getPassWord() + "\n", true); output = sp.run(new String[] {"sudo", "passwd", dialog.getUserName()}, true); if ((output == null) || (output.indexOf("passwd: Authentication token manipulation error") != -1)) { JF.showError("Error", "Failed to set new password."); } sp.log = false; loadUsers(); }//GEN-LAST:event_addUserActionPerformed private void deleteUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteUserActionPerformed int idx = users.getSelectedIndex(); if (idx == -1) return; //TODO : make sure not deleting last admin or current user String userName = usersModel.fields.get(idx)[0]; ShellProcess sp = new ShellProcess(); ArrayList<String> cmd = new ArrayList<String>(); if (!JF.showConfirm("Confirm", "Are you sure you want to delete user '" + userName + "'?")) return; cmd.add("sudo"); cmd.add("userdel"); cmd.add("-r"); //remove files cmd.add(userName); String output = sp.run(cmd, false); if (output == null) { JF.showError("Error", "Failed to delete user."); } loadUsers(); }//GEN-LAST:event_deleteUserActionPerformed private void resetPasswdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetPasswdActionPerformed int idx = users.getSelectedIndex(); if (idx == -1) return; String userName = usersModel.fields.get(idx)[0]; GetPasswordDialog dialog = new GetPasswordDialog(ConfigApp.This, true); dialog.setVisible(true); if (dialog.cancelled) return; ShellProcess sp = new ShellProcess(); sp.addResponse("Enter new UNIX password:", dialog.getPassWord() + "\n", true); sp.addResponse("Retype new UNIX password:", dialog.getPassWord() + "\n", true); String output = sp.run(new String[] {"sudo" ,"passwd", userName}, true); if ((output == null) || (output.indexOf("passwd: Authentication token manipulation error") != -1)) { JF.showError("Error", "Failed to set new password."); } loadUsers(); }//GEN-LAST:event_resetPasswdActionPerformed private void addGroupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addGroupActionPerformed int idx = users.getSelectedIndex(); if (idx == -1) return; if (addGroupCombo.getSelectedIndex() == -1) return; String userName = usersModel.fields.get(idx)[0]; ShellProcess sp = new ShellProcess(); ArrayList<String> cmd = new ArrayList<String>(); cmd.add("sudo"); cmd.add("usermod"); cmd.add("-a"); //append group cmd.add("-G"); cmd.add((String)addGroupCombo.getSelectedItem()); cmd.add(userName); String output = sp.run(cmd, false); if (output == null) { JF.showError("Error", "Failed to add user to group."); return; } loadGroups(idx); }//GEN-LAST:event_addGroupActionPerformed private void deleteGroupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteGroupActionPerformed int idx = users.getSelectedIndex(); if (idx == -1) return; int gidx = groups.getSelectedIndex(); if (gidx == -1) return; String userName = usersModel.fields.get(idx)[0]; ShellProcess sp = new ShellProcess(); ArrayList<String> cmd = new ArrayList<String>(); cmd.add("sudo"); cmd.add("usermod"); cmd.add("-G"); cmd.add(getUserGroups(idx, gidx)); cmd.add(userName); String output = sp.run(cmd, false); if (output == null) { JF.showError("Error", "Failed to add user to group."); return; } loadGroups(idx); }//GEN-LAST:event_deleteGroupActionPerformed private void usersValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_usersValueChanged int idx = users.getSelectedIndex(); if (idx == -1) return; loadUser(idx); }//GEN-LAST:event_usersValueChanged private void manageGroupsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageGroupsActionPerformed ConfigApp.This.setPanel(new GroupsPanel()); }//GEN-LAST:event_manageGroupsActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addGroup; private javax.swing.JComboBox addGroupCombo; private javax.swing.JButton addUser; private javax.swing.JButton back; private javax.swing.JButton deleteGroup; private javax.swing.JButton deleteUser; private javax.swing.JList groups; private javax.swing.JLabel jLabel1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTabbedPane jTabbedPane1; private javax.swing.JToolBar jToolBar1; private javax.swing.JButton manageGroups; private javax.swing.JButton resetPasswd; private javax.swing.JSplitPane split; private javax.swing.JTextField username; private javax.swing.JList users; // End of variables declaration//GEN-END:variables private class ListModel extends DefaultListModel { public ArrayList<String[]> fields = new ArrayList<String[]>(); } private ListModel usersModel = new ListModel(), groupsModel = new ListModel(); public void loadUsers() { usersModel.clear(); usersModel.fields.clear(); try { FileInputStream fis = new FileInputStream("/etc/passwd"); int len = fis.available(); byte buf[] = new byte[len]; int pos = 0; while (pos < len) { int read = fis.read(buf, pos, len-pos); if (read <= 0) throw new Exception("file error"); pos += read; } fis.close(); String passwd = new String(buf); String lns[] = passwd.split("\n"); for(int a=0;a<lns.length;a++) { String f[] = lns[a].split(":", -1); //0=user : 1=x : 2=uid : 3=gid : 4=comment : 5=home : 6=shell if (f[0].equals("root")) continue; if (!f[6].equals("/bin/bash")) continue; usersModel.addElement(f[0]); usersModel.fields.add(f); } } catch (Exception e) { JFLog.log(e); } users.repaint(); split.revalidate(); } private void loadUser(int idx) { String f[] = usersModel.fields.get(idx); username.setText(f[0]); loadGroups(idx); } private void loadGroups(int idx) { groupsModel.clear(); groupsModel.fields.clear(); addGroupCombo.removeAllItems(); String user = (String)users.getSelectedValue(); ArrayList<String> groupList = new ArrayList<String>(); try { FileInputStream fis = new FileInputStream("/etc/group"); String group = new String(JF.readAll(fis)); fis.close(); String lns[] = group.split("\n"); for(int a=0;a<lns.length;a++) { String f[] = lns[a].split(":", -1); //0=group : 1=x : 2=gid : 3=users // addGroupCombo.addItem(f[0]); groupList.add(f[0]); String u[] = f[3].split(","); for(int b=0;b<u.length;b++) { if (u[b].equals(user)) { groupsModel.addElement(f[0]); groupsModel.fields.add(f); break; } } if (f[0].equals(user)) { //you are always a member of your own group groupsModel.addElement(f[0]); groupsModel.fields.add(f); } } } catch (Exception e) { JFLog.log(e); } groups.repaint(); String gl[] = groupList.toArray(new String[0]); Arrays.sort(gl); for(int a=0;a<gl.length;a++) { addGroupCombo.addItem(gl[a]); } addGroupCombo.repaint(); } /** Returns groups that user is in, excluding gidx.*/ private String getUserGroups(int uidx, int gidx) { String userName = (String)usersModel.getElementAt(uidx); StringBuffer out = new StringBuffer(); for(int a=0;a<groupsModel.size();a++) { if (a == gidx) continue; //exclude deleted one String f[] = groupsModel.fields.get(a); boolean ok = false; for(int b=0;b<f.length;b++) { if (f[b].equals(userName)) {ok = true; break;} } if (ok) { if (out.length() > 0) out.append(","); out.append((String)groupsModel.getElementAt(a)); } } return out.toString(); } }