Expectations Are Considered Dangerous (2009 Resolution)

Owh crap. I have some new year resolutions :(

From the end of last year until early of today, I've managed to prevent my mind from creating any sort of even an illusion of expectations for this new year. I didn't last a week into this new year. Darn it.

Don't  expect anything, and your life will be a bliss. Learn from what Homer said, "You tried your best and you failed miserably. The lesson is, never try".

Oh I love those Simpsons.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 6. January 2009 11:48

Tags:

Nonsense

Qunut Nazilah

Qunut Nazilah Text
Ya Allah, sesungguhnya kami meletakkan-Mu di batang-batang leher musuh-musuh kami
Dan kami berlindung dengan-Mu daripada kejahatan-kejahatan mereka
Ya Allah, leburkanlah kumpulan-kumpulan mereka
Pecah belahkan dan kacau bilaukan persatuan mereka
Goncangkan pendirian mereka
Dan hantarkanlah anjing-anjing Mu ke atas mereka
Wahai Tuhan Yang Gagah Perkasa
Wahai Tuhan Yang Maha Penghukun
Wahai Tuhan yang bersifat murka
Ya Allah, Ya Allah, Ya Allah
Wahai Tuhan yang menurunkan Kitab,
Wahai Tuhan yang mengarakkan awan
Wahai Tuhan yang menewaskan bala tentera al-Ahzab
Kalahkan mereka dan menangkan kami ke atas mereka.

Mari bacakan Qunut Nazilah utk saudara-saudara kita di Gaza, Palestin yang dizalimi oleh Israel/Zionist laknatuLlah.Ada beberapa version Qunut Nazilah ni,yang ini yang aku belajar masa sekolah dulu. Boleh di baca di i'tidal terakhir mana-masa solat wajib, ketika terjadi musibah yang menimpa umat Islam.

Malunya kita, hanya doa je yang kita boleh tolong :(

Credit:
 nixk ITTutor
 From some blog
 Some other blog
 Teks Qunut Nazilah yg lebih besar

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 5. January 2009 08:20

Tags:

Tazkirah

Connecting to LDAP Using .NET and C#

Connecting to LDAP Using .NET and C#

In a previous project, I was given a task to connect to an LDAP server using .NET dan C# to do some user related operations, mainly for authentication. .NET has a pretty good support for LDAP, especially for Ms Active Directory, the Microsoft's LDAP. I found that for other kind of LDAP servers, it's quite hard to find good tutorials. I was using OpenLDAP.

So, I thought of writing this article. Before we start, it's better that we get some understanding first on what LDAP is. Terms and definitions I use here won't be entirely correct, but sufficient enough I guess to get the job done.

What is LDAP

From Wikipedia: "The Lightweight Directory Access Protocol, or LDAP, is an application protocol for querying and modifying directory services running over TCP/IP."

A directory service is commonly used to store information of people in an organization. Entries are kept hierarchically and have attributes to store it's details. You can relate to it as an electronic address or phone book.

Each entry will have a DN (Distinguished Name). This is a string that uniquely identifies the entry. For example, "cn=Ikhwan Hayat, ou=People, dc=example, dc=com".

Let's disect parts of the DN. "cn" is common name, usually the full name or nickname. It is actually a part of the attributes, that we will talk about shortly. Any attributes can be set as this part of the DN. Some uses "uid" instead of "cn". "ou" is a container. It is used to group entries. In this example, "ou=People" is used to group entries of persons or users.

The "dc=example, dc=com" is the Domain Component. It is like a domain name. In fact, most of the time, it follows the domain name of the server the LDAP is situated at.

Entries have attributes. They are just simple key-value pairs. Value can be multiple. For example, an entry can have attributes like "phone=01234567", "uid=user1", "sn=Hayat". Keys and values must be strings of characters.

Some notable attributes are such as "uid" for user id or login name and "sn" for surname". There's a special attribute called "userPassword" for keeping passwords which are usually hashed and encoded in Base64 (only strings, remember?).

Another special attribute is "objectClass". This attribute it to indicate what kind of entry is this. An objectClass can determine what attributes are mandatory or optional for an entry. A "person" objectClass maybe have "cn" and "sn" as required attributes. A "posixAccount" have "cn", "sn", "uid", "home", and "shell" as required.

Connecting to the Server (Binding)

Enough talk, let's see some code. We will be using classes from the namespace "System.DirectoryServices.Protocols" to our LDAP operations.

Actually, the popular option is "System.DirectoryServices". This is mainly used to connect to Active Directory, it offers some abstractions to make things easier. But I personally find "System.DirectoryServices.Protocols" to be much more intuitive, so I use it instead. Also, abstractions usually includes speed overheads.

There's a another option, to use Novell's LDAP Library. I tried it, but I don't like how the code is structured. I don't feel like a natural C# code.

Using "Systems.DirectoryServices.Protocols", we use LdapConnection to connect to the server. First, you create the connection, supplying the host address and optionally a port. Second, we bind to it using a DN and a password.

// With host address only
var host = "example.com";
var conn = new LdapConnection(host);

// or with port. Host address can be an IP number
var conn = new LdapConnection(new LdapDirectoryIdentifier("172.16.100.333:389"));

// Set the DN as username and include password
var adminDn = "cn=admin, dc=example, dc=com";
var adminPassword = "p";
conn.Credential = new NetworkCredential(adminDn, adminPassword);
conn.AuthType = AuthType.Basic;            
conn.SessionOptions.ProtocolVersion = 3;
conn.Bind();

An important note, for my version of OpenLDAP, I need to specifically set the LDAP protocol version as 3. I nearly cracked my head figuring this up.

Connecting is very straight forward. Next, will go for a scenario of authenticating user, changing user's password, and creating a user. These will demonstrate available LDAP operations such as searching, modifying and creating an entries.

Authenticating User (Searching)

Authentication is done by doing a bind using the user's DN and password. In some setup, the user ID is made as part of the DN, like "cn=username, ou=People, dc=example, dc=com" or "uid=username, ou=People, dc=example, dc=com". In this case, it would be dead easy to figure out the correct DN.

But we cannot actually depend on this. As I said earlier, any attribute can be made as the first part of the DN. As such, we have to search for the correct entry and retrieve the exact DN before binding.

Usernames are kept in "uid" attribute, so we just search the entry which has it. Another thing to note is that entries are kept in containers. We must first know which container stores the entries for user. Ask the sysadmin for this, but usually it's kept in "ou=People".

string uid = "ikhwan";
string container = "ou=People, dc=example, dc=com";

var conn = Connect(); // assume this method wraps 
                      // the code above to establish 
                      // and return an LdapConnection

// Create a search request
var searchRequest = new SearchRequest(container,              // search in this container
                                      "(uid=" + uid + ")",    // a filter
                                      SearchScope.OneLevel);  // how deep to search

// Send request and receive a response
var resp = (SearchResponse)conn.SendRequest(searchRequest);

// Found the DN. Ideally, you'll check if the resp.Entries do have values first.
var userDn = resp.Entries[0].DistinguishedName;

Search is done by using an LDAP filter. In this case we search for entries having attribute "uid=ikhwan". If the user is strictly kept in a specific "objectClass", we can use a filter like "(&(objectClass=posixAccount)(uid=ikhwan))". There's a simple explaination for LDAP search filter here.

After we get the DN, do a bind using this DN and the password. If it binds successfully, then the username and password is correct.

var conn = new LdapConnection(host);
conn.Credential = new NetworkCredential(userDn, "passw0rd");
conn.AuthType = AuthType.Basic;            
conn.SessionOptions.ProtocolVersion = 3;
conn.Bind();

Changing User's Password (Modifiying an Attribute)

To change the password, we change the value of the attribute "userPassword". In the previous codes, you could see that we use SearchRequest class to do a search. Similar for modifiying an entry, we use ModifyRequest.

var conn = Connect(); // assume we have a method to 
                      // connect using admin's DN

var userDn = FindUserDnFromUid("ikhwan"); // assume we have a method to
                                          // to find the DN based on uid

var newpass = GenerateHashFromPlainText("newpassw0rd");
var req = new ModifyRequest(userDn,                             // DN for entry we want to modify
                            DirectoryAttributeOperation.Replace,// replace the value
                            "userPassword",                     // the attribute we want to modify
                            newpass);                           // the new value

conn.SendRequest(req);

Simple right? Except for the "GenerateHashFromPlainText" bit :)

Modifiying an attribute's value is as simple as replacing it with the new value. But for passwords, you need to hash it first. Yyou can store it in plain text actually, but passwords should always be hashed/encrypted of course.

LDAP understands several type of hashing such as MD5, SHA, SSHA, etc. Just generate a Base64 encoding of the hash, and put it in place. I'll left the algorithm to create the hash for your imagination. Get some pointers here: http://users.ameritech.net/mhwood/ldap-sec-setup.html

Creating New User (Adding New Entry)

To create a new entry in LDAP, it's as easy as -- yes, you got it -- using the AddRequest class. Let's jump straight to the code.

var userDn = "cn=Joe Somebody, ou=People, dc=example, dc=com";

var attrs = new[] {
  new DirectoryAttribute("objectClass", "top", "person", "OpenLDAPperson"),
  new DirectoryAttribute("cn", "Joe Somebody"),
  new DirectoryAttribute("uid", "joesomebody"),
  new DirectoryAttribute("sn", "Somebody"),
  new DirectoryAttribute("userPassword", GenerateHashFromPlainText("newuserpassw0rd"))
};

var req = new AddRequest(userDn, attrs);
conn.SendRequest(req);

Here I used the an AddRequest constructor which accepts a string to be used as DN and an array of attribute key-value pairs. There's several other variations available.

Note that I passed multiple values for attribute "objectClass". Like what's I've said before, "objectClass" determined what this entry will be used for. "objectClass" can have inheritence, for example "OpenLDAPPerson" extends from "person", and all "objectClass"-es extends from "top". You have to pass all the inheritence in.

"objectClass" will determine it's mandatory attributes. So you have to satisfy that also. For example, a "person" will need a "cn" and a "sn".

Deleting A User (Deleting an Entry)

Well, dead simple, use DeleteRequest :) It's so simple, I'm going to skip this and leave it to you as an exercise :D

Conclusion

That's it, simple operations against an LDAP server using the using classes from the System.DirectoryServices.Protocols. Operations usually involves sending requests and receiving responses. Use this MSDN article to see all the operations in details: http://msdn.microsoft.com/en-us/library/bb332056.aspx

The hard part is usually figuring what's LDAP actually is. Once you grasp the basics, it's all smooth sailing from there. Hope this tutorial helps!

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 23. November 2008 10:32

Making Sure Your Server Is Accessible From Outside

At times, when setting up a server, you need to check whether the server is accessible from outside networks. You can use these simple web applications:

http://just-ping.com/
Remote ping a server or web site using our network with 35 checkpoints worldwide

http://www.just-traceroute.com/
Remote traceroute, from 4 places: Singapore, Netherlands, Australia, USA.

http://www.siteuptime.com/users/quickcheck.php
Check availability of various services (ports) such as HTTP, HTTPS, SMTP, POP3, FTP from 3 places at a time.

http://host-tracker.com/
Check website availability from a lot of places. Might take quite long to see result.

http://downforeveryoneorjustme.com/
If you need a quick one, this is a very simple website availability checker. Just one line of text and one textbox.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 20. November 2008 09:12

Tags:

GeekLife

Memastikan Jam PC Sentiasa Tepat

Beberapa hari lepas, aku perasan jam laptop aku ni tak berapa betul masanya. Pelik, sebab rasanya aku dah set supaya sync dengan NTP server.

NTP server ni tugasnya ialah memberitahu masa standard. Ia selalu digunakan utk memudahkan synchronize masa untuk komputer atau kadang-kadang handheld devices. Kita ada satu NTP server di Malaysia yang di jaga oleh Sirim. Boleh tengok di http://mst.sirim.my.

Cara utk automatik sync-kan PC anda ke server ni ialah dengan pergi ke Control Panel > Date and Time, dan ubah setting di situ. Masukkan "mst.sirim.my" sebagai lokasi server.

Selain itu, jangan lupa setkan time zone kepada GMT +8.00.

 

p.s: Terima kasih kepada satu post dari papit http://blog.mypapit.net/2008/05/ubuntu-how-to-synchronize-current-time.html

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 19. November 2008 06:08

Tags:

GeekLife

Filter, Map, Reduce Dalam C#

Dalam teknik functional programming, ada 3 higher-order function yang utama iaitu filter, map, dan reduce. Dalam functional programming, operasi ke atas sesuatu list biasanya dipermudahkan menggunakan teknik list comprehension, berbanding imperative programming (yang kebanyakan kita guna) yang biasanya menggunakan teknik looping.

Entry ni sebenarnya bukan nak cerita pasal apa itu functional programming atau higher-order function, jadi yang itu minta tolong kawan-kawan cari sendiri di Internet. Entry ini berkenaan bagaimana menggunakan filter map reduce dalam C#. Tapi sebagai perbandingan, aku akan sertakan sekali bagaimana teknik looping yang memberikan hasil yang sama.

Filter, map, dan reduce dalam C# dilakukan masing-masing melalui method Where(), Select(), dan Aggregate(). Semua ini adalah extension method yang ada di dalam System.Linq (memerlukan .NET Framework3.5). Untuk tujuan demonstrasi ini, kita gunakan satu list seperti yang berikut:

class Person 
{
	public string Name { get; set; }
	public int Age { get; set; }
}

var list = new[] {
	new Person { Name="Ikhwan", Age=26 },
	new Person { Name="Hayat", Age=55 },
	new Person { Name="Khairi", Age=15 },
	new Person { Name="Hamim", Age=14 }
};

Filter (Where)

Tujuan: Menapis satu list supaya yang tinggal hanya item yang dimahukan sahaja.
Input: List tersebut
Output: Satu list dari type yang sama yang mempunyai bilangan item dan sama atau kurang dari list asal.

Operasi yang kita ingin lakukan ialah mendapatkan Person yang mempunyai umur kurang dari 20 sahaja.

// functional
var under20 = list.Where(person => { return person.Age < 20; });

// looping
var under20 = new List();
foreach(var person in list)
{
	if (person.Age < 20)
		under20.Add(person);
}

Map (Select)

Tujuan: Menukarkan satu list dari satu type kepada satu type sama atau yang berlainan.
Input: List tersebut
Output: List dari type yang sama atau berlainan, yang mempunyai bilangan item yang sama.

Operasi yang ingin kita lakukan ialah mengumpulkan satu senarai yang mempunyai nama sahaja (array/collection of strings). List asal ialah Person, list yang terhasil ialah String.

// functional
var nameOnly = list.Select(person => { return person.Name; });

// looping
var nameOnly = new List();
foreach(var person in list)
{
	nameOnly.Add(person.Name);
}
Satu contoh lain, operasi mengumpulkan satu senarai Person dengan umur masing-masing 10 tahun akan datang. Dalam contoh ni, list asal ialah Person, hasil ialah Person juga.
// functional
var inTenYears = list.Select(person => { return new Person { Name=person.Name, Age=person.Age+10}; });

// looping
var inTenYears = new List():
foreach(var person in list)
{
	var temp = new Person { Name=person.Name, Age=person.Age+10};	
	nameOnly.Add(temp);
}

Reduce (Aggregate)

Tujuan: Memampatkan satu list menjadi satu value sahaja.
Input: List tersebut, dan seed value.
Output: Satu value.

Operasi yang ingin kita lakukan ialah mengira jumlah umur Person yang ada dalam list tersebut.

// functional
var sumAge = list.Aggregate(0, (acc, person) => { return acc + person.Age; });

// looping
var acc = 0;
foreach(var person in list)
{
	acc += person.Age;
}
var sumAge = acc;

Dalam contoh untuk looping, dua variable acc dan sumAge digunakan walaupun sebenarnya satu sudah mencukupi, saja untuk perbandingan dengan teknik functional.

Beberapa artikel menarik mengenai higher-order function:
http://diditwith.net/PermaLink,guid,a1a76478-03d2-428f-9db6-9cf4e300ea0f.aspx
http://diditwith.net/CommentView,guid,c28d79df-21e1-4084-8412-065f34c6fad2.aspx

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 18. November 2008 03:43

Tags:

C# | Code

FOSS.MY 2008

It's gotten huge! I might as well join in spreading the buzz. FOSS.MY 2008 is just around the corner, this weekend to be exact. Still not too late to register! Come join, I'll be there insyaAllah.

I originally thought it would be another lame linux/security/hacking things again, but there will actually be some interesting stuff going on. I'd like to hear about Git and memcached, which unfortunately both talks are given concurrently in different tracks. Darn it :( 

Oh well. Some other things that I want to hear about are Drupal, and... err.. that's basically it. Oh yeah, the clustering-high-availability stuffs could be interesting too. (Feel the lack of enthusiasm here? Please change the schedule FOSS comittee!)

Say hello if you see me there. I'm easy to be recognized, find the most attractive geek over there :) Lately, I'm getting quite some response saying that I look like Fahrin Ahmad. I wonder why...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 3. November 2008 10:03

Tags:

GeekLife

Sedap Kuih Raya Ini

Sedaplah kuih raya ni! Rasanya macam... err macam... macam beliung tajam yang kau tusuk-tusukkan ke hatiku pada hari penuh makna itu. Kemudiannya kau siram lukanya dengan cuka.

Pedih, kau tahu.

Rasanya sangat pedih.

Berhentilah jadi orang suci. Marilah turun ke bumi seperti kami-kami orang biasa-biasa ini. Malaikat mana boleh masuk geng-geng manusia.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 16. October 2008 10:12

Tags:

Nonsense

Haiku: Habis Ramadhan

Habis Ramadhan,
Terampunkah dosaku,
Atau celaka.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 6. October 2008 03:15

Lostprophets - 4 AM Forever

Yesterday I lost my closest friend
Yesterday I wanted time to end
I wonder if my heart will ever mend
I just let you slip away

4 AM forever

Maybe I'll never see you smile again
Maybe you thought that it was all pretend
All these words that I could never say
I just let them slip away

4 AM forever

Why don't you hear me when I'm calling out to you (to you)
Why don't you listen when I try to make it through (to you)
Goodbye, goodbye
Goodbye, you never know
Hold a little tighter

4 AM forever

Maybe one day when I can move along
Maybe someday when you can hear this song
You won't let it slip away

4 AM forever

And I'd wish the sun would never come
It's 4 AM and you are done
I hope you know you're letting go
It's 4 AM and I'm alone

Why don't you hear me when I'm calling out to you (to you)
Why don't you listen when I try to make it through (to you)
Goodbye, goodbye
Goodbye, you never know
Hold a little tighter

Why don't you hear me when I'm calling out to you (to you)
Why don't you listen when I try to make it through (to you)
Goodbye, goodbye
Goodbye, you never know
Hold a little tighter

4 AM forever...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

by Ikhwan 5. October 2008 04:37

About

Gravatar icon

My name is Ikhwan. Some may know me by my online handle 1kHz. I am not just some ordinary guy. I am totally awesome.

This is my blog, I call it "anti-keseronokan". This is not an ordinary blog. It is totally awesome.

[more total awesomeness]

Powered by BlogEngine.NET 1.4.5.0