/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
* You can obtain a copy of the License at
* http://opensource.org/licenses/cddl1.php
* See the License for the specific language governing permissions and limitations
* under the License.
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at http://opensource.org/licenses/cddl1.php.
* If applicable, add the following below this CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
*/
package org.identityconnectors.solaris.operation;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.solaris.SolarisConfiguration;
import org.identityconnectors.solaris.SolarisConnection;
import org.identityconnectors.solaris.attr.NativeAttribute;
import org.identityconnectors.solaris.operation.search.SolarisEntry;
/**
* @author David Adam
*
*/
final class CreateNativeUser {
private CreateNativeUser() {
}
private final static Map<NativeAttribute, String> CREATE_SWITCHES =
CommandSwitches.COMMON_SWITCHES;
private final static Set<String> ERRORS_USERADD = CollectionUtil.newSet("invalid", "ERROR",
"command not found", "not allowed to execute");
public static void createUser(SolarisEntry entry, GuardedString password, SolarisConnection conn) {
conn.doSudoStart();
try {
conn.executeMutexAcquireScript();
try {
createUserImpl(entry, conn);
} finally {
conn.executeMutexReleaseScript();
}
PasswdCommand.configureUserPassword(entry, password, conn);
PasswdCommand.configurePasswordProperties(entry, conn);
} finally {
conn.doSudoReset();
}
}
private static void createUserImpl(SolarisEntry entry, SolarisConnection conn) {
// create command line switches construction
String commandSwitches = formatCreateCommandSwitches(entry, conn);
String command = conn.getModeDriver().buildCreateUserCommand(entry, commandSwitches);
conn.executeCommand(command, ERRORS_USERADD);
}
/**
* creates command line switches construction.
*
* @param entry
* the entry whose attribute should be transferred to command
* line switches.
* @param conn
* @return the create command line switches based on entry's attribute/value
* pairs. Return a zero-length string in case no switch (
* {@link CreateNativeUser#CREATE_SWITCHES}) matched the attributes
* in given entry.
*/
private static String formatCreateCommandSwitches(SolarisEntry entry, SolarisConnection conn) {
StringBuilder buffer = makeOptionalSkelDir(conn);
// normalize attribute values:
Set<Attribute> normalizedAttributes = CollectionUtil.<Attribute> newSet();
Set<NativeAttribute> normalizedAttributeType =
EnumSet.of(NativeAttribute.DIR, NativeAttribute.GROUP_PRIM, NativeAttribute.SHELL);
for (Attribute attr : entry.getAttributeSet()) {
List<? extends Object> values = attr.getValue();
NativeAttribute attrType = NativeAttribute.forAttributeName(attr.getName());
if (normalizedAttributeType.contains(attrType)) {
// expecting all attributes to be single-value, that are
// normalized.
String value = AttributeUtil.getStringValue(attr);
switch (attrType) {
case DIR:
value = setHomeDirValue(value, entry, conn);
break;
case GROUP_PRIM:
value = setGroupPrimValue(value, conn);
break;
case SHELL:
value = setShellValue(value, conn);
break;
}
values = CollectionUtil.newList(value);
}
normalizedAttributes.add(AttributeBuilder.build(attr.getName(), values));
}
buffer.append(CommandSwitches.formatCommandSwitches(entry, conn, CREATE_SWITCHES));
return buffer.toString().trim();
}
/**
* @param explicitShellValue
* @return
*/
private static String setShellValue(final String explicitShellValue, SolarisConnection conn) {
if (explicitShellValue != null) {
return explicitShellValue;
}
String loginShell = null;
String configuredLoginShell = conn.getConfiguration().getLoginShell();
if (!StringUtil.isBlank(configuredLoginShell)) {
// If there is a specific login shell specified for the
// user then that takes priority.
loginShell = configuredLoginShell;
}
return loginShell;
}
/**
* @param explicitPrimGroupValue
* @return
*/
private static String setGroupPrimValue(final String explicitPrimGroupValue,
SolarisConnection conn) {
if (explicitPrimGroupValue != null) {
return explicitPrimGroupValue;
}
String defaultPrimaryGroup = null;
String configuredDefPrimGroup = conn.getConfiguration().getDefaultPrimaryGroup();
if (StringUtil.isNotBlank(configuredDefPrimGroup)) {
// If there is a specific default primary group specified for the
// user then that takes priority.
defaultPrimaryGroup = configuredDefPrimGroup;
}
return defaultPrimaryGroup;
}
/**
* optionally create a skeleton directory if given in
* {@link org.identityconnectors.solaris.SolarisConfiguration#isMakeDirectory()}
* ()}
*
* IMPL. NOTE: <i>This method is used to initialize the buffer for command
* switches.</i>
*
* @return an empty {@link StringBuilder} if the optionalProperty is not
* defined, otherwise the create the default skeleton directory for
* home.
*/
private static StringBuilder makeOptionalSkelDir(SolarisConnection conn) {
StringBuilder makeDirectory = new StringBuilder();
boolean configuredIsMakeDir = conn.getConfiguration().isMakeDirectory();
if (configuredIsMakeDir) {
makeDirectory.append(" -m");
String skeldir = conn.getConfiguration().getSkeletonDirectory();
if (StringUtil.isNotBlank(skeldir)) {
// note switch '-k' is specific for making skeleton directory,
// is not assigned to any {@link NativeAttribute}
makeDirectory.append(" -k " + skeldir + " ");
}
}
return makeDirectory;
}
/**
* set the value for {@link NativeAttribute#DIR} according to the
* {@link SolarisConfiguration#getHomeBaseDirectory()} resource
* configuration (optional).
*
* @param explicitHomeDirAttrValue
* explicit value for Home directory, if it is null then the
* default is used from the resource configuration property.
* @param conn
* @return the value with correct settings
*/
private static String setHomeDirValue(final String explicitHomeDirAttrValue,
SolarisEntry entry, SolarisConnection conn) {
if (explicitHomeDirAttrValue != null) {
return explicitHomeDirAttrValue;
}
String homeDirectory = null;
String basedir = conn.getConfiguration().getHomeBaseDirectory();
if (StringUtil.isNotBlank(basedir)) {
// If there is a specific home directory specified for the
// user then that takes priority.
StringBuffer homedirBuffer = new StringBuffer(basedir);
if (!basedir.endsWith("/")) {
homedirBuffer.append("/");
}
homedirBuffer.append(entry.getName());
homeDirectory = homedirBuffer.toString();
}
return homeDirectory;
}
}