20110911

Blind Administration

A few weeks ago I've lost the ability to see any output form my MacBook Pro.

It was a second time. For the first time I had lost the embedded led display only.
The DVI output worked fine. Then came the healing power of promise - I have to buy a new one.
But threat without the coverage it's just the bucket of words.
The MBP makes me blind completely and definately. No video output. No remote access.
No working ssh daemon, no firewall access, no future.

I thought the target mode would be the cure.
I have PowerBook Pismo with Tiger onboard. Unfortunately, the data on MBP was encrypted with
a FileVault from Snow Leopard. Either try of target mode connection, or try of manual mount failed.

Collecting of the recipe components took me many hours, often filled with an exasperation.
Hidden typos. Invisible prompts. Lurking daemons.

The recipe.
It's here to remember. It's here to save other souls.

Power On.
Listen to chime and wait a few moments, then log in yourself:
username TAB
password

Open Applications
⌘+Shift+A
and invoke your favourite text terminal by typing its name, followed by CMD+O
i t e r m ⌘+O

Confirm you're in:
$ say ok
$ sudo su
> put your password <
Confirm your personality.
$ whoami | say
Let the dogs out. Select a race, choose wisely.
$ launchctl load -w /System/Library/LaunchDaemons/telnet.plist # enable configuration and
$ launchctl load -w /System/Library/LaunchDaemons/ssh.plist    # set Disable key to false
$ launchctl start com.apple.telnetd
$ launchctl start com.openssh.sshd
Check the locks.
$ defaults read /Library/Preferences/com.apple.alf globalstate | say
2
Firewall states
  • 0 - de-activated
  • 1 - on for specific services
  • 2 - on for essential services
Open the gates.
Pretty enough for older systems (Tiger), where no reboot required:
$ ipfw flush
> 'y' to flush <
$ ipfw list | say # 'any to any' means success
Permanent solution:
$ defaults write /Library/Preferences/com.apple.alf globalstate -int 0
$ reboot
Connect and enjoy it.

Mount USB Disk drive.
sh-3.2# diskutil list| grep SAM
   1:             Windows_FAT_32 SAMSUNG                 2.0 TB     disk2s1
sh-3.2# diskutil mountDisk SAMSUNG
Volume(s) mounted successfully
Rsync your secrets.

20110103

db2setup start failure on Debian/Ubuntu

Two late evenings of life - that was the time cost of the solution discovery.
I had tried to put the DB2 Express-C 9.7.2 on 64-bit Linux system, and I failed either on Ubuntu 8.04 LTS
or on Debian 5.0 (I know it is not recommended/supported solution).

The first and the last problem was related to the db2setup startup error.
It can be seen from the console just like that:

# ./db2setup
DBI1190I db2setup is preparing the DB2 Setup wizard which will guide
you through the program setup process. Please wait.


#

But, there was the trail in the error log:

# cd /tmp
# cat db2setup.err
Exception in thread "main" java.lang.UnsatisfiedLinkError: awt (An exception was pending after running JNI_OnLoad)
at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:998)
at java.lang.ClassLoader.loadLibraryWithClassLoader(ClassLoader.java:962)
at java.lang.System.loadLibrary(System.java:465)
at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:69)
at java.security.AccessController.doPrivileged(AccessController.java:202)
at java.awt.Toolkit.loadLibraries(Toolkit.java:1605)
at java.awt.Toolkit.(Toolkit.java:1627)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at java.awt.AWTEvent.(AWTEvent.java:220)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:37)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:122)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:920)
at java.lang.reflect.Field.getFieldAccessor(Field.java:901)
at java.lang.reflect.Field.get(Field.java:360)
at com.ibm.db2.tools.common.support.AssistManager.loadVKeys(Unknown Source)
at com.ibm.db2.tools.common.support.AssistManager.(Unknown Source)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at DB2Setup.(Unknown Source)
at DB2Setup.main(Unknown Source)
#

Let me start from the beginning.

# ./db2setup
WARNING:
Can't use string to find the version of libstdc++.
Check the following web site for the up-to-date system requirements
of IBM DB2 9.7
http://www.ibm.com/software/data/db2/udb/sysreqs.html
http://www.software.ibm.com/data/db2/linux/validate
The force option "-f sysreq" is used to force the installation ...

DBI1190I db2setup is preparing the DB2 Setup wizard which will guide
you through the program setup process. Please wait.



The DISPLAY variable is not set properly. Ensure that the DISPLAY variable is set properly and that permissions are set properly to open windows on the display specified, then rerun the command.
#

Even with the -f sysreq there was no visible progress.
Before the installation begins I have installed the libaio1 and libstdc++6 as it was mentioned in the online documentation.

The installation was on the remote server, so to verify that X11 session forwarding works fine I had to install xauth and use the ssh -Y option.

# xauth list
digestive.deadsystems.com/unix:10 MIT-MAGIC-COOKIE-1 a957c95c1c862f5314b32e88c5bd9e17
# echo $DISPLAY
localhost:10.0

I have used the xarclock to check that the remote app is being displayed fine on my laptop.

"Can't use string to find the version of libstdc++." -
it was resolved by simple binutils package installation (to get the strings binary).

But, there was no progress yet.

# ./db2setup
WARNING:
The 32 bit library file libstdc++.so.6 is not found on the system.
32-bit applications may be affected.
DBI1190I db2setup is preparing the DB2 Setup wizard which will guide
you through the program setup process. Please wait.


#

Then I thought that the /tmp/db2setup.err contains the java related exception, but there is no java vm on the machine.

# java -version
-ksh93: java: not found [No such file or directory]

After the sun-java6-jre installation there was still nothing more.

# java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)


A few search queries more and I have found a tip:

GUI applications, such as the JConsole monitoring tool, on 64-bit Ubuntu with a 32-bit JVM
When running a 32-bit JVM on a 64-bit Ubuntu system, GUI applications do not start because some AWT libraries are missing. To fix the problem, install the 32-bit libraries using the ia32-libs package:
sudo apt-get install ia32-libs
The following exception is thrown if the libraries are not available:
Exception in thread "main" java.lang.UnsatisfiedLinkError: awt (An exception was pending after running JNI_OnLoad)
at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:993)
at java.lang.ClassLoader.loadLibraryWithClassLoader(ClassLoader.java:962)
at java.lang.System.loadLibrary(System.java:465)
... lines removed for clarity ...
If problems are encountered with DNS name resolution, install the package lib32nss-mdns.

But neither ia32-libs nor lib32nss-mdns installation helped me to go further.
The only benefit was the lack of warning message:

WARNING:
The 32 bit library file libstdc++.so.6 is not found on the system.
32-bit applications may be affected.

Then It looked like:

# ./db2setup
DBI1190I db2setup is preparing the DB2 Setup wizard which will guide
you through the program setup process. Please wait.


#

After the additional few hours of digging through the differences between the library sets on two machines,
on which the first have the fully operational DB2 instances and the second is the reported unlucky node, I have pointed the main responsible for all the evil - there was no libxft2. After the apt-get install libxft2 - db2setup has raised from the ashes.

Enjoy.

20110101

Un-monit

Using the monit to look after the hosts and services, sometimes you need to stop watching a particular check.
The argument for unmonitor option is the process name or host name being monitored, ex.

# monit status
[...]
Remote Host 'eye0.deadsystems.com'
status Connection failed
monitoring status monitored
[...]

# monit unmonitor eye0.deadsystems.com
# monit summary
[...]
Process 'sshd' running
Remote Host 'eye0.deadsystems.com' not monitored
[...]

20100928

User passwords may not be provided in pre-encoded form

One of the very first differences between the OpenDS and DSEE I have noticed
was the possibility of ldapmodifing the userPassword value. In OpenDS this feature is disabled by default.


$ ldapmodify -p 1389 -D cn=dirmgr -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: modify
replace: userpassword
userpassword: {SSHA512}1g9Byn7MOZ1TgZCNY8gw4NA6o8UguyYg0b48d89zJS+AyIs9OP2rHfbZ6aaqTluryTh3Ux1ZW5RSWuTjH9wvtBxFXCxJzyt0

Processing MODIFY request for cn=odsmgr,cn=Root DNs,cn=config
MODIFY operation failed
Result Code: 53 (Unwilling to Perform)
Additional Information: User passwords may not be provided in pre-encoded form

$ ldapsearch -p 1389 -D cn=dirmgr -j ~/.odspwd -b cn=config "cn=Default Password Policy" ds-cfg-allow-pre-encoded-passwords
dn: cn=Default Password Policy,cn=Password Policies,cn=config
ds-cfg-allow-pre-encoded-passwords: false

$ ldapsearch -p 1389 -D cn=dirmgr -j ~/.odspwd -b cn=config "cn=Root Password Policy" ds-cfg-allow-pre-encoded-passwords
dn: cn=Root Password Policy,cn=Password Policies,cn=config
ds-cfg-allow-pre-encoded-passwords: false


I do not know the pro and con voices in this discussion, but for me there is only one disadvantage - the ability to observe
multiple instances of the same encoded password strings. And it is only the risk when the one who would notice this fact is the bad guy.
In contrast I see only the advantages.
So...

dn: cn=Root Password Policy,cn=Password Policies,cn=config
changetype: modify
replace: ds-cfg-allow-pre-encoded-passwords
ds-cfg-allow-pre-encoded-passwords: true

LDIF has been implemented.

$ encode-password -s SSHA512 -f ~/.odspwd
Encoded Password: "{SSHA512}Gur7YkCGk4oP2sun+KqpXF4rB9wmzUgjhb3P6hBNmNRLBBQgTxSwLR5WuO41yytG9sUzslYc2HyUAM1otujRW+UkAOapbB7c"

$ ldapmodify -p 1389 -D cn=dirmgr -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: modify
replace: userpassword
userpassword: {SSHA512}Gur7YkCGk4oP2sun+KqpXF4rB9wmzUgjhb3P6hBNmNRLBBQgTxSwLR5WuO41yytG9sUzslYc2HyUAM1otujRW+UkAOapbB7c

Processing MODIFY request for cn=odsmgr,cn=Root DNs,cn=config
MODIFY operation successful for DN cn=odsmgr,cn=Root DNs,cn=config

$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.dspwd -b cn=config "cn=odsmgr" +
The simple bind attempt failed
Result Code: 49 (Invalid Credentials)
$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.odspwd -b cn=config "cn=odsmgr" +
dn: cn=odsmgr,cn=Root DNs,cn=config
modifiersName: cn=Directory Manager,cn=Root DNs,cn=config
modifyTimestamp: 20100927104857Z
createTimestamp: 20100924124513Z
pwdChangedTime: 20100927104857.435Z
creatorsName: cn=Directory Manager,cn=Root DNs,cn=config
entryDN: cn=odsmgr,cn=root dns,cn=config
entryUUID: 99296ddd-e705-468b-8112-afd19bb38821
hasSubordinates: false
subschemaSubentry: cn=schema
ds-pwp-password-policy-dn: cn=Root Password Policy,cn=Password Policies,cn=confi
g
structuralObjectClass: inetOrgPerson
numSubordinates: 0

20100926

Directory Managers. Lots of Directory Managers.

Last week I have decided to take some OpenDS practise. The practical solving of a problem is better
then hundreds lines of reading about the others activity. At least that's the way I feel.
Task: Multiple the Directory Manager account to delegate administration without providing your secret password.

In theory it is possible without any problems.
The only requirement is the object class of ds-cfg-root-dn-user.
I have copied almost the all attributes from the current "root" account into a new one.

$ ldapsearch -p 1389 -D cn=dirmgr -j ~/.odspwd -b cn=config "cn=Directory Manager"
dn: cn=Directory Manager,cn=Root DNs,cn=config
sn: Manager
ds-cfg-alternate-bind-dn: cn=dirmgr
cn: Directory Manager
givenName: Directory
objectClass: ds-cfg-root-dn-user
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
userpassword: {SSHA512}1g9Byn7MOZ1TgZCNY8gw4NA6o8UguyYg0b48d89zJS+AyIs9OP2rHfbZ6
aaqTluryTh3Ux1ZW5RSWuTjH9wvtBxFXCxJzyt0


$ ldapmodify -p 1389 -D cn=dirmgr -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: add
objectClass: ds-cfg-root-dn-user
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
cn: odsmgr
givenName: ODS
sn: Manager
userPAssword: secret

Processing ADD request for cn=odsmgr,cn=Root DNs,cn=config
ADD operation successful for DN cn=odsmgr,cn=Root DNs,cn=config

For the initial testing I have duplicated also the password.

$ ldappasswordmodify -p 1389 -D "cn=dirmgr" -j ~/.odspwd \
> -a "dn:cn=odsmgr,cn=Root DNs,cn=config" -c secret -N ~/.odspwd
The LDAP password modify operation was successful


During the cut'n'copy session of ldapmodify I have omitted ds-cfg-alternate-bind-dn intentionally.
I thought the adjective "alternate" is self-explanatory.
Wrong!

$ ldapsearch -p 1389 -D cn=odsmgr -j ~/.odspwd -b cn=config cn=odsmgr
The simple bind attempt failed
Result Code: 49 (Invalid Credentials)

$ ldapmodify -p 1389 -D "cn=dirmgr" -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: modify
add: ds-cfg-alternate-bind-dn
ds-cfg-alternate-bind-dn: cn=odsmgr

Processing MODIFY request for cn=odsmgr,cn=Root DNs,cn=config
MODIFY operation successful for DN cn=odsmgr,cn=Root DNs,cn=config

$ ldapsearch -p 1389 -D cn=odsmgr -j ~/.odspwd -b cn=config cn=odsmgr
dn: cn=odsmgr,cn=Root DNs,cn=config
sn: Manager
ds-cfg-alternate-bind-dn: cn=odsmgr
cn: odsmgr
givenName: ODS
objectClass: top
objectClass: ds-cfg-root-dn-user
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: person
userPassword: {SSHA}gF7nQ6N6gmpuufM1/8FemlwH1/HikScaVOlP3Q==

Why not to test a case with multiple ds-cfg-alternate-bind-dn attibute values.

$ ldapmodify -p 1389 -D "cn=dirmgr" -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: modify
add: ds-cfg-alternate-bind-dn
ds-cfg-alternate-bind-dn: cn=dsmgr

Processing MODIFY request for cn=odsmgr,cn=Root DNs,cn=config
MODIFY operation successful for DN cn=odsmgr,cn=Root DNs,cn=config

$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.odspwd -b cn=config cn=odsmgr
dn: cn=odsmgr,cn=Root DNs,cn=config
ds-cfg-alternate-bind-dn: cn=odsmgr
ds-cfg-alternate-bind-dn: cn=dsmgr
sn: Manager
cn: odsmgr
givenName: ODS
objectClass: ds-cfg-root-dn-user
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
userPassword: {SSHA}gF7nQ6N6gmpuufM1/8FemlwH1/HikScaVOlP3Q==

But wait a minute. Why the userPassword value is encoded with a SSHA password scheme, while
the Directory Manager and the default root scheme is pointing to SSHA512.

$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.odspwd -b cn=config cn="Directory Manager" userpassword
dn: cn=Directory Manager,cn=Root DNs,cn=config
userpassword: {SSHA512}1g9Byn7MOZ1TgZCNY8gw4NA6o8UguyYg0b48d89zJS+AyIs9OP2rHfbZ6
aaqTluryTh3Ux1ZW5RSWuTjH9wvtBxFXCxJzyt0

$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.dspwd -b cn=config "cn=Root Password Policy" \
> ds-cfg-default-password-storage-scheme
dn: cn=Root Password Policy,cn=Password Policies,cn=config
ds-cfg-default-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Sc
hemes,cn=config

The answer has come with the hint from Ludovic Poitou.
The virtual attribute of ds-pwp-password-policy-dn should be set explicitly.

$ ldapmodify -p 1389 -D cn=dsmgr -j ~/.odspwd
dn: cn=odsmgr,cn=Root DNs,cn=config
changetype: modify
add: ds-pwp-password-policy-dn
ds-pwp-password-policy-dn: cn=Root Password Policy,cn=Password Policies,cn=config

Processing MODIFY request for cn=odsmgr,cn=Root DNs,cn=config
MODIFY operation successful for DN cn=odsmgr,cn=Root DNs,cn=config

$ openssl rand -base64 12 > ~/.dspwd

$ ldappasswordmodify -p 1389 -D cn=dsmgr -j ~/.odspwd -a "cn=odsmgr,cn=Root DNs,cn=config" \
> -C ~/.odspwd -N ~/.dspwd
The LDAP password modify operation was successful

$ ldapsearch -p 1389 -D cn=dsmgr -j ~/.dspwd -b cn=config cn=odsmgr userpassword
dn: cn=odsmgr,cn=Root DNs,cn=config
userpassword: {SSHA512}BxvZzrhuVpwOv6FMc9sI1infjPC7PQ0dXXdry4ZLNgq6FJbjCVfSiLwBO
A1uzaXAscS7pkNbfkP4hG11L9DTPsRfpusta+4x

Nice.

20100921

Custom Service Packages

During each subsequent comms implementation I forget one or more steps from the following recipe.
So, here comes the milestones to remember.
For the complete documentation refer to the wikis.sun.com.

Template for basic set of packages - da.cos.skeleton.ldif can be found in directory:
/opt/sun/comms/da/lib/config-templates/
on Delegated Administrator default installation path.

Usually I use only the packages for MailUser, MailCalendarUser and MailGroup.
After the customization the file might look like:

dn: cn=wisniosMailUser,o=mailuser,o=cosTemplates,o=root
changetype: add
objectclass: top
objectclass: LDAPsubentry
objectclass: extensibleobject
objectclass: cosTemplate
cn: wisniosMailUser
mailMsgMaxBlocks: 5000
mailAllowedServiceAccess: +imap,imaps,pop,pops,smtp,smtps,http,smime:ALL
daServiceType: mail user

dn: cn=wisniosMailCalendarUser,o=mailcalendaruser,o=cosTemplates,o=root
changetype: add
objectclass: top
objectclass: LDAPsubentry
objectclass: extensibleobject
objectclass: cosTemplate
cn: wisniosMailCalendarUser
mailMsgMaxBlocks: 5000
mailAllowedServiceAccess: +imap,imaps,pop,pops,smtp,smtps,http,smime:ALL
daServiceType: calendar user
daServiceType: mail user

dn: cn=wisniosMailGroup,o=mailgroup,o=cosTemplates,o=root
changetype: add
objectclass: top
objectclass: LDAPsubentry
objectclass: extensibleobject
objectclass: cosTemplate
cn: wisniosMailGroup
mailMsgMaxBlocks: 5000
daServiceType: mail group


Dry run:

# ldapmodify -p 1389 -D cn=dirmgr -j /root/.dspwd -n -f da.cos.wisnios.ldif
!adding new entry cn=wisniosMailUser,o=mailuser,o=cosTemplates,o=root

!adding new entry cn=wisniosMailCalendarUser,o=mailcalendaruser,o=cosTemplates,o=root

!adding new entry cn=wisniosMailGroup,o=mailgroup,o=cosTemplates,o=root

Wet run:

# ldapmodify -p 1389 -D cn=dirmgr -j /root/.dspwd -f da.cos.wisnios.ldif
adding new entry cn=wisniosMailUser,o=mailuser,o=cosTemplates,o=root

adding new entry cn=wisniosMailCalendarUser,o=mailcalendaruser,o=cosTemplates,o=root

adding new entry cn=wisniosMailGroup,o=mailgroup,o=cosTemplates,o=root

Check:

# ldapsearch -p 1389 -D cn=dirmgr -j /root/.dspwd -b o=cosTemplates,o=root \
> "(&(cn=wisnios*)(objectclass=LDAPsubentry))" daServiceType
version: 1
dn: cn=wisniosMailUser,o=mailuser,o=cosTemplates,o=root
daServiceType: mail user

dn: cn=wisniosMailCalendarUser,o=mailcalendaruser,o=cosTemplates,o=root
daServiceType: calendar user
daServiceType: mail user

dn: cn=wisniosMailGroup,o=mailgroup,o=cosTemplates,o=root
daServiceType: mail group

To make sure that the changes (packages) will be visible restart the app/web container.

20100908

How to automate the SpamAssassin feeding

This post is my answer to the Sun Wikis' entry about Enabling Anti-Spam functionality in Convergence.

Technologies used:
Messaging Server
SpamAssassin
RBAC - execution profiles

Messaging Server use the two variables to hold the email accounts for feeding anti-spam system
with the positive and false positive spam messages:

  • service.feedback.spam

  • service.feedback.notspam


But there is no embedded mechanism to deal with them.
Here comes my solution.

Every time the Convergence user marks the spam (ot not spam), with the appropriate button from its interface,
the mail is being sent to the address provided within the configuration.
The email messages accumulate in the accounts and waiting for the action.

Scenario:

  • fetching messages from spam account

  • teaching spamassassin with spam

  • cleaing INBOX folder

  • fetching messages from notspam account

  • teaching SA with ham

  • cleaning account



Methods:

  • fetching messages from spam account


    1. imsexport


  • teaching spamassassin with spam


    1. sa-learn --spam


  • cleaing INBOX folder


    1. mboxutil -d

    2. mboxutil -c


  • fetching messages from notspam account


    1. imsexport


  • teaching SA with ham


    1. sa-learn --ham


  • cleaning account


    1. mboxutil -d

    2. mboxutil -c



Due to a fact the script will be invoked by root account, to get the access either to imsexport files or sa-learn with valid Bayes DB,
I have decided to use one of the Solaris RBAC mechanisms - profiles.

I would not describe the profile creation step-by-step, because the learning by example is much more valuable.

# /usr/sadm/bin/smexec add -H localhost -u root -- \
-n "SpamAssassin Administration" -t cmd -c /export/home/sa/bin/sa-learn -U 105 -G 102
Authenticating as user: root

Type /? for help, pressing accepts the default denoted by [ ]
Please enter a string value for: password ::
There is no Solaris Management Console Server running on localhost.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\
# svcadm enable wbem

# /usr/sadm/bin/smexec add -H localhost -u root -- \
-n "SpamAssassin Administration" -t cmd -c /export/home/sa/bin/sa-learn -U 105 -G 102
Authenticating as user: root

Type /? for help, pressing accepts the default denoted by [ ]
Please enter a string value for: password ::
Loading Tool: com.sun.admin.usermgr.cli.execs.UserMgrExecCli from localhost
Login to localhost as user root was successful.
Download of com.sun.admin.usermgr.cli.execs.UserMgrExecCli from localhost was successful.
You have entered a non-existent right SpamAssassin Administration.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\
# cd /usr/lib/help/profiles/locale/C
# cat RtSAAdmin.html
< HTML >
< HEAD >
< TITLE >< /TITLE >
< /HEAD >
< BODY >
SpamAssassin Administration right allows the user or role SA management.
< /BODY >
< /HTML >

^^^^^
Spaces has been added to HTML tags in due to blogspot problems with handling this kind of stuff within the post body.

# /usr/sadm/bin/smprofile add -H localhost -u root -- \
-n "SpamAssassin Administration" -d "Manage SpamAssassin" -m RtSAAdmin.html
Authenticating as user: root

Type /? for help, pressing accepts the default denoted by [ ]
Please enter a string value for: password ::
Loading Tool: com.sun.admin.usermgr.cli.profile.UserMgrProfCli from localhost
Login to localhost as user root was successful.
Download of com.sun.admin.usermgr.cli.profile.UserMgrProfCli from localhost was successful.

# tail -1 /etc/security/prof_attr
SpamAssassin Administration:::Manage SpamAssassin:help=RtSAAdmin.html

# /usr/sadm/bin/smexec add -H localhost -u root -- \
-n "SpamAssassin Administration" -t cmd -c /export/home/sa/bin/sa-learn -U 105 -G 102
Authenticating as user: root

Type /? for help, pressing accepts the default denoted by [ ]
Please enter a string value for: password ::
Loading Tool: com.sun.admin.usermgr.cli.execs.UserMgrExecCli from localhost
Login to localhost as user root was successful.
Download of com.sun.admin.usermgr.cli.execs.UserMgrExecCli from localhost was successful.

# tail -1 /etc/security/exec_attr
SpamAssassin Administration:solaris:cmd:::/export/home/sa/bin/sa-learn:uid=105;gid=102


So, running sa-learn by the user / role with "SpamAssassin Administration" profile assigned
allow access to bayes DB files with the proper rights.
Examples can be seen in the script code provided below.


#!/usr/bin/ksh
#------------------------------------
# sa-feed.ksh
# feed SpamAssassin with {NOT}SPAM
# from file in mbox format
#====================================
# author: Marcin Wisnios
# e-mail: wisnios at wisnios dot com
#------------------------------------
PATH=$PATH:/opt/sun/comms/messaging64/bin:/export/home/sa/bin

TDIR=$(mktemp -td) # temporary directory
FILE=$TDIR/INBOX # mbox file
MUSR=$(ps -o user -p $(pgrep -nf dispatcher) | tail -1) # messaging server runtime user
SUSR=$(ps -o user -p $(pgrep -nf spamd) | tail -1) # spamassassin runtime user
SPAM=$(configutil -o service.feedback.spam) # feedback account for spam
NOTSPAM=$(configutil -o service.feedback.notspam) # feedback account for not spam
BDBL=/export/home/sa/.spamassassin # Bayes DB location
SALEARN="pfexec sa-learn --dbpath $BDBL" # fixed part of sa-learn invocation

chown $MUSR $TDIR
chmod 0755 $TDIR

imsexport -s INBOX -d $TDIR -u $SPAM


[ -f $FILE ] && {
chown $SUSR $FILE

NSPAM_BEFORE=$($SALEARN --dump magic 2> /dev/null | grep nspam | awk '{print $3}')
$SALEARN --mbox --spam $FILE 2> /dev/null &&\
NSPAM_AFTER=$($SALEARN --dump magic 2> /dev/null | grep nspam | awk '{print $3}')

[ $NSPAM_BEFORE -lt $NSPAM_AFTER ] && {
mboxutil -d user/$SPAM/INBOX
mboxutil -c user/$SPAM/INBOX
}

rm $FILE
}

imsexport -s INBOX -d $TDIR -u $NOTSPAM

[ -f $FILE ] && {
chown $SUSR $FILE

NHAM_BEFORE=$($SALEARN --dump magic 2> /dev/null | grep nham | awk '{print $3}')
$SALEARN --mbox --ham $FILE 2> /dev/null &&\
NHAM_AFTER=$($SALEARN --dump magic 2> /dev/null | grep nham | awk '{print $3}')

[ $NHAM_BEFORE -lt $NHAM_AFTER ] && {
mboxutil -d user/$NOTSPAM/INBOX
mboxutil -c user/$NOTSPAM/INBOX
}
}

[ -d $TDIR ] && rm -rf $TDIR


Run the script in a way you like.
I put it directly to a crontab. Root's crontab.

Enjoy.

20100625

crle and missing libusb.so.1 library

Today I have installed SpamAssassin from a tar.gz archive on Solaris 10 10/09.
Though everything looked fine I faced the problem with invocation of sa-update - SpamAssassin rules updater.

$ sa-update
ld.so.1: gpg: fatal: libusb.so.1: open failed: No such file or directory
Killed
ld.so.1: gpg: fatal: libusb.so.1: open failed: No such file or directory
Killed
error: GPG validation failed!
The update downloaded successfully, but the GPG signature verification
failed.
channel: GPG validation failed, channel failed
$ gpg
ld.so.1: gpg: fatal: libusb.so.1: open failed: No such file or directory
Killed

(gnupg has been installed from a package from sunfreeware.com, but it was not a problem)

Quick truss session:

# truss gpg
[...]
stat64("/usr/local/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/local/ssl/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/openwin/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/X11R6/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/local/BerkeleyDB.4.7/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
stat64("/usr/lib/libusb.so.1", 0x080473A0) Err#2 ENOENT
ld.so.1: gpg: fatal: libusb.so.1: open failed: No such file or directory
[...]

find lookup:

# find /usr -name libusb.so.1
/usr/sfw/lib/libusb.so.1

...and I had to change the default library path.
The tool - crle - runtime linking environment configurator, was taken as the only fair solution.
Do not want to reproduce the manual pages, so, below is the syntax I had used.
Checking the current options:

# crle

Configuration file [version 4]: /var/ld/ld.config
Default Library Path (ELF): /lib:/usr/lib (system default)
Trusted Directories (ELF): /usr/lib/secure:/opt/sun/comms/calendar/SUNWics5/cal/lib

Command line:
crle -c /var/ld/ld.config -s /usr/lib/secure:/opt/sun/comms/calendar/SUNWics5/cal/lib


Complementation of default library path:

# crle -c /var/ld/ld.config -l /lib:/usr/lib:/usr/sfw/lib -s /usr/lib/secure:/opt/sun/comms/calendar/SUNWics5/cal/lib

[CHECK]
# crle
Configuration file [version 4]: /var/ld/ld.config
Default Library Path (ELF): /lib:/usr/lib:/usr/sfw/lib
Trusted Directories (ELF): /usr/lib/secure:/opt/sun/comms/calendar/SUNWics5/cal/lib

Command line:
crle -c /var/ld/ld.config -l /lib:/usr/lib:/usr/sfw/lib -s /usr/lib/secure:/opt/sun/comms/calendar/SUNWics5/cal/lib
# exit
$ gpg
gpg: WARNING: using insecure memory!
gpg: please see http://www.gnupg.org/faq.html for more information
gpg: directory `/export/home/sa/.gnupg' created
gpg: new configuration file `/export/home/sa/.gnupg/gpg.conf' created
gpg: WARNING: options in `/export/home/sa/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/export/home/sa/.gnupg/secring.gpg' created
gpg: keyring `/export/home/sa/.gnupg/pubring.gpg' created
gpg: Go ahead and type your message ...
^C
gpg: signal 2 caught ... exiting
$ sa-update
gpg: WARNING: using insecure memory!
gpg: please see http://www.gnupg.org/faq.html for more information
$


Final notes
The syntax being used could be shortened to a form of:

# crle -u -l /usr/sfw/lib

where -u stands for existing configuration (file /var/ld/ld.config) update.
But be aware that by omitting the -u argument you turn your box into soldered fish tin, until you turn the other directories to the default path.

# crle -l /usr/sfw/lib
# init
ld.so.1: init: fatal: libpam.so.1: open failed: No such file or directory
Killed
# crle -u -l /lib -l /usr/lib -l /usr/sfw/lib
# init
Usage: init [0123456SsQqabc]
#

20100607

svclog

Everytime I have to check the SMF log file quickly I suffer.
I suffer in due to lack of simple method which I would provide you today with.

C'n'P:

#!/usr/bin/ksh
#------------------------------------
# svclog
# ...run for your logs
#====================================
# author: Marcin Wisnios
# e-mail: wisnios at wisnios dot com
#------------------------------------

svcs $1 > /dev/null 2>&1
if [ $? -eq 1 ]; then
echo "No match."
exit
fi

if [ ! -z $1 ]; then
LOG=$(svcs -l $1 | sed 's/logfile[ ]*\(.*\)/\1/p;d')
echo "\n\t\t${LOG}\n"
else
echo "Usage: $0 FMRI [n]"
echo "n - number of lines to display"
exit
fi

if [ ! -z $2 ]; then
tail -$2 ${LOG}
else
tail -f ${LOG}
fi

Save as, for ex. /usr/local/bin/svclog and... run for your logs:

# svclog ds 3

/var/svc/log/application-sun-ds:default.log

Waiting for Directory Server instance '/instances/ds1' to start...
Directory Server instance '/instances/ds1' started: pid=434
[ Jun 7 16:53:00 Method "start" exited with status 0 ]
# svclog ms

/var/svc/log/application-sun-ms:default.log

Stopping dispatcher server 593 ... done
Stopping sched server 591 ... done
Stopping http server 590 ... done
Stopping pop server 589 ...... done
Stopping imap server 588 ... done
Stopping purge server 587 ... done
Stopping store server 584 .... done
Stopping watcher 583 ... done
[ Jun 7 23:40:12 Method "stop" exited with status 0 ]
[ Jun 7 23:40:12 Executing start method ("/opt/sun/comms/messaging64/bin/start-msg") ]
Connecting to watcher ...
Launching watcher ... 1463
Starting store server .... 1464
Checking store server status .....
- CUT -

Enjoy.

20100525

fc-fabric(ation) of server's dysfunction

Do you like minimization? I do.
But sometimes you can go one bridge too far.

Today I have switched off the set of useless services.
One after one...
Do I need... No!
Do I need... No!
Do I need Fibre Channel Fabric device support? No.

$ svcadm disable fc-fabric

Another one bites the dust.

After the couple of hours I decided to reboot the server to check its readiness to serve.
And... it failed.



Of course at the moment of failure I dit not realize it was caused by service unavailability of fc-fabric.
Unnecessary stress.

The solution has been revealed during the dependencies check.



Keep this in mind.

20100429

AIX backup / restore

The commonly used mode of backup utility back up file systems by i-node. It uses the Level param of 0 - for full,
1 to 9 for incremental backups, and takes the predefined fileset as input (/, /home, /opt, /usr, /var, etc.).
If you want to use the ordinary directory, not the one of predefined filesets use the -i switch.
It takes the list of files from the standard input (back up by name), and when used in conjunction with hyphen sign
as the target device, it can be piped directly to dd, to put the output into the file.

$ find /etc | backup -i -f - | dd of=/backup/etc.bak

To list the content of backup archive use restore with the -T switch.

$ restore -Tq -f /backup/etc.bak

To restore the individually named file use -x switch.

# restore -xqf /backup/etc.bak /etc/passwd
x /etc/passwd

...or files (in verbose mode):

# restore -xqvf /backup/etc.bak /etc/passwd /etc/security/passwd
New volume on /backup/etc.bak:
Cluster 51200 bytes (100 blocks).
Volume number 1
Date of backup: Thu Apr 29 12:22:13 2010
Files backed up by name
User root
x 560 /etc/passwd
x 288 /etc/security/passwd
total size: 848
files restored: 2

And to get back all the content of the specified subdirectory use the force of -d

# restore -xqdf /backup/etc.bak /etc/security
x /etc/security
x /etc/security/.idlck
x /etc/security/.ids
x /etc/security/.kst
x /etc/security/.profile
x /etc/security/acl
x /etc/security/aixpert
x /etc/security/aixpert/bin
x /etc/security/aixpert/bin/ISSServerSensor
x /etc/security/aixpert/bin/audit_report
x /etc/security/aixpert/bin/binaudit
[...]


Be aware that all the above actions has overwritten the original files.

20100427

mktemp portability

If you ever need to create a script, to run in the closest possible way in all the unix flavours -
beware of HP-UX behaviour of mktemp command.

It is the only unix system (I know) where mktemp do not create randomly named file/directory.

The result of its actions is just a display of generated name.

Silence is golden


$ touch .hushlogin

20100309

User interface error

Have you ever encountered similar problems during the n-time tryout of the SSL signing process?

# openssl rsa -in cakey.pem -out cakey.pem
Enter pass phrase for cakey.pem:
User interface error
unable to load Private Key
26116:error:0906A068:PEM routines:PEM_do_header:bad password read:pem_lib.c:403:

or...

# ./CA.pl -sign
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
User interface error
unable to load CA private key
26676:error:0906A068:PEM routines:PEM_do_header:bad password read:pem_lib.c:403:
Signed certificate is in newcert.pem

This is a single-echo-pill solution.

ad. 1

# echo | openssl rsa -in cakey.pem -out cakey.pem
Enter pass phrase for cakey.pem:
writing RSA key

ad. 2

# printf "y\ny\n"| ./CA.pl -sign
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
[...]
Sign the certificate? [y/n]:

1 out of 1 certificate requests certified, commit? [y/n]Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem

Enjoy.

20100303

maximum number of instances of the package

Sometimes there is a need of existence of concurrent versions of the same package.
It is not a issue why, but how to achieve this behaviour.

During the normal installation procedure of the package, with the same name but different version then already installed one,
there is a chance to see a similar message:

# pkgadd -d somepkg*dstream
[...]
Current administration requires that a unique instance of the
<somepkg> package be created. However, the maximum number of
instances of the package which may be supported at one time on the
same system has already been met.

No changes were made to the system.

To resolve the conflict change the value of MAXINST variable from inside the pkginfo file
(during the package build process).

For example, to allow the coexistence of maximum number of two packages use the following:

MAXINST=2


# pkgadd -d somepkg*dstream
[...]

Installation of <somepkg.2> was successful.

20100225

E.T. call ~home

After many years of unix systems administration, it is a pure pleasure to discover the trick
as simple as displaying the user home directory with ~username.

Examples:

$ echo ~adm
/var/adm
$ echo ~listen
/usr/net/nls
$ echo ~wisnios
/home/wisnios

20100212

digression

command+shift+L rise a google search window with the results of the selected-piece-of-text query.
Piękne. It's beautiful.

20100119

substitute multiple line pattern in sed

Today I faced a problem with a multiline replacement. I did not want to write a sophisticated regex.
I just wanted to get a copy-pasted block of code and put it in place of the old one. Selected weapon - sed.
I've chosen the /begin/,/end/ matching syntax.

['test' input file]

111
222
333
if (aaa) {
bbbbb
}xxx
}
444
while (0) {
ccccc
}
666


['change' script]

#!/usr/bin/ksh

sed '
/if (aaa)/,/\ }$/ c\
CHANGE\
WAS\
MADE
' \
test


[session]

$ ./change
111
222
333
CHANGE
WAS
MADE
444
while (0) {
ccccc
}
666

20091222

MakeLDIF.jar

Yesterday I have realized that I do not remember how to prepare the ldif file. But not just a simple ldif with a few lines of add/modify/delete subcommands. I have forgotten how to use the SLAMD project's tool - MakeLDIF. As far as I remember there was the jar - MakeLDIF. It was, but now there is not. It had taken a few moments before I found the solution. Here you go:

$ find . -name *.jar | grep -i make
$ cd tools/MakeLDIF
$ perl -e 's/(^define suffix=).*/\1o=ods/' -pi example.template
$ perl -e 's/(^define numusers)=.*/\1=1000/' -pi exa*
$ perl -e 's/(^define maildomain)=.*/\1=wisnios\.com/' -pi exa*
$ head -3 exa*
define suffix=o=ods
define maildomain=wisnios.com
define numusers=1000
$ cd ..
$ ./make-ldif.sh -t MakeLDIF/example.template -o ~/ods1k.ldif
Processed 1000 entries
Processing complete.
1002 total entries written.

And the process view of similar command execution:

/usr/jdk/instances/jdk1.5.0/bin/java -server -Xms512m -Xmx512m com.slamd.tools.makeldif.MakeLDIF
-r /export/home/slamd200-20090712/tools/MakeLDIF -t /tmp/ods.template -o /tmp/ods100k.ldif

Merry Xmas!

20091208

AIX stat equivalent


$ istat /usr/sbin/lsuser
Inode 115447 on device 10/5 File
Protection: r-xr-xr-x Set UID
Owner: 0(root) Group: 7(security)
Link count: 1 Length 84080 bytes

Last updated: Tue Dec 8 14:40:33 CST 2009
Last modified: Mon Mar 30 00:45:51 CDT 2009
Last accessed: Tue Dec 8 16:55:55 CST 2009


* lsuser hint
To display the attributes of all the users, use the ALL keyword:

$ lsuser ALL