wxWidget Helper Classes Posted: 14 May 2013 09:19 AM PDT wxWidgets consists of a large group of helper classes, that help programmers to do their job. These include classes for working with strings, files, XML files, streams, database or network. In this article, we will discuss about some helper classes that frequently used or useful for developing with wxWidget later. We will also illustrate some of the helper classes in simple console-based applications (although we can also use GUI applications). Console This is a simple console application. The application puts some text into the console window. console.cpp <br />#include <wx/string.h><br /><br />int main(int argc, char **argv)<br />{<br /> wxPuts(wxT("A wxWidgets console application"));<br />}<br /> You should get output, a string “A wxWidgets console application” on your terminal. wxString wxString is a class representing a character string. In the following example, we define three wxStrings instances. We create one string of these strings using addition operation. Create a file addition.cpp and write these into it: <br />#include <wx/string.h><br /><br />int main(int argc, char **argv)<br />{<br /> wxString str1 = wxT("Linux");<br /> wxString str2 = wxT("Operating");<br /> wxString str3 = wxT("System");<br /><br /> wxString str = str1 + wxT(" ") + str2 + wxT(" ") + str3;<br /><br /> wxPuts(str);<br />}<br /> It should give you “Linux Operating System” as the output. A method printf() of wxString can also be used for formatting the strings. #include <wx/string.h> int main(int argc, char **argv) { int flowers = 21; wxString str; str.Printf(wxT("There are %d red roses."), flowers); wxPuts(str); } The following example checks, whether a string contains another string. For this we have a Contains() method. #include <wx/string.h> int main(int argc, char **argv) { wxString str = wxT("The history of my life"); if (str.Contains(wxT("history"))) { wxPuts(wxT("Contains!")); } if (!str.Contains(wxT("plain"))) { wxPuts(wxT("Does not contain!")); } } A wxString always has length and this length can be obtained by method Len(). It will return the number of characters on string. #include <wx/string.h> int main(int argc, char **argv) { wxString str = wxT("The history of my life"); wxPrintf(wxT("The string has %ld characters\n"), str.Len()); } The MakeLower() and MakeUpper() methods can be used to make characters lower case and upper case. #include <wx/string.h> int main(int argc, char **argv) { wxString str = wxT("The history of my life"); wxPuts(str.MakeLower()); wxPuts(str.MakeUpper()); } Also note that, when the MakeLower() or MakeUpper() used, the effect will remain. Utility functions wxWidgets has several handy utility functions for executing a process, getting a home user directory or getting the OS name. In the following example, we execute the ls command. For this, we have the wxShell() function. This methods is only for for Unix. #include <wx/string.h> #include <wx/utils.h> int main(int argc, char **argv) { wxShell(wxT("ls -l")); } Another thing we can do are getting the home user directory, os name, user name, host name and total free memory. #include <wx/string.h> #include <wx/utils.h> int main(int argc, char **argv) { wxPuts(wxGetHomeDir()); wxPuts(wxGetOsDescription()); wxPuts(wxGetUserName()); wxPuts(wxGetFullHostName()); long mem = wxGetFreeMemory().ToLong(); wxPrintf(wxT("Memory: %ld\n"), mem); } It looks like wxWidget is optimized for lsb based linux distribution. wxWidget on my Slackware64, which is not using LSB, gives some expected result. Time & date wxWidget also offer utilities for working with date & time. The example shows current date or time in various formats. #include <wx/datetime.h> int main(int argc, char **argv) { wxDateTime now = wxDateTime::Now(); wxString date1 = now.Format(); wxString date2 = now.Format(wxT("%X")); wxString date3 = now.Format(wxT("%x")); wxPuts(date1); wxPuts(date2); wxPuts(date3); } Next we will show current time in different cities. #include <wx/datetime.h> int main(int argc, char **argv) { wxDateTime now = wxDateTime::Now(); wxPrintf(wxT(" Jakarta: %s\n"), now.Format(wxT("%a %T"), wxDateTime::GMT7).c_str()); wxPrintf(wxT(" Moscow: %s\n"), now.Format(wxT("%a %T"), wxDateTime::MSD).c_str()); wxPrintf(wxT("Budapest: %s\n"), now.Format(wxT("%a %T"), wxDateTime::CEST).c_str()); wxPrintf(wxT(" London: %s\n"), now.Format(wxT("%a %T"), wxDateTime::WEST).c_str()); wxPrintf(wxT("New York: %s\n"), now.Format(wxT("%a %T"), wxDateTime::EDT).c_str()); } The following example shows, how we can add date spans to our date/time. We add one month to the current time. #include <wx/datetime.h> int main(int argc, char **argv) { wxDateTime now = wxDateTime::Now(); wxString date1 = now.Format(wxT("%B %d %Y")); wxPuts(date1); wxDateSpan span(0, 1); // 0 year, 1 month wxDateTime then = now.Add(span); wxString date2 = then.Format(wxT("%B %d %Y")); wxPuts(date2); } Files wxWidgets has several classes to facilitate working with files. wxWidgets use low level access to files, as opposed to working with streams. In the following example, we use the wxFile class to create a new file and write data to it. We also test, whether the file is opened. Note, that when we create a file, it automatically stays as opened. #include <wx/file.h> int main(int argc, char **argv) { wxString str = wxT("You make me want to be a better man.\n"); wxFile file; file.Create(wxT("quote"), true); if (file.IsOpened()) wxPuts(wxT("the file is opened")); file.Write(str); file.Close(); if (!file.IsOpened()) wxPuts(wxT("the file is not opened")); } The wxTextFile is a simple class which allows to work with text files on line by line basis. It is easier to work with this class than with wxFile class.In the next example, we will print the number of lines in a file, first and last lines and finally we will read and show the contents of the file. #include <wx/textfile.h> int main(int argc, char **argv) { wxTextFile file(wxT("test.c")); file.Open(); wxPrintf(wxT("Number of lines: %d\n"), file.GetLineCount()); wxPrintf(wxT("First line: %s\n"), file.GetFirstLine().c_str()); wxPrintf(wxT("Last line: %s\n"), file.GetLastLine().c_str()); wxPuts(wxT("————————————-")); wxString s; for ( s = file.GetFirstLine(); !file.Eof(); s = file.GetNextLine() ) { wxPuts(s); } file.Close(); } The wxDir class allows us to enumerate files and directories. In the following example, we will print all files and directories available in the current working directory. #include <wx/dir.h> #include <wx/filefn.h> int main(int argc, char **argv) { wxDir dir(wxGetCwd()); wxString file; bool cont = dir.GetFirst(&file, wxEmptyString, wxDIR_FILES | wxDIR_DIRS); while (cont) { wxPuts(file); cont = dir.GetNext(&file); } } |
Introduction to wxWidgets Toolkit Posted: 14 May 2013 09:19 AM PDT In beginning it is known as wxWindows. wxWidgets is a GUI (Graphical User Interface) toolkit and library for creating C++ applications. It is an open source, mature and cross-platform toolkit. wxWidgets applications run on all major OS platforms, Windows, Unix and Mac. The project was started by Julian Smart in 1992. wxWidgets is much more than a toolkit. It provides a large variety of classes for handling streams, databases, threads, online help or application settings. wxWidgets consists of a large group of widgets. Official site of wxWidget is http://www.wxwidgets.org/ To use tutorial in this site, you should have wxWidget installed. I use wxWidget 2.9.4 mainly and can be downloaded from here http://www.wxwidgets.org/downloads/. wxWidgets gives you a single, easy-to-use API for writing GUI applications on multiple platforms. Link it with the appropriate library for your platform (Windows/Unix/Mac) and compiler (almost any popular C++ compiler), and your application will adopt the look and feel appropriate to that platform. On top of the great GUI functionality, wxWindows gives you: online help, network programming, streams, clipboard and drag and drop, multithreading, image loading and saving in a variety of popular formats, database support, HTML viewing and printing, and much more. Who Should Use wxWidgets? wxWidgets is a framework very much similar to MFC, except for a few negative points of its own. Those MFC programmers who are aware of the growing number of Linux users and who want to write cross platform GUI applications can use wxWidgets. With wxWidgets, it is very easy to use a framework based on C++ and it has a proven record of 13 years. In fact, wxWidgets is very stable and is supported on: - Windows 3.1, Windows 95/98, Windows NT, Windows 2000/XP, Windows ME, Windows CE.
- Linux and other UNIX platforms with GTK+.
- UNIX with Motif or the free Motif clone Lesstif.
- Mac OS.
- Embedded platforms are being investigated. See the wxUniversal project.
- An OS/2 port is in progress, and you can also compile wxWidgets for GTK+ or Motif on OS/2.
The C++ programming language The C++ programming language is one of the most widely used programming languages. It is used in many famous desktop applications like MS Office, Macromedia Flash, Firefox, Photoshop or 3D Max. C++ dominates also the world of PC games. It is one of the most difficult programming languages. On the other hand, programming in C++ today is different from programming 10 years ago. There are many tools and libraries that make the programming easier. For tutorials on C++ programming languages, you can visit here. Why wxWidgets? There are a number of options available for writing cross platform GUI development, like: JAVA, Mono.NET, Qt, etc. Java has failed to prove itself as an efficient alternative. Qt is good but commercial and nobody knows its future. Mono.NET seems to be good but is largely driven by Microsoft, it seems like a copy of the work done by Microsoft and it has not yet proved itself as a successful alternative. Also, people would not like to use an extra burden of layer for highly efficient software. As wxWidgets does not use any middle layer and uses only the native controls available on the platform, it gives a nice look and feel to the application. - It is very complete. There are many utility classes like :
wxRegEx , wxFTP , wxSplashScreen , wxZipInputStream , etc. - It is still heavily developed, and has a lot of support from the open source community.
- Many compilers and platforms are supported : Windows, Linux, Mac, Unix.
- There’s a lot of documentation available on the internet, forums, wxBook.
- It’s free for personal and commercial use, and is more flexible than the LGPL license.
- Whenever possible, wxWindows uses the platform SDK. This means that a program compiled on Windows will have the look and feel of a Windows program, and when compiled on a Linux machine, it will have the look and feel of a Linux program.
- Ease of learning, it has the same Event tables and similar API and classes like that of WINAPI and MFC.
- A lot of sample is provided in the samples directory of the installation, which contains how to use the basic controls, multi threading, MDI, drag and drop, sockets, printing and lots more.
- A lot of ready to use classes are available, like:
wxGenericDirCtrl , wxCalendarCtrl , wxDatePickerCtrl , wxTipWindow , wxStyledTextCtrl , wxStaticPicture , wxLEDNumberCtrl , wxEditableListBox , wxFoldPanelBar , wxGIFAnimationCtrl , wxSplashScreen , OGL (Object Graphics Library), FL (Frame Layout), etc. This is one of the main repository. - A lot of add on libraries are available to make the programming task more easier:
Main Features - Multi threading.
- Clipboard and drag and drop.
- Network programming, like:
wxSMTP , wxHTTP , wxFTP . - Image loading and saving in a variety of popular formats.
- Streams (ZIP, Network, File, etc.), like:
wxRarInputStream . - Database support, like:
wxDao . - HTML viewing and printing, like:
wxMozilla , wxIE . - XML based resource, multi language/Unicode support.
- Default style themes available with the OS (e.g.: XP style themes).
Comparison to MFC MFC and wxWidgets macros MFC version | wxWidgets version | BEGIN_MESSAGE_MAP | BEGIN_EVENT_TABLE | END_MESSAGE_MAP | END_EVENT_TABLE | DECLARE_DYNAMIC | DECLARE_CLASS | DECLARE_DYNCREATE | DECLARE_DYMAMIC_CLASS | IMPLEMENT_DYNAMIC | IMPLEMENT_CLASS | IMPLEMENT_DYNCREATE | IMPLEMENT_DYNAMIC_CLASS | IsKindOf (RUNTIME_CLASS (CWindow)) | IsKindOf (CLASSINFO(wxWindow)) | MFC and wxWidgets classes Miscellaneous Classes | MFC version | wxWidgets version | CWinApp | wxApp | CObject | wxObject | CCmdTarget | wxEvtHandler | CCommandLineInfo | wxCmdLineParser | CMenu | wxMenu, wMenuBar, wxMenuItem | CWaitCursor | wxBusyCursor | CDataExchange | wxValidator | Window Classes | MFC version | wxWidgets version | CFrameWnd | wxFrame | CMDIFrameWnd | wxMDIParentFrame | CMDIChildWnd | wxMDIChildFrame | CSplitterWnd | wxSplitterWindow | CToolBar | wxToolBar | CStatusBar | wxStatusBar | CReBar | wxCoolBar, but see contrib/src/fl and wxAUI, wxDockIt | CPropertyPage | wxPanel | CPropertySheet | wxNotebook, wxPropertySheetDialog | Dialog Classes | MFC version | wxWidgets version | CDialog | wxDialog | CColorDialog | wxColourDialog | CFileDialog | wxFileDialog | CFindReplaceDialog | wxFindReplaceDialog | CFontDialog | wxFontDialog | CPageSetupDialog | wxPageSetupDialog | CPrintDialog | wxPrintDialog | Control Classes | MFC version | wxWidgets version | CAnimateCtrl | wxMediaCtrl, wxAnimationCtrl | CButton | wxButton | CBitmapButton | wxBitmapButton | CComboBox | wxComboBox, wxChoice | CDateTimeCtrl | wxDatePickerCtrl | CEdit | wxTextCtrl | CHotKeyCtrl | None, but see Keybinder | CListBox , CDragListBox | wxListBox | CCheckListBox | wxCheckListBox | CListCtrl | wxListCtrl, wxListView | CMonthCalCtrl | wxCalendarCtrl | CProgressCtrl | wxGauge | CReBarCtrl | None, but see contrib/src/fl and wxAUI, wxDockIt | CRichEditCtrl | wxTextCtrl | CScrollBar | wxScrollBar | CSliderCtrl | wxSlider | CSpinButtonCtrl | wxSpinButton, wxSpinCtrl | CStatic | wxStaticText, wxStaticLine, wxStaticBox, wxStaticBitmap | CStatusBarCtrl | wxStatusBar | CTabCtrl | wxTabCtrl | CToolBarCtrl | wxToolBar | CToolTipCtrl | wxToolTip | CTreeCtrl | wxTreeCtrl | Graphics Classes | MFC version | wxWidgets version | CBitmap | wxBitmap, wxImage, wxIcon, wxCursor | CBrush | wxBrush | CPen | wxPen | CFont | wxFont | CImageList | wxImageList, wxIconBundle | CPalette | wxPalette | CRgn | wxRegion | CClientDC | wxClientDC | CMetaFileDC | wxMetaFileDC | CPaintDC | wxPaintDC | CWindowDC | wxWindowDC | CDC | wxDC, wxMemoryDC | Data Structure Classes | MFC version | wxWidgets version | CArray , CObArray , CPtrArray | wxArray | CStringArray | wxArrayString | CDWordArray , CByteArray , CUIntArray | wxArrayInt | CList , CPtrList , CObList | wxList | CStringList | wxArrayString, wxStringList | CMap | wxHashMap | CString | wxString | CPoint | wxPoint | CRect | wxRect | CSize | wxSize | CTime | wxDateTime | CTimeSpan | wxTimeSpan, wxDateSpan | COleVariant | wxVariant | Internet Classes | MFC version | wxWidgets version | CSocket | wxSocket | CFtpConnection | wxFTP | CHttpConnection | wxHTTP | Document/View Classes | MFC version | wxWidgets version | CDocument | wxDocument | CView | wxView | CDocTemplate , CSingleDocTemplate , CMultiDocTemplate | wxDocTemplate | Drag and Drop Classes | MFC version | wxWidgets version | COleDataSource | wxDataObject | COleDropSource | wxDropSource | COleDropTarget | wxDropTarget | File Classes | MFC version | wxWidgets version | CFile | wxFile, wxFFile, wxTextFile | CMemFile | wxMemoryInputStream, wxMemoryOutputStream | CSocketFile | wxSocketInputStream, wxSocketOutputStream | CRecentFileList | wxFileHistory | Multithreading Classes | MFC version | wxWidgets version | CWinThread | wxThread | CCriticalSection | wxCriticalSection | CMutex | wxMutex | CSemaphore | wxSemaphore | Class Hierarchy A complete hierarchy for library can be sen here.  Requirements Convinced to use wxWidgets? wxWidgets is cross platform library and currently available on Windows, UNIX, and Mac OS. To make use of wxWidgets, you currently need one of the following setups. (a) for MS-Windows: - A 32-bit or 64-bit PC running MS Windows.
- A Windows compiler: MS Visual C++ (embedded Visual C++ for wxWinCE port), Borland C++, Watcom C++, Cygwin, MinGW, Digital Mars C++. See
install.txt for details about compiler version supported. (b) for Unix: - Almost any C++ compiler, including GNU C++ and many Unix vendors compilers such as Sun CC, HP-UX aCC or SGI mipsPro.
- Almost any Unix workstation, and one of: GTK+ 2.6 or higher (GTK+ 1.2.10 may still be supported but wxGTK1 port is not maintained any longer and lacks many features of wxGTK2; GTK+ 3 is supported but is still experimental), Motif 1.2 or higher or Lesstif. If using the wxX11 port, no such widget set is required.
(c) for Mac OS/Mac OS X: - A PowerPC or Intel Mac running Mac OS X 10.4 or higher
- The Apple Developer Tools (eg. GNU C++)
Under all platforms it’s recommended to have large amounts of free hard |
Basic Programming: Designing a Good Program Posted: 14 May 2013 09:14 AM PDT The goal of every programmer is producing a good program. Nearly all programmers strive to sharpen their skill in coding and engineering stuff. But programming is not only matters of code. A good program is a program which is not only having good response and robust. But we should not forget that other factors are important for a project. In this article, I list some characteristic of good program design according to me. Minimal Complexity The main goal in any program should be to minimize complexity. As a developer, our time will be maintaining or upgrading existing code. If it is a complete mess, then your life is going to be that much harder. Try and avoid those solutions where you use a one line complex solution to replace 20 lines of easy to read code. In a year, when you come back to that code, it will take you that much longer to figure out what you did. The best practice of it will be structuration of code and following some patterns. A modularity is also good for design, don’t write all codes into a single source file. Ease of Maintenance This is making your code easy to update. Find where your code is most likely going to change, and make it easy to update. The easier you make it, the easier your life is going to be down the road. Think of it as a little insurance for your code. Loose Coupling So What is loose coupling? It is when one portion of code is not dependant on another to run properly. It is bundling code into nice little self reliant packages that don't rely on any outside code. How do you do this? Make good use of abstraction and information hiding. Extensibility This means that you design your program so that you can add or remove elements from your program without disturbing the underlying structure of the program. A good example would be a plug-in. Reusability Write code that will be able to be used in unrelated projects. Save yourself some time. Again information hiding is your best bet for making this happen. High Fan-in This refers to having a large number of classes that use a given class. This implies that you are making good use of utility classes. For example you might have a bunch of classes that use the Math class to do calculations. Low to Medium Fan-out This refers to having a low to medium amount of classes used by any given class. If you had a class that includes 7 or more classes this is considered high fan out. So try and keep the number of classes you include down to a minimum. Having a high fan-out suggests that the design may be too complex. Portability Simply put, design a system that can be moved to another environment. This isn't always a requirement of a program, but it should be considered. It might make your life easier if you find out your program does have to work on different platforms. Leanness Leanness means making the design with no extra parts. Everything that is within the design has to be there. This is generally a goal if you have speed and efficiency in mind. A good example of where this might come in handy is creating a program that has to run on a system with limited resources (cell phone, older computers) Standard Technique Try and standardize your code. If each developer puts in their own flavor of code you will end up with an unwieldy mess. Try to layout common approaches for developers to follow, and it will give your code a sense of familiarity for all developers working on it. |
How DNS Works? Posted: 14 May 2013 09:13 AM PDT Computer / machine only recognize numbers and all data are stored as symbols. However human tends to easily recognize information in format of name. Instead of IP address such as 167.205.1.34, people can remember name such as itb.ac.id. Therefore, to bridge two different system, a DNS is created. DNS is a server for translating name in human representation to number (IP address) which is known by computer. DNS is a distributed database in the purpose of identifaction and naming nodes on Internet. The term distributed in this concept refer to the concept that DNS server only store hostnames or computers or nodes under its authorities only. DNS will not store information of nodes for domain which doesn’t belong to its authority. For example: Let say there is a DNS server on domain xathrya.web.id. This server will store name on its network. The network can be its subdomain which can be accessed outside of network. The subdomain for instance: mail.xathrya.web.id, wiki.xathrya.web.id, labs.xathrya.web.id, etc. A DNS also can store information of node inside a network. Naming resource such as switch, router, etc. This resource is private inside of network and cannot be seen by outside. Hierarchy and Tree As distributed system, there are many DNS server which has authorities for their domain. They are independent and autonomous. However, every DNS server is interconnect to each other and create a large internet connection. They are exchanging information since no DNS server know every nodes in the world. DNS servers in the world are forming great tree and each node is located hierarchically. When DNS server doesn’t have name in its authority, they will ask other DNS server which might know. In the root there is a node referred as root DNS. Searching Operation When a computer inside of network want to visit a page / domain (for example: http://xathrya.web.id) it should contact nearest DNS server. This operation is known as resolving domain name. The DNS server is must be assigned on each machine. If a machine connect to DHCP network, it can acquired address of DNS server automatically. We can also set DNS server manually, depend on our Operating System. When a machine ask DNS server for a name, there are two possibilities. The server knows the address of asked name, thus the name / domain is under its authority. If this happens, DNS directly reply and giving the IP address or information of that name. But when DNS can’t resolve the name, it will begin search operations. The operation is described as below: - Local DNS will asks root DNS about address of DNS server which have authorities on .id domain.
- root DNS will gives answer local DNS about DNS server which have authority on .id domain. Let say this domain is idDNS. Now we got information of idDNS and get partial name .id.
- Local DNS will asks idDNS about the DNS server which have authority on web.id domain. Let say this domain is webidDNS. Now we got information of webidDNS and get partial name .web.id.
- Local DNS will asks webidDNS about the DNS server which have authority on xathrya.web.id domain. Let say this domain is xathryaDNS. Now we got information of xathryaDNS and get partial name xathrya.web.id.
- Local DNS sucessfully get address of xathrya.web.id, it will then answer the client and gives IP address of xathrya.web.id.
When DNS get a new name, it can cache the name for some period of time. The caching mechanism will be discussed on other article. |
DNS Cache vs Authoritative Posted: 14 May 2013 09:13 AM PDT A DNS Server has two main functions. It can acts as a resolver / cache, and it can also acts as authoritative server. Authoritative DNS is a DNS server who manage or have authority over DNS under its domain. This domain will answer any query for any domain under it authority. For example: DNS on xathrya.web.id will only responsible to translate domain name under xathrya.web.id such as mail.xathrya.web.id, labs.xathrya.web.id, etc. It will not and can not answer other domain outside of its authority. A physical DNS, can has authority over two or more domain. For example, the domain celestial-links.net is under the same authority of domain which manage xathrya.web.id. Another function DNS Server had is cache / resolver. DNS server will relay a query to other DNS who has authority over the requested domain name. When other DNS server has given the answer, this DNS will cache the answer as well as relay the answer to client. Authoritive DNS tends to non-recursive when giving answer (since they have the answer), a cache server will do a recursive operation when a query comes. A recursion occurs when the DNS tries to resolves a domain name (see How DNS Works article) from root DNS to the authoritative DNS. When designing a DNS server one should separate between DNS servers for authoritative function and Cache functions. Most people use two functions for a single server. This design is not bad but should be avoided. At least there are two reasons for splitting the task of DNS server into two different server for authoritative DNS server and cache DNS server. Mainly it concerns about securities and performance. First reason: Performance. A DNS should be scalable and have good performance. It’s about identities over internet and DNS is a vital component. When a DNS server down, some nodes / machine will not be accessed. Therefore DNS server should have good performance, it should be able to handle as many client for resolving as possible. With separation, a DNS can focus for each function. One can act as only an authoritative DNS server or as cache DNS server and thus the throughput will be as maximum as possible. Second reason: security. When a hacker has successfully taking control of a DNS server, it only has one of the DNS function. Not both. There is no guarantee that all of our DNS servers will not be taken down, but at least hackers can not take both. Another thing for consideration when designing a DNS server is the position on network. Authoritative DNS server should be located inside of DMZ network (perimeter or area of publicly known network. This network is known and accessible by public network). An authoritative DNS server is answering queries, therefore it should be able to answer the request directly. If an authoritative DNS server is behind a proxy or NAT, it would decrease the response time. In other side, the cache DNS server should be located on local network and not exposed to public network. For a network, there should be a cache DNS. This server will do queries for client inside of the network. |
Installing OpenLDAP 2.4 on Debian Squeeze Posted: 14 May 2013 09:13 AM PDT OpenLDAP is one of software that implement Lightweight Directory Access Protocol (LDAP). In this article we will do installation of OpenLDAP on Debian. Technically say, we will install OpenLDAP 2.4 which is provided by Debian repository. The benefits of LDAP, and OpenLDAP specifically, is we can achieve Single Sign On to other services such as FTP, SSH, etc. The LDAP will act as back-end which authenticates user. OpenLDAP consists of some packages, but basically we can be categorized them as three categories: main application (daemon), supporting application, and packages for extending LDAP functionalities (as well as libraries for other applications). In this article we will use Debian 6.0.7 (Squeeze) for amd64 with following packages: - slapd
- ldap-utils
- db4.8-util
The method we use here should be applicable to x86 (32 bit) Debian as well. Things to Know In previous version of OpenLDAP, all server configuration used to be stored on a single file, /etc/ldap/slapd.conf. The configuration is in plain text and quite readable format. Starting from version 2.4, the configuration now stored inside the LDAP tree, rather than on slapd.conf. If you need to migrate from the old format to new format, you can check this article. The main advantage of this approach is ability to update configuration while the server is still running. This is good for enterprise grade applications but also has drawback. The drawback is that we have to use the poorly readable LDIF syntax, just to be able to create a new database, define the database admin, configure ACLs, etc. In this article, we will only do fresh installation of OpenLDAP 2.4 on Debian Squeeze look things that change on this version. In this version, understanding about LDIF Is required and encouraged. We will see why in the later section. Obtain the Materials All the packages can be downloaded and installed from repositories. Use following command to install them: apt-get install slapd ldap-utils db4.8-util These are the minimum packages we need: slapd (as a daemon), ldap-utils (as utilities), and db4.8-util (as back-end database). LDAP is a protocol and it is not focusing on actual storage processing. The back-end for that can be berkeley DB, MySQL, PostGreSQL, etc. In this case we use db4.8 or Berkeley DB. On Installation When installing OpenLDAP we will be prompted by several questions. You can adjust the answer with your conditions. We can skip that and configure them later by invoking: dpkg-reconfigure slapd In general, on installation progress will ask you about these information: - Administrator password for this LDAP package. This is not password for the system, but the password used for manage or administrate LDAP.
- Server host, can DNS domain name (fully qualified domain name) or IP Address
- Organization name.
- Database backed to use.
- LDAP version (v2 or v3)
- Distinguish name (dn) of the machine.
- DN used as administrator.
When creating a base distinguish name (base DN), the easiest way is using FQDN (URL) as a base DN. For example: from xathrya.web.id we can create a base DN as following: dc=xathrya,dc=web,dc=id Another we should prepare is the distinguish name used for administration. For example: cn=master,dc=xathrya,dc=web,dc=id At this point, we have successfully install OpenLDAP on our Debian machine. Listing LDAP configuration As stated, OpenLDAP 2.4 use different configuration location and format. To see the running configuration, use one of this command: slapcat -b cn=config # or ldapsearch -LLQY EXTERNAL -H ldapi:/// -b cn=config Adjust LDAP Configuration To modify a configuration using a .ldif file, use following command: ldapmodify -Y EXTERNAL -H ldapi:// -f <ldif file>.ldif A configuration can be written on LDIF file. This snippet can be read as an example: # Increase log level dn: cn=config changetype: modify replace: olcLogLevel olcLogLevel: stats # Add indexes dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: uid eq - add: oldDbIndex olcDbIndex: cn eq - add: olcDbIndex olcDbIndex: ou eq - add: olcDbIndex olcDbIndex: dc eq That example will modify log level and add new indexes on attributes. Database Definition In this new format, database definition is performed through LDIF file. Create a directory on filesystem to store all files related to this database. This directory should be separated from main / root of ldap directory mkdir /var/lib/ldap-database chown openldap.openldap /var/lib/ldap-database Next, load create an LDIF file, let call it as new-db.ldif. Adjust it with your setting: dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcSuffix: dc=example,dc=com olcDbDirectory: /var/lib/ldap-database olcRootDN: cn=Manager,dc=example,dc=com olcRootPW: secret olcDbIndex: cn,sn,uid pres,eq,approx,sub olcDbIndex: objectClass eq olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=Admin,dc=example,dc=com" write by * none olcAccess: to * by self write by dn.base="cn=Admin,dc=example,dc=com" write by * read Then load it with following command: ldapadd -Y EXTERNAL -H ldapi:/// -f new-db.ldif In a LDAP tree, we do not have ordered elements. This is why we have this optional {n} syntax which allows database ordering. |
LDAP Scheme Posted: 14 May 2013 09:10 AM PDT To declare a directory or an object, LDAP used scheme system. Scheme or schema is simply a packaging unit. It is a collection of valid object class and attributes. The attributes are declared and registered through LDAP system and can be widely known by it. Every object class and attributes must be defined inside of scheme. An attribute defined in one schema can be used by an objectclass defined in another schema. It is wise to say scheme is like a blueprint of object. When we want to instantiate / create an object, we should refer to the blueprint. Object defined outside of blueprint won’t be recognized / not accepted. Even after declaring objects and attributes inside of scheme, the scheme won’t be used unless it is included in the configuration file. Schema decides what information are stored in LDAP. Therefore, we can’t carelessly stored all data in LDAP. All object class and attributes should be defined inside of schema, including connection between object classes and attributes. Each schema can only accommodate object class and attributes for specific purpose. For example: a schema samba is a scheme to accommodate information needed by samba. On default setting, LDAP (OpenLDAP) has included four schemes ready to use. Those schemes are: - core.schema
- Core function of OpenLDAP
- cosine.schema
- Schema for Cosine and x.500
- nis.schema
- Specific schema for access NIS
- interorgperson.schema
- Schema for internet organization person entry.
All schemas are usually written as plain text which have .schema extension. To write a schema, an understanding of object class and attributes should be acquired which will be discussed in other article. Here is the relation of schema, object class, and attributes:  |
LDAP Attributes Posted: 14 May 2013 09:09 AM PDT Attribute is the atomic structure of schema and a member of object class. Attribute typically contain data. Every attribute is included in one or more object classes. Therefore, some object class might have same attribute. Once defined in a schema, it can also be used by any object class. Attribute has a name as identifier. The name is used for identifying the attribute, distinguish one attribute from other attribute. Attribute should be unique. Attribute is also a container for value(s). It is an entry of which value is stored. The value could be a single-value or multi-value. To define an attribute, we have following syntax: attributetype whsp "(" whsp numericoid whsp [ "NAME" qdescrs ] [ "DESC" qdescrs ] [ "OBSOLETE" whsp ] [ "SUP" woid ] [ "EQUALITY" woid ] [ "ORDERING" woid ] [ "SUBSTR" woid ] [ "SYNTAX" whsp noidlen whsp ] [ "SINGLE-VALUE" whsp ] [ "COLLECTIVE" whsp ] [ "NO-USER-NOTIFICATION" whsp ] [ "USAGE" whsp AttributeUsage ] whsp ")" In each attribute, a numericoid should be given. This is the OID Used by LDAP system and should be uniform. Let’s dive deeper into the meaning of each syntax: - NAME
- Defined the attribute’s name. This name should be unique globally (in system). The name is a pair of two string, and written inside of parenthesis. The first string is alias which usually abbreaviation of the second string. The second string is the ful string. If the string is composed of two or more word, it should be trimmed so there is no whitespace.
- DESC
- Description for this attribute.
- OBSOLETE
- Optional. When this attribute is defined as obsolete, LDAP is informed that the attribute is obsoleted and should not be used.
- SUP
- Optional. Define parent of this attribute.
- EQUALITY caseIgnorematch
- Define the properties of this attribute where a searching operation is used over this attribute.A searching can be done in two mode: case sensitive and case insensitive. If a case insensitive mode is desired, we have to declared the attribute using matchingRule caseIgnoreMatch. matchingRule is a special purpose attribute for searching.
- More information about LDAP searching could be read from corresponding article.
- ORDERING ‘matchingRule’
- Used for matching rules of attributes combination.
- SUBSTR ‘caseIgnoreSubstringMatch’
- Define properties of this attribute when used in searching operation based on substring. The searching operation can be done in case insensitive or using matchingRule caseIgnoreSubstringMatch.
- SYNTAX
- Define oid of this attribute.
- SINGLE-VALUE
- Define whether this attribute can be used once in object class. For example: an attribute PersonName should only used once within a class. When not defined as SINGLE-VALUE, LDAP will automatically infer that the attribute can be used multiple times.
Now let’s define a simple attribute as an example: attributetype ( 2.3.4.5 NAME ( 'cn' 'commonName' ) SUP name ) Here is the relation of attributes with schema and object class  |
LDAP Object Class Posted: 14 May 2013 09:09 AM PDT The concept of object here is similar to concept of object in Object Oriented Programming. In Lightweight Directory Access Protocol (LDAP), object class is a set of attributes.It is defined inside a schema and may be organized in a hierarchy. This concept is similar to object in real world, where object in real world might consists of other elements. For example: a car is assembly of tire, wheel, chassis, engine, etc. An object class is not different from that. An object in LDAP is a collection of attributes. When we said a class (in object class) we refer to the design / blueprint. We can create as many car as we want from a blueprint with same specification, same power, same dimension, everything same. And also object class is. An object class is a blueprint to create an object we can use in LDAP. When an object is created, it is an instance of an object class. Object class is hierarchical. It can inherit attributes from its parent. In real world, we can say that an object motorcycle is derived from a bicycle. It is a bike with an engine. In LDAP, we can see that object class InetOrgPerson is a descendant of object class organizationalPerson and inherit avery attributes organizationalPerson has. To define an object class, we follow this syntax: objectclass whsp "(" whsp numericoid whsp [ "NAME" qdescrs ] [ "DESC" qdescrs ] [ "OBSOLETE" whsp ] [ "SUP" oids ] [ ( "ABSTRACT" / "STRUCTURAL" / AUXILIARY" ) whsp ] [ "MUST" oids ] [ "MAY" oids ] whsp ")" An object class is declared by a keyword objectclass and followed by a whitespace (whsp) and a numericoid or Organizational Identification number. This number should be unique globally if we want to build an enterprise system. The numericoid is used for identifying object class, attributes, syntax, matching rules, etc. The numericoid is assigned by IANA. If you want to build an enterprise level and a production machine, please acquired one. If you just want to experiment, you can do that in private network with any numericoid. Let’s dive deeper into the object class declaration: - NAME
- Defined the object class’ name. This name should be unique globally.
- DESC
- Description for this object class.
- OBSOLETE
- Optional. When this object class is defined as obsolete, LDAP is informed that the object class is obsoleted and should not be used.
- SUP
- Optional. Define parent / super class of this object class. The object class given in this argument will act as parent and the newly create object class will inherit all properties from the parent object class.
- ABSTRACT / STRUCTURAL / AUXILIARY
- Define types of object class.
- An abstract class defining an abstract class / non existing class / class that should not be exists. Well this is ambiguous, but it means the abstract class can not be instantiated in DIT.
- A structural class defining a common node in hierarchy. The class can be instantiated as a node in LDAP tree (DIT).
- An auxiliary class is an object with attributes but unlike structural class, it cannot create its own instance in DIT. This object should be used as auxiliary of complement of structural class.
- MUST
- Define attributes that should be exists if we want to use this object. The given object should be written as a list separated by dollar sign $.
- MAY
- Define optional attributes that can exists in this class.
Let see one example: objectclass ( 2.3.4.5 NAME 'country' SUP top STRUCTURAL MUST c MAY ( searchGuide $ description ) ) We can write them cascade like in the example, or as one long line. In above example, we define an object class with OID 2.3.4.5. This object class’ name is country having top as a parent. This class is structural. An attribute countryName or c should declared before using this object. Attribute searchGuide is an optional. Here is the relation of object class with schema and attributes:  |
Installing WebUI: LuCI Posted: 14 May 2013 09:05 AM PDT LuCI is a Web User Interface for accessing OpenWRT. For some version of OpenWRT, it is included. For one who want simplicity, WebUI might be suitable as it support router’s administration using graphics. But on some release, LuCI is not included by default. Therefore we need to install it manually. Before proceeding, at least you know how to use opkg. If not, please refer to this, or this page for detail instruction. Listing the Packages To see all available packages to administer OpenWRT through LuCI, use following command on terminal: opkg update opkg list luci-* Installation via package repository Retrieve current list of available packages in repository. If you think your list is up to date, then it is optional step. opkg update Installing LuCI without HTTPS support: opkg install luci If you desire for HTTPS support, install this: opkg install luci-ssl Offline Installation If you plan for offline installation, you can download the packages and transfer them to OpenWRT box into the RAM disk in /tmp/luci-offline-packages (the folder might be not exists, create it first or use other folder in /tmp). This is the list of packages we need: -
liblua -
lua -
libuci-lua -
libubus-lua -
uhttpd -
luci-lib-ipkg -
luci-i18n-english -
luci-sgi-cgi -
luci-lib-core -
luci-lib-nixio -
luci-lib-sys -
luci-lib-web -
luci-proto-core -
luci-theme-base -
luci-theme-openwrt -
luci-mod-admin-core -
luci-mod-admin-full Installation can be done using: for pkg in liblua lua libuci-lua libubus-lua uhttpd luci-lib-ipkg luci-i18n-english luci-sgi-cgi luci-lib-core luci-lib-nixio luci-lib-sys luci-lib-web luci-proto-core luci-theme-base luci-theme-openwrt luci-mod-admin-core luci-mod-admin-full; do opkg install /tmp/luci-offline-packages/$pkg*.ipk; done Additionally, the following packages are needed for basic wireless configuration: libiw, libiwinfo, libiwinfo-lua. Starting LuCI (uHTTPd) server) To enable and start LuCI, invoke following commands: /etc/init.d/uhttpd enable /etc/init.d/uhttpd start Notes When install LuCI using this article guide’s we are install it on top of Apache Web Server. |