Juan Hernandez has uploaded a new change for review.

Change subject: [WIP] Local authentication
......................................................................

[WIP] Local authentication

This patch adds an authentication provider that uses the local users and
groups database. It will appear in the system as a new "local"
authentication domain.

Access to the user database is implemented using the libc name service
switch functions, so it will work with the local database stored in the
/etc/passwd and /etc/group files as well as with external databases like
NIS or LDAP.

The authentication is implemented using SSH, so when the user types its
user name and password the engine will try to open a SSH connection to
localhost using that user name and password. It that succeeds the user
is allowed to log in to the webadmin or user portal.

The complete description of this feature is available here:

http://www.ovirt.org/Features/Local_Authentication

Change-Id: Ia418368dc8959e3e176a7f252fcc91fb682045ff
Signed-off-by: Juan Hernandez <juan.hernan...@redhat.com>
---
M backend/manager/modules/bll/pom.xml
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SearchQuery.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapBrokerUtils.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapFactory.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryData.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryDataImpl.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalAuthenticateUserCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerCommandBase.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerImpl.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdGroupByGroupIdCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdListCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserNameCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGroup.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchGroupsByQueryCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchUserByQueryCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUser.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserAuthenticator.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserDatabase.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
M packaging/fedora/spec/ovirt-engine.spec.in
M pom.xml
22 files changed, 987 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/63/11863/1

diff --git a/backend/manager/modules/bll/pom.xml 
b/backend/manager/modules/bll/pom.xml
index c1d01ef..94933c3 100644
--- a/backend/manager/modules/bll/pom.xml
+++ b/backend/manager/modules/bll/pom.xml
@@ -167,7 +167,24 @@
        <artifactId>jboss-ejb-api_3.1_spec</artifactId>
        <version>${javax.ejb.api.version}</version>
      </dependency>
+     
+    <dependency>
+      <groupId>org.apache.mina</groupId>
+      <artifactId>mina-core</artifactId>
+      <version>${mina-core.version}</version>
+    </dependency>
 
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+      <version>${sshd-core.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>net.java.dev.jna</groupId>
+      <artifactId>jna</artifactId>
+    </dependency>
+            
   </dependencies>
 
   <build>
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SearchQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SearchQuery.java
index d5a1d74..6530447 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SearchQuery.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SearchQuery.java
@@ -196,6 +196,18 @@
         ldapQueryData.setDomain(data.getDomain());
         ldapQueryData.setFilterParameters(new Object[] { 
data.getQueryForAdBroker() });
 
+        // Get the raw text as typed by the user (this should probably be
+        // changed, the front end should pass the raw text typed by the user
+        // directly to avoid this error prone parsing):
+        String pattern = getParameters().getSearchPattern();
+        if (pattern.startsWith(SearchObjects.AD_USER_OBJ_NAME) || 
pattern.startsWith(SearchObjects.AD_GROUP_OBJ_NAME)) {
+            int index = pattern.indexOf("=");
+            if (index != -1) {
+                String text = pattern.substring(index + 1);
+                ldapQueryData.setQueryText(text);
+            }
+        }
+
         @SuppressWarnings("unchecked")
         List<T> result = (List<T>) getLdapFactory(data.getDomain())
                 .RunAdAction(adActionType,
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapBrokerUtils.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapBrokerUtils.java
index ea0c86d..b5b553c 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapBrokerUtils.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapBrokerUtils.java
@@ -55,6 +55,7 @@
         if (!filterInternalDomain) {
             results.add(Config.<String> 
GetValue(ConfigValues.AdminDomain).trim());
         }
+        results.add(Config.<String> GetValue(ConfigValues.LocalDomain).trim());
         return results;
     }
 
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapFactory.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapFactory.java
index 88a3027..6cdce41 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapFactory.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapFactory.java
@@ -8,16 +8,22 @@
 
     private static LdapBroker internalInstance;
     private static LdapBroker ldapInstance;
+    private static LdapBroker localInstance;
+
     private static String internalDomain = Config.<String> 
GetValue(ConfigValues.AdminDomain).trim();
+    private static String localDomain = Config.<String> 
GetValue(ConfigValues.LocalDomain).trim();
 
     static {
         internalInstance = new InternalBrokerImpl();
         ldapInstance = new LdapBrokerImpl();
+        localInstance = new LocalBrokerImpl();
     }
 
     public static LdapBroker getInstance(String domain) {
         if (domain.equalsIgnoreCase(internalDomain)) {
             return internalInstance;
+        } else if (domain.equalsIgnoreCase(localDomain)) {
+            return localInstance;
         } else {
             return ldapInstance;
         }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryData.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryData.java
index a9acaf1..a8673f6 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryData.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryData.java
@@ -18,4 +18,7 @@
 
     public void setDomain(String domain);
 
+    public String getQueryText();
+
+    public void setQueryText(String text);
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryDataImpl.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryDataImpl.java
index 502d142..29c64a1 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryDataImpl.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LdapQueryDataImpl.java
@@ -6,6 +6,7 @@
     private Object[] filterParameters;
     private Object[] baseDNParameters;
     private String domain;
+    private String text;
 
     @Override
     public LdapQueryType getLdapQueryType() {
@@ -47,4 +48,13 @@
         this.domain = domain;
     }
 
+    @Override
+    public String getQueryText() {
+        return text;
+    }
+
+    @Override
+    public void setQueryText(String text) {
+        this.text = text;
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalAuthenticateUserCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalAuthenticateUserCommand.java
new file mode 100644
index 0000000..e911645
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalAuthenticateUserCommand.java
@@ -0,0 +1,39 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.dal.VdcBllMessages;
+
+public class LocalAuthenticateUserCommand extends LocalBrokerCommandBase {
+    public LocalAuthenticateUserCommand(LdapUserPasswordBaseParameters 
parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Make sure that the user exists in the database:
+        final String login = getParameters().getLoginName();
+        final LocalUser local = getDatabase().getUserByName(login);
+        if (local == null) {
+            final UserAuthenticationResult result = new 
UserAuthenticationResult(VdcBllMessages.USER_FAILED_TO_AUTHENTICATE);
+            setReturnValue(result);
+            setSucceeded(false);
+            return;
+        }
+
+        // Perform validation of credentials:
+        final String password = getParameters().getPassword();
+        final boolean authenticated = getAuthenticator().authenticate(login, 
password);
+        if (!authenticated) {
+            final UserAuthenticationResult result = new 
UserAuthenticationResult(VdcBllMessages.USER_FAILED_TO_AUTHENTICATE);
+            setReturnValue(result);
+            setSucceeded(false);
+            return;
+        }
+
+        // Fine, the user has been authenticated successfully:
+        final LdapUser user = mapUser(local);
+        final UserAuthenticationResult result = new 
UserAuthenticationResult(user);
+        setReturnValue(result);
+        setSucceeded(true);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerCommandBase.java
new file mode 100644
index 0000000..766887b
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerCommandBase.java
@@ -0,0 +1,143 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.ovirt.engine.core.common.businessentities.LdapGroup;
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public abstract class LocalBrokerCommandBase extends BrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalBrokerCommandBase.class);
+
+    // Fake domain name:
+    protected static final String DOMAIN = "local";
+
+    // The local authenticator and database:
+    private static final LocalUserAuthenticator AUTHENTICATOR = new 
LocalUserAuthenticator();
+    private static final LocalUserDatabase DATABASE = new LocalUserDatabase();
+
+    // Prefixes used to build map local user and group ids to UUIDS:
+    private static long UID_PREFIX = 0xaaa0000000000000l;
+    private static long GID_PREFIX = 0xbbb0000000000000l;
+
+    protected LocalUserAuthenticator getAuthenticator() {
+        return AUTHENTICATOR;
+    }
+
+    protected LocalUserDatabase getDatabase() {
+        return DATABASE;
+    }
+
+    protected static Guid uid2uuid(final long uid) {
+        final UUID uuid = new UUID(UID_PREFIX, uid);
+        return new Guid(uuid);
+    }
+
+    protected static int guid2uid(final Guid guid) {
+        final UUID uuid = guid.getUuid();
+        if (uuid.getMostSignificantBits() == UID_PREFIX) {
+            return (int) uuid.getLeastSignificantBits();
+        }
+        else {
+            throw new RuntimeException("The UUID \"" + uuid + "\" doesn't 
contain a valid user id.");
+        }
+    }
+
+    protected static int guid2gid(final Guid guid) {
+        final UUID uuid = guid.getUuid();
+        if (uuid.getMostSignificantBits() == GID_PREFIX) {
+            return (int) uuid.getLeastSignificantBits();
+        }
+        else {
+            throw new RuntimeException("The UUID \"" + uuid + "\" doesn't 
contain a valid group id.");
+        }
+    }
+
+    protected static Guid gid2uuid(final long gid) {
+        final UUID uuid = new UUID(GID_PREFIX, gid);
+        return new Guid(uuid);
+    }
+
+    protected LocalBrokerCommandBase(final LdapBrokerBaseParameters 
parameters) {
+        super(parameters);
+    }
+
+    public String getPROTOCOL() {
+        return "Local";
+    }
+
+    @Override
+    public LdapReturnValueBase execute() {
+        try {
+            executeQuery();
+        }
+        catch (RuntimeException exception) {
+            log.error("Error in executing local user broker command.", 
exception);
+            _ldapReturnValue.setSucceeded(false);
+            _ldapReturnValue.setReturnValue(null);
+        }
+        return _ldapReturnValue;
+    }
+
+    protected static LdapUser mapUser(final LocalUser local) {
+        // Create an empty user and set the basic attributes:
+        final LdapUser user = new LdapUser();
+        user.setDomainControler(DOMAIN);
+        user.setUserName(local.getName());
+        user.setUserId(uid2uuid(local.getUid()));
+
+        // Get the rest of the attributes from the GECOS field, at the moment 
we
+        // assume that it contains the name of the user, the department, and 
the
+        // e-mail address separated by commas:
+        final String[] gecosFields = local.getGecos().split(",");
+        if (gecosFields.length > 0) {
+            final String[] gecosNameParts = gecosFields[0].split(" ");
+            if (gecosNameParts.length == 0) {
+                user.setName(local.getName());
+            }
+            else {
+                if (gecosNameParts.length > 0) {
+                    user.setName(gecosNameParts[0]);
+                }
+                if (gecosNameParts.length > 1) {
+                    user.setSurName(gecosNameParts[1]);
+                }
+            }
+        }
+        if (gecosFields.length > 1) {
+            user.setDepartment(gecosFields[1]);
+        }
+        if (gecosFields.length > 2) {
+            user.setEmail(gecosFields[2]);
+        }
+
+        // Get the list of groups:
+        final List<LocalGroup> groups = 
DATABASE.getGroupsByUserName(local.getName());
+        final List<String> names = new ArrayList<String>(groups.size());
+        for (LocalGroup group : groups) {
+            names.add(group.getName());
+        }
+        user.setMemberof(names);
+
+        // Return the mapped user:
+        return user;
+    }
+
+    protected static LdapGroup mapGroup(final LocalGroup local) {
+        // Create an empty group and set the basic attributes:
+        final LdapGroup group = new LdapGroup();
+        group.setdomain(DOMAIN);
+        group.setname(local.getName());
+        group.setid(gid2uuid(local.getGid()));
+
+        // Return the mapped group:
+        return group;
+    }
+
+    protected abstract void executeQuery();
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerImpl.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerImpl.java
new file mode 100644
index 0000000..2f05e69
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalBrokerImpl.java
@@ -0,0 +1,8 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+public class LocalBrokerImpl extends LdapBrokerBase {
+    @Override
+    protected String getBrokerType() {
+        return "Local";
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdGroupByGroupIdCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdGroupByGroupIdCommand.java
new file mode 100644
index 0000000..b1e1157
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdGroupByGroupIdCommand.java
@@ -0,0 +1,39 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import org.ovirt.engine.core.common.businessentities.LdapGroup;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalGetAdGroupByGroupIdCommand extends LocalBrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalGetAdUserByUserIdCommand.class);
+
+    public LocalGetAdGroupByGroupIdCommand(final LdapSearchByIdParameters 
parameters) {
+        super(parameters);
+    }
+
+    private Guid getGroupId() {
+        return ((LdapSearchByIdParameters) getParameters()).getId();
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Extract the local group id that is embedded in the GUID of the 
group:
+        final Guid guid = getGroupId();
+        final int gid = guid2gid(guid);
+
+        // Try to find the matching group:
+        final LocalGroup local = getDatabase().getGroupByGid(gid);
+        if (local != null) {
+            final LdapGroup group = mapGroup(local);
+            setReturnValue(group);
+            setSucceeded(true);
+            return;
+        }
+
+        // No luck:
+        log.warn("Can't find group for id \"" + guid + "\".");
+        setSucceeded(false);
+     }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdCommand.java
new file mode 100644
index 0000000..fcc9775
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdCommand.java
@@ -0,0 +1,39 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalGetAdUserByUserIdCommand extends LocalBrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalGetAdUserByUserIdCommand.class);
+
+    public LocalGetAdUserByUserIdCommand(final LdapSearchByIdParameters 
parameters) {
+        super(parameters);
+    }
+
+    private Guid getUserId() {
+        return ((LdapSearchByIdParameters) getParameters()).getId();
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Extract the local user id that is embedded in the GUID of the user:
+        final Guid guid = getUserId();
+        final int uid = guid2uid(guid);
+
+        // Try to find the matching user:
+        final LocalUser local = getDatabase().getUserByUid(uid);
+        if (local != null) {
+            final LdapUser user = mapUser(local);
+            setReturnValue(user);
+            setSucceeded(true);
+            return;
+        }
+
+        // No luck:
+        log.warn("Can't find user for id \"" + guid + "\".");
+        setSucceeded(false);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdListCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdListCommand.java
new file mode 100644
index 0000000..b8bf692
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserIdListCommand.java
@@ -0,0 +1,41 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.compat.Guid;
+
+public class LocalGetAdUserByUserIdListCommand extends LocalBrokerCommandBase {
+    public LocalGetAdUserByUserIdListCommand(final 
LdapSearchByIdListParameters parameters) {
+        super(parameters);
+    }
+
+    private List<Guid> getUserIds() {
+        return ((LdapSearchByIdListParameters) getParameters()).getUserIds();
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Extract the user identifiers from the given GUIDs:
+        final List<Guid> guids = getUserIds();
+        final List<Integer> uids = new ArrayList<Integer>(guids.size());
+        for (final Guid guid : guids) {
+            final int uid = guid2uid(guid);
+            uids.add(uid);
+        }
+
+        // Get the list of users from the local database and build the
+        // corresponding group entities:
+        final List<LocalUser> locals = getDatabase().getUsersByUid(uids);
+        final List<LdapUser> groups = new ArrayList<LdapUser>(locals.size());
+        for (final LocalUser local : locals) {
+            final LdapUser group = mapUser(local);
+            groups.add(group);
+        }
+
+        // Return the results:
+        setReturnValue(groups);
+        setSucceeded(true);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserNameCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserNameCommand.java
new file mode 100644
index 0000000..c434b1c
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGetAdUserByUserNameCommand.java
@@ -0,0 +1,35 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalGetAdUserByUserNameCommand extends LocalBrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalGetAdUserByUserNameCommand.class);
+
+    public LocalGetAdUserByUserNameCommand(final 
LdapSearchByUserNameParameters parameters) {
+        super(parameters);
+    }
+
+    private String getUserName() {
+        return ((LdapSearchByUserNameParameters) 
getParameters()).getUserName();
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Try to find the matching user:
+        final String name = getUserName();
+        final LocalUser local = getDatabase().getUserByName(name);
+        if (local != null) {
+            final LdapUser user = mapUser(local);
+            setReturnValue(user);
+            setSucceeded(true);
+            return;
+        }
+
+        // No luck:
+        log.warn("Can't find user for name \"" + name + "\".");
+        setSucceeded(false);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGroup.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGroup.java
new file mode 100644
index 0000000..6d097af
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalGroup.java
@@ -0,0 +1,28 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+/**
+ * A simple representation of a local group. Note that this is not complete
+ * because we don't need all the properties of groups.
+ */
+public class LocalGroup {
+    // The attributes of the group:
+    private long gid;
+    private String name;
+
+    public LocalGroup(long gid, String name) {
+        this.gid = gid;
+        this.name = name;
+    }
+
+    public long getGid() {
+        return gid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return name;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchGroupsByQueryCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchGroupsByQueryCommand.java
new file mode 100644
index 0000000..6fd9db2
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchGroupsByQueryCommand.java
@@ -0,0 +1,48 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.ovirt.engine.core.common.businessentities.LdapGroup;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalSearchGroupsByQueryCommand extends LocalBrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalSearchGroupsByQueryCommand.class);
+
+    public LocalSearchGroupsByQueryCommand(final LdapSearchByQueryParameters 
parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Find the search criteria that the user typed in the search box:
+        final LdapSearchByQueryParameters queryParameters = 
(LdapSearchByQueryParameters) getParameters();
+        final LdapQueryData queryData = queryParameters.getLdapQueryData();
+        final String queryText = queryData.getQueryText();
+        final String filterText = "^" + queryText.replace("*", ".*") + "$";
+        final Pattern filterPattern = Pattern.compile(filterText);
+        log.info("Filter pattern is \"" + filterPattern + "\".");
+
+        // This will be the result:
+        final List<LdapGroup> results = new ArrayList<LdapGroup>();
+
+        // Iterate the groups in the database and select those whose that are
+        // not primary and whose name matches the pattern:
+        final List<LocalGroup> locals = getDatabase().getNonPrimaryGroups();
+        for (final LocalGroup local : locals) {
+            final Matcher nameMatcher = filterPattern.matcher(local.getName());
+            if (nameMatcher.find()) {
+                final LdapGroup group = mapGroup(local);
+                results.add(group);
+            }
+        }
+
+        // Return the resulting list of groups:
+        setReturnValue(results);
+        setSucceeded(true);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchUserByQueryCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchUserByQueryCommand.java
new file mode 100644
index 0000000..5b8e81b
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalSearchUserByQueryCommand.java
@@ -0,0 +1,47 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.ovirt.engine.core.common.businessentities.LdapUser;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalSearchUserByQueryCommand extends LocalBrokerCommandBase {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalSearchUserByQueryCommand.class);
+
+    public LocalSearchUserByQueryCommand(final LdapSearchByQueryParameters 
parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQuery() {
+        // Find the search criteria that the user typed in the search box:
+        final LdapSearchByQueryParameters queryParameters = 
(LdapSearchByQueryParameters) getParameters();
+        final LdapQueryData queryData = queryParameters.getLdapQueryData();
+        final String queryText = queryData.getQueryText();
+        final String filterText = "^" + queryText.replace("*", ".*") + "$";
+        final Pattern filterPattern = Pattern.compile(filterText);
+        log.info("Filter pattern is \"" + filterPattern + "\".");
+
+        // These will be the results:
+        final List<LdapUser> results = new ArrayList<LdapUser>();
+
+        // Run the query:
+        for (final LocalUser local : getDatabase().getAllUsers()) {
+            final Matcher nameMatcher = filterPattern.matcher(local.getName());
+            final Matcher gecosMatcher = 
filterPattern.matcher(local.getGecos());
+            if (nameMatcher.find() || gecosMatcher.find()) {
+                final LdapUser user = mapUser(local);
+                results.add(user);
+            }
+        }
+
+        // Return the resulting list of users:
+        setReturnValue(results);
+        setSucceeded(true);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUser.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUser.java
new file mode 100644
index 0000000..c4516ea
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUser.java
@@ -0,0 +1,41 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+/**
+ * A simple representation of a local user. Note that this is not complete
+ * because we don't need all the properties of users, for example we don't need
+ * the home directory, so it is not included.
+ */
+public class LocalUser {
+    // The attributes of the user:
+    private int uid;
+    private int gid;
+    private String name;
+    private String gecos;
+
+    public LocalUser(int uid, int gid, String name, String gecos) {
+        this.uid = uid;
+        this.gid = gid;
+        this.name = name;
+        this.gecos = gecos;
+    }
+
+    public int getUid() {
+        return uid;
+    }
+
+    public int getGid() {
+        return gid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getGecos() {
+        return gecos;
+    }
+
+    public String toString() {
+        return name;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserAuthenticator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserAuthenticator.java
new file mode 100644
index 0000000..6b92d10
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserAuthenticator.java
@@ -0,0 +1,127 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
+import org.apache.sshd.client.future.AuthFuture;
+import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.common.future.CloseFuture;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class LocalUserAuthenticator {
+    // The log:
+    private static final Log log = 
LogFactory.getLog(LocalUserAuthenticator.class);
+
+    // The host and port to connect to with SSH for user authentication (don't
+    // see any reason to have this configurable at the moment):
+    private static final String SSH_HOST = "localhost";
+    private static final int SSH_PORT = 22;
+    private static final int SSH_TIMEOUT = 10;
+
+    // Timeout for the authentication operation (this should probably be
+    // configurable):
+    private static final int SSH_AUTH_TIMEOUT = 10;
+
+    // The SSH client used to check authentication:
+    private SshClient sshClient;
+
+    protected synchronized SshClient getSshClient() {
+        if (sshClient == null) {
+            createSshClient();
+        }
+        return sshClient;
+    }
+
+    private void createSshClient() {
+        // Create the SSH client:
+        sshClient = SshClient.setUpDefaultClient();
+        sshClient.start();
+        log.info("Local auth SSH client created and started.");
+
+        // Remember to destroy it during shutdown:
+        Runtime.getRuntime().addShutdownHook(
+            new Thread("Destroy local authentication SSH client") {
+                public void run() {
+                    sshClient.stop();
+                    log.info("Local auth SSH client stopped.");
+                }
+            }
+        );
+    }
+
+    protected ClientSession openSshSession() {
+        try {
+            log.info(
+                "Requesting SSH connection to host \"" + SSH_HOST +
+                "\" and port \"" + SSH_PORT + "\".");
+            final ConnectFuture future = getSshClient().connect(SSH_HOST, 
SSH_PORT);
+            future.await(SSH_TIMEOUT, TimeUnit.SECONDS);
+            if (!future.isConnected()) {
+                log.error(
+                    "Failed to create SSH connection to host \"" + SSH_HOST +
+                    "\" and port \"" + SSH_PORT + "\", will return null.");
+                return null;
+            }
+            else {
+                log.info(
+                    "Created SSH connection to host \"" + SSH_HOST +
+                    "\" and port \"" + SSH_PORT + "\".");
+                return future.getSession();
+            }
+        }
+        catch (Exception exception) {
+            log.error(
+                "Failed to create SSH connection to host \"" + SSH_HOST +
+                "\" and port \"" + SSH_PORT + "\", will return null.",
+                exception);
+            return null;
+        }
+    }
+
+    protected void closeSshSession(final ClientSession sshSession) {
+        try {
+            log.info("Requesting close of SSH connection.");
+            final CloseFuture future = sshSession.close(true);
+            future.await(SSH_TIMEOUT, TimeUnit.SECONDS);
+            if (!future.isClosed()) {
+                log.warn("Failed to close SSH connection, will continue 
anyway.");
+            }
+            else {
+                log.info("Closed SSH connection.");
+            }
+        }
+        catch (Exception exception) {
+            log.warn("Failed to close SSH connection, will continue anyway.", 
exception);
+        }
+    }
+
+    public boolean authenticate(final String login, final String password) {
+        // Open a SSH connection to do the authentication (and remember to 
close it once done):
+        final ClientSession sshSession = openSshSession();
+        try {
+            final AuthFuture future = sshSession.authPassword(login, password);
+            future.await(SSH_AUTH_TIMEOUT, TimeUnit.SECONDS);
+            if (future.isSuccess()) {
+                log.info(
+                    "SSH authentication for user \"" + login +
+                    "\" finished and the user is authenticated.");
+                return true;
+            }
+            else {
+                log.info(
+                    "SSH authentication for user \"" + login +
+                    "\" finished but the user is not authenticated.");
+                return false;
+            }
+        }
+        catch (Exception exception) {
+            log.error("Failed to perform SSH authentication.", exception);
+            return false;
+        }
+        finally {
+            closeSshSession(sshSession);
+        }
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserDatabase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserDatabase.java
new file mode 100644
index 0000000..c67fe1c
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker/LocalUserDatabase.java
@@ -0,0 +1,285 @@
+package org.ovirt.engine.core.bll.adbroker;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+
+public class LocalUserDatabase {
+    // The log:
+    private static final Log log = LogFactory.getLog(LocalUserDatabase.class);
+
+    public static class passwd extends Structure {
+        public String pw_name;
+        public String pw_passwd;
+        public int pw_uid;
+        public int pw_gid;
+        public String pw_gecos;
+        public String pw_dir;
+        public String pw_shell;
+    };
+
+    public static class group extends Structure {
+        public String gr_name;
+        public String gr_passwd;
+        public int gr_gid;
+        public Pointer gr_mem;
+    };
+
+    // A subset of the methods of the C library that we need to handle the
+    // users and groups databases:
+    private interface C extends Library {
+        // Functions to iterate over the database of users:
+        void setpwent();
+        void endpwent();
+        passwd getpwent();
+
+        // Functions to iterate over the database of groups:
+        void setgrent();
+        void endgrent();
+        group getgrent();
+
+        // Functions to retrieve a specific entry from the database of users:
+        int getpwnam_r(String name, passwd pwd, ByteBuffer buf, long buflen, 
PointerByReference result);
+        int getpwuid_r(int uid, passwd pwd, ByteBuffer buf, long buflen, 
PointerByReference result);
+
+        // Functions to retrieve a specific entry from the database of groups:
+        int getgrnam_r(String name, group grp, ByteBuffer buf, long buflen, 
PointerByReference result);
+        int getgrgid_r(int gid, group grp, ByteBuffer buf, long buflen, 
PointerByReference result);
+
+        // Function to retrieve the list of members of a group:
+        int getgrouplist(String user, int group, int[] groups, IntByReference 
ngroups);
+
+        // We need this to decide what should be the size of the buffer passed
+        // to the whatever_r functions above:
+        int _SC_GETGR_R_SIZE_MAX = 69;
+        int _SC_GETPW_R_SIZE_MAX = 70;
+        long sysconf(int name);
+    };
+
+    // Load the native C library:
+    private C c = (C) Native.loadLibrary("c", C.class);
+
+    // The locations of relevant files:
+    private static final File LOGIN_DEFS_FILE = new File("/etc/login.defs");
+
+    // Parameters loaded from /etc/login.defs file:
+    private long uidMin = 1000;
+    private long uidMax = 60000;
+    private long gidMin = 1000;
+    private long gidMax = 60000;
+
+    // The sizes of the buffers used by the functions that retrieve users and
+    // groups:
+    private int pwdBufferSize;
+    private int grpBufferSize;
+
+    public LocalUserDatabase() {
+        // This is loaded only once, when the instance is created, so if it
+        // needs to be reloaded the instance will need to be created, which
+        // probably means that the engine will need to be restarted:
+        loadLoginDefs();
+
+        // Get the sizes of the buffers:
+        pwdBufferSize = (int) c.sysconf(C._SC_GETPW_R_SIZE_MAX);
+        grpBufferSize = (int) c.sysconf(C._SC_GETGR_R_SIZE_MAX);
+    }
+
+    private void loadLoginDefs() {
+        // Do nothing if the file doesn't exist:
+        if (!LOGIN_DEFS_FILE.exists()) {
+            log.warn("The file \"" + LOGIN_DEFS_FILE.getAbsolutePath() + "\" 
doesn't exist.");
+            return;
+        }
+
+        // Try to load it:
+        FileReader loginDefsReader = null;
+        Properties loginDefs = null;
+        try {
+            loginDefsReader = new FileReader(LOGIN_DEFS_FILE);
+            loginDefs = new Properties();
+            loginDefs.load(loginDefsReader);
+        }
+        catch (IOException exception) {
+            log.error("Error while loading file \"" + 
LOGIN_DEFS_FILE.getAbsolutePath() + "\".");
+            return;
+        }
+        finally {
+            try {
+                loginDefsReader.close();
+            }
+            catch (IOException exception) {
+                log.warn("Error while closing file \"" + 
LOGIN_DEFS_FILE.getAbsolutePath() + "\" ignored.");
+            }
+        }
+
+        // Load the upper and lower limits of users and groups identifiers:
+        uidMin = Long.valueOf(loginDefs.getProperty("UID_MIN"));
+        uidMax = Long.valueOf(loginDefs.getProperty("UID_MAX"));
+        gidMin = Long.valueOf(loginDefs.getProperty("GID_MIN"));
+        gidMax = Long.valueOf(loginDefs.getProperty("GID_MAX"));
+    }
+
+    private LocalUser mapUser(passwd pwd) {
+        if (pwd.pw_uid != 0 && (pwd.pw_uid < uidMin || pwd.pw_uid > uidMax)) {
+            return null;
+        }
+        return new LocalUser(pwd.pw_uid, pwd.pw_gid, pwd.pw_name, 
pwd.pw_gecos);
+    }
+
+    private LocalGroup mapGroup(group grp) {
+        if (grp.gr_gid < gidMin || grp.gr_gid > gidMax) {
+            return null;
+        }
+        return new LocalGroup(grp.gr_gid, grp.gr_name);
+    }
+
+    /**
+     * Returns the complete list of users stored in the local database.
+     */
+    public synchronized List<LocalUser> getAllUsers() {
+        final List<LocalUser> result = new ArrayList<LocalUser>();
+        try {
+            c.setpwent();
+            passwd pwd = null;
+            while ((pwd = c.getpwent()) != null) {
+                final LocalUser user = mapUser(pwd);
+                if (user != null) {
+                    result.add(user);
+                }
+            }
+        }
+        finally {
+            c.endpwent();
+        }
+        return result;
+    }
+
+    /**
+     * Returns the complete list of groups stored in the local database. This
+     * includes primary groups, so it is usually better to use
+     * <code>getNonPrimaryGroups</code> instead.
+     */
+    public synchronized List<LocalGroup> getAllGroups() {
+        final List<LocalGroup> result = new ArrayList<LocalGroup>();
+        try {
+            c.setgrent();
+            group grp = null;
+            while ((grp = c.getgrent()) != null) {
+                final LocalGroup group = mapGroup(grp);
+                if (group != null) {
+                    result.add(group);
+                }
+            }
+        }
+        finally {
+            c.endgrent();
+        }
+        return result;
+    }
+
+    public synchronized List<LocalGroup> getNonPrimaryGroups() {
+        final List<LocalGroup> results = new ArrayList<LocalGroup>();
+        for (LocalGroup group : getAllGroups()) {
+            final LocalUser user = getUserByName(group.getName());
+            if (user == null || user.getGid() != group.getGid()) {
+                results.add(group);
+            }
+        }
+        return results;
+    }
+
+    public LocalUser getUserByName(String name) {
+        final passwd pwd = new passwd();
+        final PointerByReference result = new PointerByReference();
+        final ByteBuffer buffer = ByteBuffer.allocateDirect(pwdBufferSize);
+        c.getpwnam_r(name, pwd, buffer, (long) buffer.capacity(), result);
+        if (result.getPointer() == null) {
+            return null;
+        }
+        return mapUser(pwd);
+    }
+
+    public LocalUser getUserByUid(final int uid) {
+        final passwd pwd = new passwd();
+        final PointerByReference result = new PointerByReference();
+        final ByteBuffer buffer = ByteBuffer.allocateDirect(pwdBufferSize);
+        c.getpwuid_r(uid, pwd, buffer, (long) buffer.capacity(), result);
+        if (result.getPointer() == null) {
+            return null;
+        }
+        return mapUser(pwd);
+    }
+
+    public List<LocalUser> getUsersByUid(final List<Integer> uids) {
+        final List<LocalUser> result = new ArrayList<LocalUser>();
+        for (int uid : uids) {
+            final LocalUser user = getUserByUid(uid);
+            if (user != null) {
+                result.add(user);
+            }
+        }
+        return result;
+    }
+
+    public LocalGroup getGroupByName(final String name) {
+        final group grp = new group();
+        final PointerByReference result = new PointerByReference();
+        final ByteBuffer buffer = ByteBuffer.allocateDirect(grpBufferSize);
+        c.getgrnam_r(name, grp, buffer, (long) buffer.capacity(), result);
+        if (result.getPointer() == null) {
+            return null;
+        }
+        return mapGroup(grp);
+    }
+
+    public List<LocalGroup> getGroupsByUserName(final String name) {
+        final LocalUser user = getUserByName(name);
+        if (user == null) {
+            return Collections.emptyList();
+        }
+        final List<LocalGroup> results = new ArrayList<LocalGroup>();
+        final IntByReference size = new IntByReference(4);
+        int[] gids = new int[size.getValue()];
+        for (;;) {
+            if (c.getgrouplist(name, user.getGid(), gids, size) != -1) {
+                break;
+            }
+            gids = new int[size.getValue()];
+        }
+        for (int gid : gids) {
+            if (gid != user.getGid()) {
+                LocalGroup group = getGroupByGid(gid);
+                if (group != null) {
+                    results.add(group);
+                }
+            }
+        }
+        return results;
+    }
+
+    public LocalGroup getGroupByGid(final int gid) {
+        final group grp = new group();
+        final PointerByReference result = new PointerByReference();
+        final ByteBuffer buffer = ByteBuffer.allocateDirect(grpBufferSize);
+        c.getgrgid_r(gid, grp, buffer, (long) buffer.capacity(), result);
+        if (result.getPointer() == null) {
+            return null;
+        }
+        return mapGroup(grp);
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
index 64a191d..981f6ea 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
@@ -711,6 +711,14 @@
     @DefaultValueAttribute("")
     PredefinedVMProperties(273),
 
+    /**
+     * The name of the domain used for local authentication. This is
+     * relevant only for display, as it is not a real domain name.
+     */
+    @TypeConverterAttribute(String.class)
+    @DefaultValueAttribute("local")
+    LocalDomain(316),
+
     @TypeConverterAttribute(Integer.class)
     @DefaultValueAttribute("250")
     MaxNumberOfHostsInStoragePool(274),
diff --git a/packaging/fedora/spec/ovirt-engine.spec.in 
b/packaging/fedora/spec/ovirt-engine.spec.in
index 4b8b98c..231ac62 100644
--- a/packaging/fedora/spec/ovirt-engine.spec.in
+++ b/packaging/fedora/spec/ovirt-engine.spec.in
@@ -220,6 +220,7 @@
 Requires: java
 Requires: javassist
 Requires: jboss-interceptors-1.1-api
+Requires: jna
 Requires: objectweb-asm
 Requires: openssh
 Requires: openssl
@@ -419,7 +420,8 @@
 # spring-asm *IS* required on rhel-6
 rm -rf %{buildroot}%{engine_ear}/lib/spring-asm*.jar
 
-# Then for the system jar files (using build-classpath):
+# Replace jar files in the .ear lib directory with links to their actual
+# locations:
 while read jar_name lib_path
 do
   rm -rf %{buildroot}%{engine_ear}/lib/${lib_path}*.jar
@@ -436,6 +438,7 @@
 dom4j dom4j
 geronimo-validation validation-api
 hibernate-validator hibernate-validator
+jna jna
 objectweb-asm/asm-all asm-all
 quartz quartz
 slf4j/api slf4j-api
diff --git a/pom.xml b/pom.xml
index 815d3f7..b1c861d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,6 +88,7 @@
     <maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version>
     <gwt.plugin.version>2.3.0</gwt.plugin.version>
     <test-jar.plugin.version>2.2</test-jar.plugin.version>
+    <jna.version>3.4.0</jna.version>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -260,6 +261,11 @@
         <version>${gwt.version}</version>
         <scope>runtime</scope>
       </dependency>
+      <dependency>
+        <groupId>net.java.dev.jna</groupId>
+        <artifactId>jna</artifactId>
+        <version>${jna.version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
   <dependencies>


--
To view, visit http://gerrit.ovirt.org/11863
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia418368dc8959e3e176a7f252fcc91fb682045ff
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <juan.hernan...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to