Blog

LDAP CONFIGURATION FOR USER AND GROUP CENTRALISED AUTHENTICATION ON UBUNTU 12.04 LTS – PART-1

Tags: autofsautomountcentralized authenticationdatabaseldap clientldap servernfsquotaubuntu server

Published on: June 12, 2012 by Scott S

LDAP CONFIGURATION FOR USER AND GROUP CENTRALISED AUTHENTICATION ON UBUNTU 12.04 LTS – PART-1

Scenario:

I’m breaking down the tutorial into three parts, where the first part (PART-1) explains the basic user and group centralization, the second part (PART-2) explains how to setup automatic mounting of ldap user home directory using nfs and autofs, setting up disk quotas for ldap users and allowing an ldap user to change his own password and the third part (PART-3) helps to configure TLS (SSL cert based) LDAP authentication.

PART-1

Before going directly into the configurations, I’ll explain the basic concepts of LDAP. LDAP stands for Lightweight Directory Access Protocol. If you want to make a directory information available over the network, this is the way to do it. What makes LDAP so useful is that it works over TCP/IP networks, so the information can be accessed through LDAP by anyone with an internet connection as well. It is also an open protocol, which means directories can be stored on any type of machine (i.e. Windows 2000, Red Hat Linux, Ubuntu, Mac OS X). The protocol is client-server related, where the client makes requests to the server and the server addresses those requests. So basically LDAP is a protocol that is designed to access information.

One thing to keep in mind is that LDAP is a directory not a database. So wherever I use the term database, I’m referring LDAP directory. One major advantage of LDAP directory over database is that directories are designed for reads while a database is really designed to read and write. This makes directories much faster for finding information. You will need to have a clear idea about object oriented programming model for better understanding about the LDAP Directory structure in detail.

Object Oriented Model was introduced to make the application development in a more structural and organized way. This basically works on the concept of objects and classes. I’ll explain the basics of a class and an object here using a real life example. If I want to develop an application to store the details of certain cars, I’ll create a class named cars. Then I’ll define attributes like color, no: of gears, model etc to the class. Once the class attributes are defined, I’ll create a new object called Mercedes-Benz under car class. Then we can assign values to the newly created object using the attributes of class cars. So a class is a collection of objects having similar attribute types. Basics of C++/Java or any other OOPs programming language is an added advantage for learning the concepts of Object Oriented Programming and LDAP.

LDAP works on the same principle. All the data or information are stored in directories/databases as variables and objects in a tree structure. The properties of the objects or variables are defined by the class it belongs to.

Before going further we should know what a SCHEMA is:

Schemas are something that packages or combines almost similar objectClasses and attributes. It is basically the the “design” of our directory structure. An objectClass is an attribute that helps to assign classes to objects. It defines the name of the class an object belongs to. ObjectClasses contain zero or more attributes. Attributes have names (and sometimes abbreviations or aliases) and typically contain data/information. An objectClass will have a name and set of mandatory and optional attributes.

For example an objectClass named organizationalPerson, defines sn and cn as mandatory attributes and userPassword, telephoneNumber, seeAlso and description as optional fields. A couple of those attributes probably need explaining. sn is surname and cn is common name, which we can use to store the person’s full name.

So an object defined in this class will share the attribute of the objectClasses defined. The objectClass may be part of a hierarchy in which it inherits all the characteristics of its parent objectClasses. There are a plenty of objectClasses available in the default LDAP default package which contains the attributes for almost all common applications. We can create custom objectClasses and add attributes to it based on the application we develop. But that are advanced configurations which I’m not covering in this tutorial.

Data is represented in an LDAP enabled directory as a hierarchy of objects, each of which is called an entry. The resulting tree structure is called a Data Information Tree (DIT). The top of the tree is commonly called the root or base DN.

Each entry in the tree has one parent entry (object) and zero or more child entries (objects). Each child entry (object) is a sibling of its parent’s other child entries. Most important thing to remember is that an entry(object) can be composed of (is an instance of) one or more objectClasses.

As I mentioned that LDAP has a tree directory structure a root node(object) must exist, which is called the base DN or root (DN= Distinguished Name). Base DN is used to uniquely identify the root of the DIT(Directory Information Tree) which is helpful in fetching data by starting the search from the root of ldap directory. DN is used to identify a particular object uniquely. A DIT is the complete tree structure of our LDAP directory tree.

We now need to know how to add objects/data to an LDAP directory. Here is where we learn about LDIF(LDAP Data Interchange Format) files.

The tree structure and initial population of data is performed by adding entries (with their associated objectClasses and attributes) starting from the root of the DIT and progressing down the hierarchy. Thus, a parent entry must always have been added before attempting to add any child entries. Adding entries may be done in a variety of ways, one of which is using LDIF files which I’m explaining in this tutorial. LDIFs are text files that describe the tree hierarchy (Directory Information Tree (DIT)) and the data to be added to each attribute. I’ll explain how the data is added to the LDAP directory as and when I’m explaining the configuration of LDAP on Ubuntu server LTS 12.04 below:

Let us now get into the actual configuration of LDAP for user centralization. I’m explaining the concepts of LDAP needed to set-up centralized user and groups for remote login on ubuntu 12.04.

For using LDAP as authentication of user accounts, we can use the posixAccount objectClass. This is an auxiliary class (class that inherits another class properties) and adds cn, uid, uidNumber, gidNumber and homeDirectory mandatory attributes and userPassword, loginShell, gecos and description as optional attributes.

The LDAP directory is a tree structure with a root node or the admin node under which all other nodes reside. We will begin with a basic tree containing two nodes below the root: (note that the node I’m referring is the Root directory object.

People” node where your users will be stored

Groups” node where your groups will be stored

Because posixAccount objectClass is auxiliary, we can add it to our People object for people/users that we want to authenticate.

I’m using my primary base DN as mentioned below:

dc=int,dc=sages,dc=com

so my FQDN is int.sages.com which is my root object.

Here dc is Domain Component. This is also part of a DN, and is often used to define the name of your top-level-domain/directory.

LDAP SERVER CONFIGURATION:

With the assumption that Ubuntu 12.04 LTS Server is already installed and hostname set to ldapserver.int.sages.com. You can use your desired hostname. But make sure that the hostname resolves correctly to the the ldap server. You can use the server IP(192.168.1.xxx) to configure LDAP if the DNS is not set for the hostname.

First login to the ubuntu server 12.04 LTS as root:

root@ubuntuserver:]#

make sure all the packages are updated and upgraded by running the following command

root@ubuntuserver:]# apt-get update && apt-get upgrade -y

Once all the packages are updated we are ready to install the LDAP packages and the necessary utils. You can install by the following command :

root@ubuntuserver:]# apt-get install slapd ldap-utils -y

During the installation you will be prompted for a ldap admin password twice which needs to be set. (screenshot shown below) I’m using the password as “sages123” in this tutorial.

(click to enlarge all screenshots)

Re-enter you Password once again.

Some additional information needs to be configured for slapd. Run the following command to reconfigure slapd

root@ubuntuserver:]# dpkg-reconfigure slapd

You will get a curses based CUI to reconfigure slapd. Configure slapd using the details mentioned below:

-> Omit OpenLDAP server configuration? No

->DNS domain name: The installation will ask for the DNS domain name. The DNS domain name is used to construct the base DN of the LDAP directory. My DNS Domain name will be int.sages.com. Configure the base DNS domain accordingly for your domain. The base DN will be the root directory of your LDAP server.

-> Organization Name: Enter the name of the organization to use in the base DN of your LDAP directory. I’m using Support Sages as my Organization name. You can use your’s.

-> Administrator password: You will be prompted to enter the LDAP admin password twice. I’m using sages123 as the password as I mentioned earlier.

Re-enter the password once again:

->Database backend to use: Select HDB as the backend databse to use.

Answer a few questions more:

->Do you want the database to be removed when slapd is purged? NO

->Move old database? Yes

->Allow LDAPv2 protocol? NO

Make sure that the following entries are set correctly in /etc/ldap/ldap.conf. Please note that this is the config file for LDAP server whereas it is /etc/ldap.conf for an LDAP client.

==============================================================

BASE dc=int,dc=sages,dc=com

URI ldap://ldapserver.int.sages.com

SIZELIMIT 12

TIMELIMIT 15

DEREF never

=============================================================

Once these are configured the LDAP server is ready for use.

The slapd configuration is stored as a special LDAP directory with a predefined schema and DIT. There are specific objectClasses used to carry global configuration options, schema definitions, backend and database definitions etc.

The slapd configuration tree has a very specific structure. The root of the tree is named cn=config and contains global configuration settings. Slapd is designed to be configured within slapd itself by specifying  a separate DIT for that purpose. This allows one to dynamically configure slapd without the need to restart the service. This configuration database consists of a collection of text-based LDIF files located under /etc/ldap/slapd.d. This way of working is known by several names: the slapd-config method, the RTC method (Real Time Configuration), or the cn=config method.
The slapd installation process set up two DITs. One for slapd-config(cn=config) and one for our own data
(dc=int,dc=sages,dc=com).

First lets add some logging level for cn=config. The olcLogLevel directive specifies the level at which debugging statements and operation statistics should be syslogged. This logging helps in troubleshooting common issues. For example all the LDAP authentication logs are in /var/log/auth.log by default.

Create a new file log.ldif and the entries as mentioned below:

root@ubuntuserver:]# vi log.ldif
================================
dn: cn=config
changetype: modify
add: olcLogLevel
olcLogLevel: stat
================================

Then use the ldapmodify command to modify cn=config entry(object) as shown below.

root@ubuntuserver:]# ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f log.ldif

You will see an output like:

================================
modifying entry “cn=config”
================================

Once the loglevel is defined, we shall add some indices to ldap database to ease the directory information lookup using olcDbIndex directive.
So what are indicies? They are known ad LDAP indexes. As the name defines it helps to identify entries matching search criteria in an LDAP directory using indexes. Normally in LDAP there are three basic index types implemented:

Equality or Value indexes are used to identify entries containing an attribute value that exactly matches a given value.
Presence indexes are used to identify entries that contain at least one value for a given attribute.
Substring indexes are used to identify entries that contain an attribute value matching a given substring.

Let see how these are implemented in an LDAP server. Open a new file indices.ldif and the entries as mentioned below:

root@ubuntuserver:]# vi indices.ldif
================================
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: uid eq,pres,sub
================================

The fourth line above makes present, equality, and substring indices to be maintained for uid attribute types. The olcDbIndex directive specifies the indices to maintain for the given attribute. The index keywords correspond to the common types of matches that may be used in an LDAP search filter.

Then use the ldapmodify command as shown below:

root@ubuntuserver:]# ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f indices.ldif

You will see an output as shown below:

=======================================
modifying entry “olcDatabase={1}hdb,cn=config”
=======================================

You can see the added indices by typing the following command:

root@ubuntuserver:]# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config ‘(olcDatabase={1}hdb)’ olcDbIndex

You should see the following output:

================================
‘(olcDatabase={1}hdb)’ olcDbIndex
dn: olcDatabase={1}hdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: uid eq,pres,sub
================================

That is it, we have configured our ldap server successfully and is ready to authenticate user.

It is now time to populate our LDAP directory so that we can authenticate  a user. LDAP directory uses LDIF data format. The LDAP Data Interchange Format (LDIF) is used to represent LDAP entries in a simple text format as I mentioned earlier. We can create LDIF files and then use the ldapadd command to add data. The ldap-utils package installed earlier helps to use common LDAP commands like ldapadd, ldapsearch, ldapmodify etc.

Below is an ldif file format for adding one OU named Users for storing user information and another OU named Groups under our base DN dc=int,dc=sages,dc=com

Create a new file named base.ldif and add the entries as given below:

root@ubuntuserver:]#  vi base.ldif

================================

# Create top-level object in domain

dn: dc=int,dc=sages,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: Example Organization
dc: Example
description: LDAP Example

#Creating User object

dn: ou=Users,dc=int,dc=sages,dc=com
objectClass: organizationalUnit
ou: Users

#Creating Group object

dn: ou=Groups,dc=int,dc=sages,dc=com
objectClass: organizationalUnit
ou: Groups

#Creating our first ldapuser “ldapuser1” with uidnumber=10000 and gidnumber=10000 as user under Users OU

dn: uid=ldapuser1,ou=Users,dc=int,dc=sages,dc=com
objectClass: o3. ssl cert authenticationrganizationalPerson
objectClass: person
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: ldapuser1
sn: Sages
givenName: Support
cn: Support Sages
displayName: Support Sages
uidNumber: 10000
gidNumber: 10000
userPassword: sages123
gecos: Support Sages
loginShell: /bin/bash
homeDirectory: /home/ldapuser1
mail: supportsages@gmail.com
telephoneNumber: 000-000-0000
st: NY
manager: uid=ldapuser1,ou=Users,dc=int,dc=sages,dc=com
shadowExpire: -1
shadowFlag: 0
shadowWarning: 7
shadowMin: 8
shadowMax: 999999
shadowLastChange: 10877
title: System Administrator

# Here we are naming the group with gid=10000 as ldapgroup1 under Groups OU

dn: cn=ldapgroup1,ou=Groups,dc=int,dc=sages,dc=com
objectClass: posixGroup
cn: ldapgroup1
gidNumber: 10000

================================

We define all the required attributes like cn(canonical name), homeDirectory, loginShell etc. Make sure to use a gid and uid number such that it doesn’t get conflicted with any of the system created users uid or gid. Also the userPassword attribute must be set correctly. As mentioned earlier,  I’m using sages123 as my slapd admin password. Now we use the ldapadd command to add the ldif file to the LDAP directory as shown below:

root@ubuntuserver:]# ldapadd -x -D cn=admin,dc=int,dc=sages,dc=com -w sages123 -f base.ldif

You will see a similar output as shown below:

==========================================================

adding new entry “OU=Users,dc=int,dc=sages,dc=com”
adding new entry “OU=Groups,dc=int,dc=sages,dc=com”
adding new entry “uid=ldapuser1,OU=Users,dc=int,dc=sages,dc=com”
adding new entry “cn=ldapgroup1,OU=Groups,dc=int,dc=sages,dc=com”
=============================================================
Thats it!! Everything has been setup on the server side. Make sure to create the home directory /home/testuser.

You can test if the ldapuser is added by the following command:

root@ubuntuserver:]# id ldapuser1

This should return the uid and gid of ldapuser1.

Now is the time to learn how to add new users and groups to our LDAP directory. Adding users using ldif file is a difficult process if the number of users are more. To overcome this we can use the ldapscripts.

root@ubuntuserver:]# apt-get install ldapscripts

Next, edit the config file /etc/ldapscripts/ldapscripts.conf uncommenting and changing the following to match your environment:

================================
SERVER=localhost
BINDDN=’cn=admin,dc=int,dc=sages,dc=com’
BINDPWDFILE=”/etc/ldapscripts/ldapscripts.passwd”
SUFFIX=’dc=int,dc=sages,dc=com’
GSUFFIX=’ou=Groups’
USUFFIX=’ou=People’
MSUFFIX=’ou=Computers’
GIDSTART=10000
UIDSTART=10000
MIDSTART=10000
================================
Now, create the ldapscripts.passwd file to allow authenticated access to the directory:

root@ubuntuserver:]# sh -c “echo -n ‘sages123’ > /etc/ldapscripts/ldapscripts.passwd”
root@ubuntuserver:]# chmod 400  /etc/ldapscripts/ldapscripts.passwd

The ldapscripts are now ready to help manage your directory. The following are some examples of how to use the scripts:

root@ubuntuserver:]# ldapaddgroup testgroup 10005

This will create a new group named testgroup with gid 10005

root@ubuntuserver:]#  ldapadduser testuser testgroup

The above command will create a new ldap user named testuser with primary group as testgroup.

root@ubuntuserver:]# ldapsetpassword testuser

The above command helps to set a new login LDAP password for our new user testuser

There are many more scripts like ldapdeleteuser, ldapmodify user etc. You can learn more about ldapscripts at http://manpages.ubuntu.com/manpages/lucid/man5/ldapscripts.5.html .

LDAP CLIENT CONFIGURATION:

Lets now proceed and see how an LDAP client can be setup for user authentication. I’m using UBUNTU DESKTOP 12.04 as my LDAP client.

Once you have a working LDAP server, the auth-client-config and libnss-ldap packages take the pain out of configuring an Ubuntu client to authenticate using LDAP. To install the packages login to LDAP client as root user and enter the following command in a terminal:

ldapclient@ubuntudesktop:]# apt-get install libnss-ldap

During the install a menu dialog will ask you connection details about your LDAP server.

->LDAP server Uniform Resource Identifier (the uri to identify our LDAP server) : ldap://ldapserver.int.sages.com

You can use the IP address of the LDAP server (192.168.1.xxx) if DNS is not configured for hostname.

-> Distinguished Name(DN) for base search: dc=int,dc=sages,dc=com

-> LDAP version to use: 3

-> Make local root database admin: YES

-> Does the LDAP database require login: NO

->LDAP admin account: cn=admin,dc=int,dc=sages,dc=com

-> LDAP root account password:


If you make a mistake when entering your information you can recall the dialog screen again using:

ldapclient@ubuntudesktop:]# dpkg-reconfigure ldap-auth-config

All the configuration are mirrored to /etc/ldap.conf. Make sure all the details are configured correctly in /etc/ldap.conf

Now that libnss-ldap is configured. Enable the auth-client-config LDAP profile by entering:

ldapclient@ubuntudesktop:]# auth-client-config -t nss -p lac_ldap

(-t: only modifies /etc/nsswitch.conf, -p: name of the profile to enable, disable, etc and lac_ldap: the auth-client-config profile that is part of the ldap-auth-config package )

Now use the pam-auth-update utility, configure the system to use LDAP for authentication:

ldapclient@ubuntudesktop:]# pam-auth-update

Make sure LDAP Authentication is also selected along with the already selected authentication methods. After this your /etc/nsswitch.conf file will have the entries for ldap.

You should now be able to login using user credentials stored in the LDAP directory.

To test this :

ldapclient@ubuntudesktop:]# su – testuser

You will be switched to testuser with present working directory as /home/testuser

testuser@ubuntudesktop:]#

This is the basic setup where we use LDAP for user and group centralization. Now lets proceed to PART-2 for further configurations on setting up automatic mounting of ldap user home directory using nfs and autofs, setting up disk quotas for ldap users and allowing an ldap user to change his own password.

PART-1

Before going directly into the configurations, I’ll explain the basic concepts of LDAP. LDAP stands for Lightweight Directory Access Protocol. If you want to make a directory information available over the network, this is the way to do it. What makes LDAP so useful is that it works over TCP/IP networks, so the information can be accessed through LDAP by anyone with an internet connection as well. It is also an open protocol, which means directories can be stored on any type of machine (i.e. Windows 2000, Red Hat Linux, Ubuntu, Mac OS X). The protocol is client-server related, where the client makes requests to the server and the server addresses those requests. So basically LDAP is a protocol that is designed to access information.

One thing to keep in mind is that LDAP is a directory not a database. So wherever I use the term database, I’m referring LDAP directory. One major advantage of LDAP directory over database is that directories are designed for reads while a database is really designed to read and write. This makes directories much faster for finding information. You will need to have a clear idea about object oriented programming model for better understanding about the LDAP Directory structure in detail.

Object Oriented Model was introduced to make the application development in a more structural and organized way. This basically works on the concept of objects and classes. I’ll explain the basics of a class and an object here using a real life example. If I want to develop an appliation to store the details of certain cars, I’ll create a class named cars. Then I’ll define attributes like colour, no: of gears, model etc to the class. Once the class attributes are defined, I’ll create a new object called Mercedes-Benz under car class. Then we can assign values to the newly created object using the attributes of class cars. So a class is a collection of objects having similar attribute types. Basics of C++/Java or any other OOPs programming language is an added advantage for learning the concepts of Object Oriented Programming and LDAP.

LDAP works on the same principle. All the data or information are stored in directories/databases as variables and objects in a tree structure. The properties of the objects or variables are defined by the class it belongs to.

Before going further we should know what a SCHEMA is:

Schemas are something that packages or combines almost similar objectClasses and attributes. It is basically the the “design” of our directory structure. An objectClass is an attribute that helps to assign classes to objects. It defines the name of the class an object belongs to. Objectclasses contain zero or more attributes. Attributes have names (and sometimes abbreviations or aliases) and typically contain data/information. An objectClass will have a name and set of mandatory and optional attributes.

For example an objectClass named organizationalPerson, defines sn and cn as mandatory attributes and userPassword, telephoneNumber, seeAlso and description as optional fields. A couple of those attributes probably need explaining. sn is surname and cn is common name, which we can use to store the person’s full name.

So an object defined in this class will share the attribute of the objectClasss defined. The objectclass may be part of a hierarchy in which it inherits all the characteristics of its parent objectclasses. There are a plenty of objectClasses available in the default LDAP default package which contains the attributes for almost all common applications. We can create custom objectClasses and add attributes to it based on the application we develop. But that are advanced configurations which I’m not covering in this tutorial.

Data is represented in an LDAP enabled directory as a hierarchy of objects, each of which is called an entry. The resulting tree structure is called a Data Information Tree (DIT). The top of the tree is commonly called the root or base DN.

Each entry in the tree has one parent entry (object) and zero or more child entries (objects). Each child entry (object) is a sibling of its parent’s other child entries. Most important thing to remember is that an entry(object) can be composed of (is an instance of) one or more objectClasses.

As I mentioned that LDAP has a tree directory structure a root node(object) must exist, which is called the base DN or root (DN= Distinguished Name). Base DN is used to uniquely identify the root of the DIT(Directory Information Tree) which is helpful in fetching data by starting the search from the root of ldap directory. DN is used to identify a particular object uniquely. A DIT is the complete tree structure of our LDAP directory tree.

We now need to know how to add objects/data to an LDAP directory. Here is where we learn about LDIF(LDAP Data Interchange Format) files.

The tree structure and initial population of data is performed by adding entries (with their associated objectClasses and attributes) starting from the root of the DIT and progressing down the hierarchy. Thus, a parent entry must always have been added before attempting to add any child entries. Adding entries may be done in a variety of ways, one of which is using LDIF files which I’m explaining in this tutorial. LDIFs are text files that describe the tree hierarchy (Directory Information Tree (DIT)) and the data to be added to each attribute. I’ll explain how the data is added to the LDAP directory as and when I’m explaining the configuration of LDAP on Ubuntu server LTS 12.04 below:

Let us now get into the actual configuration of LDAP for user centralization. I’m explaining the concepts of LDAP needed to set-up centralized user and groups for remote login on ubuntu 12.04.

For using LDAP as authentication of user accounts, we can use the posixAccount objectClass. This is an auxiliary class (class that inherits another class properties) and adds cn, uid, uidNumber, gidNumber and homeDirectory mandatory attributes and userPassword, loginShell, gecos and description as optional attributes.

The LDAP directory is a tree structure with a root node or the admin node under which all other nodes reside. We will begin with a basic tree containing two nodes below the root: (note that the node I’m referring is the Root directory object.

“People” node where your users will be stored

“Groups” node where your groups will be stored

Because posixAccount objectClass is auxiliary, we can add it to our People object for people/users that we want to authenticate.

I’m using my primary base DN as mentioned below:

dc=int,dc=sages,dc=com

so my FQDN is int.sages.com which is my root object.

here dc is Domain Component. This is also part of a DN, and is often used to define the name of your top-level-domain/directory.

LDAP SERVER CONFIGURATION:

With the assumption that Ubuntu 12.04 LTS Server is already installed and hostname set to ldapserver.int.sages.com. You can use your desired hostname. But make sure that the hostname resolves correctly to the the ldap server. You can use the server IP(192.168.1.xxx) to configure LDAP if the DNS is not set for the hostname.

First login to the ubuntu server 12.04 LTS as root:

root@ubuntuserver:]#

make sure all the packages are updated and upgraded by running the following command

root@ubuntuserver:]# apt-get update && apt-get upgrade -y

Once all the packages are updated we are ready to install the LDAP packages and the necessary utils. You can install by the following command :

root@ubuntuserver:]# apt-get install slapd ldap-utils -y

During the installation you will be prompted for a ldap admin password twice which needs to be set. (screenshot shown below) I’m using the password as “sages123” in this tutorial.

Category : General, Howtos, Linux, Training

Scott S

Scott S

Scott follows his heart and enjoys design and implementation of advanced, sophisticated enterprise solutions. His never ending passion towards technological advancements, unyielding affinity to perfection and excitement in exploration of new areas, helps him to be on the top of everything he is involved with. This amateur bike stunting expert probably loves cars and bikes much more than his family. He currently spearheads the Enterprise Solutions and Infrastructure Consultancy wing of SupportSages.

You may also read:

Comments

Add new commentSIGN IN

Let's Connect

Get new updates

Categories

$0.000 items