diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js
index c6adb9b67a..44a7e75729 100755
--- a/adapters/oidc/js/src/main/resources/keycloak.js
+++ b/adapters/oidc/js/src/main/resources/keycloak.js
@@ -154,7 +154,7 @@
return;
} else if (initOptions) {
if (initOptions.token || initOptions.refreshToken) {
- setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken, false);
+ setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
kc.timeSkew = initOptions.timeSkew || 0;
if (loginIframe.enable) {
@@ -406,10 +406,10 @@
timeLocal = (timeLocal + new Date().getTime()) / 2;
var tokenResponse = JSON.parse(req.responseText);
- setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], true);
-
kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
+ setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token']);
+
kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
p.setSuccess(true);
@@ -444,7 +444,7 @@
kc.clearToken = function() {
if (kc.token) {
- setToken(null, null, null, true);
+ setToken(null, null, null);
kc.onAuthLogout && kc.onAuthLogout();
if (kc.loginRequired) {
kc.login();
@@ -525,7 +525,7 @@
function authSuccess(accessToken, refreshToken, idToken, fulfillPromise) {
timeLocal = (timeLocal + new Date().getTime()) / 2;
- setToken(accessToken, refreshToken, idToken, true);
+ setToken(accessToken, refreshToken, idToken);
if ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) ||
(kc.refreshTokenParsed && kc.refreshTokenParsed.nonce != oauth.storedNonce) ||
@@ -609,7 +609,7 @@
return promise.promise;
}
- function setToken(token, refreshToken, idToken, useTokenTime) {
+ function setToken(token, refreshToken, idToken) {
if (kc.tokenTimeoutHandle) {
clearTimeout(kc.tokenTimeoutHandle);
kc.tokenTimeoutHandle = null;
@@ -629,9 +629,12 @@
kc.resourceAccess = kc.tokenParsed.resource_access;
if (kc.onTokenExpired) {
- var start = useTokenTime ? kc.tokenParsed.iat : (new Date().getTime() / 1000);
- var expiresIn = kc.tokenParsed.exp - start;
- kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn * 1000);
+ var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
+ if (expiresIn <= 0) {
+ kc.onTokenExpired();
+ } else {
+ kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
+ }
}
} else {
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index 809890a03d..8922532ad2 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -83,7 +83,6 @@
org.keycloakkeycloak-kerberos-federation
-
org.keycloak
@@ -110,6 +109,12 @@
+
+
+ org.keycloak
+ keycloak-sssd-federation
+
+
org.keycloak
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/federation-sssd-setup.sh b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/federation-sssd-setup.sh
new file mode 100644
index 0000000000..6a0eae2130
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/federation-sssd-setup.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Setup for SSSD
+SSSD_FILE="/etc/sssd/sssd.conf"
+
+if [ -f "$SSSD_FILE" ];
+then
+ sed -i '/ldap_tls_cacert/a ldap_user_extra_attrs = mail:mail, sn:sn, givenname:givenname, telephoneNumber:telephoneNumber' $SSSD_FILE
+ sed -i 's/nss, sudo, pam/nss, sudo, pam, ifp/' $SSSD_FILE
+ sed -i '/\[ifp\]/a allowed_uids = root\nuser_attributes = +mail, +telephoneNumber, +givenname, +sn' $SSSD_FILE
+ systemctl restart sssd
+else
+ echo "Please make sure you have $SSSD_FILE into your system! Aborting."
+ exit 1
+fi
+
+# Setup for PAM
+PAM_FILE="/etc/pam.d/keycloak"
+
+if [ ! -f "$PAM_FILE" ];
+then
+cat < $PAM_FILE
+ auth required pam_sss.so
+ account required pam_sss.so
+EOF
+else
+ echo "$PAM_FILE already exists. Skipping it..."
+ exit 0
+fi
+
+
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-services/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-services/main/module.xml
index de03ed8e8b..8cf1cde89b 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-services/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-services/main/module.xml
@@ -35,6 +35,7 @@
+
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml
new file mode 100644
index 0000000000..ad16f3c4dd
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-sssd-federation/main/module.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/federation/pom.xml b/federation/pom.xml
index 663f857a0b..dc702ccfab 100755
--- a/federation/pom.xml
+++ b/federation/pom.xml
@@ -35,6 +35,7 @@
ldapkerberos
+ sssd
diff --git a/federation/sssd/pom.xml b/federation/sssd/pom.xml
new file mode 100644
index 0000000000..7d109e82a5
--- /dev/null
+++ b/federation/sssd/pom.xml
@@ -0,0 +1,56 @@
+
+
+
+ keycloak-parent
+ org.keycloak
+ 2.2.0-SNAPSHOT
+ ../../pom.xml
+
+ 4.0.0
+
+ keycloak-sssd-federation
+ Keycloak SSSD Federation
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ ${maven.compiler.target}
+
+
+
+
+
+
+
+ junit
+ junit
+ test
+
+
+ net.java.dev.jna
+ jna
+
+
+ org.keycloak
+ keycloak-core
+ provided
+
+
+ org.keycloak
+ keycloak-server-spi
+ provided
+
+
+ org.jboss.logging
+ jboss-logging
+ provided
+
+
+
+
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java b/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java
new file mode 100644
index 0000000000..ffdf02dd6e
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/LibraryLoader.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cx.ath.matthew;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Bruno Oliveira.
+ */
+public class LibraryLoader {
+
+ private static final Logger LOGGER = Logger.getLogger(LibraryLoader.class.getSimpleName());
+
+ private static final String[] PATHS = {"/usr/lib/", "/usr/lib64/", "/usr/local/lib/", "/opt/local/lib/"};
+ private static final String LIBRARY_NAME = "libunix_dbus_java";
+ private static final String VERSION = "0.0.8";
+ private static boolean loadSucceeded;
+
+ public static void load() {
+ for (String path : PATHS) {
+ try {
+ System.load(String.format("%s/%s.so.%s", path, LIBRARY_NAME, VERSION));
+ loadSucceeded = true;
+ break;
+ } catch (UnsatisfiedLinkError e) {
+ loadSucceeded = false;
+ }
+
+ }
+
+ if (!loadSucceeded) LOGGER.log(Level.WARNING, "libunix_dbus_java not found\n" +
+ "Please, make sure you have the package libunix-dbus-java installed.");
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/debug/Debug.java b/federation/sssd/src/main/java/cx/ath/matthew/debug/Debug.java
new file mode 100644
index 0000000000..30c4d8549d
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/debug/Debug.java
@@ -0,0 +1,671 @@
+/* Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+/* This header is separate from features.h so that the compiler can
+ include it implicitly at the start of every compilation. It must
+ not itself include or any other header that includes
+ because the implicit include comes before any feature
+ test macros that may be defined in a source file before it first
+ explicitly includes a system header. GCC knows the name of this
+ header in order to preinclude it. */
+/* glibc's intent is to support the IEC 559 math functionality, real
+ and complex. If the GCC (4.9 and later) predefined macros
+ specifying compiler intent are available, use them to determine
+ whether the overall intent is to support these features; otherwise,
+ presume an older compiler has intent to support these features and
+ define these macros by default. */
+/* wchar_t uses Unicode 7.0.0. Version 7.0 of the Unicode Standard is
+ synchronized with ISO/IEC 10646:2012, plus Amendments 1 (published
+ on April, 2013) and 2 (not yet published as of February, 2015).
+ Additionally, it includes the accelerated publication of U+20BD
+ RUBLE SIGN. Therefore Unicode 7.0.0 is between 10646:2012 and
+ 10646:2014, and so we use the date ISO/IEC 10646:2012 Amd.1 was
+ published. */
+/* We do not support C11 . */
+/*
+ * Java Debug Library
+ *
+ * Copyright (c) Matthew Johnson 2005
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.debug;
+
+import cx.ath.matthew.utils.Hexdump;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Add debugging to your program, has support for large projects with multiple
+ * classes and debug levels per class. Supports optional enabling of debug
+ * per-level per-class and debug targets of files, Streams or stderr.
+ * Also supports timing between debug outputs, printing of stack traces for Throwables
+ * and files/line numbers on each message.
+ *
+ * Debug now automatically figures out which class it was called from, so all
+ * methods passing in the calling class are deprecated.
+ *
+ *
+ * The defaults are to print all messages to stderr with class and method name.
+ *
+ *
+ * Should be called like this:
+ *
+ *
+ * if (Debug.debug) Debug.print(Debug.INFO, "Debug Message");
+ *
+ */
+public class Debug {
+ /**
+ * This interface can be used to provide custom printing filters
+ * for certain classes.
+ */
+ public static interface FilterCommand {
+ /**
+ * Called to print debug messages with a custom filter.
+ *
+ * @param output The PrintStream to output to.
+ * @param level The debug level of this message.
+ * @param location The textual location of the message.
+ * @param extra Extra information such as timing details.
+ * @param message The debug message.
+ * @param lines Other lines of a multiple-line debug message.
+ */
+ public void filter(PrintStream output, int level, String location, String extra, String message, String[] lines);
+ }
+
+ /**
+ * Highest priority messages
+ */
+ public static final int CRIT = 1;
+ /**
+ * Error messages
+ */
+ public static final int ERR = 2;
+ /**
+ * Warnings
+ */
+ public static final int WARN = 3;
+ /**
+ * Information
+ */
+ public static final int INFO = 4;
+ /**
+ * Debug messages
+ */
+ public static final int DEBUG = 5;
+ /**
+ * Verbose debug messages
+ */
+ public static final int VERBOSE = 6;
+ /**
+ * Set this to false to disable compilation of Debug statements
+ */
+ public static final boolean debug = false;
+ /**
+ * The current output stream (defaults to System.err)
+ */
+ public static PrintStream debugout = System.err;
+ private static Properties prop = null;
+ private static boolean timing = false;
+ private static boolean ttrace = false;
+ private static boolean lines = false;
+ private static boolean hexdump = false;
+ private static long last = 0;
+ private static int balen = 36;
+ private static int bawidth = 80;
+ private static Class saveclass = null;
+ //TODO: 1.5 private static Map, FilterCommand> filterMap = new HashMap, FilterCommand>();
+ private static Map filterMap = new HashMap();
+
+ /**
+ * Set properties to configure debugging.
+ * Format of properties is class => level, e.g.
+ *
+ * The debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which
+ * correspond to all messages up to that level. The special words YES, ALL and TRUE
+ * cause all messages to be printed regardless of level. All other terms disable
+ * messages for that class. CRIT and ERR messages are always printed if debugging is enabled
+ * unless explicitly disabled.
+ * The special class name ALL can be used to set the default level for all classes.
+ *
+ * @param prop Properties object to use.
+ */
+ public static void setProperties(Properties prop) {
+ Debug.prop = prop;
+ }
+
+ /**
+ * Read which class to debug on at which level from the given File.
+ * Syntax the same as Java Properties files:
+ *
+ * The debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which
+ * correspond to all messages up to that level. The special words YES, ALL and TRUE
+ * cause all messages to be printed regardless of level. All other terms disable
+ * messages for that class. CRIT and ERR messages are always printed if debugging is enabled
+ * unless explicitly disabled.
+ * The special class name ALL can be used to set the default level for all classes.
+ *
+ * @param f File to read from.
+ */
+ public static void loadConfig(File f) throws IOException {
+ prop = new Properties();
+ prop.load(new FileInputStream(f));
+ }
+
+ /**
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static boolean debugging(Class c, int loglevel) {
+ if (debug) {
+ if (null == c) return true;
+ return debugging(c.getName(), loglevel);
+ }
+ return false;
+ }
+
+ public static boolean debugging(String s, int loglevel) {
+ if (debug) {
+ try {
+ if (null == s) return true;
+ if (null == prop) return loglevel <= DEBUG;
+ String d = prop.getProperty(s);
+ if (null == d || "".equals(d)) d = prop.getProperty("ALL");
+ if (null == d) return loglevel <= ERR;
+ if ("".equals(d)) return loglevel <= ERR;
+ d = d.toLowerCase();
+ if ("true".equals(d)) return true;
+ if ("yes".equals(d)) return true;
+ if ("all".equals(d)) return true;
+ if ("verbose".equals(d)) return loglevel <= VERBOSE;
+ if ("debug".equals(d)) return loglevel <= DEBUG;
+ if ("info".equals(d)) return loglevel <= INFO;
+ if ("warn".equals(d)) return loglevel <= WARN;
+ if ("err".equals(d)) return loglevel <= ERR;
+ if ("crit".equals(d)) return loglevel <= CRIT;
+ int i = Integer.parseInt(d);
+ return i >= loglevel;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Output to the given Stream
+ */
+ public static void setOutput(PrintStream p) throws IOException {
+ debugout = p;
+ }
+
+ /**
+ * Output to the given file
+ */
+ public static void setOutput(String filename) throws IOException {
+ debugout = new PrintStream(new FileOutputStream(filename, true));
+ }
+
+ /**
+ * Output to the default debug.log
+ */
+ public static void setOutput() throws IOException {
+ setOutput("./debug.log");
+ }
+
+ /**
+ * Log at DEBUG
+ *
+ * @param d The object to log
+ */
+ public static void print(Object d) {
+ if (debug) {
+ if (d instanceof String)
+ print(DEBUG, (String) d);
+ else if (d instanceof Throwable)
+ print(DEBUG, (Throwable) d);
+ else if (d instanceof byte[])
+ print(DEBUG, (byte[]) d);
+ else if (d instanceof Map)
+ printMap(DEBUG, (Map) d);
+ else print(DEBUG, d);
+ }
+ }
+
+ /**
+ * Log at DEBUG
+ *
+ * @param o The object doing the logging
+ * @param d The object to log
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Object o, Object d) {
+ if (debug) {
+ if (o instanceof Class)
+ saveclass = (Class) o;
+ else
+ saveclass = o.getClass();
+ print(d);
+ }
+ }
+
+ /**
+ * Log an Object
+ *
+ * @param o The object doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param d The object to log with d.toString()
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Object o, int loglevel, Object d) {
+ if (debug) {
+ if (o instanceof Class)
+ saveclass = (Class) o;
+ else
+ saveclass = o.getClass();
+ print(loglevel, d);
+ }
+ }
+
+ /**
+ * Log a String
+ *
+ * @param o The object doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param s The log message
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Object o, int loglevel, String s) {
+ if (debug) {
+ if (o instanceof Class)
+ saveclass = (Class) o;
+ else
+ saveclass = o.getClass();
+ print(loglevel, s);
+ }
+ }
+
+ /**
+ * Log a Throwable
+ *
+ * @param o The object doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param t The throwable to log with .toString and .printStackTrace
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Object o, int loglevel, Throwable t) {
+ if (debug) {
+ if (o instanceof Class)
+ saveclass = (Class) o;
+ else
+ saveclass = o.getClass();
+ print(loglevel, t);
+ }
+ }
+
+ /**
+ * Log a Throwable
+ *
+ * @param c The class doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param t The throwable to log with .toString and .printStackTrace
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Class c, int loglevel, Throwable t) {
+ if (debug) {
+ saveclass = c;
+ print(loglevel, t);
+ }
+ }
+
+ /**
+ * Log a Throwable
+ *
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param t The throwable to log with .toString and .printStackTrace
+ * @see #setThrowableTraces to turn on stack traces.
+ */
+ public static void print(int loglevel, Throwable t) {
+ if (debug) {
+ String timestr = "";
+ String[] data = getTraceElements();
+ if (debugging(data[0], loglevel)) {
+ if (timing) {
+ long now = System.currentTimeMillis();
+ timestr = "{" + (now - last) + "} ";
+ last = now;
+ }
+ String[] lines = null;
+ if (ttrace) {
+ StackTraceElement[] ste = t.getStackTrace();
+ lines = new String[ste.length];
+ for (int i = 0; i < ste.length; i++)
+ lines[i] = "\tat " + ste[i].toString();
+ }
+ _print(t.getClass(), loglevel, data[0] + "." + data[1] + "()" + data[2], timestr, t.toString(), lines);
+ }
+ }
+ }
+
+ /**
+ * Log a byte array
+ *
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param b The byte array to print.
+ * @see #setHexDump to enable hex dumping.
+ * @see #setByteArrayCount to change how many bytes are printed.
+ * @see #setByteArrayWidth to change the formatting width of hex.
+ */
+ public static void print(int loglevel, byte[] b) {
+ if (debug) {
+ String timestr = "";
+ String[] data = getTraceElements();
+ if (debugging(data[0], loglevel)) {
+ if (timing) {
+ long now = System.currentTimeMillis();
+ timestr = "{" + (now - last) + "} ";
+ last = now;
+ }
+ String[] lines = null;
+ if (hexdump) {
+ if (balen >= b.length)
+ lines = Hexdump.format(b, bawidth).split("\n");
+ else {
+ byte[] buf = new byte[balen];
+ System.arraycopy(b, 0, buf, 0, balen);
+ lines = Hexdump.format(buf, bawidth).split("\n");
+ }
+ }
+ _print(b.getClass(), loglevel, data[0] + "." + data[1] + "()" + data[2], timestr, b.length + " bytes", lines);
+ }
+ }
+ }
+
+ /**
+ * Log a String
+ *
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param s The string to log with d.toString()
+ */
+ public static void print(int loglevel, String s) {
+ if (debug)
+ print(loglevel, (Object) s);
+ }
+
+ /**
+ * Log an Object
+ *
+ * @param c The class doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param d The object to log with d.toString()
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Class c, int loglevel, Object d) {
+ if (debug) {
+ saveclass = c;
+ print(loglevel, d);
+ }
+ }
+
+ /**
+ * Log a String
+ *
+ * @param c The class doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param s The log message
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void print(Class c, int loglevel, String s) {
+ if (debug) {
+ saveclass = c;
+ print(loglevel, s);
+ }
+ }
+
+ private static String[] getTraceElements() {
+ String[] data = new String[]{"", "", ""};
+ try {
+ Method m = Thread.class.getMethod("getStackTrace", new Class[0]);
+ StackTraceElement[] stes = (StackTraceElement[]) m.invoke(Thread.currentThread(), new Object[0]);
+ for (StackTraceElement ste : stes) {
+ if (Debug.class.getName().equals(ste.getClassName())) continue;
+ if (Thread.class.getName().equals(ste.getClassName())) continue;
+ if (Method.class.getName().equals(ste.getClassName())) continue;
+ if (ste.getClassName().startsWith("sun.reflect")) continue;
+ data[0] = ste.getClassName();
+ data[1] = ste.getMethodName();
+ if (lines)
+ data[2] = " " + ste.getFileName() + ":" + ste.getLineNumber();
+ break;
+ }
+ } catch (NoSuchMethodException NSMe) {
+ if (null != saveclass)
+ data[0] = saveclass.getName();
+ } catch (IllegalAccessException IAe) {
+ } catch (InvocationTargetException ITe) {
+ }
+ return data;
+ }
+
+ /**
+ * Log an Object
+ *
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param o The object to log
+ */
+ public static void print(int loglevel, Object o) {
+ if (debug) {
+ String timestr = "";
+ String[] data = getTraceElements();
+ if (debugging(data[0], loglevel)) {
+ if (timing) {
+ long now = System.currentTimeMillis();
+ timestr = "{" + (now - last) + "} ";
+ last = now;
+ }
+ _print(o.getClass(), loglevel, data[0] + "." + data[1] + "()" + data[2], timestr, o.toString(), null);
+ }
+ }
+ }
+
+ /**
+ * Log a Map
+ *
+ * @param o The object doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param m The Map to print out
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void printMap(Object o, int loglevel, Map m) {
+ if (debug) {
+ if (o instanceof Class)
+ saveclass = (Class) o;
+ else
+ saveclass = o.getClass();
+ printMap(loglevel, m);
+ }
+ }
+
+ /**
+ * Log a Map
+ *
+ * @param c The class doing the logging
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param m The Map to print out
+ * @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in.
+ */
+ //TODO: 1.5 @Deprecated()
+ public static void printMap(Class c, int loglevel, Map m) {
+ if (debug) {
+ saveclass = c;
+ printMap(loglevel, m);
+ }
+ }
+
+ /**
+ * Log a Map at DEBUG log level
+ *
+ * @param m The Map to print out
+ */
+ public static void printMap(Map m) {
+ printMap(DEBUG, m);
+ }
+
+ /**
+ * Log a Map
+ *
+ * @param loglevel The level to log at (DEBUG, WARN, etc)
+ * @param m The Map to print out
+ */
+ public static void printMap(int loglevel, Map m) {
+ if (debug) {
+ String timestr = "";
+ String[] data = getTraceElements();
+ if (debugging(data[0], loglevel)) {
+ if (timing) {
+ long now = System.currentTimeMillis();
+ timestr = "{" + (now - last) + "} ";
+ last = now;
+ }
+ Iterator i = m.keySet().iterator();
+ String[] lines = new String[m.size()];
+ int j = 0;
+ while (i.hasNext()) {
+ Object key = i.next();
+ lines[j++] = "\t\t- " + key + " => " + m.get(key);
+ }
+ _print(m.getClass(), loglevel, data[0] + "." + data[1] + "()" + data[2], timestr, "Map:", lines);
+ }
+ }
+ }
+
+ /**
+ * Enable or disable stack traces in Debuging throwables.
+ */
+ public static void setThrowableTraces(boolean ttrace) {
+ Debug.ttrace = ttrace;
+ }
+
+ /**
+ * Enable or disable timing in Debug messages.
+ */
+ public static void setTiming(boolean timing) {
+ Debug.timing = timing;
+ }
+
+ /**
+ * Enable or disable line numbers.
+ */
+ public static void setLineNos(boolean lines) {
+ Debug.lines = lines;
+ }
+
+ /**
+ * Enable or disable hexdumps.
+ */
+ public static void setHexDump(boolean hexdump) {
+ Debug.hexdump = hexdump;
+ }
+
+ /**
+ * Set the size of hexdumps.
+ * (Default: 36)
+ */
+ public static void setByteArrayCount(int count) {
+ Debug.balen = count;
+ }
+
+ /**
+ * Set the formatted width of hexdumps.
+ * (Default: 80 chars)
+ */
+ public static void setByteArrayWidth(int width) {
+ Debug.bawidth = width;
+ }
+
+ /**
+ * Add a filter command for a specific type.
+ * This command will be called with the output stream
+ * and the text to be sent. It should perform any
+ * changes necessary to the text and then print the
+ * result to the output stream.
+ */
+ public static void addFilterCommand(Class c, FilterCommand f)
+ //TODO 1.5: public static void addFilterCommand(Class extends Object> c, FilterCommand f)
+ {
+ filterMap.put(c, f);
+ }
+
+ private static void _print(Class c, int level, String loc, String extra, String message, String[] lines) {
+ //TODO 1.5: FilterCommand f = filterMap.get(c);
+ FilterCommand f = (FilterCommand) filterMap.get(c);
+ if (null == f) {
+ debugout.println("[" + loc + "] " + extra + message);
+ if (null != lines)
+ for (String s : lines)
+ debugout.println(s);
+ } else
+ f.filter(debugout, level, loc, extra, message, lines);
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/NotConnectedException.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/NotConnectedException.java
new file mode 100644
index 0000000000..836f5d6229
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/NotConnectedException.java
@@ -0,0 +1,35 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+import java.net.SocketException;
+
+public class NotConnectedException extends SocketException {
+ public NotConnectedException() {
+ super("The Socket is Not Connected");
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java
new file mode 100644
index 0000000000..eb143fe6a9
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/USInputStream.java
@@ -0,0 +1,94 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class USInputStream extends InputStream {
+ public static final int MSG_DONTWAIT = 0x40;
+
+ private native int native_recv(int sock, byte[] b, int off, int len, int flags, int timeout) throws IOException;
+
+ private int sock;
+ boolean closed = false;
+ private byte[] onebuf = new byte[1];
+ private UnixSocket us;
+ private boolean blocking = true;
+ private int flags = 0;
+ private int timeout = 0;
+
+ public USInputStream(int sock, UnixSocket us) {
+ this.sock = sock;
+ this.us = us;
+ }
+
+ public void close() throws IOException {
+ closed = true;
+ us.close();
+ }
+
+ public boolean markSupported() {
+ return false;
+ }
+
+ public int read() throws IOException {
+ int rv = 0;
+ while (0 >= rv) rv = read(onebuf);
+ if (-1 == rv) return -1;
+ return 0 > onebuf[0] ? -onebuf[0] : onebuf[0];
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (closed) throw new NotConnectedException();
+ int count = native_recv(sock, b, off, len, flags, timeout);
+ /* Yes, I really want to do this. Recv returns 0 for 'connection shut down'.
+ * read() returns -1 for 'end of stream.
+ * Recv returns -1 for 'EAGAIN' (all other errors cause an exception to be raised)
+ * whereas read() returns 0 for '0 bytes read', so yes, I really want to swap them here.
+ */
+ if (0 == count) return -1;
+ else if (-1 == count) return 0;
+ else return count;
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ public UnixSocket getSocket() {
+ return us;
+ }
+
+ public void setBlocking(boolean enable) {
+ flags = enable ? 0 : MSG_DONTWAIT;
+ }
+
+ public void setSoTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java
new file mode 100644
index 0000000000..d8c85a7718
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/USOutputStream.java
@@ -0,0 +1,78 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class USOutputStream extends OutputStream {
+ private native int native_send(int sock, byte[] b, int off, int len) throws IOException;
+
+ private native int native_send(int sock, byte[][] b) throws IOException;
+
+ private int sock;
+ boolean closed = false;
+ private byte[] onebuf = new byte[1];
+ private UnixSocket us;
+
+ public USOutputStream(int sock, UnixSocket us) {
+ this.sock = sock;
+ this.us = us;
+ }
+
+ public void close() throws IOException {
+ closed = true;
+ us.close();
+ }
+
+ public void flush() {
+ } // no-op, we do not buffer
+
+ public void write(byte[][] b) throws IOException {
+ if (closed) throw new NotConnectedException();
+ native_send(sock, b);
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (closed) throw new NotConnectedException();
+ native_send(sock, b, off, len);
+ }
+
+ public void write(int b) throws IOException {
+ onebuf[0] = (byte) (b % 0x7F);
+ if (1 == (b % 0x80)) onebuf[0] = (byte) -onebuf[0];
+ write(onebuf);
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ public UnixSocket getSocket() {
+ return us;
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java
new file mode 100644
index 0000000000..24fd20cd1f
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixIOException.java
@@ -0,0 +1,43 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+import java.io.IOException;
+
+/**
+ * An IO Exception which occurred during UNIX Socket IO
+ */
+public class UnixIOException extends IOException {
+ private int no;
+ private String message;
+
+ public UnixIOException(int no, String message) {
+ super(message);
+ this.message = message;
+ this.no = no;
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java
new file mode 100644
index 0000000000..8851637436
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocket.java
@@ -0,0 +1,350 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+import cx.ath.matthew.LibraryLoader;
+import cx.ath.matthew.debug.Debug;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Represents a UnixSocket.
+ */
+public class UnixSocket {
+ static {
+ LibraryLoader.load();
+ }
+
+ private native void native_set_pass_cred(int sock, boolean passcred) throws IOException;
+
+ private native int native_connect(String address, boolean abs) throws IOException;
+
+ private native void native_close(int sock) throws IOException;
+
+ private native int native_getPID(int sock);
+
+ private native int native_getUID(int sock);
+
+ private native int native_getGID(int sock);
+
+ private native void native_send_creds(int sock, byte data) throws IOException;
+
+ private native byte native_recv_creds(int sock, int[] creds) throws IOException;
+
+ private UnixSocketAddress address = null;
+ private USOutputStream os = null;
+ private USInputStream is = null;
+ private boolean closed = false;
+ private boolean connected = false;
+ private boolean passcred = false;
+ private int sock = 0;
+ private boolean blocking = true;
+ private int uid = -1;
+ private int pid = -1;
+ private int gid = -1;
+
+ UnixSocket(int sock, UnixSocketAddress address) {
+ this.sock = sock;
+ this.address = address;
+ this.connected = true;
+ this.os = new USOutputStream(sock, this);
+ this.is = new USInputStream(sock, this);
+ }
+
+ /**
+ * Create an unconnected socket.
+ */
+ public UnixSocket() {
+ }
+
+ /**
+ * Create a socket connected to the given address.
+ *
+ * @param address The Unix Socket address to connect to
+ */
+ public UnixSocket(UnixSocketAddress address) throws IOException {
+ connect(address);
+ }
+
+ /**
+ * Create a socket connected to the given address.
+ *
+ * @param address The Unix Socket address to connect to
+ */
+ public UnixSocket(String address) throws IOException {
+ this(new UnixSocketAddress(address));
+ }
+
+ /**
+ * Connect the socket to this address.
+ *
+ * @param address The Unix Socket address to connect to
+ */
+ public void connect(UnixSocketAddress address) throws IOException {
+ if (connected) close();
+ this.sock = native_connect(address.path, address.abs);
+ this.os = new USOutputStream(this.sock, this);
+ this.is = new USInputStream(this.sock, this);
+ this.address = address;
+ this.connected = true;
+ this.closed = false;
+ this.is.setBlocking(blocking);
+ }
+
+ /**
+ * Connect the socket to this address.
+ *
+ * @param address The Unix Socket address to connect to
+ */
+ public void connect(String address) throws IOException {
+ connect(new UnixSocketAddress(address));
+ }
+
+ public void finalize() {
+ try {
+ close();
+ } catch (IOException IOe) {
+ }
+ }
+
+ /**
+ * Closes the connection.
+ */
+ public synchronized void close() throws IOException {
+ if (Debug.debug) Debug.print(Debug.INFO, "Closing socket");
+ native_close(sock);
+ sock = 0;
+ this.closed = true;
+ this.connected = false;
+ os = null;
+ is = null;
+ }
+
+ /**
+ * Returns an InputStream for reading from the socket.
+ *
+ * @return An InputStream connected to this socket.
+ */
+ public InputStream getInputStream() {
+ return is;
+ }
+
+ /**
+ * Returns an OutputStream for writing to the socket.
+ *
+ * @return An OutputStream connected to this socket.
+ */
+ public OutputStream getOutputStream() {
+ return os;
+ }
+
+ /**
+ * Returns the address this socket is connected to.
+ * Returns null if the socket is unconnected.
+ *
+ * @return The UnixSocketAddress the socket is connected to
+ */
+ public UnixSocketAddress getAddress() {
+ return address;
+ }
+
+ /**
+ * Send a single byte of data with credentials.
+ * (Works on BSDs)
+ *
+ * @param data The byte of data to send.
+ */
+ public void sendCredentialByte(byte data) throws IOException {
+ if (!connected) throw new NotConnectedException();
+ native_send_creds(sock, data);
+ }
+
+ /**
+ * Receive a single byte of data, with credentials.
+ * (Works on BSDs)
+ *
+ * @param data The byte of data to send.
+ * @see getPeerUID
+ * @see getPeerPID
+ * @see getPeerGID
+ */
+ public byte recvCredentialByte() throws IOException {
+ if (!connected) throw new NotConnectedException();
+ int[] creds = new int[]{-1, -1, -1};
+ byte data = native_recv_creds(sock, creds);
+ pid = creds[0];
+ uid = creds[1];
+ gid = creds[2];
+ return data;
+ }
+
+ /**
+ * Get the credential passing status.
+ * (only effective on linux)
+ *
+ * @return The current status of credential passing.
+ * @see setPassCred
+ */
+ public boolean getPassCred() {
+ return passcred;
+ }
+
+ /**
+ * Return the uid of the remote process.
+ * Some data must have been received on the socket to do this.
+ * Either setPassCred must be called on Linux first, or recvCredentialByte
+ * on BSD.
+ *
+ * @return the UID or -1 if it is not available
+ */
+ public int getPeerUID() {
+ if (-1 == uid)
+ uid = native_getUID(sock);
+ return uid;
+ }
+
+ /**
+ * Return the gid of the remote process.
+ * Some data must have been received on the socket to do this.
+ * Either setPassCred must be called on Linux first, or recvCredentialByte
+ * on BSD.
+ *
+ * @return the GID or -1 if it is not available
+ */
+ public int getPeerGID() {
+ if (-1 == gid)
+ gid = native_getGID(sock);
+ return gid;
+ }
+
+ /**
+ * Return the pid of the remote process.
+ * Some data must have been received on the socket to do this.
+ * Either setPassCred must be called on Linux first, or recvCredentialByte
+ * on BSD.
+ *
+ * @return the PID or -1 if it is not available
+ */
+ public int getPeerPID() {
+ if (-1 == pid)
+ pid = native_getPID(sock);
+ return pid;
+ }
+
+ /**
+ * Set the credential passing status.
+ * (Only does anything on linux, for other OS, you need
+ * to use send/recv credentials)
+ *
+ * @param enable Set to true for credentials to be passed.
+ */
+ public void setPassCred(boolean enable) throws IOException {
+ native_set_pass_cred(sock, enable);
+ passcred = enable;
+ }
+
+ /**
+ * Get the blocking mode.
+ *
+ * @return true if reads are blocking.
+ * @see setBlocking
+ */
+ public boolean getBlocking() {
+ return blocking;
+ }
+
+ /**
+ * Set the blocking mode.
+ *
+ * @param enable Set to false for non-blocking reads.
+ */
+ public void setBlocking(boolean enable) {
+ blocking = enable;
+ if (null != is) is.setBlocking(enable);
+ }
+
+ /**
+ * Check the socket status.
+ *
+ * @return true if closed.
+ */
+ public boolean isClosed() {
+ return closed;
+ }
+
+ /**
+ * Check the socket status.
+ *
+ * @return true if connected.
+ */
+ public boolean isConnected() {
+ return connected;
+ }
+
+ /**
+ * Check the socket status.
+ *
+ * @return true if the input stream has been shutdown
+ */
+ public boolean isInputShutdown() {
+ return is.isClosed();
+ }
+
+ /**
+ * Check the socket status.
+ *
+ * @return true if the output stream has been shutdown
+ */
+ public boolean isOutputShutdown() {
+ return os.isClosed();
+ }
+
+ /**
+ * Shuts down the input stream.
+ * Subsequent reads on the associated InputStream will fail.
+ */
+ public void shutdownInput() {
+ is.closed = true;
+ }
+
+ /**
+ * Shuts down the output stream.
+ * Subsequent writes to the associated OutputStream will fail.
+ */
+ public void shutdownOutput() {
+ os.closed = true;
+ }
+
+ /**
+ * Set timeout of read requests.
+ */
+ public void setSoTimeout(int timeout) {
+ is.setSoTimeout(timeout);
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java
new file mode 100644
index 0000000000..0baba479bb
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/unix/UnixSocketAddress.java
@@ -0,0 +1,86 @@
+/*
+ * Java Unix Sockets Library
+ *
+ * Copyright (c) Matthew Johnson 2004
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+package cx.ath.matthew.unix;
+
+/**
+ * Represents an address for a Unix Socket
+ */
+public class UnixSocketAddress {
+ String path;
+ boolean abs;
+
+ /**
+ * Create the address.
+ *
+ * @param path The path to the Unix Socket.
+ * @param abs True if this should be an abstract socket.
+ */
+ public UnixSocketAddress(String path, boolean abs) {
+ this.path = path;
+ this.abs = abs;
+ }
+
+ /**
+ * Create the address.
+ *
+ * @param path The path to the Unix Socket.
+ */
+ public UnixSocketAddress(String path) {
+ this.path = path;
+ this.abs = false;
+ }
+
+ /**
+ * Return the path.
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Returns true if this an address for an abstract socket.
+ */
+ public boolean isAbstract() {
+ return abs;
+ }
+
+ /**
+ * Return the Address as a String.
+ */
+ public String toString() {
+ return "unix" + (abs ? ":abstract" : "") + ":path=" + path;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof UnixSocketAddress)) return false;
+ return ((UnixSocketAddress) o).path.equals(this.path);
+ }
+
+ public int hashCode() {
+ return path.hashCode();
+ }
+}
diff --git a/federation/sssd/src/main/java/cx/ath/matthew/utils/Hexdump.java b/federation/sssd/src/main/java/cx/ath/matthew/utils/Hexdump.java
new file mode 100644
index 0000000000..63f37194db
--- /dev/null
+++ b/federation/sssd/src/main/java/cx/ath/matthew/utils/Hexdump.java
@@ -0,0 +1,147 @@
+/*
+ * Java Hexdump Library
+ *
+ * Copyright (c) Matthew Johnson 2005
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To Contact the author, please email src@matthew.ath.cx
+ *
+ */
+
+package cx.ath.matthew.utils;
+
+import java.io.PrintStream;
+
+public class Hexdump {
+ public static final char[] hexchars = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ public static String toHex(byte[] buf) {
+ return toHex(buf, 0, buf.length);
+ }
+
+ public static String toHex(byte[] buf, int ofs, int len) {
+ StringBuffer sb = new StringBuffer();
+ int j = ofs + len;
+ for (int i = ofs; i < j; i++) {
+ if (i < buf.length) {
+ sb.append(hexchars[(buf[i] & 0xF0) >> 4]);
+ sb.append(hexchars[buf[i] & 0x0F]);
+ sb.append(' ');
+ } else {
+ sb.append(' ');
+ sb.append(' ');
+ sb.append(' ');
+ }
+ }
+ return sb.toString();
+ }
+
+ public static String toAscii(byte[] buf) {
+ return toAscii(buf, 0, buf.length);
+ }
+
+ public static String toAscii(byte[] buf, int ofs, int len) {
+ StringBuffer sb = new StringBuffer();
+ int j = ofs + len;
+ for (int i = ofs; i < j; i++) {
+ if (i < buf.length) {
+ if (20 <= buf[i] && 126 >= buf[i])
+ sb.append((char) buf[i]);
+ else
+ sb.append('.');
+ } else
+ sb.append(' ');
+ }
+ return sb.toString();
+ }
+
+ public static String format(byte[] buf) {
+ return format(buf, 80);
+ }
+
+ public static String format(byte[] buf, int width) {
+ int bs = (width - 8) / 4;
+ int i = 0;
+ StringBuffer sb = new StringBuffer();
+ do {
+ for (int j = 0; j < 6; j++) {
+ sb.append(hexchars[(i << (j * 4) & 0xF00000) >> 20]);
+ }
+ sb.append('\t');
+ sb.append(toHex(buf, i, bs));
+ sb.append(' ');
+ sb.append(toAscii(buf, i, bs));
+ sb.append('\n');
+ i += bs;
+ } while (i < buf.length);
+ return sb.toString();
+ }
+
+ public static void print(byte[] buf) {
+ print(buf, System.err);
+ }
+
+ public static void print(byte[] buf, int width) {
+ print(buf, width, System.err);
+ }
+
+ public static void print(byte[] buf, int width, PrintStream out) {
+ out.print(format(buf, width));
+ }
+
+ public static void print(byte[] buf, PrintStream out) {
+ out.print(format(buf));
+ }
+
+ /**
+ * Returns a string which can be written to a Java source file as part
+ * of a static initializer for a byte array.
+ * Returns data in the format 0xAB, 0xCD, ....
+ * use like:
+ * javafile.print("byte[] data = {")
+ * javafile.print(Hexdump.toByteArray(data));
+ * javafile.println("};");
+ */
+ public static String toByteArray(byte[] buf) {
+ return toByteArray(buf, 0, buf.length);
+ }
+
+ /**
+ * Returns a string which can be written to a Java source file as part
+ * of a static initializer for a byte array.
+ * Returns data in the format 0xAB, 0xCD, ....
+ * use like:
+ * javafile.print("byte[] data = {")
+ * javafile.print(Hexdump.toByteArray(data));
+ * javafile.println("};");
+ */
+ public static String toByteArray(byte[] buf, int ofs, int len) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = ofs; i < len && i < buf.length; i++) {
+ sb.append('0');
+ sb.append('x');
+ sb.append(hexchars[(buf[i] & 0xF0) >> 4]);
+ sb.append(hexchars[buf[i] & 0x0F]);
+ if ((i + 1) < len && (i + 1) < buf.length)
+ sb.append(',');
+ }
+ return sb.toString();
+ }
+}
diff --git a/federation/sssd/src/main/java/org/freedesktop/DBus.java b/federation/sssd/src/main/java/org/freedesktop/DBus.java
new file mode 100644
index 0000000000..1aa180a4ab
--- /dev/null
+++ b/federation/sssd/src/main/java/org/freedesktop/DBus.java
@@ -0,0 +1,530 @@
+/*
+ D-Bus Java Implementation
+ Copyright (c) 2005-2006 Matthew Johnson
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of either the GNU Lesser General Public License Version 2 or the
+ Academic Free Licence Version 2.1.
+
+ Full licence texts are included in the COPYING file with this program.
+*/
+package org.freedesktop;
+
+import org.freedesktop.dbus.DBusInterface;
+import org.freedesktop.dbus.DBusSignal;
+import org.freedesktop.dbus.Position;
+import org.freedesktop.dbus.Struct;
+import org.freedesktop.dbus.Tuple;
+import org.freedesktop.dbus.UInt16;
+import org.freedesktop.dbus.UInt32;
+import org.freedesktop.dbus.UInt64;
+import org.freedesktop.dbus.Variant;
+import org.freedesktop.dbus.exceptions.DBusException;
+import org.freedesktop.dbus.exceptions.DBusExecutionException;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.Map;
+
+public interface DBus extends DBusInterface {
+ public static final int DBUS_NAME_FLAG_ALLOW_REPLACEMENT = 0x01;
+ public static final int DBUS_NAME_FLAG_REPLACE_EXISTING = 0x02;
+ public static final int DBUS_NAME_FLAG_DO_NOT_QUEUE = 0x04;
+ public static final int DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1;
+ public static final int DBUS_REQUEST_NAME_REPLY_IN_QUEUE = 2;
+ public static final int DBUS_REQUEST_NAME_REPLY_EXISTS = 3;
+ public static final int DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4;
+ public static final int DBUS_RELEASE_NAME_REPLY_RELEASED = 1;
+ public static final int DBUS_RELEASE_NAME_REPLY_NON_EXISTANT = 2;
+ public static final int DBUS_RELEASE_NAME_REPLY_NOT_OWNER = 3;
+ public static final int DBUS_START_REPLY_SUCCESS = 1;
+ public static final int DBUS_START_REPLY_ALREADY_RUNNING = 2;
+
+ /**
+ * All DBus Applications should respond to the Ping method on this interface
+ */
+ public interface Peer extends DBusInterface {
+ public void Ping();
+ }
+
+ /**
+ * Objects can provide introspection data via this interface and method.
+ * See the Introspection Format.
+ */
+ public interface Introspectable extends DBusInterface {
+ /**
+ * @return The XML introspection data for this object
+ */
+ public String Introspect();
+ }
+
+ /**
+ * A standard properties interface.
+ */
+ public interface Properties extends DBusInterface {
+ /**
+ * Get the value for the given property.
+ *
+ * @param interface_name The interface this property is associated with.
+ * @param property_name The name of the property.
+ * @return The value of the property (may be any valid DBus type).
+ */
+ public A Get(String interface_name, String property_name);
+
+ /**
+ * Set the value for the given property.
+ *
+ * @param interface_name The interface this property is associated with.
+ * @param property_name The name of the property.
+ * @param value The new value of the property (may be any valid DBus type).
+ */
+ public void Set(String interface_name, String property_name, A value);
+
+ /**
+ * Get all properties and values.
+ *
+ * @param interface_name The interface the properties is associated with.
+ * @return The properties mapped to their values.
+ */
+ public Map GetAll(String interface_name);
+ }
+
+ /**
+ * Messages generated locally in the application.
+ */
+ public interface Local extends DBusInterface {
+ public class Disconnected extends DBusSignal {
+ public Disconnected(String path) throws DBusException {
+ super(path);
+ }
+ }
+ }
+
+ /**
+ * Initial message to register ourselves on the Bus.
+ *
+ * @return The unique name of this connection to the Bus.
+ */
+ public String Hello();
+
+ /**
+ * Lists all connected names on the Bus.
+ *
+ * @return An array of all connected names.
+ */
+ public String[] ListNames();
+
+ /**
+ * Determine if a name has an owner.
+ *
+ * @param name The name to query.
+ * @return true if the name has an owner.
+ */
+ public boolean NameHasOwner(String name);
+
+ /**
+ * Get the connection unique name that owns the given name.
+ *
+ * @param name The name to query.
+ * @return The connection which owns the name.
+ */
+ public String GetNameOwner(String name);
+
+ /**
+ * Get the Unix UID that owns a connection name.
+ *
+ * @param connection_name The connection name.
+ * @return The Unix UID that owns it.
+ */
+ public UInt32 GetConnectionUnixUser(String connection_name);
+
+ /**
+ * Start a service. If the given service is not provided
+ * by any application, it will be started according to the .service file
+ * for that service.
+ *
+ * @param name The service name to start.
+ * @param flags Unused.
+ * @return DBUS_START_REPLY constants.
+ */
+ public UInt32 StartServiceByName(String name, UInt32 flags);
+
+ /**
+ * Request a name on the bus.
+ *
+ * @param name The name to request.
+ * @param flags DBUS_NAME flags.
+ * @return DBUS_REQUEST_NAME_REPLY constants.
+ */
+ public UInt32 RequestName(String name, UInt32 flags);
+
+ /**
+ * Release a name on the bus.
+ *
+ * @param name The name to release.
+ * @return DBUS_RELEASE_NAME_REPLY constants.
+ */
+ public UInt32 ReleaseName(String name);
+
+ /**
+ * Add a match rule.
+ * Will cause you to receive messages that aren't directed to you which
+ * match this rule.
+ *
+ * @param matchrule The Match rule as a string. Format Undocumented.
+ */
+ public void AddMatch(String matchrule) throws Error.MatchRuleInvalid;
+
+ /**
+ * Remove a match rule.
+ * Will cause you to stop receiving messages that aren't directed to you which
+ * match this rule.
+ *
+ * @param matchrule The Match rule as a string. Format Undocumented.
+ */
+ public void RemoveMatch(String matchrule) throws Error.MatchRuleInvalid;
+
+ /**
+ * List the connections currently queued for a name.
+ *
+ * @param name The name to query
+ * @return A list of unique connection IDs.
+ */
+ public String[] ListQueuedOwners(String name);
+
+ /**
+ * Returns the proccess ID associated with a connection.
+ *
+ * @param connection_name The name of the connection
+ * @return The PID of the connection.
+ */
+ public UInt32 GetConnectionUnixProcessID(String connection_name);
+
+ /**
+ * Does something undocumented.
+ */
+ public Byte[] GetConnectionSELinuxSecurityContext(String a);
+
+ /**
+ * Does something undocumented.
+ */
+ public void ReloadConfig();
+
+ /**
+ * Signal sent when the owner of a name changes
+ */
+ public class NameOwnerChanged extends DBusSignal {
+ public final String name;
+ public final String old_owner;
+ public final String new_owner;
+
+ public NameOwnerChanged(String path, String name, String old_owner, String new_owner) throws DBusException {
+ super(path, new Object[]{name, old_owner, new_owner});
+ this.name = name;
+ this.old_owner = old_owner;
+ this.new_owner = new_owner;
+ }
+ }
+
+ /**
+ * Signal sent to a connection when it loses a name
+ */
+ public class NameLost extends DBusSignal {
+ public final String name;
+
+ public NameLost(String path, String name) throws DBusException {
+ super(path, name);
+ this.name = name;
+ }
+ }
+
+ /**
+ * Signal sent to a connection when it aquires a name
+ */
+ public class NameAcquired extends DBusSignal {
+ public final String name;
+
+ public NameAcquired(String path, String name) throws DBusException {
+ super(path, name);
+ this.name = name;
+ }
+ }
+
+ /**
+ * Contains standard errors that can be thrown from methods.
+ */
+ public interface Error {
+ /**
+ * Thrown if the method called was unknown on the remote object
+ */
+ @SuppressWarnings("serial")
+ public class UnknownMethod extends DBusExecutionException {
+ public UnknownMethod(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Thrown if the object was unknown on a remote connection
+ */
+ @SuppressWarnings("serial")
+ public class UnknownObject extends DBusExecutionException {
+ public UnknownObject(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Thrown if the requested service was not available
+ */
+ @SuppressWarnings("serial")
+ public class ServiceUnknown extends DBusExecutionException {
+ public ServiceUnknown(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Thrown if the match rule is invalid
+ */
+ @SuppressWarnings("serial")
+ public class MatchRuleInvalid extends DBusExecutionException {
+ public MatchRuleInvalid(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Thrown if there is no reply to a method call
+ */
+ @SuppressWarnings("serial")
+ public class NoReply extends DBusExecutionException {
+ public NoReply(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Thrown if a message is denied due to a security policy
+ */
+ @SuppressWarnings("serial")
+ public class AccessDenied extends DBusExecutionException {
+ public AccessDenied(String message) {
+ super(message);
+ }
+ }
+ }
+
+ /**
+ * Description of the interface or method, returned in the introspection data
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Description {
+ String value();
+ }
+
+ /**
+ * Indicates that a DBus interface or method is deprecated
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Deprecated {
+ }
+
+ /**
+ * Contains method-specific annotations
+ */
+ public interface Method {
+ /**
+ * Methods annotated with this do not send a reply
+ */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface NoReply {
+ }
+
+ /**
+ * Give an error that the method can return
+ */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Error {
+ String value();
+ }
+ }
+
+ /**
+ * Contains GLib-specific annotations
+ */
+ public interface GLib {
+ /**
+ * Define a C symbol to map to this method. Used by GLib only
+ */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface CSymbol {
+ String value();
+ }
+ }
+
+ /**
+ * Contains Binding-test interfaces
+ */
+ public interface Binding {
+ public interface SingleTests extends DBusInterface {
+ @Description("Returns the sum of the values in the input list")
+ public UInt32 Sum(byte[] a);
+ }
+
+ public interface TestClient extends DBusInterface {
+ @Description("when the trigger signal is received, this method should be called on the sending process/object.")
+ public void Response(UInt16 a, double b);
+
+ @Description("Causes a callback")
+ public static class Trigger extends DBusSignal {
+ public final UInt16 a;
+ public final double b;
+
+ public Trigger(String path, UInt16 a, double b) throws DBusException {
+ super(path, a, b);
+ this.a = a;
+ this.b = b;
+ }
+ }
+
+ }
+
+ public interface Tests extends DBusInterface {
+ @Description("Returns whatever it is passed")
+ public Variant Identity(Variant input);
+
+ @Description("Returns whatever it is passed")
+ public byte IdentityByte(byte input);
+
+ @Description("Returns whatever it is passed")
+ public boolean IdentityBool(boolean input);
+
+ @Description("Returns whatever it is passed")
+ public short IdentityInt16(short input);
+
+ @Description("Returns whatever it is passed")
+ public UInt16 IdentityUInt16(UInt16 input);
+
+ @Description("Returns whatever it is passed")
+ public int IdentityInt32(int input);
+
+ @Description("Returns whatever it is passed")
+ public UInt32 IdentityUInt32(UInt32 input);
+
+ @Description("Returns whatever it is passed")
+ public long IdentityInt64(long input);
+
+ @Description("Returns whatever it is passed")
+ public UInt64 IdentityUInt64(UInt64 input);
+
+ @Description("Returns whatever it is passed")
+ public double IdentityDouble(double input);
+
+ @Description("Returns whatever it is passed")
+ public String IdentityString(String input);
+
+ @Description("Returns whatever it is passed")
+ public Variant[] IdentityArray(Variant[] input);
+
+ @Description("Returns whatever it is passed")
+ public byte[] IdentityByteArray(byte[] input);
+
+ @Description("Returns whatever it is passed")
+ public boolean[] IdentityBoolArray(boolean[] input);
+
+ @Description("Returns whatever it is passed")
+ public short[] IdentityInt16Array(short[] input);
+
+ @Description("Returns whatever it is passed")
+ public UInt16[] IdentityUInt16Array(UInt16[] input);
+
+ @Description("Returns whatever it is passed")
+ public int[] IdentityInt32Array(int[] input);
+
+ @Description("Returns whatever it is passed")
+ public UInt32[] IdentityUInt32Array(UInt32[] input);
+
+ @Description("Returns whatever it is passed")
+ public long[] IdentityInt64Array(long[] input);
+
+ @Description("Returns whatever it is passed")
+ public UInt64[] IdentityUInt64Array(UInt64[] input);
+
+ @Description("Returns whatever it is passed")
+ public double[] IdentityDoubleArray(double[] input);
+
+ @Description("Returns whatever it is passed")
+ public String[] IdentityStringArray(String[] input);
+
+ @Description("Returns the sum of the values in the input list")
+ public long Sum(int[] a);
+
+ @Description("Given a map of A => B, should return a map of B => a list of all the As which mapped to B")
+ public Map> InvertMapping(Map a);
+
+ @Description("This method returns the contents of a struct as separate values")
+ public Triplet DeStruct(TestStruct a);
+
+ @Description("Given any compound type as a variant, return all the primitive types recursively contained within as an array of variants")
+ public List> Primitize(Variant