<?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>Adam Young's Web Log</title>
	<atom:link href="http://adam.younglogic.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://adam.younglogic.com</link>
	<description>The Notebook of a Programmer Climber Musician Ex-Soldier</description>
	<lastBuildDate>Fri, 17 Feb 2012 22:03:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Working with Keystone Authenticate</title>
		<link>http://adam.younglogic.com/2012/02/working-with-keystone-authenticate/</link>
		<comments>http://adam.younglogic.com/2012/02/working-with-keystone-authenticate/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 22:03:07 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[Openstack]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1779</guid>
		<description><![CDATA[Here is a little utility I&#8217;ve worked up while working with the Openstack Keystone code. To extract the token out of the JSON, use the following pyton script #!/usr/bin/python from sys import stdin import json print json.load(stdin)['access']['token']['id'] Which I save in ~/bin/extract_keystone_id.py Here&#8217;s the Curl to fetch a token from Keystone, assuming you &#8216;ve loaded [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a little utility I&#8217;ve worked up while working with the Openstack Keystone code.</p>
<p><span id="more-1779"></span></p>
<p>To extract the token out of the JSON,  use the following pyton script</p>
<pre class="brush:python">
#!/usr/bin/python

from sys import stdin
import json
print json.load(stdin)['access']['token']['id']
</pre>
<p>Which I save in  ~/bin/extract_keystone_id.py</p>
<p>Here&#8217;s the Curl to fetch a token from  Keystone, assuming you &#8216;ve loaded up the sample data from the unit tests:</p>
<pre class="brush:bash">
curl -v   -H "Content-Type:application/json"  -s  -H "Accept:applicaton/json"  -d '{"auth":{"passwordCredentials":{"userId":"foo", "password":"foo2"} ,"tenantName":"bar"}}'   -X POST  http://0.0.0.0:35357/v2.0/tokens  | ~/bin/extract_keystone_id.py
</pre>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/working-with-keystone-authenticate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Openstack Keystone LDAP Redux</title>
		<link>http://adam.younglogic.com/2012/02/openstack-keystone-ldap-redux/</link>
		<comments>http://adam.younglogic.com/2012/02/openstack-keystone-ldap-redux/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 17:27:55 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Openstack]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1841</guid>
		<description><![CDATA[A recent change in the structure of the Openstack Keystone architecture resulted in the loss of support for an LDAP Backend. I&#8217;ve been working to rectify that.  Here&#8217;s my set up and the design decisions I&#8217;ve made so far.  Since this code is not yet submitted for code review,  there is a good chance that [...]]]></description>
			<content:encoded><![CDATA[<p>A recent change in the structure of the Openstack Keystone architecture resulted in the loss of support for an LDAP Backend. I&#8217;ve been working to rectify that.  Here&#8217;s my set up and the design decisions I&#8217;ve made so far.  Since this code is not yet submitted for code review,  there is a good chance that it will change prior to deployment.</p>
<p><span id="more-1841"></span></p>
<p>Users will be stored in a flat collection. <strong>ou=Users,$SUBTREE</strong> and be based on the standard LDAP objectClass <strong>inetOrgPerson</strong> which is defined in <em>/etc/openldap/schema/inetorgperson.ldif</em>. Currently, only two fields are used: <strong>cn</strong> and <strong>sn</strong>. <strong>cn</strong> is used for the bind call, and is the <strong>id</strong> field in the <strong>user</strong> object.</p>
<p>Tenants are in a collection that is a peer to Users. Tenants are instancs of the <strong>groupOfNames</strong> object class defined in /etc/openldap/schema/core.ldif. Tenant membership is indicated by the presence of the User&#8217;s <strong>DN</strong> in the tenant&#8217;s <strong>members</strong> attribute.</p>
<p>Roles are instances of the LDAP object class <strong>organizationalRole</strong> defined in <em>/etc/openldap/schema/core.ldif.</em> Role assignment is indicated by the presence of the User&#8217;s DN in the <strong>roleOccupant</strong> attribute.</p>
<p>Configuration of LDAP for the Keystone server is provided by the [LDAP] stanza in the appropriate keystone.conf file. Here are the supported values</p>
<ul>
<li>url</li>
<li>user</li>
<li>password</li>
<li>suffix</li>
<li>use_dumb_member</li>
<li>user_tree_dn</li>
<li>tenant_tree_dn</li>
<li>role_tree_dn</li>
</ul>
<p>And an example of what my config file looks like:</p>
<pre class=brush:plain">
[ldap]
url = ldap://localhost
tree_dn = dc=younglogic,dc=com
user_tree_dn = ou=Users,dc=younglogic,dc=com
role_tree_dn = ou=Roles,dc=younglogic,dc=com
tenant_tree_dn = ou=Groups,dc=younglogic,dc=com
user = dc=Manager,dc=younglogic,dc=com
password = freeipa4all
backend_entities = ['Tenant', 'User', 'UserRoleAssociation', 'Role']
suffix =cn=younglogic,cn=com

[identity]
driver = keystone.identity.backends.ldap.Identity
</pre>
<p>Not all of these fields need to be specified.  It is expected that the user will supply simply the <strong>suffix</strong> field,  and not override the values of <strong>user_tree_dn</strong>,<strong>role_tree_dn</strong>, or <strong>tenant_tree_dn</strong>.</p>
<p><strong>backend_entities</strong> is not currently honored.  It is expected that LDAP will instead either manage all of these or non e of them,  with token management handled by a different backend provider.</p>
<p><strong>use_dumb_member</strong> is still honored from the previous incarnation, but has not been tested, nor do I understand the intention of this code.</p>
<p>The unit tests for the LDAP code use a common code sournce with the other Identity management backends.  To run just the LDAP unit tests,  from the Keystone directory, run</p>
<pre class="brush:bash">
 python ./run_tests.py  test_backend_ldap
</pre>
<p>Additionally,  the unit tests can be run against a live OpenLDAP server by running.</p>
<pre class="brush:bash">
 python ./run_tests.py  _ldap_livetest
</pre>
<p>All tests pass successfully on my development machine as of this posting.</p>
<p>&nbsp;</p>
<p>I&#8217;m running Fedora 16, which supports OpenLDAP. Specifically I am running openldap-servers-2.4.26-5.fc16.x86_64. To start the service, run</p>
<pre class="brush:bash">sudo service slapd start</pre>
<p>To configure the server, I use a file I call manager.ldif:</p>
<pre class="brush:bash">dn:  olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=younglogic,dc=com
-
replace: olcRootDN
olcRootDN: dc=Manager,dc=younglogic,dc=com
-
add: olcRootPW
olcRootPW: {SSHA}lBDIdfwvZkITal0k9tdhiCUolxpf6anu</pre>
<p>You should modify the suffix for your organization.<br />
Execute the configuration with:</p>
<pre class="brush:bash"> sudo ldapmodify -Y EXTERNAL -H ldapi:///  -f ./manager.ldif</pre>
<p>And test that you can now do a simple bind to the localhost server.</p>
<pre class="brush:bash">ldapsearch -x -D "dc=Manager,dc=younglogic,dc=com" -H ldap://localhost  -w freeipa4all  -b ou=Groups,dc=younglogic,dc=com "(objectClass=*)"</pre>
<p>Now set up the subtree for Keystone. I use file I call org.ldif</p>
<pre class="brush:bash">dn: dc=younglogic,dc=com
dc: younglogic
objectClass: dcObject
objectClass: organizationalUnit
ou: younglogic

dn: ou=Groups,dc=younglogic,dc=com
objectClass: top
objectClass: organizationalUnit
ou: groups

dn: ou=Users,dc=younglogic,dc=com
objectClass: top
objectClass: organizationalUnit
ou: users

dn: ou=Roles,dc=younglogic,dc=com
objectClass: top
objectClass: organizationalUnit
ou: users</pre>
<p>Technically, the Roles ou is not required. My original thought was that this collection would contain the superset of roles possible for all of the Tenants. However, I have not implemented that.</p>
<p><a href="https://github.com/admiyo/keystone/tree/ldap3" title="Github LDAP" target="_blank">Current code is commited to Github</a>  I will update this link if I rebase the branch.</p>
<p>Update:  fixed typos in the config file segment.  user_tree_dn etc should start with ou, not cn.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/openstack-keystone-ldap-redux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Programmatic EXTERNAL SASL connection to OpenLDAP</title>
		<link>http://adam.younglogic.com/2012/02/exteranl-sasl/</link>
		<comments>http://adam.younglogic.com/2012/02/exteranl-sasl/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 16:30:27 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1811</guid>
		<description><![CDATA[The documentation on the OpenLDAP site discusses modifying the ldif files used to start up the server.  If you try to do this on a Fedora or Debian based install,  you will find that the server does not start up.  The HASH of the files is stored and compared with the contents at start up [...]]]></description>
			<content:encoded><![CDATA[<p>The documentation on the OpenLDAP site discusses modifying the ldif files used to start up the server.  If you try to do this on a Fedora or Debian based install,  you will find that the server does not start up.  The HASH of the files is stored and compared with the contents at start up time.  There is a better way.</p>
<p><span id="more-1811"></span></p>
<p>On my OpenLDAP install,  there are three databases served by SLAPD.  The first two  are for  configuration and  monitoring.  The third is the one that acts as the backing store for authentication and other data that is publicly served.  When the server starts up,  it is configured with a common name of   cn=example,cn=com,  which is obviously sample data.  To modify this,  requires changing the values in the config database.</p>
<p>Below is an ldif file that would change the Common name, as well as set the userid and password for managing the directory</p>
<pre class="brush:bash">dn:  olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=younglogic,dc=com
-
replace: olcRootDN
olcRootDN: dc=Manager,dc=younglogic,dc=com
-
add: olcRootPW
olcRootPW: {SSHA}lBDIdfwvZkITal0k9tdhiCUolxpf6anu</pre>
<p>I generated the HASH using the <strong>slappasswd</strong> command line tool.<br />
To modify the config, you then execute ldapmodify.</p>
<pre class="brush:bash">sudo ldapmodify -Y EXTERNAL -H ldapi:///  -f /home/ayoung/etc/managerbase.ldif</pre>
<p>What is this EXTERNAL? It is a SASL mechanism that uses the underlying system configured authentication. This is the NSS value that you would get back from getent. The default install protects the configuration database using the root credentials. The URL ldapi:/// is a Unix socket connection to /var/run/ldapi.</p>
<p>What happens if you want to modify the configuration pragmatically? The steps to make a SASL External connection are not to clear.  In order to figure out how to do it, I&#8217;ve started poking inside of the ldapmodify code from the openldap source. The CLI tools are under openldap/clients/tools/. The connection is created in the file common.c. From what I&#8217;ve seen elsewhere on the web, I know it needs to resolve to one of the ldap*bind calls. In my file, inside the function tool_bind, I see it on line 1469</p>
<pre class="brush:c">	rc = ldap_sasl_interactive_bind_s(
          ld, binddn, sasl_mech,
	   sctrlsp, NULL, sasl_flags, lutil_sasl_interact, defaults )</pre>
<p>Now, I&#8217;ve run this through ltrace and I&#8217;ve seen</p>
<pre class="brush:bash">ldap_sasl_interactive_bind_s(0x1abf290, 0, 0x1abf030, 0, 0</pre>
<p>So I know to expect binddn to be null, and sasl_mech needs to have a real value. Look in the argument parsing part of the code for the -Y flag tells that this is a pass through of the string passed on the command line.</p>
<pre class="brush:c">    case 'Y':
        /*error chcking ellided here*/
	sasl_mech = ber_strdup( optarg );</pre>
<p>So that should be the string EXTERNAL for our purposes.</p>
<p>The next two parameters are 0, sctrlsp and (surprise) NULL.</p>
<p>sasl_flags looks like it is set to the default in the top of the file and never modified in our code path:</p>
<pre class="brush:c">unsigned	sasl_flags = LDAP_SASL_AUTOMATIC;</pre>
<p>That leaves the last two parameters. One is a callback function <strong>lutil_sasl_interact</strong> and one is the <strong>defaults</strong> structure. The function lutil_sasl_interact is defined in the file openldap/libraries/liblutil/sasl.c. Between it and the function <strong>interaction</strong> which it calls, we are talking about 200 lines of code. For now, I am just going to cut and paste that code into my C file and get all of the headers coorect to run it. Later, I&#8217;ll step through it in the debugger to see what it is really doing.</p>
<p>The defaults structure is also defined in the sasl/c file specified above. From the ldap_bind man page:</p>
<blockquote><p>The interact function uses the provided defaults to handle requests from the SASL library for particular authentication parameters. There is no defined format for the defaults information; it is up to the caller to use whatever format is appropriate for the supplied interact function. The sasl_interact parameter comes from the underlying SASL library. When used with Cyrus SASL this is an array of sasl_interact_t structures. The Cyrus SASL library will prompt for a variety of inputs, including:&#8230;</p></blockquote>
<p>Again, I will cut and paste this code into my file and get it running. In order to compile I need to add the flags</p>
<pre class="brush:plain">CFLAGS=-lldap -llber -lsasl2 -g -I/usr/include/sasl</pre>
<p>Once I can compile and run, I can dump out the contents of the config directory. Stepping through the code I discover a few things. In the code that builds the defaults, the non-zero values are. defaults-&gt;authcid = &#8220;root&#8221; and defaults-&gt;mech &#8220;EXTERNAL&#8221;. When the function lutil_sasl_interact is called, the parameters are: The ldap structure from our init, flags=0, defaults, and in, which is cast to at sasl_interact_t. The only part of this that seems interesting to us is that it requests SASL_CB_USER from interact, which basically checks the user is root. The code then makes the most elegant use of a goto that I&#8217;ve seen in a long while, skips a whole load of interactive code, and returns the default:</p>
<pre class="brush:c">use_default:
		/* input must be empty */
		interact-&gt;result = (dflt &amp;&amp; *dflt) ? dflt : "";
		interact-&gt;len = strlen( interact-&gt;result )</pre>
<p>This says to me that the interaction callback function could be reduced to:</p>
<pre class="brush:c">int do_interact(
	LDAP *ld,
	unsigned flags,
	void *defaults,
	void *in )
{
	sasl_interact_t *interact = in;
	lutilSASLdefaults * sasl_defaults = (lutilSASLdefaults *)defaults;
	const char *dflt = interact-&gt;defresult;
	dflt = sasl_defaults-&gt;authzid;
	interact-&gt;result = (dflt &amp;&amp; *dflt) ? dflt : "";
	interact-&gt;len = strlen( interact-&gt;result );
	return LDAP_SUCCESS;
}</pre>
<p>But now I see that the defaults passed in are defined external to the ldap code. We can drop all of the pointers except the one to the authzid. In fact, we can just make this a char *.</p>
<p>Here&#8217;s the code in a functional state. It leaks memory, which would need to be cleaned up for a real application.</p>
<pre class="brush:c">

#include <sasl.h>
#include <ldap.h>
#include <stdio.h>

int do_interact(
		LDAP *ld,
		unsigned flags,
		void *defaults,
		void *in )
{
  sasl_interact_t *interact = in;
  char * sasl_defaults = (char  *)defaults;
  const char *dflt = interact-&gt;defresult;
  dflt = sasl_defaults;
  interact-&gt;result = (dflt &amp;&amp; *dflt) ? dflt : "";
  interact-&gt;len = strlen( interact-&gt;result );
  return LDAP_SUCCESS;
}

int main(){
  printf("Start\n");
  LDAP *ldap;
  int rc;
  struct berval *servercredp;
  unsigned long version = LDAP_VERSION3;
  LDAPMessage *res;
  char ** vals;
  int message_count;
  int i,j,k;

  if (( rc = ldap_initialize(&amp;ldap,  "ldapi:///")) != LDAP_SUCCESS)
    {
      perror ( NULL );
      return( 1 );
    }

  rc = ldap_set_option(ldap,
		       LDAP_OPT_PROTOCOL_VERSION,
		       (void*)&amp;version);
  char * defaults;
  char * sasl_mech = "EXTERNAL";
  char * sasl_realm = NULL;
  char * sasl_authc_id = NULL;
  char * sasl_authz_id = NULL;
  struct berval	passwd = { 0, NULL };
  unsigned	sasl_flags = LDAP_SASL_AUTOMATIC;
  LDAPControl	**sctrlsp = NULL;

  ldap_get_option( ldap, LDAP_OPT_X_SASL_AUTHZID, &amp;defaults );

  char *	binddn = NULL;
  rc = ldap_sasl_interactive_bind_s( ldap, binddn, sasl_mech,
				     sctrlsp,
				     NULL, sasl_flags, do_interact, defaults );

  if ((rc =  ldap_search_ext_s
       (
	ldap,
	"cn=config",
	LDAP_SCOPE_SUBTREE,
	"(objectClass=*)",
	NULL,
	0,
	NULL,
	NULL,
	NULL,
	0,
	&amp;res ) != LDAP_SUCCESS))
    {
      printf("ldap_search  failed with 0x%x.\n",rc);
      perror ( NULL );
      return( 1 );
    }
  LDAPMessage *entry = ldap_first_entry( ldap, res );

  int entry_count = ldap_count_entries(ldap, res);
  for (i = 0 ; i &lt; entry_count; i++){
    printf("dn: %s\n",ldap_get_dn(ldap, entry));
    BerElement * ber;
    char * attribute = ldap_first_attribute(ldap,entry, &amp;ber);
    while(attribute){
      printf ("attribute = %s\n",attribute);
      attribute = ldap_next_attribute(ldap,entry, ber);
    }
    ber_free(ber,0);
    entry = ldap_next_entry(ldap, entry);

  }
  return 0;

}</pre>
<p>Note: The reason I do SASL using a -I option in the makefile instead of sasl/sasl.h is that the code formatter is messing it up.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/exteranl-sasl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DNS Managers in FreeIPA</title>
		<link>http://adam.younglogic.com/2012/02/dns-managers-in-freeipa/</link>
		<comments>http://adam.younglogic.com/2012/02/dns-managers-in-freeipa/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 02:48:21 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[FreeIPA]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1753</guid>
		<description><![CDATA[The Domain Name System (DNS) is an essential part of systems management. If you need to manage multiple physical hosts you&#8217;d really benefit by a degree of control of some subset of DNS. With Virtual machines, the sheer number of hosts created demand a responsive DNS. Kerberos, X509 and other security mechanisms require a proper [...]]]></description>
			<content:encoded><![CDATA[<p>The Domain Name System (DNS) is an essential part of systems management. If you need to manage multiple physical hosts you&#8217;d really benefit by a degree of control of some subset of DNS. With Virtual machines, the sheer number of hosts created demand a responsive DNS. Kerberos, X509 and other security mechanisms require a proper DNS configuration. Yet, for many organizations, DNS is locked down by IT to a very static set of records. Earlier articles discussed <a title="User Group Managers" href="http://adam.younglogic.com/2012/02/group-managers-in-freeipa/" target="_blank">User Groups</a>, <a title="Hostgroup Managers" href="http://adam.younglogic.com/2012/02/hostgroup-managers-freeipa/" target="_blank">Host Groups</a>, and <a title="Netgroup Managers" href="http://adam.younglogic.com/2012/02/netgroup-managers-in-freeipa/" target="_blank">Netgroups</a>. The final installment in this series discsusses how to delegate DNS Zone management in FreeIPA.</p>
<p><span id="more-1753"></span></p>
<p>First, create a Zone for the project, and one DNS record</p>
<pre class="brush:bash">[root@f16server ~]# ipa dnszone-add beowulf.younglogic.com
Authoritative nameserver: f16server.ayoung.boston.devel.redhat.com
Administrator e-mail address [hostmaster.beowulf.younglogic.com.]:
Zone name: beowulf.younglogic.com
Authoritative nameserver: f16server.ayoung.boston.devel.redhat.com.
Administrator e-mail address: hostmaster.beowulf.younglogic.com.
SOA serial: 2012110201
SOA refresh: 3600
SOA retry: 900
SOA expire: 1209600
SOA minimum: 3600
Active zone: TRUE
Dynamic update: FALSE
[root@f16server ~]# ipa dnsrecord-add
Zone name: beowulf.younglogic.com
Record name: www1
[A record]: 10.10.2.1
[AAAA record]: feed:0123::babe
Record name: www1
A record: 10.10.2.1
AAAA record: feed:0123::babe</pre>
<p>Here&#8217;s the LDAP details of what we just created:</p>
<pre class="brush:bash">[root@f16server ~]# ipa dnszone-show beowulf.younglogic.com --all --raw
dn: idnsname=beowulf.younglogic.com,cn=dns,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
idnsname: beowulf.younglogic.com
idnssoamname: f16server.ayoung.boston.devel.redhat.com.
idnssoarname: hostmaster.beowulf.younglogic.com.
idnssoaserial: 2012110201
idnssoarefresh: 3600
idnssoaretry: 900
idnssoaexpire: 1209600
idnssoaminimum: 3600
idnszoneactive: TRUE
idnsallowdynupdate: FALSE
nsrecord: f16server.ayoung.boston.devel.redhat.com.
objectclass: top
objectclass: idnsrecord
objectclass: idnszone</pre>
<p>Notice that the A and AAAA records are not visible in the DNS Zone object. Since we are not just modifying values of attributes, we can&#8217;t perform the same type of delegation as we did with User Groups, Host Groups or Netgroups. Lets take a look at the LDAP details of the Record.</p>
<pre class="brush:bash">[root@f16server ~]# ipa dnsrecord-show beowulf.younglogic.com www1 --all --raw
dn: idnsname=www1,idnsname=beowulf.younglogic.com,cn=dns,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
idnsname: www1
arecord: 10.10.2.1
aaaarecord: feed:0123::babe
objectclass: top
objectclass: idnsrecord</pre>
<p>A and AAAA records that have the same <strong>idnsname</strong> go into the same LDAP object. PTR and CNAME records would all be put into additional attributes of this object if they, too, had the same idnsname. This LDAP object is a subordinate object to the Zone, beowulf.younglogic.com.</p>
<p>Thus, we can use the <strong>Subtree</strong> permission type to manage access to this resource. The subtree is the <strong>distinguished name</strong> (DN) of the DNS Zone.</p>
<pre class="brush:bash">[root@f16server ~]# ipa permission-add 'beowulf-dns-modify'  --permissions=add,delete
[Attributes]:
[Type]:
[Member of group]:
[Filter]:
[Subtree]: idnsname=beowulf.younglogic.com,cn=dns,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
[Target group]:
-------------------------------------
Added permission "beowulf-dns-modify"
-------------------------------------
  Permission name: beowulf-dns-modify
  Permissions: add, delete
  Subtree: ldap:///idnsname=beowulf.younglogic.com,cn=dns,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com</pre>
<p>We could use the <strong>objectname</strong> and <strong>cn</strong> as we did before, but  <strong>subtree</strong> is better documentation to our intent.</p>
<p>Again, we need to add the permission to the privilege.</p>
<pre class="brush:bash">[root@f16server ~]# ipa privilege-add-permission beowulf-manage --permission=beowulf-dns-modify
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project
  Permissions: beowulf-manage, beowulf-manage-group, beowulf-hostgroup-modify,
               beowulf-netgroup-modify, beowulf-dns-modify
  Granting privilege to roles: beowulf-managers
-----------------------------
Number of permissions added 1
-----------------------------</pre>
<p>Test it out with the <em>admiyo</em> account (that already has the Role beowulf-managers. This time, we&#8217;ll add both an A and AAAA record, which are managed by the same object in BINDs LDAP backend.</p>
<pre class="brush:bash">[root@f16server ~]# ipa privilege-add-permission beowulf-manage --permission=beowulf-dns-modify
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project
  Permissions: beowulf-manage, beowulf-manage-group, beowulf-hostgroup-modify,
               beowulf-netgroup-modify, beowulf-dns-modify
  Granting privilege to roles: beowulf-managers
-----------------------------
Number of permissions added 1
-----------------------------
[root@f16server ~]# kinit admiyo
Password for admiyo@F16SERVER.AYOUNG.BOSTON.DEVEL.REDHAT.COM:
[root@f16server ~]# ipa dnsrecord-add
Zone name: beowulf.younglogic.com
Record name: mail1
[A record]: 10.10.2.3
[AAAA record]: feed:babe:beef::cafe
  Record name: mail1
  A record: 10.10.2.3
  AAAA record: feed:babe:beef::cafe</pre>
<p>These four articles have attempted to show how the access controls of FreeIPA allow a system administrator to delegate specific actions to power users in their organization. From the simplest and most targeted of Target Groups, through simple and then more complex filter queries, then finally subtree queries. While FreeIPA can abstract you away from having to understand LDAP,  it does not prevent you from doing so.  Instead,  LDAP know how built on top of the structure provided with FreeIPA can help to craft secure and flexible delegation policy.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/dns-managers-in-freeipa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netgroup Managers in FreeIPA</title>
		<link>http://adam.younglogic.com/2012/02/netgroup-managers-in-freeipa/</link>
		<comments>http://adam.younglogic.com/2012/02/netgroup-managers-in-freeipa/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 19:40:01 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[FreeIPA]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1765</guid>
		<description><![CDATA[The last two articles described how to delegate management of user groups and host groups. The other way to manage both hosts and users in FreeIPA is with Netgroups. Although Netgroups are a concept from NIS, FreeIPA takes them to the next level, and makes them into containers capable of managing both users and groups. [...]]]></description>
			<content:encoded><![CDATA[<p>The last two articles described how to delegate management of <a href="http://adam.younglogic.com/2012/02/group-managers-in-freeipa/" title="User group Managers" target="_blank">user groups</a> and  <a href="http://adam.younglogic.com/2012/02/hostgroup-managers-freeipa/" title="Hostgroup Managers" target="_blank">host groups</a>.   The other way to manage both hosts and users in FreeIPA is with Netgroups.  Although Netgroups are a concept from NIS,  FreeIPA takes them to the next level,  and makes them into containers capable of managing both users and groups.  This article shows how to delegate the control of a netgroup to a specified user.<br />
<span id="more-1765"></span></p>
<p>First,  create a netgroup</p>
<pre class="brush:bash">
[root@f16server ~]# ipa netgroup-add
Netgroup name: beowulf-netgroup
Description: Beowulf Resources
---------------------------------
Added netgroup "beowulf-netgroup"
---------------------------------
  Netgroup name: beowulf-netgroup
  Description: Beowulf Resources
  NIS domain name: ayoung.boston.devel.redhat.com
  IPA unique ID: 71ea8d08-5530-11e1-9487-525400ff995b
</pre>
<p>To illustrate the differences between user groups, host groups, and netgroups,  lets add some elements to the netgroup.</p>
<pre class="brush:bash">
[root@f16server ~]# ipa netgroup-add-member beowulf-netgroup
[member user]: admiyo
[member group]: editors
[member host]: www1.ayoung.boston.devel.redhat.com
[member host group]: beowulf-hosts
[member netgroup]:
  Netgroup name: beowulf-netgroup
  Description: Beowulf Resources
  NIS domain name: ayoung.boston.devel.redhat.com
  Member User: admiyo
  Member Group: editors
  Member Host: www1.ayoung.boston.devel.redhat.com
  Member Hostgroup: beowulf-hosts
</pre>
<p>This shows the LDAP underpinning of the FreeIPA code.  Note where the entities are stored.</p>
<pre class="brush:bash">
[root@f16server ~]# ipa netgroup-show beowulf-netgroup --all --raw
  dn: ipauniqueid=71ea8d08-5530-11e1-9487-525400ff995b,cn=ng,cn=alt,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  cn: beowulf-netgroup
  description: Beowulf Resources
  nisdomainname: ayoung.boston.devel.redhat.com
  ipauniqueid: 71ea8d08-5530-11e1-9487-525400ff995b
  memberhost: fqdn=www1.ayoung.boston.devel.redhat.com,cn=computers,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  memberhost: cn=beowulf-hosts,cn=hostgroups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  memberuser: cn=editors,cn=groups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  memberuser: uid=admiyo,cn=users,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  objectclass: ipaobject
  objectclass: ipaassociation
  objectclass: ipanisnetgroup
</pre>
<p>Note that both users and user groups are in the <strong>memberuser</strong> field,  where as hosts and host groups are in the <strong>memberhost</strong> field.</p>
<p>So to be able to modify the netgroup,  the user needs permissions to the memberuser and memberhost  attributes.  For the objectclass,  specify  <strong>ipanisnetgroup</strong>. </p>
<p>Before moving on I deleted these members,  as I want to use them again later on for testing.</p>
<pre class="brush:bash">
[root@f16server ~]# ipa permission-add 'beowulf-netgroup-modify'  --permissions=write --attrs=memberhost,memberuser  --filter='(&#038;(cn=beowulf-netgroup)(objectclass=ipanisnetgroup ))'
------------------------------------------
Added permission "beowulf-netgroup-modify"
------------------------------------------
  Permission name: beowulf-netgroup-modify
  Permissions: write
  Attributes: memberhost, memberuser
  Filter: (&#038;(cn=beowulf-netgroup)(objectclass=ipanisnetgroup ))

[root@f16server ~]# ipa privilege-add-permission beowulf-manage --permission=beowulf-netgroup-modify
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project
  Permissions: beowulf-manage, beowulf-manage-group, beowulf-hostgroup-modify,
               beowulf-netgroup-modify
  Granting privilege to roles: beowulf-managers
-----------------------------
Number of permissions added 1
-----------------------------
</pre>
<p>Finally, to test.</p>
<pre class="brush:bash">

[root@f16server ~]# kinit admiyo
Password for admiyo@F16SERVER.AYOUNG.BOSTON.DEVEL.REDHAT.COM:
[root@f16server ~]# ipa netgroup-add-member beowulf-netgroup --hosts www1.ayoung.boston.devel.redhat.com --users admiyo
  Netgroup name: beowulf-netgroup
  Description: Beowulf Resources
  NIS domain name: ayoung.boston.devel.redhat.com
  Member User: admiyo
  Member Group: editors
  Member Host: www1.ayoung.boston.devel.redhat.com
  Member Hostgroup: beowulf-hosts
-------------------------
Number of members added 2
-------------------------
[root@f16server ~]# ipa netgroup-remove-member beowulf-netgroup --hosts www1.ayoung.boston.devel.redhat.com --users admiyo
  Netgroup name: beowulf-netgroup
  Description: Beowulf Resources
  NIS domain name: ayoung.boston.devel.redhat.com
  Member Group: editors
  Member Hostgroup: beowulf-hosts
---------------------------
Number of members removed 2
---------------------------
</pre>
<p>Again, I deleted the  elements that I added as admin before.  If you add the same entry twice,  you will get errors.  You can delete them as the delegated user as well as add them.</p>
<p>Since Netgroups can be used pretty much anywhere that user groups and hostgroups can be used (SUDO, and HBAC especially)  they are likely to become your first point of contact for management.  Like user groups and hosts groups,  they both provide nesting.  In fact, a netgroup can be nested inside a host group or a user group, and elements will gain membership in the corresponding host groups or user groups.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/netgroup-managers-in-freeipa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hostgroup Managers in FreeIPA</title>
		<link>http://adam.younglogic.com/2012/02/hostgroup-managers-freeipa/</link>
		<comments>http://adam.younglogic.com/2012/02/hostgroup-managers-freeipa/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 01:54:09 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1768</guid>
		<description><![CDATA[Last article I discussed delegating the authority to manage group membership using FreeIPA. A related topic delegating the ability to manage groups of hosts. There are two different collections for managing hosts: host groups, and netgroups. The approach to delegating authority for managing each of these is similar, but with important differences. First up: hostgroups. [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Group Managers in Freeipa" href="http://adam.younglogic.com/2012/02/group-managers-in-freeipa/" target="_blank">Last article</a> I discussed delegating the authority to manage group membership using FreeIPA. A related topic delegating the ability to manage groups of hosts. There are two different collections for managing hosts: host groups, and netgroups. The approach to delegating authority for managing each of these is similar, but with important differences. First up: hostgroups.<br />
<span id="more-1768"></span><br />
To create a hostgroup for Beowulf hosts:</p>
<pre class="brush:bash">[root@f16server ~]# ipa hostgroup-add beowulf-hosts
Description: Hosts for the Beowulf project
-------------------------------
Added hostgroup "beowulf-hosts"
-------------------------------
  Host-group: beowulf-hosts
  Description: Hosts for the Beowulf project</pre>
<p>Unlike the user groups, there is no preset form of ACI Permission for specifying a host group. Instead, we will have to specify the LDAP object that we wish to grant permission on. Again, it will be on the &#8220;member&#8221; attribute. Lets look at what we just created. To Look at the underlying LDAP object of something in FreeIPA, we use the entity-show command coupled with the &#8211;raw and &#8211;all flags</p>
<pre class="brush:bash">[root@f16server ~]# ipa hostgroup-show beowulf-hosts --all --raw
  dn: cn=beowulf-hosts,cn=hostgroups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  cn: beowulf-hosts
  description: Hosts for the Beowulf project
  ipauniqueid: 70999114-5513-11e1-bde4-525400ff995b
  mepmanagedentry: cn=beowulf-hosts,cn=ng,cn=alt,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  objectclass: ipaobject
  objectclass: ipahostgroup
  objectclass: nestedGroup
  objectclass: groupOfNames
  objectclass: top
  objectclass: mepOriginEntry</pre>
<p>In order to specify this object, we will use the combination of the objectclass an a uniqu identifier. The best unique ID is the text value of the host group name, held in the common name field: cn: beowulf-hosts. THe appropriate objectclass is ipahostgroup, as that is the only one that indicates this is a group of hosts, all of the other objectclasses can potentially be used for other things. Here&#8217;s what creating the ACI Permission looks like (to include adding it to the privilge).</p>
<pre class="brush:bash">
[root@f16server ~]# ipa permission-add 'beowulf-hostgroup-modify'  --permissions=write --attrs=member  --filter='(&amp;(cn=beowulf-hosts)(objectclass=ipahostgroup ))'
-------------------------------------------
Added permission "beowulf-hostgroup-modify"
-------------------------------------------
  Permission name: beowulf-hostgroup-modify
  Permissions: write
  Attributes: member
  Filter: (&amp;(cn=beowulf-hosts)(objectclass=ipahostgroup ))
[root@f16server ~]# ipa privilege-add-permission beowulf-manage --permission=beowulf-hostgroup-modify
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project
  Permissions: beowulf-manage, beowulf-manage-group, beowulf-dns-manage,
               beowulf-hostgroup-modify
  Granting privilege to roles: beowulf-managers
-----------------------------
Number of permissions added 1
-----------------------------</pre>
<p>Since the user admiyo already has a role that contains this privilege, that user should now be able to manage adding and removing hosts from that host group.</p>
<pre class="brush:bash">
[root@f16server ~]# kinit admiyo
Password for admiyo@F16SERVER.AYOUNG.BOSTON.DEVEL.REDHAT.COM:
[root@f16server ~]# ipa hostgroup-add-member beowulf-hosts --hosts www1.ayoung.boston.devel.redhat.com
  Host-group: beowulf-hosts
  Description: Hosts for the Beowulf project
  Member hosts: www1.ayoung.boston.devel.redhat.com
-------------------------
Number of members added 1
-------------------------</pre>
<p>It took me a few tries to get the filter correct for this one. Note that the operators are prefix. Some filters will get through the CLI fine, but won&#8217;t select the object you want. To confirm that you do have the right object, I recommend using ldapsearch to get the query right before adding the permission.</p>
<pre class="brush:bash">
[root@f16server ~]#  ldapsearch -x -b "dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com" "(&amp;( cn=beowulf-hosts)(objectclass=ipahostgroup))"
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (&amp;( cn=beowulf-hosts)(objectclass=ipahostgroup))
# requesting: ALL
#

# beowulf-hosts, hostgroups, accounts, f16server.ayoung.boston.devel.redhat.com
dn: cn=beowulf-hosts,cn=hostgroups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
objectClass: ipaobject
objectClass: ipahostgroup
objectClass: nestedGroup
objectClass: groupOfNames
objectClass: top
objectClass: mepOriginEntry
cn: beowulf-hosts
description: Hosts for the Beowulf project
ipaUniqueID: 70999114-5513-11e1-bde4-525400ff995b
mepManagedEntry: cn=beowulf-hosts,cn=ng,cn=alt,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
member: fqdn=www1.ayoung.boston.devel.redhat.com,cn=computers,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1</pre>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/hostgroup-managers-freeipa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Group Managers in FreeIPA</title>
		<link>http://adam.younglogic.com/2012/02/group-managers-in-freeipa/</link>
		<comments>http://adam.younglogic.com/2012/02/group-managers-in-freeipa/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 03:20:17 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[FreeIPA]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1739</guid>
		<description><![CDATA[The power of a hierarchical database lies in its access controls. FreeIPA gives you a set of tools that you can use in order to delegate authority using those access controls. Here&#8217;s an example.  Let say you are running a web site where people can create projects.  In order to create a project,  you send [...]]]></description>
			<content:encoded><![CDATA[<p>The power of a hierarchical database lies in its access controls. FreeIPA gives you a set of tools that you can use in order to delegate authority using those access controls.<span id="more-1739"></span></p>
<p>Here&#8217;s an example.  Let say you are running a web site where people can create projects.  In order to create a project,  you send in a ticket to  request the project creation.  Once that project has been created,  people ask you to join their projects.  Once the project is created,  as the project lead,  you can add and remove people from the project,  but they have to be in the system.</p>
<p>Yes,  I know,  very theoretical,  where would we ever see an organization like that?</p>
<p>A user named admiyo requests a project for people interested in Beowulf projects.  The IPA Admin creates it. In addition,  the admin has to create a Role, a Privilege, and a Permission  that will allow the user to manage that group,  assign the Permission to the Privilege and the Privilege to the Role.  Finally,  the Admin has to assign that role to the user admiyo.</p>
<pre class="brush:bash">[root@f16server ~]# ipa group-add beowulf --desc "Imagine a Beowulf Cluster...."
---------------------
Added group "beowulf"
---------------------
  Group name: beowulf
  Description: Imagine a Beowulf Cluster....
  GID: 500400007
[root@f16server ~]# ipa role-add
Role name: beowulf-managers
Description: Manage the Assets of the Beowulf project
-----------------------------
Added role "beowulf-managers"
-----------------------------
  Role name: beowulf-managers
  Description: Manage the Assets of the Beowulf project
[root@f16server ~]# ipa privilege-add
Privilege name: beowulf-manage
Description: Manage the Assets of the Beowulf project
--------------------------------
Added privilege "beowulf-manage"
--------------------------------
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project</pre>
<p>For user groups, the simplest way to create the permission is to user the targetgroup keyword.</p>
<pre class="brush:bash">[root@f16server ~]# ipa permission-add 'beowulf-manage-group' --targetgroup=beowulf --permissions=write --attrs=member
---------------------------------------
Added permission "beowulf-manage-group"
---------------------------------------
  Permission name: beowulf-manage-group
  Permissions: write
  Attributes: member
  Target group: beowulf</pre>
<p>Now the assignments:</p>
<pre class="brush:bash">[root@f16server ~]# ipa role-add-privilege Role name: beowulf-managers
[privilege]: beowulf-manage
  Role name: beowulf-managers
  Description: Manage the Assets of the Beowulf project
  Privileges: beowulf-manage
----------------------------
Number of privileges added 1
----------------------------
[root@f16server ~]# ipa privilege-add-permission Privilege name: beowulf-manage
[permission]: beowulf-manage-group
  Privilege name: beowulf-manage
  Description: Manage the Assets of the Beowulf project
  Permissions: beowulf-manage, beowulf-manage-group
  Granting privilege to roles: beowulf-managers
-----------------------------
Number of permissions added 1
-----------------------------
[root@f16server ~]# ipa role-add-member
Role name: beowulf-managers
[member user]: admiyo
[member group]:
[member host]:
[member host group]:
  Role name: beowulf-managers
  Description: Manage the Assets of the Beowulf project
  Member users: admiyo
  Privileges: beowulf-manage
-------------------------
Number of members added 1
-------------------------</pre>
<p>I&#8217;d like to point out that I had very little idea what the CLI was going to ask for on these. I just trusted it to walk me through, and it did. The one exception was the creation of the permission,  as it doesn&#8217;t prompt for the &#8211;attrs field</p>
<p>Now to test it out.</p>
<pre class="brush:bash">[root@f16server ~]# kinit admiyo
Password for admiyo@F16SERVER.AYOUNG.BOSTON.DEVEL.REDHAT.COM:
[root@f16server ~]# ipa group-add-member
Group name: beowulf
[member user]: kfrog
[member group]:
  Group name: beowulf
  Description: Imagine a Beowulf Cluster....
  GID: 500400007
  Member users: kfrog
-------------------------
Number of members added 1
-------------------------</pre>
<p>This same technique can be used with the other entities in FreeIPA. In the future, I&#8217;ll show how to do delegation for Host Groups and Netgroups. In theory, delegation of a DNS domain can be done the same way, but I haven&#8217;t worked through that yet.</p>
<p>This process can and should be streamlined (I&#8217;ve already submitted a ticket for that)  but could be fairly easily scripted, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/group-managers-in-freeipa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A second Kerberos Realm</title>
		<link>http://adam.younglogic.com/2012/02/a-second-kerberos-realm/</link>
		<comments>http://adam.younglogic.com/2012/02/a-second-kerberos-realm/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 20:14:32 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[FreeIPA]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1737</guid>
		<description><![CDATA[With the release of KRB5 1.10 A Kerberos workstation can finally have two different TGTs from two different KDCs active at the same time. Until this technology makes it into the major distributions, we are stuck with the limitation of the browser only knowing about one TGT/KDC/Realm at a time.  If you find yourself needing [...]]]></description>
			<content:encoded><![CDATA[<p>With the release of KRB5 1.10 A Kerberos workstation can finally have two different TGTs from two different KDCs active at the same time. Until this technology makes it into the major distributions, we are stuck with the limitation of the browser only knowing about one TGT/KDC/Realm at a time.  If you find yourself needing to talk to a second KDC without disrupting your primary,  here are the steps you can take.</p>
<p><span id="more-1737"></span></p>
<ol>
<li>Start firefox as you normally would.</li>
<li>Open up a command line prompt</li>
<li>Get the Kerberos Configuration file for the new server.  This can be done by copying the new KDC&#8217;s  /etc/krb5.conf to a local file.  For this example  ~/etc/krb5-105.conf Set an environment variable pointing to the new file: export KRB5_CONFIG=/home/ayoung/etc/krb5-105.conf</li>
<li>decide on a location for a second Kerberos Credential cache and set an environment variable to point to it:  export KRB5CCNAME=/home/ayoung/etc/krb5cc</li>
<li>kinit to the new location. echo secretpassword | kinit admin</li>
<li>Run firefox from the command line but using a new profile and not talking to the original instance:  firefox &#8211;no-remote -P</li>
<li>Point the new firefox instance at a web page that is part of the new Kerberos Realm.</li>
</ol>
<p>&nbsp;</p>
<p>When you are done, make sure you shut down the new firefox instance prior to shutting down your default one, or Firefox will reassign your profiel on next start up to be the newly created profile as opposed to your default.</p>
<p>Once The new Kerberos release is available,  I&#8217;ll show how to avoid having to do all of the extra steps.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/02/a-second-kerberos-realm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cloud Narrative</title>
		<link>http://adam.younglogic.com/2012/01/cloud-narrative/</link>
		<comments>http://adam.younglogic.com/2012/01/cloud-narrative/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 17:45:42 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1729</guid>
		<description><![CDATA[Identity Management (IdM) needs change as an organization grows in size. For an example, I&#8217;ll describe a fictional company, and take it from the smallest to largest stages. While, to some degree, the industry of this firm really doesn&#8217;t matter, I am going to use a small import business started by a single individual and [...]]]></description>
			<content:encoded><![CDATA[<p>Identity Management (IdM) needs change as an organization grows in size. For an example, I&#8217;ll describe a fictional company, and take it from the smallest to largest stages. While, to some degree, the industry of this firm really doesn&#8217;t matter, I am going to use a small import business started by a single individual and scale it up to a multinational corporation. As the organization grows in size, the technical needs will drive the scope and scale of the identity management solutions required.<br />
(This is my writing Cross posted from the FreeIPA wiki)</p>
<p><span id="more-1729"></span></p>
<h2>Scenario</h2>
<p>Ms. N. Zappa has just come back from a masters degree program in Jakarta. While living in Indonesia, she established connections with several furniture producers, and she starts a small import/export business in the Boston area. She has contacts at a handful of stores already from previous experience. She moves back in with her folks, who have agreed that she can use a section of the garage for storage, and she outsources all technical issues to a small web services firm. They register the domain name ZappasImports.com for her, set up an account a large cloud provider who provide web and email services. Her information management needs are for tracking orders, suppliers, and customers, which she keeps in a set of spreadsheets that she backs up to the cloud on a nightly basis.</p>
<p>When there is just one person in Zappas, the IdM needs are purely between N Zappa and the cloud provider. Her Internet services contractor has set up an account with the Cloud provider. The Zappa account has two users associated with it: nzappa and the contractor. This authentication is done against the Cloud Providers Authentication Database.</p>
<h2>Initial Setup</h2>
<p>The contractor sets up three applications for Zappas. A static web server, remote backups, and email. The email server is a managed service, and runs on the same email server as many of the other clients of the Cloud Provider. At this point, the Cloud provider is really just an Internet Service Provider. The website has a simple WebDAV interface and runs as a virtual host on shared web server. Remote backups are done via WebDAV. The Cloud provider manages all these services in order to scale up the number of customers it can handle without overloading its own infrastructure. Because the web applications are run on shared servers, they are responsive. If the overall load increases, the Cloud provider can scale up by allocating more virtual machines.</p>
<h2>Contractor with multiple Clients</h2>
<p>Zappas is not the only company the web services company manages. They have a portfolio of customers. The cloud deployment approach matches their development methods and skill set. They do not want to have a separate account with the cloud provider for each of their clients. Instead, the user accounts are associated with the client accounts. In addition, the web services firm is itself a client of the cloud provider, with systems that are somewhat comparable to those that they are setting up for Zappas.</p>
<h2>Initial Growth</h2>
<p>There are two potential next steps. One is that the company adds personnel. The other is when Zappas wants to start tracking and authenticating people outside of her company. These are two fairly different directions. They can happen in either order. Lets look at the external issue first.</p>
<h2>External Identity Management</h2>
<p>After a few months of operations, she realizes that she is having a much lower rate of return customers than she anticipated. She wants to communicate better with the people that have bought from here before to encourage repeat business, as well as to gauge the relative degree of satisfaction her customers have had with their purchases.</p>
<p>Zappa&#8217;s sets up a single external application, a customer order portal. This runs on a dedicated virtual machine, and uses a software package that the cloud provider has pre-canned. It uses an internal database, either PostgreSQL or MySQL with a table for user accounts. Authentication is done via Basic-Auth. The system is accessed via Web over SSL. This requires that the Web server have a publicly routed static IP address. The Cloud Provider runs a certificate authority, and issues a certificate for the web service to Zappa&#8217;s Imports. The Customer database is pre-populated with email addresses from a spreadsheet. Passwords are set to expired, which allows the users to reset them using their email addresses as verification. She emails her customers about the system and they start using it.</p>
<p>She also starts a blog, to describe the process she goes through to find new furniture, to explain the history behind some of the more interesting designs, and to introduce people to the culture of Indonesia. Again, this starts off as a managed service by the Cloud service provider: a WordPress instance with another dedicated back-end database. At first she enables public commenting, but the high degree of spam dictates that she somehow authenticate the comments. Instead, she decides that the appropriate thing for her business is to limit comments to people that have either purchased or are thinking of purchasing furniture from her. She could choose to use OpenID or a different Web Single Sign on solution, but that provides her no way to cross reference posts with her customer database. She wants to integrate the two systems. She also is not really happy with the order tracking system, and thinks she might want to switch to a different software package. While all three software packages she has been looking at provide embedded Identity management, they are all incompatible with one another. However, all of them support external authentication. She decides to extract the IdM out into a dedicated system in order to federate her customer focused applications more easily.</p>
<h2>Internal Identity Management</h2>
<p>Her business grows and she gets an office manager. She rents space at a local warehouse and a small office nearby. They set up accounts with a handful of delivery companies and need to be able to integrate the tracking of packages. The international nature of the business dictates that they get an account that specializes in international trade. Zappas has sufficient business going direct to end consumers that they set up a web catalog and order placement system. This dictates that they have a content management system, and that they establish a relationship with professional photographers in the remote countries that can supply their catalog with high quality images. They have a handful of contractors on retainer that can deliver and assemble some of the more complex pieces. The organization grows a little further. The company is producing enough revenue that she has a full time sales manager. During the busy season, she also hires seasonal help.</p>
<p>When Zappas hires her first employee, she needs to set up a new email account. This is likely done in the Cloud provider&#8217;s IdM system. She also needs to add the new employees desktop to the back up system. While the new employee is nominally an office manager, in practical terms she is helping with all aspects of the business, which means she needs to be able to perform administrative activities on the systems hosted in the cloud. The IdM solution they&#8217;ve chose supports this by adding the user to a group specific to each of the applications.<br />
Analysis</p>
<p>&#8220;There is nothing more practical than a good theory.&#8221; &#8211;Kurt Lewin</p>
<p>There are patterns that show up in all implementations of IdM systems. Recognizing them will help in implementation of future systems.</p>
<h2>Delegation</h2>
<p>Her organization may look simple, but Zappa&#8217;s Imports has most of the identity management needs of a large organization. She has distinct external contacts that she needs to segregate from each other. Each has a different set of permissible activities based on role. , but there are certain activities that the partners can do that the the office manager can&#8217;t. With the addition of the sales manager the organization has grown to the point that she can (and must) delegate management responsibilities: this is the critical point for an identity management system. The sales manager needs to be able to hire a temporary worker, give that worker limited access, and then revoke it after the busy period. Perhaps the temp can take orders, but is not allowed to handle returns. In addition, the sales manager needs to be able to schedule and track a contractor that is heading to a customer site to do an assembly.</p>
<p>The IdM system manages three types of relationships. First, it manages the relationship between The cloud provider and Zappa&#8217;s imports. Second, it manages relationships between the Zappa&#8217;s imports employees. Finally, it manages the relationships between Zappa&#8217;s Imports and the people that do business with Zappa&#8217;s. From Zappa&#8217;s perspective, adding a new application and adding an additional employee are related tasks. At first, both are handled by Ms. Zappa. By the end, are performed by employees who have been delegated the authority to perform these tasks.</p>
<h2>Ownership</h2>
<p>Probably the largest question in cloud IdM integration is who owns the information. The Zappas customer list and suppliers list are probably the most valuable assets of the company. If the cloud provider wants to maintain its own customers, they need to provide sufficient reason to trust their Id solution. On the other hand, they need to protect their own assets. In their organization, Ms. Zappa is a client, and she can add and remove servers based on her contract and quality of service agreement with the cloud provider. As the organization grows, this is certainly one of the actions she will want to delegate to the CTO, who will later delegate it to the Operations Manager when Zappa&#8217;s Imports grows to the size to hire one.<br />
Avoiding Lock In</p>
<p>Although companies like Zappa&#8217;s are not going to be jumping from one cloud provider to another each week, they still want to avoid vendor lock in. Zappa&#8217;s applications should have no dependencies on elements internal to the cloud provider that cannot be redirected to a different cloud provider. This is going to be more and more important as the company scales up. A Cloud provider can prove to be a poor fit for an organization for multiple reasons, and not all of those can be foreseen upfront. In the case of Zappa&#8217;s, technology is an enabler for business, but it is not the company&#8217;s forte. By contracting with a decent internet services firm, she has offloaded some of the decisions. She shouldn&#8217;t be locked in indefinitely to a technology decision made today that is secondary to the core of the business.</p>
<p>It is helpful to think of the federation of Identity Management systems as single solutions, with carefully specified integration points between the component parts. By having two systems, you firewall off one segment of your users from another. However, it is worth noting that there are a couple issues this does not address. If there are two systems, and one is deemed canonical, and information is pushed from one to the other, they are acting as a single system, and thus the potential for elevation of privileges is still there.</p>
<h2>Enterprise</h2>
<p>A few years down the road, Zappa&#8217;s is doing well, and has grown to a middle sized companies. N Zappa maintains her role as CEO and President, but is completely out of the software side of the company. Dealing with the relationships essential to her business must be supported by technology, not derailed by the management of technology. Zappa&#8217;s has all of the major subdivisions that one would expect to see in a middle sized company. Marketing and Sales are now distinct operations. Operations has a full time call center as well as full time employees for deliveries that require assembly. IT has also grown to support the needs of the organization. On the supply side, several employees have been hired in remote offices to handle the purchasing in several countries. The full time Human Resources manager has contracted to a small number of staffing firms for filling the variations the yearly cycle.</p>
<h2>Techno Mix</h2>
<p>The information systems are now a mix of in-house, application service provider, and cloud hosted applications. Zappa&#8217;s works mainly with two cloud providers that offer differentiated offerings due to geographic location and international issues. Applications for supply, foreign tax and travel, and shipping are hosted in a company in Jakarta. The eCommerce web site and partner Business-to-Business portal is hosted stateside. Zappa&#8217;s has consolidated IdM in-house, and shares a subset of its user database with the various technology partners.</p>
<p>The load on the cloud providers systems has scaled up with the company. When orders were measured in single-digits per day, billing was likely at a flat rate. At scale, the daily variations and fluctuation are significant. Auditing the systems becomes a requirement for legal and financial reasons. Different portions of Zappa&#8217;s have different budgets, and pay for the usage of the cloud out of separate accounts.</p>
<h2>Authentication Tokens</h2>
<p>For authentication of employees, Zappa&#8217;s has moved from a userid/password model to a cryptographically secure system, based on technologies like Kerberos, hardware tokens, smart-cards and so forth. Different systems require the ability to accept different authentication mechanisms: the corporate blog needs a HW token in order to post an article, but allow OpenID authentication for a customer to post a follow up comment. Some of the suppliers and partners have advanced technologically as well, and have their own authentication systems that they want to use when performing business with Zappa&#8217;s. The wide number of web sites in use have dictated a single sign on solution that needs to span across the public internet, and that works around the fact that some of the sites only allow network traffic on ports 443 and 80.</p>
<p>By this point, a standardized mechanism for managing the IdM across all of these systems has become essential. Adding in a new application cannot force changes to the schema. Each additional application cannot silo its own user database. Centralized management is a must; replication to remote sites must be rapid. Elevation of privileges is a major risk and the IdM must have rock solid protections built in against it.</p>
<p>The cloud provider is an integral partner to Zappas. It has to provide seamless integration of Identity Management. Trust and audit are two sides of the same issue: Zappas needs to know what is going on at the Cloud provider. Access to the systems running as virtual machines in the cloud has to be tightly managed. At the same time, the cloud provider finds it self in the same relationship with many other companies, some of which are competitors to Zappos. For legal and financial reasons, the cloud providers needs to provide segregation between its clients. The number of clients it is managing means that the system has to work completely automated.</p>
<h2>Conclusion</h2>
<p>This narrative has attempted to put the scale and scope of identity management issues in a cloud deployment into to perspective. The fictional company matches the needs of many real companies, as well as many non-corporate entities. The scope of the identity management solutions vary with the scope of the problem or number of problems that they attempt to solve. As our fictional company grew, its needs changed, as did the corresponding Identity Management Solution. The ability to tune the software packages that your company uses will help determine how quickly the company can react to new business opportunities or deal with set backs. A larger organization has more contact points, more needs, and thus cannot as easily rewrite the configuration of their applications to deal with a different IdM solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/01/cloud-narrative/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Please don&#8217;t title  your post  &#8220;Conference Update&#8221;</title>
		<link>http://adam.younglogic.com/2012/01/please-dont-title-your-post-conference-update/</link>
		<comments>http://adam.younglogic.com/2012/01/please-dont-title-your-post-conference-update/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 17:15:42 +0000</pubDate>
		<dc:creator>Adam Young</dc:creator>
				<category><![CDATA[Metablog]]></category>

		<guid isPermaLink="false">http://adam.younglogic.com/?p=1713</guid>
		<description><![CDATA[Everyone at FUDcon posts a FUDcon update. Everyone at OLS posts and OLS update. They come in massive blocks, and I personally can&#8217;t process them all. Adam doesn&#8217;t scale. Instead, please post a shorter post with the crucial piece or pieces that you&#8217;ve learned, and title it that way. You can mention that you learned [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone at FUDcon posts a FUDcon update.  Everyone at OLS posts and OLS update.  They come in massive blocks, and I personally can&#8217;t process them all.  Adam doesn&#8217;t scale.  Instead, please post a shorter post with the crucial piece or pieces that you&#8217;ve learned, and title it that way.  You can mention that you learned it at Fudcon,  but please provide a better orienting title to you post.  I do really want to read them.  Since I can&#8217;t make it to all the conferences,  I count on you,  the community, to provide a filter.</p>
]]></content:encoded>
			<wfw:commentRss>http://adam.younglogic.com/2012/01/please-dont-title-your-post-conference-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

