Home > Articles > Operating Systems, Server > Solaris

  • Print
  • + Share This
Like this article? We recommend

Testing the Code

Now let's test the code and play with some commands. Before testing the code, remember to enable the plug-in LOG level in the LDAP server, from the administrator's console or from the command line as follows:

CODE EXAMPLE 13 Enabling the Plug-In Log Level

<sunone slapd-sunblueprints>~$ ldapmodify -p 10389 -D "cn=Directory Manager" -w manager0
dn: cn=config
changetype: modify
replace: nsslapd-infolog-area
nsslapd-infolog-area: 65536
^D

Let's try a UNIX command. The language is defined to accept UNIX escape commands such as the following:

! pwd \;
! man cat \;

Many UNIX programs support this useful feature (for example, mail, vi).

The following example executes two commands. Notice that the ! escape symbol is expected at beginning of the line and a terminating '\;' sequence is required. Refer to the triggers.l file and the LEXer specification file for the lexical details of the language.

CODE EXAMPLE 14 Executing Commands

triggers>> !uname -a \;
! man pwd \;
.
Calling extended operation 4.3.2.1
------------- Your input ----------------
!uname -a \;
! man pwd \;

.
-----------------------------------------

------------- Server output ----------------
Statement #0
Error code: 0
Error msg: Unix shell command successfully executed
Linux alfa 2.4.18-3 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown

Statement #1
Error code: 0
Error msg: Unix shell command successfully executed
PWD(1)                           PWD(1)



NOME
    pwd - stampa il nome della directory di lavoro corrente

SINTASSI
    pwd
    pwd {--help,--version}

DESCRIZIONE
    Questa documentazione non ? mantenuta da lungo tempo e
    potrebbe essere inaccurata o incompleta. La documentazione
    in Texinfo ? ora la fonte autorevole.

    Questa pagina di manuale documenta la versione GNU di pwd.
    pwd stampa il nome della directory corrente risolvendolo
    completamente.  Cio?, tutte le componenti del nome stam-
    pato saranno nomi di directory reali -- nessuna sar? un
    link simbolico.

    Si noti che molte shell Unix forniscono un proprio comando
    pwd interno con funzionalit? simili cosicch? il semplice,
    interattivo comando pwd di solito eseguito sar? quello
    della shell e non questo.

  OPZIONI
    --help Mostra nello standard output un messaggio d'aiuto
       ed esce con successo.

    --version
       Mostra nello standard output informazioni sulla
       versione ed esce con successo.


FSF          GNU Shell Utilities         PWD(1)

--------------------------------------------
Triggers Client
Insert your commands, a line with '.' terminates input

We executed the commands uname -a and man pwd. Both are executed on the server, where Sun Java System Directory Server and the extended operation run. You could use this feature for a minimal remote administration if you like, but our goal was just to show an advanced use of the extended operation. Consider also that this kind of feature could introduce serious security concerns, especially if the remote server runs with root account privileges.

Now let's review the log error file to determine what happened.

CODE EXAMPLE 15 Reviewing the Log File

[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_service_fn - conn=2 op=1 msgId=1 - Entering pb=0x8354d60
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_service_fn - conn=2 op=1 msgId=1 - Request with OID: 4.3.2.1 Value from client: !uname -a \;
! man pwd \;
.
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_parse_client_req - conn=2 op=1 msgId=1 - Entering with params(0x8354d60,0x8118348,0x42b796fc)
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_parse_client_req - conn=2 op=1 msgId=1 - Creating the temporary file for parsing
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_parse_client_req - conn=2 op=1 msgId=1 - Opening the temporary file for parsing
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_parse_client_req - conn=2 op=1 msgId=1 - <<!uname -a \;
! man pwd \;

.>>
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_parse_client_req - conn=2 op=1 msgId=1 - Now parsing...
[..cut...]
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_apply_statements: - conn=2 op=1 msgId=1 - trg_apply_statements(0x8354d60,0x42b796fc, 0x43d1191c)
[...cut..]
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_execute_unixcmd - conn=2 op=1 msgId=1 - Entering (index=0)
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_execute_unixcmd - conn=2 op=1 msgId=1 - Returning
[20/Oct/2003:01:47:58 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_execute_unixcmd - conn=2 op=1 msgId=1 - Entering (index=1)
[20/Oct/2003:01:47:59 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_execute_unixcmd - conn=2 op=1 msgId=1 - Returning
[20/Oct/2003:01:47:59 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_apply_statements: - conn=2 op=1 msgId=1 - Returning 0
[20/Oct/2003:01:47:59 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_service_fn - conn=2 op=1 msgId=1 - Client statements executed
[20/Oct/2003:01:47:59 +0200] - INFORMATION - (PID=3018,ThID=13325) trg_service_fn - conn=2 op=1 msgId=1 - OID sent to client:
Value sent to client:
Statement #0
Error code: 0
Error msg: Unix shell command successfully executed
Linux alfa 2.4.18-3 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown

Statement #1
Error code: 0
Error msg: Unix shell command successfully executed
PWD(1)                           PWD(1)
...

The code traces heavily, and we can see the full stack of calls:

  • trg_service_fn accepts the extended operation invocation and calls

  • trg_parse_client_req to parse the client command list, then calls

  • trg_apply_statements, which in turn, for every user command, issues a call to an execution routine, in this case

  • trg_execute_unixcmd, which issues popen library call to execute the UNIX command and returns the output to

  • trg_service_fn, which collects all the output from the execution functions in the extended operation response and

  • trg_service_fn returns the data to the client

This patterns repeats for any command issued by a user at the client application prompt; what changes is the actual trg_execute_<command> called.

Now, let's create our first trigger.

CODE EXAMPLE 16 Creating a Trigger

TRIGGERS>> create or replace trigger SunBlueprintsBigTrigger on 'ou=testadd,o=sunblueprints' before ldap_add action ignore;
.
------------- Server output ----------------
Statement #0
Error code: 0
Error msg: Trigger SunBlueprintsBigTrigger successfully added
--------------------------------------------
TRIGGERS>> list all triggers;
.
------------- Server output ----------------
Statement #0
Error code: 0
Error msg: 1 triggers found
SunBlueprintsBigTrigger
--------------------------------------------

The example defines a trigger called SunBlueprintsBigTrigger on the directory entry o=testadd, ou=SunBlueprints to be triggered before the entry is added to the directory information tree (DIT). As the action, we specify IGNORE, which means do nothing or skip the operation.

The list all triggers instruction shows you all the available triggers under ou=triggers,o=sunblueprints, which is where we store them. As a proof of this, perform the following LDAP search:

CODE EXAMPLE 17 Performing an LDAP Search

<sunone slapd-sunblueprints>~$ ldapsearch -p 10389 -D "cd=Trigger Manager" -w manager0 -b "ou=triggers,o=sunblueprints" objectclass=trigger"
dn: cn=SunBlueprintsBigTrigger,ou=triggers,o=sunblueprints
objectClass: trigger
objectClass: top
cn: SunBlueprintsBigTrigger
on: ou=testadd,o=sunblueprints
before: 1
enabled: true
explain: create or replace trigger SunBlueprintsBigTrigger on ou=testadd,ou=sun
 blueprints add action ignore
action: 2
actiondn:

The search reports exactly one entry, our trigger. Note the explanation attribute, which stores the whole create instruction, as typed by the administrator. Now create the entry, and see what happens.

CODE EXAMPLE 18 Creating an Entry

<sunone slapd-sunblueprints>~$ ldapmodify -p 10389 -D "cd=Trigger Manager" -w manager0
dn: ou=testadd, o=sunblueprints
changetype: add
objectclass: organizationalUnit
ou: testadd
description: Ciao mondo! (how Italians say Hello world!)

adding new entry ou=testadd, o=sunblueprints
ldap_add: Operations error
ldap_add: additional info: Trigger SunBlueprintsBigTrigger forbids the creation of entry ou=testadd,o=sunblueprints

It works; we receive the expected message because of the IGNORE action triggered by SunBlueprintsBigTrigger. Reviewing the log file shows the following:

CODE EXAMPLE 19 Verifying the Log File

[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) triggers_pre_add_fn - conn=2 op=1 msgId=30 - Entering
[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) triggers_pre_add_fn - conn=2 op=1 msgId=30 - Looking for triggers...
[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) find_trigger - conn=2 op=1 msgId=30 - Entering(0x8352190, 0x47312008, (&(&(on=ou=testadd,o=sunblueprints)(before=1))(enabled=true)))
[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) find_trigger - conn=2 op=1 msgId=30 - Getting results
[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) find_trigger - conn=2 op=1 msgId=30 - Returning
[21/Oct/2003:02:05:57 +0200] - INFORMATION - (PID=4017,ThID=25625) triggers_pre_add_fn - conn=2 op=1 msgId=30 - Found triggers ou=testadd,o=sunblueprints
...

The routine triggers_pre_add_fn is the add pre-operation function of our pre-operation plug-in. It calls find_trigger to search for triggers. When it finds one, it executes. As a counter proof, now let's delete the trigger, and re-add the test entry:

CODE EXAMPLE 20 Deleting the Trigger and Reading the Test Entry

TRIGGERS>> delete trigger SunBlueprintsBigTrigger;
.
 ------------- Server output ----------------
Statement #0
Error code: 0
Error msg: Trigger SunBlueprintsBigTrigger successfully deleted
 --------------------------------------------
TRIGGERS>> list all triggers;
.
 ------------- Server output ----------------
Statement #0
Error code: 0
Error msg: 1 triggers found
trgme
 --------------------------------------------

Try to add the entry again:

CODE EXAMPLE 21 Adding a Duplicate Entry

<sunone slapd-sunblueprints>~$ ldapmodify -p 10389 -D "cn=Directory Manager" -w manager0
dn: ou=testadd, o=sunblueprints
changetype: add
objectclass: organizationalUnit
ou: testadd
description: Ciao mondo! (how Italians say for Hello world!)

adding new entry ou=testadd, o=sunblueprints

No problem now, because we deleted the trigger on this entry. Our language provides a construct to temporarily disable a trigger instead of removing it.

To disable a trigger, use the following as an example:

CODE EXAMPLE 22 Disabling a Trigger

TRIGGERS>> disable trigger SunBlueprintsBigTrigger;
.
 ------------- Server output ----------------
Statement #0
Error code: 0
Error msg: Trigger SunBlueprintsBigTrigger successfully disabled
 --------------------------------------------

If you repeat the LDAP add of the ou=testadd test entry, it will work. It works because the triggers_pre_add_fn function that is called before the internal add calls the find_trigger with a search filter such as the following:

(&(&(on=ou=testadd,o=sunblueprints)(before=0))(enabled=true))) 

This filter searches expressly for only enabled triggers.

The LDAP triggers language has many other possibilities. Our code example implements only some of them. We invite you to discover the other features and functions.

  • + Share This
  • 🔖 Save To Your Account