<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>-= n8v =- &#187; MySQL</title>
	<atom:link href="http://n8v.enteuxis.org/tags/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://n8v.enteuxis.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 27 Sep 2011 00:52:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2-beta2-18055</generator>
		<item>
		<title>LDAP powered by MySQL on RHEL5</title>
		<link>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/</link>
		<comments>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 02:01:12 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=133</guid>
		<description><![CDATA[Background We need a quick-and-dirty LDAP server with basically a list of usernames and passwords to point Cisco ACS gear at, in order to provide people with limited-time authentication tokens to a wireless network. I need to populate that with an HL7 interface in Perl and make a web app UI frontend (preferably using symfony). [...]]]></description>
			<content:encoded><![CDATA[<h3>Background</h3>

<p>We need a quick-and-dirty <abbrev title="Lightweight Directory Access Protocol">LDAP</abbrev> server with basically a list of usernames and passwords to point Cisco ACS gear at, in order to provide people with limited-time authentication tokens to a wireless network.  I need to populate that with an <a href="http://hl7toolkit.sf.net">HL7 interface in Perl</a> and make a web app UI frontend (preferably using symfony).  The latter two interfaces are well established around here with MySQL, so I am trying to use OpenLDAP&#8217;s SQL backend to make that happen naturally.</p>

<h4>Simplifications</h4>

<p>Unlike other similar implementations out there, I have smaller goals:</p>

<ul>
    <li>The database will be updated/written by the HL7 interface and web interface.  The LDAP tools don&#8217;t need to write to it.</li>
    <li>All my user data should fit nicely into two tables (users and groups&#8230; and another table to relate many-to-many), and two Objectclasses in LDAPland.</li>
</ul>

<p><span id="more-133"></span></p>

<h3>Resources</h3>

<p>These were unexpectedly hard to Google up, which is partly why I&#8217;m documenting them here for Posterity.</p>

<ul>
    <li>Zytrax has an open source book about LDAP entitled <a href="http://www.zytrax.com/books/ldap/">LDAP for Rocket Scientists</a>, which has <a href="http://www.zytrax.com/books/ldap/ch2/index.html#basic">an excellent chapter about LDAP concepts</a>, which is nice since I don&#8217;t really understand LDAP like I do the other technologies involved.</li>

    <li><a href="http://www.openldap.org/doc/admin24/backends.html#SQL">Section &#8220;10.10.2. back-sql Configuration&#8221; of the OpenLDAP manual</a></li>
    <li>The <a href="http://linux.die.net/man/5/slapd-sql">slapd-sql man page</a> is indispensible.  See especially the &#8220;METAINFORMATION USED&#8221; section.</li>
    <li>The <a href="http://www.openldap.org/devel/cvsweb.cgi/~checkout~/servers/slapd/back-sql/rdbms_depend/README?rev=1.4.4.1&#038;hideattic=1&#038;sortbydate=0">README that comes with the back-sql samples</a></li>
    <li>The samples themselves (either unpack <var>servers/slapd/back-sql/rdbms_depend/mysql</var> from the <a href="http://www.openldap.org/software/download/">source tarball </a>or <a href="http://www.openldap.org/devel/cvsweb.cgi/servers/slapd/back-sql/rdbms_depend/mysql/?hideattic=1&#038;sortbydate=0">browse them</a>, but you&#8217;ll probably want them unpacked so you can feed the schema to the <var>mysql </var> client.  MOST OF WHAT YOU NEED TO LEARN is demonstrated in the samples.</li>
    <li>This <a href="http://www.flatmtn.com/article/setting-ldap-back-sql#LdapBacksql-2">4-year-old blog article at/by &#8220;Flat Mountain&#8221;</a> is sketchy but an improvement over the documents above!</li>
    <li><a href="http://www.docunext.com/blog/2006/10/openldap-mysql-documentation.html">Albert Lash at DocuNext has a 2-year-old post similar to this one </a> with another list of fine references! 
    <li>This <a href="http://www.darold.net/projects/ldap_pg/HOWTO/index.html">HOWTO for OpenLDAP and Postgresql</a> by Gilles Darold is far superior than the other articles, but needs adaptation of course for MySQL</li>
    <li>Likewise, here&#8217;s <a href="http://www.easysoft.com/applications/openldap/back-sql-odbc.html">a good article for doing the same thing with Oracle/MSSQL</a></li>
    <li>And here are some <a href="http://www.cmu.edu/acs/ldap/sql_notes">extended notes from someone who did it with Oracle</a>, including another explanation of the data mapping part.</li>

</ul>

<h3>I. Install Stuff</h3>

<p>I&#8217;m using <abbr title="Red Hat Enterprise Linux 5.0">RHEL5</abbr> on a virtual machine.  Your package system may vary.  You may in fact have to compile from source to get SQL support in LDAP.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> yum <span class="kw2">install</span> openldap openldap-clients openldap-servers openldap-devel openldap-servers-sql</pre></div></div>


<h3>II. Get and unpack the source code for the MySQL samples</h3>

<ol>
    <li><a href="http://www.openldap.org/software/download/">Download the source tarball</a> to your machine</li>
    <li>Unpack it


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">tar</span> zxf openldap-stable-<span class="nu0">20080813</span>.tgz</pre></div></div>



</li>
</ol>

<h3>III. Create the database and tables</h3>

<p>Make sure the mysql server is running of course.  We&#8217;re assuming it&#8217;s on the same host as the LDAP server.</p>

<p>Create the database (<samp>my_db_name</samp>) and a password-having user (<samp>my_mysql_user</samp>) with all privileges to that database (I recommend the MySQL Administrator GUI for this, strangely enough since I usually dislike clicking on stuff).  You should be able to connect to your database like this now:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ mysql -umy_mysql_user <span class="re5">-pxxxxxxxxxxxxx</span>  my_db_name</pre></div></div>


<p>Build the tables that configure how OpenLDAP talks to the database.</p>

<ol>
    <li><var>cd</var> into <var>servers/slapd/back-sql/rdbms_depend/mysql</var> from the unpacked openldap source</li>
    <li>Feed <var>backsql_create.sql</var> to the &#8216;mysql&#8217; client


<div class="wp_syntax"><div class="code"><pre class="bash">$ mysql -umy_mysql_user <span class="re5">-pxxxxxxxxxxxxx</span>  my_db_name <span class="sy0">&lt;</span> backsql_create.sql</pre></div></div>



</li>
</ol>

<h3>IV. Hack the basic config files</h3>

<h4>a. <var>slapd.conf</var></h4>

<p>Basically I&#8217;m starting from the <var>slapd.conf</var> in the rdbms_depend/mysql sample (see above), but folding in some RedHatese file locations from the distributed <var>slapd.conf</var>.</p>

<p>I define an adminstrative user with the <code>rootdn </code> and <code>rootpw</code> directives.  Use <var>slappasswd</var> to generate the hashed password:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ slappasswd <span class="re5">-h</span> <span class="br0">&#123;</span>crypt<span class="br0">&#125;</span></pre></div></div>


<p>and type in the password.  It will spit out the string you need, which is prefixed by the algorithm in curly braces.</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># See slapd.conf<span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span> for details on configuration options.
# This file should NOT be world readable.
#
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
&nbsp;
pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args
# Timeout in seconds, <span class="nu0">0</span> <span class="sy0">=</span><span class="re2"> never</span>
idletimeout     <span class="nu0">30</span>
threads         <span class="nu0">32</span>
# Debuging level, <span class="nu0">0</span> <span class="sy0">=</span><span class="re2"> none</span>
loglevel        <span class="nu0">32</span>
&nbsp;
# THIS IS IMPORTANT-- without it you will get <span class="st0">&quot;&lt;database&gt; failed init (sql)!&quot;</span>
# Load dynamic backend modules:
modulepath    /usr/lib/openldap
# modules available in openldap-servers-sql RPM package:
moduleload back_sql.la
&nbsp;
&nbsp;
#######################################################################
# SQL Database Definitions
#######################################################################
&nbsp;
database        sql
suffix          <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span>
rootdn          <span class="st0">&quot;cn=root,ou=Users,ou=Junk,ou=AK,DC=,mycompany,DC=com&quot;</span>
rootpw          <span class="br0">&#123;</span>CRYPT<span class="br0">&#125;</span>xxxxxxxxxxxx
&nbsp;
#  The name of the ODBC datasource <span class="br0">&#40;</span>from odbc.ini,
#     not necessarily the database instance<span class="br0">&#41;</span> to use.
dbname          my_database
dbuser          my_database_user
dbpasswd        xxxxxxxxxxxxxxxx
&nbsp;
# this is important because my simple view for the ldap_entries table
# has no 'organization' object.  See `man slapd-sql`.
baseObject
&nbsp;
subtree_cond    <span class="st0">&quot;ldap_entries.dn LIKE CONCAT('%',?)&quot;</span>
insentry_stmt   <span class="st0">&quot;INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)&quot;</span>
has_ldapinfo_dn_ru      no
&nbsp;
&nbsp;
#######################################################################
# Access Control
#    see http://www.openldap.org/doc/admin24/access-control.html
#    and `man slapd.access`
#######################################################################
&nbsp;
# Here we define who can see which parts of the directory
&nbsp;
# Hide the password attribute <span class="br0">&#40;</span>except for the root user of course<span class="br0">&#41;</span> but
#   allow authentication against it
access to attrs<span class="sy0">=</span><span class="re2">userPassword</span>
        by anonymous auth
        by * none
&nbsp;
# don't allow anonymous access
# allow authenticated users to see their own entry
access to *
        by self read
        by * none</pre></div></div>


<p>I started without the Access Control section and added it after I had things basically working.</p>

<h4>b. ODBC config files</h4>

<p>In my case they are in <var>/etc/odbc.ini</var> and <var>/etc/odbcinst.ini</var> already existed and just needed a MySQL section added to <var>odbcinst.ini</var> and a section for this particular database in <var>odbc.ini</var>, but I had to get the paths right for Red Hat.  See the MySQL section of step 2 of the <a href="http://www.openldap.org/devel/cvsweb.cgi/~checkout~/servers/slapd/back-sql/rdbms_depend/README?rev=1.5&#038;hideattic=1&#038;sortbydate=0">samples README document</a></p>

<p><var>/etc/odbcinst.ini</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># Driver from the MyODBC package
# Setup from the unixODBC package
<span class="re0"><span class="br0">&#91;</span>MySQL<span class="br0">&#93;</span></span>
<span class="re1">Description</span>     <span class="sy0">=</span><span class="re2"> ODBC for MySQL</span>
<span class="re1">Driver</span>          <span class="sy0">=</span><span class="re2"> /usr/lib/libmyodbc3.so  # note, filename includes a 3, differs from docs</span>
<span class="re1">Setup</span>           <span class="sy0">=</span><span class="re2"> /usr/lib/libodbcmyS.so</span>
<span class="re1">FileUsage</span>       <span class="sy0">=</span><span class="re2"> 1</span></pre></div></div>


<p><var>/etc/odbc.ini</var></p>


<div class="wp_syntax"><div class="code"><pre class="ini"><span class="re0"><span class="br0">&#91;</span>my_database<span class="br0">&#93;</span></span>
<span class="re1">Description</span>         <span class="sy0">=</span><span class="re2"> my database</span>
<span class="re1">Driver</span>              <span class="sy0">=</span><span class="re2"> MySQL</span>
<span class="re1">Trace</span>               <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">Database</span>            <span class="sy0">=</span><span class="re2"> my_db_name</span>
<span class="re1">Servername</span>          <span class="sy0">=</span><span class="re2"> localhost</span>
<span class="re1">UserName</span>            <span class="sy0">=</span><span class="re2"> my_database_user</span>
<span class="re1">Password</span>            <span class="sy0">=</span><span class="re2"> xxxxxxxxxxxxxxxxx</span>
<span class="re1">ReadOnly</span>            <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">RowVersioning</span>       <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ShowSystemTables</span>    <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ShowOidColumn</span>       <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">FakeOidIndex</span>        <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ConnSettings</span>        <span class="sy0">=</span>
<span class="re1">SOCKET</span>              <span class="sy0">=</span><span class="re2"> /var/lib/mysql/mysql.sock</span></pre></div></div>


<p>(OK, here&#8217;s where I dinked with the example database and read lots of examples and stuff, but hopefully you can skip that because of this excellent documentation <img src='http://n8v.enteuxis.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>

<h3>V. Create and populate your user and group tables</h3>

<p>These are my basic tables of users and groups:</p>


<div class="wp_syntax"><div class="code"><pre class="sql"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_user <span class="br0">&#40;</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  username <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  password <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  first_name <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  last_name <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="sy0">,</span>username<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_group <span class="br0">&#40;</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  <span class="st0">`name`</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_group_member <span class="br0">&#40;</span>
  <span class="co1">-- unique id isn't necessary but easier for symfony</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  my_user_id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  my_group_id <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">,</span>
  <span class="kw1">UNIQUE</span> <span class="kw1">KEY</span> uniquepair <span class="br0">&#40;</span>my_user_id<span class="sy0">,</span>my_group_id<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;</pre></div></div>


<p>You&#8217;ll need to populate the tables with a user or two and at least one group, of course.</p>

<h3>VI. Insert the special configuration rows</h3>

<p>I entered these data sets using the <a href="http://dev.mysql.com/downloads/gui-tools/">MySQL Administrator</a> GUI.  The most helpful explanation was in the &#8220;METAINFORMATION USED&#8221; section of the <a href="http://linux.die.net/man/5/slapd-sql">slapd-sql man page</a>.</p>

<p>Basically, the <samp>ldap_*</samp> tables show the SQL backend how to map the database tables onto LDAP objects.  <a href="http://www.oav.net/mirrors/LDAP-ObjectClasses.html#atDisplayName">This is a nice reference to the common LDAP object schemas</a>.  That&#8217;s important because you can only map your database fields to fields in the schema for the objectClass you&#8217;re using (unless you want to start making your own schema, which is beyond my scope here).  In my case I&#8217;m using <var>inetOrgPerson</var>, which inherits from <var>organizationalPerson</var>, which inherits from <var>Person</var>, and for groups, <var>groupOfUniqueNames</var>.</p>

<p>The <strong>ldap_entry_objclasses</strong> table needs one row for each objectClass we&#8217;re using:</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>entry_id</th><th>oc_name</th></tr>
<tr>
<td>1</td><td>inetOrgPerson</td></tr>
<tr>
<td>2</td><td>groupOfUniqueNames</td></tr>
</table>

<p>The <strong>ldap_oc_mappings</strong> table also has a row for each objectClass, and it shows the sql backend how to find objects corresponding to those object classes.</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>id</th><th>name</th><th>keytbl</th><th>keycol</th><th>create_proc</th><th>delete_proc</th><th>expect_return</th></tr>
<tr>
<td>1</td><td>inetOrgPerson</td><td>my_user</td><td>id</td><td></td><td></td><td>0</td></tr>
<tr>
<td>2</td><td>groupOfUniqueNames</td><td>my_group</td><td>id</td><td></td><td></td><td>0</td></tr>
</table>

<p>The <strong>ldap_attr_mappings</strong> table is the most complex part.  Basically you&#8217;re showing the sql backend how to build queries that map the database columns onto LDAP attributes.</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>id</th><th>oc_<wbr />map_<wbr />id</th><th>name</th><th>sel_<wbr />expr</th><th>sel_<wbr />expr<wbr />_u</th><th>from_tbls</th><th>join_where</th><th>add_proc</th><th>delete_<wbr />proc</th><th>param_<wbr />order</th><th>expect_<wbr />return</th></tr>
<tr>
<td>1</td><td>1</td><td>cn</td><td>concat( first_name, &#8216; &#8216;, last_name )</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>2</td><td>1</td><td>givenName</td><td>first_name</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>3</td><td>1</td><td>sn</td><td>last_name</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>4</td><td>1</td><td>userPassword</td><td>password</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>5</td><td>1</td><td>uid</td><td>username</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>7</td><td>2</td><td>cn</td><td>name</td><td></td><td>my_group</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>8</td><td>2</td><td>uniqueMember</td><td>dn</td><td></td><td>my_group, my_<wbr />group_<wbr />member gu, my_<wbr />user u, ldap_<wbr />entries</td><td>my_group.id = gu.<wbr />my_<wbr />group_<wbr />id and gu.<wbr />my_<wbr />user_<wbr />id = u.id and oc_<wbr />map_<wbr />id = 1 and keyval = u.id</td><td></td><td></td><td>3</td><td>0</td></tr>
</table>

<h4>Create a view for the <abbrev title="Distinguished Name">DN</abbrev>s in ldap_entries</h4>

<p>I&#8217;m going to use the username field in my DN instead of the common name (CN) in most examples, because it&#8217;s more guaranteed to be unique, and <a href="http://www.zytrax.com/books/ldap/apa/dn-rdn.html">it is apparently OK to do so</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="sql"><span class="kw1">DROP</span> <span class="kw1">TABLE</span> ldap_entries;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">VIEW</span> ldap_entries <span class="kw1">AS</span>
  <span class="kw1">SELECT</span> 
    <span class="co1">-- differentiate id spaces here </span>
    <span class="br0">&#40;</span><span class="nu0">100000</span> <span class="sy0">+</span> my_user<span class="sy0">.</span>id<span class="br0">&#41;</span> <span class="kw1">AS</span> id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- calculate a DN for each user</span>
    ucase<span class="br0">&#40;</span>concat<span class="br0">&#40;</span>
     <span class="st0">'uid='</span><span class="sy0">,</span> my_user<span class="sy0">.</span>username<span class="sy0">,</span> 
     <span class="st0">',ou=Users,ou=Junk,ou=AK,DC=mycompany,DC=com'</span>
    <span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> dn<span class="sy0">,</span> 
&nbsp;
    <span class="co1">-- the id of the inetOrgUser objectClass in ldap_entry_objclasses</span>
    <span class="nu0">1</span> <span class="kw1">AS</span> oc_map_id<span class="sy0">,</span>    
&nbsp;
    <span class="co1">-- zero for every row </span>
    <span class="co1">-- (see baseObject in the `slapd-sql` man page)</span>
    <span class="nu0">0</span> <span class="kw1">AS</span> parent<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- the real id in the user table</span>
    my_user<span class="sy0">.</span>id <span class="kw1">AS</span> keyval 
&nbsp;
  <span class="kw1">FROM</span>
    my_user 
&nbsp;
<span class="kw1">UNION</span> 
&nbsp;
  <span class="kw1">SELECT</span> 
    <span class="co1">-- a different id space</span>
    <span class="br0">&#40;</span><span class="nu0">200000</span> <span class="sy0">+</span> my_group<span class="sy0">.</span>id<span class="br0">&#41;</span> <span class="kw1">AS</span> id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- calculate a DN for each object in our group table </span>
    ucase<span class="br0">&#40;</span>concat<span class="br0">&#40;</span>
    <span class="st0">'cn='</span><span class="sy0">,</span>my_group<span class="sy0">.</span>name<span class="sy0">,</span>
     <span class="st0">',ou=Users,ou=Junk,ou=AK,DC=mycompany,DC=com'</span>
    <span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> dn
&nbsp;
    <span class="co1">-- the id of groupOfUniqueNames in ldap_entry_objclasses</span>
    <span class="nu0">2</span> <span class="kw1">AS</span>  oc_map_id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- like above</span>
    <span class="nu0">0</span> <span class="kw1">AS</span> parent<span class="sy0">,</span>
    my_group<span class="sy0">.</span>id <span class="kw1">AS</span> id 
&nbsp;
  <span class="kw1">FROM</span> 
    my_group</pre></div></div>


<h3>VII. Test and stuff</h3>

<h4>Launch the Slap daemon</h4>

<p>It&#8217;s nice to launch <var>slapd</var> in debug mode in one terminal.  This is pretty verbose and will hopefully tell you if you&#8217;ve got something wrong in your mapping tables or anything:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>slapd <span class="re5">-d</span> <span class="nu0">5</span></pre></div></div>


<h4>Test connectivity and data with an LDAP client</h4>

<p>Hint:  it would help to <strong>LEARN HOW TO USE <a href="http://linux.die.net/man/1/ldapsearch">ldapsearch</a> correctly.</strong></p>

<p>Connect anonymously and spit out all the LDAP data (if ACL allows it&#8211; by slapd.conf above allows anonymous connections but won&#8217;t show any of the data):</p>


<div class="wp_syntax"><div class="code"><pre class="bash">ldapsearch <span class="re5">-x</span> <span class="re5">-s</span> sub <span class="re5">-b</span> <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span> <span class="st0">&quot;(objectClass=*)&quot;</span></pre></div></div>


<p>Connect as root (the special account defined in slapd.conf) and show all the data in the directory:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">ldapsearch <span class="re5">-x</span> <span class="re5">-D</span> <span class="re2">uid</span>=root,<span class="re2">ou</span>=USERS,<span class="re2">OU</span>=JUNK,<span class="re2">OU</span>=AK,<span class="re2">DC</span>=MYCOMPANY,<span class="re2">DC</span>=COM <span class="re5">-w</span> xxxxxxxxx <span class="re5">-s</span> sub <span class="re5">-b</span> <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span> <span class="st0">&quot;(objectClass=*)&quot;</span></pre></div></div>


<p>Here&#8217;s an example of what it shows me:</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># extended LDIF
#
# LDAPv3
# base &lt;ou<span class="sy0">=</span><span class="re2">Junk,ou=AK,DC=mycompany,DC=com&gt; with scope subtree</span>
# filter: <span class="br0">&#40;</span>objectClass<span class="sy0">=</span><span class="re2">*<span class="br0">&#41;</span></span>
# requesting: ALL
#
&nbsp;
# Junk, AK, mycompany.com
dn: ou<span class="sy0">=</span><span class="re2">Junk,ou=AK,dc=mycompany,dc=com</span>
objectClass: extensibleObject
description: builtin baseObject for back-sql
description: all entries mapped in the <span class="st0">&quot;ldap_entries&quot;</span> table
description: must have <span class="st0">&quot;0&quot;</span> in the <span class="st0">&quot;parent&quot;</span> column
ou: Junk
&nbsp;
# TESTUSER, USERS, JUNK, AK, MYCOMPANY.COM
dn: uid<span class="sy0">=</span><span class="re2">TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: inetOrgPerson
cn: test user
ou: guest
sn: user
uid: testuser
givenName: test
userPassword:: dGVzdHBhc3M<span class="sy0">=</span>
&nbsp;
# <span class="nu0">1234567890</span>, USERS, JUNK, AK, MYCOMPANY.COM
dn: uid<span class="sy0">=</span><span class="re2">1234567890,ou=USERS,ou=JUNK,ou=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: inetOrgPerson
cn: test2 user2
ou: guest
sn: user2
uid: <span class="nu0">1234567890</span>
givenName: test2
userPassword:: MTIzNDU2Nzg5MA<span class="sy0">=</span><span class="re2">=</span>
&nbsp;
...
&nbsp;
# VALIDUSERS, GROUPS, JUNK, AK, MYCOMPANY.COM
dn: cn<span class="sy0">=</span><span class="re2">VALIDUSERS,ou=GROUPS,ou=JUNK,ou=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: groupOfUniqueNames
cn: validUsers
uniqueMember: uid<span class="sy0">=</span><span class="re2">1234567890,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
...
uniqueMember: uid<span class="sy0">=</span><span class="re2">TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
&nbsp;
# search result
search: <span class="nu0">2</span>
result: <span class="nu0">0</span> Success
&nbsp;
# numResponses: <span class="nu0">8</span>
# numEntries: <span class="nu0">7</span></pre></div></div>


<p>Connect as a valid user and ask for everything, but according to my ACLs the user can only see itself:
<pre>
ldapsearch -x -D uid=TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM -w testpass -s sub -b "ou=Junk,ou=AK,DC=mycompany,DC=com" "(objectClass=*)"
</pre></p>

<h4>Additional Considerations</h4>

<p><var>chkconfig</var> is the Red Hat tool for managing init scripts&#8211; here&#8217;s how to make sure the slapd starts at boot time.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> chkconfig <span class="re5">--add</span> ldap
$ <span class="kw2">sudo</span> chkconfig ldap on</pre></div></div>


<p>Ah, Mr. Flat Mountain reminds,</p>

<blockquote>
9) Ports for the Firewall

LDAP runs on port 389/tcp by default and LDAP over SSL is 636/tcp.
</blockquote>

<p>Securing communication between the LDAP client and OpenLDAP server with SSL/TLS is beyond my scope here, but it seems to be much better documented.</p>

<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

