| /******************************************************************************* |
| * Copyright (c) 2001, 2009 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.useradmin; |
| |
| import java.security.*; |
| import org.eclipse.osgi.util.NLS; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| import org.osgi.service.log.LogService; |
| import org.osgi.service.prefs.*; |
| |
| /* |
| * UserAdminStore is responsible for managing the persistence data of the useradmin |
| * service. It uses the PersistenceNode service as its underlying storage. |
| */ |
| |
| public class UserAdminStore { |
| |
| static protected final String propertiesNode = "properties"; //$NON-NLS-1$ |
| static protected final String credentialsNode = "credentials"; //$NON-NLS-1$ |
| static protected final String membersNode = "members"; //$NON-NLS-1$ |
| static private final String typesNode = "types"; //$NON-NLS-1$ |
| static protected final String basicString = "basic"; //$NON-NLS-1$ |
| static protected final String requiredString = "required"; //$NON-NLS-1$ |
| static protected final String typeString = "type"; //$NON-NLS-1$ |
| static protected final String persistenceUserName = "UserAdmin"; //$NON-NLS-1$ |
| |
| protected ServiceReference prefsRef; |
| protected ServiceRegistration userAdminListenerReg; |
| protected UserAdmin useradmin; |
| protected LogTracker log; |
| protected Preferences rootNode; |
| protected PreferencesService preferencesService; |
| |
| protected UserAdminStore(PreferencesService preferencesService, UserAdmin useradmin, LogTracker log) { |
| this.preferencesService = preferencesService; |
| this.useradmin = useradmin; |
| this.log = log; |
| } |
| |
| protected void init() throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| |
| public Object run() throws BackingStoreException { |
| rootNode = preferencesService.getUserPreferences(persistenceUserName); |
| loadRoles(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void addRole(final org.osgi.service.useradmin.Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences node = rootNode.node(role.getName()); |
| node.putInt(typeString, role.getType()); |
| node.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void removeRole(final org.osgi.service.useradmin.Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences node = rootNode.node(role.getName()); |
| node.removeNode(); |
| rootNode.node("").flush(); //$NON-NLS-1$ |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void clearProperties(final org.osgi.service.useradmin.Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences propertyNode = rootNode.node(role.getName() + "/" + propertiesNode); //$NON-NLS-1$ |
| propertyNode.clear(); |
| if (propertyNode.nodeExists(typesNode)) |
| propertyNode.node(typesNode).removeNode(); |
| propertyNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void addProperty(final org.osgi.service.useradmin.Role role, final String key, final Object value) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences propertyNode = rootNode.node(role.getName() + "/" + propertiesNode); //$NON-NLS-1$ |
| Preferences propertyTypesNode = propertyNode.node(typesNode); |
| if (value instanceof String) { |
| propertyNode.put(key, (String) value); |
| propertyTypesNode.putBoolean(key, true); |
| } else //must be a byte array, then |
| { |
| propertyNode.putByteArray(key, (byte[]) value); |
| propertyTypesNode.putBoolean(key, false); |
| } |
| propertyNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void removeProperty(final org.osgi.service.useradmin.Role role, final String key) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences propertyNode = rootNode.node(role.getName() + "/" + propertiesNode); //$NON-NLS-1$ |
| propertyNode.remove(key); |
| if (propertyNode.nodeExists(typesNode)) |
| propertyNode.node(typesNode).remove(key); |
| propertyNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void clearCredentials(final org.osgi.service.useradmin.Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences credentialNode = rootNode.node(role.getName() + "/" + credentialsNode); //$NON-NLS-1$ |
| credentialNode.clear(); |
| if (credentialNode.nodeExists(typesNode)) |
| credentialNode.node(typesNode).removeNode(); |
| credentialNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void addCredential(final org.osgi.service.useradmin.Role role, final String key, final Object value) throws BackingStoreException { |
| |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences credentialNode = rootNode.node(role.getName() + "/" + credentialsNode); //$NON-NLS-1$ |
| Preferences credentialTypesNode = credentialNode.node(typesNode); |
| if (value instanceof String) { |
| credentialNode.put(key, (String) value); |
| credentialTypesNode.putBoolean(key, true); |
| } else //assume it is a byte array |
| { |
| credentialNode.putByteArray(key, (byte[]) value); |
| credentialTypesNode.putBoolean(key, false); |
| } |
| credentialNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, NLS.bind(UserAdminMsg.Backing_Store_Write_Exception, new Object[] {NLS.bind(UserAdminMsg.adding_Credential_to__15, role.getName())}), ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| |
| } |
| |
| protected void removeCredential(final org.osgi.service.useradmin.Role role, final String key) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences credentialNode = rootNode.node(role.getName() + "/" + credentialsNode); //$NON-NLS-1$ |
| credentialNode.remove(key); |
| if (credentialNode.nodeExists(typesNode)) |
| credentialNode.node(typesNode).remove(key); |
| credentialNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void addMember(final Group group, final Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences memberNode = rootNode.node(group.getName() + "/" + membersNode); //$NON-NLS-1$ |
| memberNode.put(role.getName(), basicString); |
| memberNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, NLS.bind(UserAdminMsg.Backing_Store_Write_Exception, new Object[] {NLS.bind(UserAdminMsg.adding_member__18, role.getName(), group.getName())}), ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void addRequiredMember(final Group group, final Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences memberNode = rootNode.node(group.getName() + "/" + membersNode); //$NON-NLS-1$ |
| memberNode.put(role.getName(), requiredString); |
| memberNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, NLS.bind(UserAdminMsg.Backing_Store_Write_Exception, new Object[] {NLS.bind(UserAdminMsg.adding_required_member__21, role.getName(), group.getName())}), ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void removeMember(final Group group, final Role role) throws BackingStoreException { |
| try { |
| AccessController.doPrivileged(new PrivilegedExceptionAction() { |
| public Object run() throws BackingStoreException { |
| Preferences memberNode = rootNode.node(group.getName() + "/" + membersNode); //$NON-NLS-1$ |
| memberNode.remove(role.getName()); |
| memberNode.flush(); |
| return (null); |
| } |
| }); |
| } catch (PrivilegedActionException ex) { |
| log.log(LogService.LOG_ERROR, NLS.bind(UserAdminMsg.Backing_Store_Write_Exception, new Object[] {NLS.bind(UserAdminMsg.removing_member__24, role.getName(), group.getName())}), ex); |
| throw ((BackingStoreException) ex.getException()); |
| } |
| } |
| |
| protected void loadRoles() throws BackingStoreException { |
| synchronized (this) { |
| createAnonRole(); |
| |
| String[] children = rootNode.node("").childrenNames(); //$NON-NLS-1$ |
| |
| for (int i = 0; i < children.length; i++) { |
| if (useradmin.getRole(children[i]) == null) //check to see if it is already loaded |
| { //(we may have had to load some roles out of |
| loadRole(rootNode.node(children[i]), null); // order due to dependencies) |
| //modified to solve defect 95982 |
| } |
| } |
| } |
| } |
| |
| /* modified to solve defect 95982 */ |
| protected void loadRole(Preferences node, Role role) throws BackingStoreException { |
| int type = node.getInt(typeString, Integer.MIN_VALUE); |
| |
| if (type == Integer.MIN_VALUE) { |
| String errorString = NLS.bind(UserAdminMsg.Backing_Store_Read_Exception, new Object[] {NLS.bind(UserAdminMsg.Unable_to_load_role__27, node.name())}); |
| BackingStoreException ex = new BackingStoreException(errorString); |
| log.log(LogService.LOG_ERROR, errorString, ex); |
| throw (ex); |
| } |
| if (role == null) { |
| role = (Role) useradmin.createRole(node.name(), type, false); |
| } |
| Preferences propsNode = node.node(propertiesNode); |
| String[] keys = propsNode.keys(); |
| UserAdminHashtable properties = (UserAdminHashtable) role.getProperties(); |
| Object value; |
| |
| //load properties |
| Preferences propsTypesNode = propsNode.node(typesNode); |
| for (int i = 0; i < keys.length; i++) { |
| if (propsTypesNode.getBoolean(keys[i], true)) |
| value = propsNode.get(keys[i], null); |
| else |
| value = propsNode.getByteArray(keys[i], null); |
| properties.put(keys[i], value, false); |
| } |
| |
| //load credentials |
| if (type == org.osgi.service.useradmin.Role.USER || type == org.osgi.service.useradmin.Role.GROUP) { |
| Object credValue; |
| Preferences credNode = node.node(credentialsNode); |
| Preferences credTypesNode = credNode.node(UserAdminStore.typesNode); |
| keys = credNode.keys(); |
| UserAdminHashtable credentials = (UserAdminHashtable) ((User) role).getCredentials(); |
| for (int i = 0; i < keys.length; i++) { |
| if (credTypesNode.getBoolean(keys[i], true)) |
| credValue = credNode.get(keys[i], null); |
| else |
| credValue = credNode.getByteArray(keys[i], null); |
| credentials.put(keys[i], credValue, false); |
| } |
| } |
| |
| //load group members |
| if (type == org.osgi.service.useradmin.Role.GROUP) { |
| Preferences memberNode = node.node(membersNode); |
| keys = memberNode.keys(); |
| for (int i = 0; i < keys.length; i++) { |
| value = memberNode.get(keys[i], null); |
| Role member = (Role) useradmin.getRole(keys[i]); |
| if (member == null) //then we have not loaded this one yet, so load it |
| { |
| loadRole(rootNode.node(keys[i]), null); // modified to solve defect 95982 |
| member = (Role) useradmin.getRole(keys[i]); |
| } |
| if (value.equals(requiredString)) { |
| ((Group) role).addRequiredMember(member, false); |
| } else { |
| ((Group) role).addMember(member, false); |
| } |
| } |
| } |
| } |
| |
| protected void destroy() { |
| try { |
| rootNode.flush(); |
| rootNode = null; |
| preferencesService = null; |
| } catch (BackingStoreException ex) { |
| log.log(LogService.LOG_ERROR, UserAdminMsg.Backing_Store_Write_Exception, ex); |
| } |
| } |
| |
| private void createAnonRole() throws BackingStoreException { |
| Role role = null; |
| if (!rootNode.nodeExists(Role.anyoneString)) { |
| //If the user.anyone role is not present, create it |
| role = (Role) useradmin.createRole(Role.anyoneString, org.osgi.service.useradmin.Role.ROLE, true); |
| } |
| /* modified to solve defect 95982 */ |
| if (role != null) |
| loadRole(rootNode.node(Role.anyoneString), role); |
| else |
| loadRole(rootNode.node(Role.anyoneString), null); |
| } |
| |
| } |