The Blog of Warren Strange
Strange Brew
Archives
« June 2008
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18
19
20
21
22
23
24
25
26
27
28
29
30
     
       
Today
XML
Search

Links
 

Today's Page Hits: 200

Main | Next page »
20080617 Tuesday June 17, 2008
A Sun Identity Manger Resource Adapter for Google Apps


Google Apps provides a nice provisioning API to manage Google Apps accounts.


Using this API I have written a custom resource adapter for Sun for Sun Java System Identity Manager. Here is a screen shot showing the configured adapter:







This adapter enables you to manage the full life cycle of Google Apps accounts through Identity Manager. This includes the standard CRUD operations (Create, Read, Update, Delete) as well as enable/disable account, change/reset password and support for reconciliation.

Here is a screen shot showing the results of running a full reconciliation:





Along with the adapter, there is a user form provided that is compatible with the IdM dynamic tabbed user form framework:





As you can see from the above form, you can manage the Google Apps nicknames (mail aliases) for the user.


If you are interested in testing out this adapter, please drop me a note ( my email is warren dot strange at sun.com). My plan is to open source the adapter code - but this will be done in conjunction with a future IdM release. There is some exciting news coming on that front - can't say more right now, so stay tuned!












posted by warren Jun 17 2008, 10:25:28 AM MDT Permalink Comments [2]

20080430 Wednesday April 30, 2008
Apple adds Java SE 6 support


Better late than never....


http://www.macrumors.com/2008/04/29/apple-adds-java-se-6-to-leopard/




posted by warren Apr 30 2008, 01:19:04 AM MDT Permalink

20080422 Tuesday April 22, 2008
A script to add 3rd party artifacts to your maven repository


I find the maven command line very obtuse and have trouble remembering the right incantation to add 3rd party jars to a local repository.


Here is a small bash script which might be useful to others. You will need to edit this for your environment.


#!/bin/bash
# Add 3rd party jars to maven in a batch
# Usage: madd groupid version jar1 jar2 ...
#
# Edit the mvn command as per your repo setup

if [ $# -lt 3 ]; then
echo Usage: $0 groupid version jar1 jar2...
exit 1
fi

GROUPID=$1
shift
VERSION=$1
shift

for file in $*
do
ARTIFACTID=`echo $file | sed -e 's/\.jar//'`
mvn deploy:deploy-file -DgroupId=$GROUPID -DartifactId=$ARTIFACTID \
-Dversion=$VERSION -Dpackaging=jar -Dfile=$file \
-Durl=http://localhost:8081/nexus/content/repositories/thirdparty \
-DrepositoryId=thirdparty
done


posted by warren Apr 22 2008, 04:01:40 PM MDT Permalink

20080310 Monday March 10, 2008
Identity Manager IDE released as open source!


The Identity Manager IDE plugin for Netbeans has now been released as open source under the CDDL license.

Get it while it's hot @ http://identitymanageride.dev.java.net/



Highlights include support for Netbeans 6.0, and a new "Object Builder" to manage IdM Objects.



posted by warren Mar 10 2008, 10:29:13 AM MDT Permalink

20080218 Monday February 18, 2008
Getting Groovy with OpenSSO REST Services


Recent builds of OpenSSO now include WS-* and REST identity services. Check out Marina Sum's blog for an excellent overview.


Now it turns out that Groovy is a great way to explore REST services. Here is an example using OpenSSO (if you are trying this out at home change your base URL to reflect your OpenSSO installation).



def baseurl = "http://localhost:28080/opensso/identity/"

// Create and execute REST query string
def query = { String action, Map args ->
def s = baseurl + action;
def sep = "?"
args.each { key,value ->
def encoded = java.net.URLEncoder.encode(value,"UTF-8")
s += "${sep}${key}=${encoded}"
sep = "&"
}
return s.toURL().text
}

// authenticate to OpenSSO
def authenticate = { username, password ->
String s = query("authenticate", [ username:username, password:password] )
int i = s.indexOf('=')
if( i >= 0 )
return s.substring(i+1).trim()
else
return s;
}

// fetch the users attributes. Must supply the token returned by authenticate
def getAttributes = { token -> query("attributes", [subjectid:token]) }

// Test to see if the user identified by token is allowed to access the URI
def authorize = { token, uri, action = "GET" -> query("authorize", [subjectid:token, uri:uri, action:action]) }

def token = authenticate("user1", "password")

println getAttributes(token)
println authorize(token, "http://localhost:8080/protected")





As Mr. Powers would say, Groovy Baby"

posted by warren Feb 18 2008, 12:02:53 PM MST Permalink

20071115 Thursday November 15, 2007
Netbeans / JRuby Tip: Setting up Rails database.yml for Derby

Tip o the day for getting JRuby/Rails running with Derby:

Your database.yml needs to look something like this:


development:
    adapter: jdbc
    driver: org.apache.derby.jdbc.ClientDriver
    username: fred
    password: password
    url: jdbc:derby://localhost:1527/ruby_dev


Make sure you copy derbyclient.jar to your Jruby install directory (e.g. ~netbeans-installdir/ruby1/jruby-1.0.2/lib)



Powered by ScribeFire.


posted by warren Nov 15 2007, 09:32:20 PM MST Permalink

20070420 Friday April 20, 2007
Fun with Spring, Ldap and Java Annotations


I thought it would be neat to have a way to persist Java objects to and from an Ldap directory. Kinda like "Hibernate lite" for directories. I saw several inquiries on the Hibernate forums discussing a custom mapper for Ldap - but nothing has ever been implemented. The concensus seems to be that it ought to be possible - but perhaps the relational model that Hibernate is based on is not a great fit for Ldap.


In any event, I created a very simple package which I have Dubbed "Slapper". The readme is presented below. If you think this has value, drop me a note and I may extend the implementation...






Slapper


What does it stand for? How about “Simple Ldap Mapper”. OK, yes it is kinda lame


In a nutshell, Slapper is a utility package that uses annotations to persist Java POJOs to and from an Ldap directory. This is a very simplistic mapper - It currently does not handle any relationship navigation. This package uses Spring Ldap.


To use Slapper, you first create a POJO (well almost a POJO, as it must implement the DirObject interface) that has the appropriate annotations. Here is an example:



@ObjectClass({"inetorgperson", "organizationalperson", "person", "top"})
public class UserAccount implements DirObject {
private Name name;
private String commonName;
private String lastName;
private byte[] userPassword;

@DirectoryAttribute("userPassword" )
public byte[] getUserPassword() {
return userPassword;
}

public void setUserPassword(byte[] userPassword) {
this.userPassword = userPassword;
}


@DirectoryAttribute(value="cn")
public String getCommonName() {
return commonName;
}

/**
*
* @param commonName
*/
public void setCommonName(String commonName) {
this.commonName = commonName;
}


.....


The next step is to configure your Spring beans.xml to create a DAO object that can read and write to this object type. Here is an
example:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="contextSource" class="org.springframework.ldap.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="userName" value="cn=Directory Manager" />
<property name="password" value="passw0rd" />
</bean>

<bean id="ldapTemplate" class="org.springframework.ldap.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>

<bean name="userMarshaller" class="com.my2do.slapper.Marshaller">
<constructor-arg value="com.my2do.slapper.example.UserAccount"/>
</bean>

<bean id="userDAO" class="com.my2do.slapper.LdapDAOImpl">
<property name="ldapTemplate" ref="ldapTemplate" />
<property name="marshaller" ref="userMarshaller"/>
</bean>

</beans>


The ldapTemplate is standard Spring Ldap code (see the Spring docs for the details). The only tricky bit of the above is the Marshaller. This is a class that knows how to marshal annotated POJOs
to and from directory attributes. The marshaller processes @DirectoryAttribute annotations and maps them to the appropriate Ldap attribute. In the above example, the userDAO bean is configured to read and write beans of type UserAccount.


The DAO interface is fairly simple at this point:


public interface LdapDAO {

/**
* Retrieve an ldap object from the directory
* @param dn String Dn of the object
* @return Returns an object populated with directory attributes. The
* type of the object will be that created by the underlying Marshaller
*/
public Object getObject(String dn);
/**
* Retrieve an ldap object from the directory
* @param name (ldap dn) of the object to fetch
* @return Returns an object populated with directory attributes. The
* type of the object will be that created by the underlying Marshaller
*/
public Object getObject(Name name);

/**
* Create the object in the directory. The Dn of the object
* must be set properly (getName() must return a valid Dn). The objects
* attributes will be extracted with the Marsheller instance and sent
* to the directory.
* @param obj object to create.
*
*/
public void create(DirObject obj) ;

/**
* Delete the object from the directory. The objects getName() must
* return a valid Dn.
*
* @param obj Object to delete
*/
public void delete(DirObject obj) ;

/**
* Updated the given object.
* The object will first be read back from the directory, and only
* changed attributes will be modified.
* @param obj Object to update
*/
public void update(DirObject obj) ;

/**
* Setter for marhsaller. This will normally be injected by Spring,
* but is exposed as part of the interface in case you want
* to control the Marshalling strategy
* @param m Marshaller instance that knows how to marshal directory
* attributes to/from an object
*/
public void setMarshaller(Marshaller m);

/**
* Very simple search function. Will search at the base dn and subtrees for
* objects which meet the filter criteria. Objects will be marshalled into the
* list.
*/
public List search(Name base, String filter );

}


Putting it all together, here is a sample test that shows how the API
is used (some code has been elided for brevity...)



...

public class SlapperTest {
BeanFactory factory;
LdapDAO userDAO;

public SlapperTest() {
Resource r = new FileSystemResource("test/beans.xml");
factory = new XmlBeanFactory(r);
userDAO = (LdapDAO) factory.getBean("userDAO");
}


@Test
public void crudTest() throws InvalidNameException {
UserAccount ua = new UserAccount();
Name name= new LdapName("uid=test2, ou=People");

ua.setName(name );
ua.setCommonName("Fred Flinstone");
ua.setLastName("Flinstone");
userDAO.create(ua);

// try to create the user twice - should get an error
try {
userDAO.create(ua);
fail("Expected to get an exception");
} catch(DataIntegrityViolationException ex) {
System.out.println("OK - Got expected exception" + ex);
}

UserAccount ua2 = (UserAccount)userDAO.getObject(name);

System.out.println("Got user back " + ua2 + " is equal " + ua2.equals(ua) );

assertNotNull(ua2);

// Dn compare is broken due to bug in LdapName.equals() .....
//assertEquals( ua, ua2);
// so compare some other attribute
assertEquals( ua.getCommonName(), ua2.getCommonName());

// update the user. Only the changes will get sent to the directory
ua.setMobile("555-1212");
ua.setLastName("Rubble");
userDAO.update(ua);
// read it back and make sure the mobile got set
ua2 = (UserAccount)userDAO.getObject(name);
assertEquals( ua.getMobile(), ua2.getMobile());

// delete the user
userDAO.delete(ua);
System.out.println("deleted user " + ua);
// deleting twice seems to be silentluy ignored. OK?
userDAO.delete(ua);
}

@Test
public void simpleSearchTest() throws InvalidNameException {

LdapName base = new LdapName("ou=People");

//String filter = "& (objectclass=inetorgperson) (uid=user*)";

// build a filter that matches all inetorgperson objects whose
// uid starts with user*
// These are the sample users created by the OpenDS installer
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "inetorgperson"));
filter.and(new WhitespaceWildcardsFilter("uid", "user "));
System.out.println("Using filter " + filter.encode() );

// List l will be populated with UserAccount objects
// Assumes we have some sample users in the directory
List l = userDAO.search(base, filter.encode());
assertEquals( l.get(0).getClass(), UserAccount.class );

System.out.println("Got search result =" + l);

}

}


Powered by ScribeFire.


posted by warren Apr 20 2007, 03:22:27 PM MDT Permalink

LdapName.equals() not so equal?
Is it just me, or is LdapName.equals() brain dead? My expectation is that two LdapName's are equal if they represent the same underlying Ldap Dn. Instead, the comparison seems to be case and white space sensitive. OK, I see I'm not the only one who has this problem.

Powered by ScribeFire.


posted by warren Apr 20 2007, 11:17:06 AM MDT Permalink

20070327 Tuesday March 27, 2007
SPML 2.0 presentation
Curious about SPML 2.0 ? Here is an overview presentation that nicely explains the core concepts.

Powered by ScribeFire.


posted by warren Mar 27 2007, 10:39:51 AM MDT Permalink Comments [3]

20070301 Thursday March 01, 2007
Using OpenSSO authentication with JBoss SEAM




The new security model in SEAM makes it easy to plug in different authentication mechanisms. After a couple of hours of hacking (OK, it was more like 6 hours...),  I had the sample SEAM booking demo using OpenSSO for authentication. 


The user enters their OpenSSO username and password on the Booking demo log on page, and the application uses the OpenSSO APIs to authenticate to an OpenSSO server. [If you are trying this out at home, remember that the user must be registered in both OpenSSO AND the SEAM application for this to work. If the user authenticates to OpenSSO, but is not registered in the Booking demo, they will get an error message to this effect].



This code has a long way to go to be truly useful. For example, it does not handle any of the following:



Policy Agent vs. Agentless Deployment



The easiest way to obtain the above missing features is to install an OpenSSO policy agent in the hosting container (GlassFish, in my case).   That being said, I would really love to be able to get this working without requiring the installation of a policy agent.

It would be nice to hand someone a .war file, and have it "just work" without any modification of the container.   This may turn out to be a rather difficult exercise. We will see how far I get...


Deploying the Example



If you are interested in playing with the example, you can download the NetBeans project from http://mediacast.sun.com/share/warren/seamBookingWithOpenSSO.zip

You will also need to download and install OpenSSO, and I suggest you also get the OpenSSO examples as well.

The deployed .war file must contain the amsdk.jar file. In addition, you will need to include an AMConfig.properties file that matches your environment. This configuration file is used by the client code to find and authenticate against the OpenSSO server.

The easiest way to generate a valid AMConfig file is to run the "setup" script in the OpenSSO examples, and test it using the sample "login" script.


Most of the action (no pun intended) is in the AuthenticatorAction.java code. Pasted here for your viewing pleasure:


package org.jboss.seam.example.booking;

import com.sun.identity.authentication.AuthContext;
import com.sun.identity.authentication.spi.AuthLoginException;
import java.io.IOException;
import java.util.List;
import static org.jboss.seam.ScopeType.EVENT;
import static org.jboss.seam.ScopeType.SESSION;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.core.FacesMessages;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;

/**
 *
 * @author warren
 */
@Stateful
@Scope(EVENT)
@Name("authenticator")
public class AuthenticatorAction implements Authenticator {
    @In Identity identity;
   
    @PersistenceContext EntityManager em;
   
    @Out(required=false, scope = SESSION)
    private User user;
   
    @Logger private Log log;
   
    private static final String orgName = "opensso";
    private static final String moduleName = "DataStore";
   
    /**
     *
     * @return
     * @throws com.sun.identity.authentication.spi.AuthLoginException
     */
    protected AuthContext getAuthContext() throws AuthLoginException {
        AuthContext lc = new AuthContext(orgName);
        AuthContext.IndexType indexType = AuthContext.IndexType.MODULE_INSTANCE;
        lc.login(indexType, moduleName);
        return lc;
    }
   
    /**
     *
     * @param lc
     * @return
     * @throws UnsupportedCallbackException
     */
    protected boolean login(AuthContext lc) throws UnsupportedCallbackException {
        boolean succeed = false;
        Callback[] callbacks = null;
       
        // get information requested from module
        while (lc.hasMoreRequirements()) {
            callbacks = lc.getRequirements();
            if (callbacks != null) {
                addLoginCallbackMessage(callbacks);
                lc.submitRequirements(callbacks);
            }
        }
       
        if (lc.getStatus() == AuthContext.Status.SUCCESS) {
            log.info("Login succeeded.");
            succeed = true;
        } else if (lc.getStatus() == AuthContext.Status.FAILED) {
            log.error("Login failed.");
        } else {
            log.error("Unknown status: " + lc.getStatus());
        }

        return succeed;
    }
   
    private void addLoginCallbackMessage(Callback[] callbacks)
            throws UnsupportedCallbackException {
        int i = 0;
        try {
            for (i = 0; i < callbacks.length; i++) {
                if (callbacks[i] instanceof TextOutputCallback) {
                } else if (callbacks[i] instanceof NameCallback) {
                    handleNameCallback((NameCallback)callbacks[i]);
                } else if (callbacks[i] instanceof PasswordCallback) {
                    handlePasswordCallback((PasswordCallback)callbacks[i]);
                } else
                    throw new UnsupportedCallbackException(callbacks[i]);
            }
        } catch (IOException e) {
            log.error("Login Failed", e);
            throw new UnsupportedCallbackException(callbacks[i],e.getMessage());
        }
    }
   
    private void handleNameCallback(NameCallback nc) throws IOException {
        nc.setName(identity.getUsername());
    }
   
    private void handlePasswordCallback(PasswordCallback pc) throws IOException {
        String passwd = identity.getPassword();
        pc.setPassword(passwd.toCharArray());
    }
   
    /**
     *
     * @return true if the user was succesfully authenticated, false otherwise
     */
    public boolean authenticate() {
        log.trace("Username=" + identity.getUsername() +
                " password=" + identity.getPassword());
        try     {
            User user = null;
            AuthContext lc = getAuthContext();
            log.debug("Got Authcontext=" + lc);
           
            if (login(lc)) {
                log.info("OpenSSO login for user #0 succeeded", identity.getUsername());
               
                if( ! fetchDBUser(identity.getUsername())) {
                    String msg = "OpenSSO login succeded, but there is no user with this name in the datbase";
                    log.error(msg);
                    FacesMessages.instance().add(msg);
                    return false;
                }
               
                return true;
            }
            return false;
        } catch (AuthLoginException ex) {
            log.error("AuthLogin problem", ex);
            return false;
        } catch(UnsupportedCallbackException ex2) {
            log.error("Callback problem", ex2);
            return false;
        }
    }
   
    private boolean fetchDBUser(String username) {
       
        List results = em.createQuery(
                "select u from User u where u.username=:username")
                .setParameter("username", username)
                .getResultList(); 
        if ( results.size()==0 ) {
            return false;
        } else {
            user = (User) results.get(0);
            return true;
        }
    }
   
   
    @Remove @Destroy
    public void destroy() {}
}




powered by performancing firefox


posted by warren Mar 01 2007, 10:36:53 AM MST Permalink Comments [1]

20070221 Wednesday February 21, 2007
Seam Security demo running on Glassfish


After a little hacking, I have the new JBoss Seam booking demo running under GlassFish. This is based on Seam 1.1.6GA and uses the new Seam security model (which looks very cool).

The sample source code that ships with the Seam 1.1.6 glassfish demo is missing some crucial settings:


I also reworked the demo to make it open as a Netbeans Enterprise project.  If you want to run this, you will need:


You can download the NetBeans project file at  http://mediacast.sun.com/share/warren/seamBooking.zip


You will need to define a few Libraries using the NetBeans library manager.  I wish there was a nice way of exporting library definitions in NetBeans - but until then I have resorted to the hack of packing up my library definitions from ~/.netbeans/....  as a zip file. If you are brave, you can try dropping these into your own private NetBeans library folder (after editing the library paths), or failing that, have a look at the xml defs and it should be fairly obvious which jar files you need to include. 

Here are the Netbeans library xml definitions: http://mediacast.sun.com/share/warren/SEAM-Libraries.zip


Enjoy





powered by performancing firefox


posted by warren Feb 21 2007, 04:35:52 PM MST Permalink Comments [2]

My Presentation from the Reboot Security and Privacy conference

A few folks asked for an electronic copy of my presentation (Identity Management Lessons learned) given at the reboot Security and Privacy conference.
You can download the OpenOffice format from here

posted by warren Feb 21 2007, 10:25:10 AM MST Permalink Comments [2]

20070212 Monday February 12, 2007
Buildix - project in a box


Those crafty ThoughtWorkers stole my idea! 

Buildix  provides a turnkey vmware image with all the goodies to kick start a development project, including subversion, a project wiki, a bug tracker,  and Cruise Control. 

In my humble experience, many organizations lack a basic project support infrastructure - and you often spend a couple of weeks pulling this stuff together. Buildix is going to be a huge time saver.   This is exactly the sweet spot for virtualization.



[PS: I'd love to see this running as a Xen image on OpenSolaris!]






powered by performancing firefox


posted by warren Feb 12 2007, 10:05:43 PM MST Permalink

20070211 Sunday February 11, 2007
i-Names


A nice introduction to i-Names can be found here http://www.xdi.org/i-names-explained.html


In a nutshell, an i-Name adds a level of indirection to an address. This is certainly an idea whose time has come. I have often wondered why the postal service has never adopted such a scheme?




powered by performancing firefox


posted by warren Feb 11 2007, 04:46:54 PM MST Permalink

20070106 Saturday January 06, 2007
Update: running SlimServer on Solaris


Eric Bautsch has kindly given me permission to post his latest updates for running slimserver on Solaris. He has made a few improvements over my previous scripts, so you might want to use these instead.


Here is a shell script used to build the slimserver distribution:

cd /usr/local
gunzip -c /sw/src/audio/slimserver/SlimServer_v6.5.0.tar.gz | tar xfv - \
        >> ${LOG} 2>&1
mv SlimServer_v6.5.0 slimserver >> ${LOG} 2>&1
mkdir /usr/local/slimserver/cachedir >> ${LOG} 2>&1
chown -R slimsrv:slimsrv slimserver >> ${LOG} 2>&1
cd slimserver/Bin >> ${LOG} 2>&1
export PATH=${PATH}:/opt/SUNWspro/bin:/usr/sfw/sbin
echo "/usr/bin/perl\n/usr/local/slimserver\n/tmp" | \
        ./build-perl-modules.pl >> ${LOG} 2>&1
cd /tmp/XML-Parser* >> ${LOG} 2>&1
perl Makefile.PL EXPATLIBPATH=/usr/sfw/lib EXPATINCPATH=/usr/sfw/include \
        >> ${LOG} 2>&1
cd /usr/local/slimserver/Bin >> ${LOG} 2>&1
echo "/usr/bin/perl\n/usr/local/slimserver\n/tmp" | \
        ./build-perl-modules.pl >> ${LOG} 2>&1
cp -p /sw/src/audio/slimserver/my.tt /usr/local/slimserver/MySQL >> ${LOG} 2>&1
cp -p /sw/src/audio/slimserver/slimrun /usr/local/slimserver >> ${LOG} 2>&1

svccfg import /sw/src/audio/slimserver/slimserver_manifest >> ${LOG} 2>&1
svcadm enable slimserver >> ${LOG} 2>&1

Note: The above double call of the build-perl-modules.pl with the manual build of XML-Parser was neccessary because XML parser requires expat but appears to be unable to pick up that it's in /usr/sfw, despite set PATH and LD_LIBRARY_PATH.

my.tt is simply modifed in that mysql provided in /usr/sfw does not like innodb, default-character-set and default-collation, so I have hashed these out.

slimrun is attached and simply sets the PATH to find mysqld prior to calling slimserver.



Here is the slimrun script:


#!/bin/sh

PATH=/usr/sbin:/usr/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/dt/bin:/usr/platform/i86pc/sbin:/usr/sfw/bin:/usr/sfw/sbin
export PATH

exec /usr/local/slimserver/slimserver.pl --cachedir=/usr/local/slimserver/cachedir --user=slimsrv --group=slimsrv --audiodir=/apps/jukebox/NEW/xmcd --prefsfile=/usr/local/slimserver/cachedir/slimserver.pref --pidfile=/usr/local/slimserver/cachedir/slimserver.pid $*





Here is the updated manifest

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='slimserver'>
  <service name='application/slimserver' type='service' version='1'>
        <create_default_instance enabled='false'/>
        <single_instance/>
<dependency name='name-services' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/milestone/name-services' />
</dependency>
<dependency name='network' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/milestone/network' />
</dependency>
<dependency name='local-filesystems' grouping='require_all' type='service' restart_on='none'>
<service_fmri value='svc:/system/filesystem/local' />
</dependency>
        <exec_method type='method' name='start'
                exec='/usr/local/slimserver/slimrun --daemon'
                timeout_seconds='30' />
        <exec_method type='method' name='stop'
         exec=':kill'
                timeout_seconds='30' />
        <stability value='Unstable' />
        <template>
               <common_name>
                        <loctext xml:lang='C'>Slim Server</loctext>
                </common_name>
                <documentation>
                        <doc_link name='SlimDevices Home' uri='http://www.slimdevices.com/'/>
                </documentation>
        </template>
  </service>
</service_bundle>





powered by performancing firefox


posted by warren Jan 06 2007, 12:53:36 PM MST Permalink